pmb.chroot package¶
Submodules¶
pmb.chroot.apk module¶
- pmb.chroot.apk.install(packages: list[str], chroot: Chroot, build: bool = True, quiet: bool = False) None ¶
Install packages from pmbootstrap’s local package index or the pmOS/Alpine binary package mirrors. Iterate over all dependencies recursively, and build missing packages as necessary.
- Parameters:
packages – list of pkgnames to be installed
suffix – the chroot suffix, e.g. “native” or “rootfs_qemu-amd64”
build – automatically build the package, when it does not exist yet or needs to be updated, and it is inside pmaports. For the special case that all packages are expected to be in Alpine’s repositories, set this to False for performance optimization.
- pmb.chroot.apk.install_run_apk(to_add: list[str], to_add_local: list[Path], to_del: list[str], chroot: Chroot) None ¶
Run apk to add packages, and ensure only the desired packages get explicitly marked as installed.
- Parameters:
to_add – list of pkgnames to install, without their dependencies
to_add_local – return of packages_get_locally_built_apks()
to_del – list of pkgnames to be deleted, this should be set to conflicting dependencies in any of the packages to be installed or their dependencies (e.g. [“unl0kr”])
chroot – the chroot suffix, e.g. “native” or “rootfs_qemu-amd64”
- pmb.chroot.apk.installed(suffix: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>) dict[str, ApkindexBlock] ¶
Read the list of installed packages (which has almost the same format, as an APKINDEX, but with more keys).
- Returns:
a dictionary with the following structure: { “postmarketos-mkinitfs”: ApkindexBlock }
- pmb.chroot.apk.packages_get_locally_built_apks(package_list: list[str], arch: Arch) list[Path] ¶
Iterate over packages and if existing, get paths to locally built packages. This is used to force apk to upgrade packages to newer local versions, even if the pkgver and pkgrel did not change.
- Parameters:
packages – list of pkgnames
arch – architecture that the locally built packages should have
- Returns:
Pair of lists, the first is the input packages with local apks removed. the second is a list of apk file paths that are valid inside the chroots, e.g. [“/mnt/pmbootstrap/packages/x86_64/hello-world-1-r6.apk”, …]
- pmb.chroot.apk.packages_split_to_add_del(packages)¶
Sort packages into “to_add” and “to_del” lists depending on their pkgname starting with an exclamation mark.
- Parameters:
packages – list of pkgnames
- Returns:
(to_add, to_del) - tuple of lists of pkgnames, e.g. ([“hello-world”, …], [“some-conflict-pkg”, …])
pmb.chroot.binfmt module¶
pmb.chroot.init module¶
- class pmb.chroot.init.UsrMerge(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)¶
Bases:
Enum
Merge /usr while initializing chroot. https://systemd.io/THE_CASE_FOR_THE_USR_MERGE/
- AUTO = 0¶
- OFF = 2¶
- ON = 1¶
- pmb.chroot.init.copy_resolv_conf(chroot: Chroot) None ¶
Use pythons super fast file compare function (due to caching) and copy the /etc/resolv.conf to the chroot, in case it is different from the host. If the file doesn’t exist, create an empty file with ‘touch’.
- pmb.chroot.init.init_keys()¶
All Alpine and postmarketOS repository keys are shipped with pmbootstrap. Copy them into $WORK/config_apk_keys, which gets mounted inside the various chroots as /etc/apk/keys.
This is done before installing any package, so apk can verify APKINDEX files of binary repositories even though alpine-keys/postmarketos-keys are not installed yet.
- pmb.chroot.init.mark_in_chroot(chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>) None ¶
Touch a flag so we can know when we’re running in chroot (and don’t accidentally flash partitions on our host). This marker gets removed in pmb.chroot.shutdown (pmbootstrap shutdown).
pmb.chroot.initfs module¶
- pmb.chroot.initfs.extract(flavor: str | None, chroot: Chroot, extra: bool = False) Path ¶
Extract the initramfs to /tmp/initfs-extracted or the initramfs-extra to /tmp/initfs-extra-extracted and return the outside extraction path.
- pmb.chroot.initfs.ls(flavor, suffix, extra=False)¶
pmb.chroot.initfs_hooks module¶
- pmb.chroot.initfs_hooks.list_aports() list[str] ¶
pmb.chroot.mount module¶
- pmb.chroot.mount.create_device_nodes(chroot: Chroot) None ¶
Create device nodes for null, zero, full, random, urandom in the chroot.
- pmb.chroot.mount.mount_chroot_image(chroot: Chroot) None ¶
Mount an IMAGE type chroot, to modify an existing rootfs image. This doesn’t support split images yet!
- pmb.chroot.mount.mount_dev_tmpfs(chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>) None ¶
Mount tmpfs inside the chroot’s dev folder to make sure we can create device nodes, even if the filesystem of the work folder does not support it.
- pmb.chroot.mount.remove_mnt_pmbootstrap(chroot: Chroot) None ¶
Safely remove /mnt/pmbootstrap directories from the chroot, without running rm -r as root and potentially removing data inside the mountpoint in case it was still mounted (bug in pmbootstrap, or user ran pmbootstrap 2x in parallel). This is similar to running ‘rm -r -d’, but we don’t assume that the host’s rm has the -d flag (busybox does not).
pmb.chroot.other module¶
- pmb.chroot.other.copy_xauthority(chroot: Chroot) None ¶
Copy the host system’s Xauthority file to the pmos user inside the chroot, so we can start X11 applications from there.
- pmb.chroot.other.kernel_flavor_installed(chroot: Chroot, autoinstall: bool = True) str | None ¶
Get installed kernel flavor. Optionally install the device’s kernel beforehand.
- Parameters:
suffix – the chroot suffix, e.g. “native” or “rootfs_qemu-amd64”
autoinstall – install the device’s kernel if it is not installed
- Returns:
string with the installed kernel flavor, e.g. [“postmarketos-qcom-sdm845”]
None if no kernel is installed
pmb.chroot.run module¶
- pmb.chroot.run.exists(username: str, chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>) bool ¶
Checks if username exists in the system
- Parameters:
username – User name
- Returns:
bool
- pmb.chroot.run.root(cmds: Sequence[PathString], chroot: Chroot = <pmb.core.chroot.Chroot object>, working_dir: PurePath = PurePosixPath('/'), output: RunOutputTypePopen = 'log', output_return: Literal[False] = False, check: bool | None = None, env: Env = {}, disable_timeout: bool = False, add_proxy_env_vars: bool = True) subprocess.Popen ¶
- pmb.chroot.run.root(cmds: Sequence[PathString], chroot: Chroot = <pmb.core.chroot.Chroot object>, working_dir: PurePath = PurePosixPath('/'), output: RunOutputTypeDefault = 'log', output_return: Literal[False] = False, check: bool | None = None, env: Env = {}, disable_timeout: bool = False, add_proxy_env_vars: bool = True) int
- pmb.chroot.run.root(cmds: Sequence[PathString], chroot: Chroot = <pmb.core.chroot.Chroot object>, working_dir: PurePath = PurePosixPath('/'), output: RunOutputType = 'log', output_return: Literal[True] = False, check: bool | None = None, env: Env = {}, disable_timeout: bool = False, add_proxy_env_vars: bool = True) str
- pmb.chroot.run.rootm(cmds: ~collections.abc.Sequence[~collections.abc.Sequence[~pathlib.Path | str]], chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>, working_dir: ~pathlib.PurePath = PurePosixPath('/'), output: ~typing.Literal['log', 'stdout', 'interactive', 'tui', 'null'] | ~typing.Literal['background', 'pipe'] = 'log', output_return: bool = False, check: bool | None = None, env: dict[str, ~pathlib.Path | str] = {}, disable_timeout: bool = False, add_proxy_env_vars: bool = True) str | int | Popen ¶
Run a list of commands inside a chroot as root.
- Parameters:
env – dict of environment variables to be passed to the command, e.g. {“JOBS”: “5”}
working_dir – chroot-relative working directory
add_proxy_env_vars – if True, preserve HTTP_PROXY etc. vars from host environment. pmb.chroot.user sets this to False when calling pmb.chroot.root, because it already makes the variables part of the cmd argument.
See pmb.helpers.run_core.core() for a detailed description of all other arguments and the return value.
- pmb.chroot.run.user(cmd: Sequence[PathString], chroot: Chroot = <pmb.core.chroot.Chroot object>, working_dir: Path = PosixPath('/'), output: RunOutputTypePopen = 'log', output_return: Literal[False] = False, check: bool | None = None, env: Env = {}) subprocess.Popen ¶
- pmb.chroot.run.user(cmd: Sequence[PathString], chroot: Chroot = <pmb.core.chroot.Chroot object>, working_dir: Path = PosixPath('/'), output: RunOutputTypeDefault = 'log', output_return: Literal[False] = False, check: bool | None = None, env: Env = {}) int
- pmb.chroot.run.user(cmd: Sequence[PathString], chroot: Chroot = <pmb.core.chroot.Chroot object>, working_dir: Path = PosixPath('/'), output: RunOutputType = 'log', output_return: Literal[True] = False, check: bool | None = None, env: Env = {}) str
- pmb.chroot.run.userm(cmds: ~collections.abc.Sequence[~collections.abc.Sequence[~pathlib.Path | str]], chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>, working_dir: ~pathlib.Path = PosixPath('/'), output: ~typing.Literal['log', 'stdout', 'interactive', 'tui', 'null'] | ~typing.Literal['background', 'pipe'] = 'log', output_return: bool = False, check: bool | None = None, env: dict[str, ~pathlib.Path | str] = {}) str | int | Popen ¶
Run a command inside a chroot as “user”. We always use the BusyBox implementation of ‘su’, because other implementations may override the PATH environment variable (#1071).
- Parameters:
env – dict of environment variables to be passed to the command, e.g. {“JOBS”: “5”}
See pmb.helpers.run_core.core() for a detailed description of all other arguments and the return value.
pmb.chroot.shutdown module¶
- pmb.chroot.shutdown.kill_adb()¶
Kill adb daemon if it’s running.
- pmb.chroot.shutdown.kill_sccache()¶
Kill sccache daemon if it’s running. Unlike ccache it automatically spawns a daemon when you call it and exits after some time of inactivity.
- pmb.chroot.shutdown.shutdown(only_install_related=False)¶
- pmb.chroot.shutdown.shutdown_cryptsetup_device(name: str) None ¶
- Parameters:
name – cryptsetup device name, usually “pm_crypt” in pmbootstrap
pmb.chroot.zap module¶
- pmb.chroot.zap.del_chroot(path: Path, confirm: bool = True, dry: bool = False) None ¶
- pmb.chroot.zap.zap(confirm: bool = True, dry: bool = False, pkgs_local: bool = False, http: bool = False, pkgs_local_mismatch: bool = False, pkgs_online_mismatch: bool = False, distfiles: bool = False, rust: bool = False, netboot: bool = False) None ¶
Shutdown everything inside the chroots (e.g. adb), umount everything and then safely remove folders from the work-directory.
- Parameters:
dry – Only show what would be deleted, do not delete for real
pkgs_local – Remove all self-compiled packages (!)
http – Clear the http cache (used e.g. for the initial apk download)
pkgs_local_mismatch – Remove the packages that have a different version compared to what is in the aports folder.
pkgs_online_mismatch – Clean out outdated binary packages downloaded from mirrors (e.g. from Alpine)
distfiles – Clear the downloaded files cache
rust – Remove rust related caches
netboot – Remove images for netboot
NOTE: This function gets called in pmb/config/init.py, with only get_context().config.work and args.device set!
- pmb.chroot.zap.zap_pkgs_local_mismatch(confirm: bool = True, dry: bool = False) None ¶
- pmb.chroot.zap.zap_pkgs_online_mismatch(confirm=True, dry=False)¶