~postmarketos/pmbootstrap

7384b653c6ac06057ea4521f4e03b3a1417570e6 — Caleb Connolly 1 year, 1 month ago 392e82d usrmerge
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 <kc@postmarketos.org>
2 files changed, 60 insertions(+), 3 deletions(-)

M pmb/chroot/init.py
M pmb/config/__init__.py
M pmb/chroot/init.py => pmb/chroot/init.py +58 -3
@@ 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_"):

M pmb/config/__init__.py => pmb/config/__init__.py +2 -0
@@ 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",