171 lines
4.8 KiB
Python
171 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import os
|
|
import subprocess
|
|
|
|
from stuff.houdini import Houdini
|
|
from stuff.houdini_hack import Houdini_Hack
|
|
from stuff.magisk import Magisk
|
|
from stuff.mindthegapps import MindTheGapps
|
|
import tools.helper as helper
|
|
|
|
|
|
SUPPORTED_ANDROID_VERSIONS = ["13.0.0"]
|
|
|
|
|
|
def ensure_base_image(container_runtime, android_version):
|
|
base_image = "redroid/redroid:{}-latest".format(android_version)
|
|
inspect = subprocess.run(
|
|
[container_runtime, "image", "inspect", base_image],
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL,
|
|
check=False,
|
|
)
|
|
local_present = inspect.returncode == 0
|
|
|
|
helper.print_color(
|
|
"Trying to pull base image {} first ...".format(base_image),
|
|
helper.bcolors.GREEN,
|
|
)
|
|
pull = subprocess.run([container_runtime, "pull", base_image], check=False)
|
|
if pull.returncode == 0:
|
|
return "pulled"
|
|
|
|
if local_present:
|
|
helper.print_color(
|
|
"Online pull failed, falling back to local image cache ...",
|
|
helper.bcolors.YELLOW,
|
|
)
|
|
return "present"
|
|
|
|
tar_name = "redroid-redroid-{}-latest.tar".format(android_version)
|
|
tar_path = os.path.join(helper.get_image_dir(), tar_name)
|
|
if not os.path.isfile(tar_path):
|
|
raise FileNotFoundError(
|
|
"Online pull for {} failed, local image cache is missing, and offline archive {} was not found".format(
|
|
base_image,
|
|
tar_path,
|
|
)
|
|
)
|
|
|
|
helper.print_color(
|
|
"Online pull failed, loading local image archive {} ...".format(tar_path),
|
|
helper.bcolors.YELLOW,
|
|
)
|
|
subprocess.run([container_runtime, "load", "-i", tar_path], check=True)
|
|
return tar_path
|
|
|
|
|
|
def build_layers(args):
|
|
dockerfile = "FROM redroid/redroid:{}-latest\n".format(args.android)
|
|
tags = [args.android]
|
|
|
|
if args.mindthegapps:
|
|
MindTheGapps(args.android).install()
|
|
dockerfile += "COPY mindthegapps /\n"
|
|
tags.append("mindthegapps")
|
|
|
|
if args.houdini:
|
|
arch = helper.host()[0]
|
|
if arch not in {"x86", "x86_64"}:
|
|
raise ValueError("Houdini only makes sense on x86/x86_64 hosts")
|
|
Houdini(args.android).install()
|
|
Houdini_Hack(args.android).install()
|
|
dockerfile += "COPY houdini /\n"
|
|
tags.append("houdini")
|
|
|
|
if args.magisk:
|
|
Magisk().install()
|
|
dockerfile += "COPY magisk /\n"
|
|
tags.append("magisk")
|
|
|
|
return dockerfile, tags
|
|
|
|
|
|
def print_recommended_flow(image_name):
|
|
print("\nRecommended 5570 launch")
|
|
print(
|
|
"python run_redroid.py "
|
|
"--image {} "
|
|
"--bridge libhoudini "
|
|
"--device-profile pixel-7-pro "
|
|
"--data-dir ~/data-redroid13 "
|
|
"--port 5570 "
|
|
"--replace\n".format(image_name)
|
|
)
|
|
print("Recommended post-boot hardening")
|
|
print(
|
|
"python bootstrap_redroid.py "
|
|
"--serial 127.0.0.1:5570 "
|
|
"--device-profile pixel-7-pro "
|
|
"--proxy-host auto "
|
|
"--install-extreme-script\n"
|
|
)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="Build the minimal Android 13 redroid image used for the optimized 5570 setup."
|
|
)
|
|
parser.add_argument(
|
|
"-a",
|
|
"--android-version",
|
|
dest="android",
|
|
default="13.0.0",
|
|
choices=SUPPORTED_ANDROID_VERSIONS,
|
|
help="Android base image to build from",
|
|
)
|
|
parser.add_argument(
|
|
"-mtg",
|
|
"--install-mindthegapps",
|
|
dest="mindthegapps",
|
|
action="store_true",
|
|
help="Install MindTheGapps into the image",
|
|
)
|
|
parser.add_argument(
|
|
"-i",
|
|
"--install-houdini",
|
|
dest="houdini",
|
|
action="store_true",
|
|
help="Install libhoudini and the Android 13 compatibility hack",
|
|
)
|
|
parser.add_argument(
|
|
"-m",
|
|
"--install-magisk",
|
|
dest="magisk",
|
|
action="store_true",
|
|
help="Install Kitsune Mask / Magisk Delta bootless payload",
|
|
)
|
|
parser.add_argument(
|
|
"-c",
|
|
"--container",
|
|
dest="container",
|
|
default="docker",
|
|
choices=["docker", "podman"],
|
|
help="Container runtime",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
base_image_source = ensure_base_image(args.container, args.android)
|
|
dockerfile, tags = build_layers(args)
|
|
|
|
print("\nDockerfile\n{}".format(dockerfile))
|
|
with open("./Dockerfile", "w", encoding="utf-8") as handle:
|
|
handle.write(dockerfile)
|
|
|
|
image_name = "redroid/redroid:" + "_".join(tags)
|
|
subprocess.run([args.container, "build", "-t", image_name, "."], check=True)
|
|
helper.print_color(
|
|
"Successfully built {}".format(image_name),
|
|
helper.bcolors.GREEN,
|
|
)
|
|
print("Base image source: {}".format(base_image_source))
|
|
|
|
if args.houdini:
|
|
print_recommended_flow(image_name)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|