Files
AXP-Resurection/vendor/sunfish-a16/magisk/apply_releasetools_hook.py
sunfish-admin deaaf42caa 009: Magisk ship pack through US-S5-1 + US-S4 OpenSSH/Jelly/Gallery2.
Release-keys/AVB, CVE clean+hi batches, Yama/slabrand, Pro branding,
bundled apps, and AXP-class product surface docs/scripts.
2026-10-05 10:42:00 +02:00

150 lines
5.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""Idempotent Magisk preroot hook into releasetools common.py (LOS 23.2 / A16).
Gate (either is enough):
- ``out/.magisk/READY`` present (preferred — survives ninja/soong env scrubbing)
- ``SUNFISH_A16_MAGISK_PREROOT=1``
Matches sfX extendrom inject (always-on once staged), adapted for A16 + our
vendor path. ``RunAndCheckOutput`` env is merged with ``os.environ`` so PATH /
ANDROID_BUILD_TOP survive (extendrom only passed ``system_root_image``; that
works via shebang but is fragile under sandboxes).
"""
from __future__ import annotations
import argparse
import os
import pathlib
import re
import sys
MARKER = "SUNFISH_A16: Magisk preroot hook"
MARKER_VER = "SUNFISH_A16: Magisk preroot hook v2"
BUILD_HOOK = '''
# SUNFISH_A16: Magisk preroot hook v2 (before AVB)
# Gate: staged out/.magisk/READY and/or SUNFISH_A16_MAGISK_PREROOT=1
_sf_top = os.getenv("ANDROID_BUILD_TOP") or os.environ.get("PWD") or os.getcwd()
_sf_ready = os.path.isfile(os.path.join(_sf_top, "out", ".magisk", "READY"))
_sf_env = os.environ.get("SUNFISH_A16_MAGISK_PREROOT") == "1"
if _sf_ready or _sf_env:
if ((partition_name == "boot" and info_dict.get("init_boot") != "true")
or partition_name == "init_boot"):
mpatcher = [
os.path.join(_sf_top, "vendor/sunfish-a16/magisk/patch.sh"),
img.name,
_sf_top,
]
logger.info("SUNFISH_A16 Magisk patching (build): %s", img.name)
_sf_penv = os.environ.copy()
_sf_penv["system_root_image"] = info_dict.get("system_root_image", "false")
_sf_penv.setdefault("ANDROID_BUILD_TOP", _sf_top)
RunAndCheckOutput(mpatcher, verbose=True, env=_sf_penv)
'''
PREBUILT_HOOK = '''
# SUNFISH_A16: Magisk preroot hook v2 (prebuilt)
_sf_top = os.getenv("ANDROID_BUILD_TOP") or os.environ.get("PWD") or os.getcwd()
_sf_ready = os.path.isfile(os.path.join(_sf_top, "out", ".magisk", "READY"))
_sf_env = os.environ.get("SUNFISH_A16_MAGISK_PREROOT") == "1"
if _sf_ready or _sf_env:
if ((prebuilt_name == "boot.img" or prebuilt_name == "init_boot.img")
and os.path.exists(prebuilt_path)):
if info_dict is None:
info_dict = OPTIONS.info_dict
bimg = os.path.join(_sf_top, prebuilt_path)
logger.info("SUNFISH_A16 Magisk patching (prebuilt): %s", bimg)
mpatcher = [
os.path.join(_sf_top, "vendor/sunfish-a16/magisk/patch.sh"),
bimg,
_sf_top,
]
_sf_penv = os.environ.copy()
_sf_penv["system_root_image"] = info_dict.get("system_root_image", "false")
_sf_penv.setdefault("ANDROID_BUILD_TOP", _sf_top)
RunAndCheckOutput(mpatcher, verbose=True, env=_sf_penv)
'''
def _strip_old_hooks(text: str) -> str:
"""Remove prior SUNFISH Magisk hook blocks (v1 gated or v2)."""
# Build hook: from our comment through just before AVB block
text = re.sub(
r"\n # SUNFISH_A16: Magisk preroot hook(?: v2)? \(before AVB\).*?"
r"(?=\n # AVB: if enabled)",
"\n",
text,
count=1,
flags=re.S,
)
# Prebuilt hook: after BOOTABLE_IMAGES assign, before "if os.path.exists(prebuilt_path)"
text = re.sub(
r"( prebuilt_path = os\.path\.join\(unpack_dir, \"BOOTABLE_IMAGES\", prebuilt_name\)\n)"
r"\n # SUNFISH_A16: Magisk preroot hook(?: v2)? \(prebuilt\).*?"
r"(?=\n if os\.path\.exists\(prebuilt_path\):)",
r"\1",
text,
count=1,
flags=re.S,
)
return text
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--top", default=os.environ.get("ANDROID_BUILD_TOP", ""))
ap.add_argument("--dry-run", action="store_true")
ap.add_argument(
"--force",
action="store_true",
help="Replace an existing SUNFISH Magisk hook with v2",
)
args = ap.parse_args()
top = pathlib.Path(args.top or ".")
target = top / "build/make/tools/releasetools/common.py"
if not target.is_file():
print(f"ERROR: missing {target}", file=sys.stderr)
return 2
text = target.read_text()
if MARKER_VER in text and not args.force:
print(f"already applied (v2): {target}")
return 0
if MARKER in text or MARKER_VER in text:
if not args.force and MARKER_VER not in text:
# old v1 present — upgrade
pass
text = _strip_old_hooks(text)
needle_avb = (
' # AVB: if enabled, calculate and add hash to boot.img or recovery.img.\n'
' if info_dict.get("avb_enable") == "true":\n'
' avbtool = info_dict["avb_avbtool"]\n'
' if partition_name == "recovery":'
)
idx = text.find(needle_avb)
if idx < 0:
print("ERROR: AVB anchor not found", file=sys.stderr)
return 3
text = text[:idx] + BUILD_HOOK + "\n" + text[idx:]
assign = ' prebuilt_path = os.path.join(unpack_dir, "BOOTABLE_IMAGES", prebuilt_name)\n'
idx2 = text.find(assign)
if idx2 < 0:
print("ERROR: prebuilt assign not found", file=sys.stderr)
return 4
insert_at = idx2 + len(assign)
text = text[:insert_at] + PREBUILT_HOOK + "\n" + text[insert_at:]
if args.dry_run:
print("dry-run OK (v2)")
return 0
target.write_text(text)
print(f"applied v2 -> {target}")
return 0
if __name__ == "__main__":
sys.exit(main())