From 7384b653c6ac06057ea4521f4e03b3a1417570e6 Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Tue, 18 Jul 2023 00:37:57 +0100 Subject: [PATCH] HACK: pmb.chroot: support usrmerge Because we bootstrap a chroot directly with apk, instead of fetching a preliminary rootfs, it's non-trivial to init with usrmerge. Instead we need to do some kinda janky shell-scripting to convert the minimal rootfs to a merged-usr setup. Add the necessary jank to do this. Additionally, pass in the local binary repository when running apk.static so that custom-built versions of alpine-base or dependencies will be used. Signed-off-by: Caleb Connolly --- pmb/chroot/init.py | 61 +++++++++++++++++++++++++++++++++++++++--- pmb/config/__init__.py | 2 ++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/pmb/chroot/init.py b/pmb/chroot/init.py index e2622ffc..694ec870 100644 --- a/pmb/chroot/init.py +++ b/pmb/chroot/init.py @@ -74,6 +74,53 @@ def init_keys(args): pmb.helpers.run.root(args, ["cp", key, target]) + +# XXX: FIXME: how do this better? +def _usrmerge(args, chroot): + """ + Migrate a chroot to merged /usr layout by generating + and running a shell script, this is much faster than + doing it all in plain python + + Args: + args: args + chroot (str): path to the chroot + """ + def mv_files(script, src, dest): + for root, dirs, files in os.walk(os.path.join(chroot, src), topdown=False): + fdir = os.path.relpath(root, os.path.join(chroot, src)) + if fdir == ".": + fdir = "" + else: + script += f"mkdir -p {os.path.join(chroot, dest, fdir)};" + for file in files: + script += f"mv -f {os.path.join(root, file)} " \ + f"{os.path.join(chroot, dest, fdir, file)};" + script += f"rm -rf {os.path.join(chroot, src)};" + return script + + # Move /bin, /sbin, and /usr/sbin to /usr/bin + script = "" + script = mv_files(script, "bin", "usr/bin") + script = mv_files(script, "sbin", "usr/bin") + script = mv_files(script, "usr/sbin", "usr/bin") + # Move /lib to /usr/lib + script = mv_files(script, "lib", "usr/lib") + # Create symlinks + script += f"ln -s usr/bin {chroot}/bin;" + script += f"ln -s usr/bin {chroot}/sbin;" + script += f"ln -s bin {chroot}/usr/sbin;" + script += f"ln -s usr/lib {chroot}/lib;" + + # path = "/tmp/postmarketOS-chroot-migrate.sh" + # with open(path, "w") as f: + # f.write(script) + # f.flush() + + #pmb.helpers.run.user(args, ["chmod", "+x", path]) + pmb.helpers.run.root(args, ["sh", "-c", script]) + + def init(args, suffix="native"): # When already initialized: just prepare the chroot chroot = f"{args.work}/chroot_{suffix}" @@ -104,13 +151,21 @@ def init(args, suffix="native"): pmb.chroot.apk.update_repository_list(args, suffix) pmb.config.workdir.chroot_save_init(args, suffix) + channel_cfg = pmb.config.pmaports.read_config_channel(args) + mirrordir_alpine = channel_cfg["mirrordir_alpine"] + host_pkg_repo = os.path.join(args.work, "packages", mirrordir_alpine) # Install alpine-base pmb.helpers.repo.update(args, arch) pmb.chroot.apk_static.run(args, ["--root", chroot, - "--cache-dir", apk_cache, - "--initdb", "--arch", arch, - "add", "alpine-base"]) + "--cache-dir", apk_cache, + "--initdb", "--arch", arch, + "--repository", host_pkg_repo, + "add", "alpine-base"]) + + # XXX: add argument parsing for this + if args.merge_usr: + _usrmerge(args, chroot) # Building chroots: create "pmos" user, add symlinks to /home/pmos if not suffix.startswith("rootfs_"): diff --git a/pmb/config/__init__.py b/pmb/config/__init__.py index fd75a00f..18c9c6b9 100644 --- a/pmb/config/__init__.py +++ b/pmb/config/__init__.py @@ -99,6 +99,7 @@ config_keys = [ "ui", "ui_extras", "user", + "merge_usr", "work", ] @@ -138,6 +139,7 @@ defaults = { "ui": "console", "ui_extras": False, "user": "user", + "merge_usr": True, "work": os.path.expanduser("~") + "/.local/var/pmbootstrap", "boot_size": "256", "extra_space": "0", -- 2.45.2