pmb.helpers package¶
Submodules¶
pmb.helpers.apk_static module¶
- pmb.helpers.apk_static.download(file)¶
Download a single file from an Alpine mirror.
- pmb.helpers.apk_static.extract(version, apk_path)¶
Extract everything to temporary locations, verify signatures and reported versions. When everything is right, move the extracted apk.static to the final location.
- pmb.helpers.apk_static.extract_temp(tar, sigfilename)¶
Extract apk.static and signature as temporary files.
- pmb.helpers.apk_static.init() None ¶
Download, verify, extract $WORK/apk.static.
- pmb.helpers.apk_static.read_signature_info(tar)¶
Find various information about the signature that was used to sign /sbin/apk.static inside the archive (not to be confused with the normal apk archive signature!)
- Returns:
(sigfilename, sigkey_path)
- pmb.helpers.apk_static.verify_signature(files, sigkey_path)¶
Verify the signature with openssl.
- Parameters:
files – return value from extract_temp()
- Raises:
RuntimeError – when verification failed and removes temp files
pmb.helpers.apk module¶
- pmb.helpers.apk.check_outdated(version_installed, action_msg)¶
Check if the provided alpine version is outdated.
This depends on the alpine mirrordir (edge, v3.12, …) related to currently checked out pmaports branch.
- Parameters:
version_installed – currently installed apk version, e.g. “2.12.1-r0”
action_msg – string explaining what the user should do to resolve this
- Raises:
RuntimeError if the version is outdated
- pmb.helpers.apk.run(command: Sequence[Path | str], chroot: Chroot, with_progress: bool = True) None ¶
Run an apk subcommand.
- Parameters:
command – apk subcommand in list form
with_progress – whether to print a progress bar
chroot – chroot to run the command in
- Raises:
RuntimeError – when the apk command fails
pmb.helpers.aportupgrade module¶
- pmb.helpers.aportupgrade.get_package_version_info_github(repo_name: str, ref: str | None) PackageVersionInfo ¶
- pmb.helpers.aportupgrade.get_package_version_info_gitlab(gitlab_host: str, repo_name: str, ref: str | None) PackageVersionInfo ¶
- pmb.helpers.aportupgrade.init_req_headers() None ¶
- pmb.helpers.aportupgrade.upgrade(args: PmbArgs, pkgname: str, git: bool = True, stable: bool = True) None ¶
Find new versions of a single package and upgrade it.
- Parameters:
pkgname – the name of the package
git – True if git packages should be upgraded
stable – True if stable packages should be upgraded
- pmb.helpers.aportupgrade.upgrade_all(args: PmbArgs) None ¶
Upgrade all packages, based on args.all, args.all_git and args.all_stable.
pmb.helpers.args module¶
pmb.helpers.cli module¶
- class pmb.helpers.cli.ReadlineTabCompleter(options: list[str])¶
Bases:
object
Store intermediate state for completer function.
- completer_func(input_text: str, iteration: int) str | None ¶
- Parameters:
input_text – text that shall be autocompleted
iteration – how many times “tab” was hit
- pmb.helpers.cli.ask(question='Continue?', choices=['y', 'n'], default='n', lowercase_answer=True, validation_regex=None, complete=None)¶
Ask a question on the terminal.
- Parameters:
question – display prompt
choices – short list of possible answers, displayed after prompt if set
default – default value to return if user doesn’t input anything
lowercase_answer – if True, convert return value to lower case
validation_regex – if set, keep asking until regex matches
complete – set to a list to enable tab completion
- pmb.helpers.cli.confirm(question: str = 'Continue?', default: bool = False, no_assumptions: bool = False) bool ¶
Convenience wrapper around ask for simple yes-no questions with validation.
- Parameters:
no_assumptions – ask for confirmation, even if “pmbootstrap -y’ is set
- Returns:
True for “y”, False for “n”
- pmb.helpers.cli.progress_flush() None ¶
Finish printing a progress bar.
This will erase the line. Does nothing in non-interactive mode.
- pmb.helpers.cli.progress_print(progress: float) None ¶
Print a snapshot of a progress bar to STDOUT.
Call progress_flush to end printing progress and clear the line. No output is printed in non-interactive mode.
- Parameters:
progress – completion percentage as a number between 0 and 1
pmb.helpers.devices module¶
- pmb.helpers.devices.find_path(codename: str, file: str = '') Path | None ¶
Find path to device APKBUILD under device/*/device-.
- Parameters:
codename – device codename
file – file to look for (e.g. APKBUILD or deviceinfo), may be empty
- Returns:
path to APKBUILD
- pmb.helpers.devices.list_codenames(vendor: str | None = None, archived: bool = True) list[str] ¶
Get all devices, for which aports are available.
- Parameters:
vendor – vendor name to choose devices from, or None for all vendors
archived – include archived devices
- Returns:
[“first-device”, “second-device”, …]
- pmb.helpers.devices.list_vendors() set[str] ¶
Get all device vendors, for which aports are available.
- Returns:
{“vendor1”, “vendor2”, …}
pmb.helpers.exceptions module¶
- exception pmb.helpers.exceptions.BuildFailedError¶
Bases:
Exception
Exception to be raised when pmbootstrap fails to build a package. This is handled separately from NonBugError as it needs to be treated differently as we want to hint to users that they can check the log for more information when a build fails.
- exception pmb.helpers.exceptions.NonBugError¶
Bases:
Exception
Exception which originates from a problem not caused by pmbootstrap’s code. This could for example be raised if there is an error in a package pmboostrap is interacting with in some way.
pmb.helpers.file module¶
- pmb.helpers.file.is_older_than(path, seconds)¶
Check if a single file is older than a given amount of seconds.
- pmb.helpers.file.is_up_to_date(path_sources, path_target=None, lastmod_target=None)¶
Check if a file is up-to-date by comparing the last modified timestamps.
(just like make does it).
- Parameters:
path_sources – list of full paths to the source files
path_target – full path to the target file
lastmod_target – the timestamp of the target file. specify this as alternative to specifying path_target.
- pmb.helpers.file.replace(path: Path, old: str, new: str) None ¶
- pmb.helpers.file.replace_apkbuild(args: PmbArgs, pkgname: str, key: str, new: int | str, in_quotes: bool = False) None ¶
Replace one key=value line in an APKBUILD and verify it afterwards.
- Parameters:
pkgname – package name, e.g. “hello-world”
key – key that should be replaced, e.g. “pkgver”
new – new value
in_quotes – expect the value to be in quotation marks (“”)
- pmb.helpers.file.symlink(file: Path, link: Path) None ¶
Check if the symlink is already present, otherwise create it.
pmb.helpers.frontend module¶
pmb.helpers.git module¶
- class pmb.helpers.git.RemoteType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)¶
Bases:
Enum
- FETCH = 'fetch'¶
- PUSH = 'push'¶
- static from_git_output(git_remote_type: str) RemoteType ¶
- pmb.helpers.git.branch_looks_official(repo: Path, branch: str) bool ¶
- Check if a given branch follows the patterns of official branches in
pmaports or aports.
- Returns:
True if it looks official, False otherwise
- pmb.helpers.git.can_fast_forward(path: Path, branch_upstream: str, branch: str = 'HEAD') bool ¶
- pmb.helpers.git.clean_worktree(path: Path, silent: bool = False) bool ¶
Check if there are not any modified files in the git dir.
- pmb.helpers.git.clone(name_repo: str) None ¶
Clone a git repository to $WORK/cache_git/$name_repo.
(or to the overridden path set in args, as with
pmbootstrap --aports
).- Parameters:
name_repo – short alias used for the repository name, from pmb.config.git_repos (e.g. “aports_upstream”, “pmaports”)
- pmb.helpers.git.get_files(repo: Path) list[str] ¶
Get all files inside a git repository, that are either already in the git tree or are not in gitignore.
Do not list deleted files. To be used for creating a tarball of the git repository.
- Parameters:
path – top dir of the git repository
- Returns:
all files in a git repository as list, relative to path
- pmb.helpers.git.get_path(name_repo: str) Path ¶
Get the path to the repository.
The path is either the default one in the work dir, or a user-specified one in args.
- Returns:
full path to repository
- pmb.helpers.git.get_topdir(repo: Path) Path ¶
Get top-dir of git repo.
- Returns:
the top dir of the git repository
- pmb.helpers.git.get_upstream_remote(aports: Path) str ¶
Find the remote, which matches the git URL from the config.
Usually “origin”, but the user may have set up their git repository differently.
- pmb.helpers.git.list_remotes(aports: Path) list[str] ¶
- pmb.helpers.git.migrate_upstream_remote() None ¶
Migrate pmaports git remote URL from gitlab.com to gitlab.postmarketos.org.
- pmb.helpers.git.pull(repo_name: str) int ¶
Check if on official branch and essentially try
git pull --ff-only
.Instead of really doing
git pull --ff-only
, do it in multiple steps (fetch, merge --ff-only
), so we can display useful messages depending on which part fails.- Returns:
integer, >= 0 on success, < 0 on error
- pmb.helpers.git.rev_parse(path: Path, revision: str = 'HEAD', extra_args: list = [], silent: bool = False) str ¶
Run “git rev-parse” in a specific repository dir.
- Parameters:
path – to the git repository
extra_args – additional arguments for
git rev-parse
. Pass--abbrev-ref
to get the branch instead of the commit, if possible.
- Returns:
commit string like “90cd0ad84d390897efdcf881c0315747a4f3a966” or (with
--abbrev-ref
): the branch name, e.g. “master”
- pmb.helpers.git.set_remote_url(repo: Path, remote_name: str, remote_url: str, remote_type: RemoteType) None ¶
pmb.helpers.http module¶
- pmb.helpers.http.cache_file(prefix: str, url: str) Path ¶
- pmb.helpers.http.download(url: str, prefix: str, cache: bool = True, loglevel: int = 20, allow_404: Literal[False] = False, flush_progress_bar_on_404: bool = False) Path ¶
- pmb.helpers.http.download(url: str, prefix: str, cache: bool = True, loglevel: int = 20, allow_404: Literal[True] = False, flush_progress_bar_on_404: bool = False) Path | None
Download a file to disk.
- Parameters:
url – the http(s) address of to the file to download
prefix – for the cache, to make it easier to find (cache files get a hash of the URL after the prefix)
cache – if True, and url is cached, do not download it again
loglevel – change to logging.DEBUG to only display the download message in ‘pmbootstrap log’, not in stdout. We use this when downloading many APKINDEX files at once, no point in showing a dozen messages.
allow_404 – do not raise an exception when the server responds with a 404 Not Found error. Only display a warning on stdout (no matter if loglevel is changed).
flush_progress_bar_on_404 – download happens while a progress bar is displayed, flush it before printing a warning for 404
- Returns:
path to the downloaded file in the cache or None on 404
- pmb.helpers.http.retrieve(url: str, headers: dict[str, str] | None = None, allow_404: Literal[False] = False) str ¶
- pmb.helpers.http.retrieve(url: str, headers: dict[str, str] | None = None, allow_404: Literal[True] = False) str | None
Fetch the content of a URL and returns it as string.
- Parameters:
url – the http(s) address of to the resource to fetch
headers – dict of HTTP headers to use
allow_404 – do not raise an exception when the server responds with a 404 Not Found error. Only display a warning
- Returns:
str with the content of the response
- pmb.helpers.http.retrieve_json(*args, **kwargs)¶
Fetch the contents of a URL, parse it as JSON and return it.
See retrieve() for the list of all parameters.
pmb.helpers.lint module¶
- pmb.helpers.lint.check(pkgnames: Sequence[str]) None ¶
Run apkbuild-lint on the supplied packages.
- Parameters:
pkgnames – Names of the packages to lint
- pmb.helpers.lint.get_custom_valid_options() list[str] ¶
Build a list of custom valid APKBUILD options that apkbuild-lint should not complain about. The list consists of hardcoded options from pmb.config.apkbuild_custom_valid_options like pmb:gpu-accel, as well as dynamically generated options from kconfigcheck.toml (pmb:kconfigcheck-libcamera etc.).
pmb.helpers.logging module¶
- pmb.helpers.logging.add_verbose_log_level() None ¶
Add a new log level “verbose”, which is below “debug”.
Also monkeypatch logging, so it can be used with logging.verbose().
This function is based on work by Voitek Zylinski and sleepycal: https://stackoverflow.com/a/20602183 All stackoverflow user contributions are licensed as CC-BY-SA: https://creativecommons.org/licenses/by-sa/3.0/
- pmb.helpers.logging.critical(msg: object, *args: str, **kwargs: Any) None ¶
- pmb.helpers.logging.debug(msg: object, *args: str, **kwargs: Any) None ¶
- pmb.helpers.logging.disable() None ¶
- pmb.helpers.logging.error(msg: object, *args: str, **kwargs: Any) None ¶
- pmb.helpers.logging.fatal(msg: object, *args: str, **kwargs: Any) None ¶
- pmb.helpers.logging.info(msg: object, *args: str, **kwargs: Any) None ¶
- pmb.helpers.logging.init(logfile: Path, verbose: bool, details_to_stdout: bool = False) None ¶
Set log format and add the log file descriptor to logfd, add the verbose log level.
- pmb.helpers.logging.log(level: int, msg: object, *args: str, **kwargs: Any) None ¶
- class pmb.helpers.logging.log_handler(details_to_stdout: bool = False, quiet: bool = False)¶
Bases:
StreamHandler
Write to stdout and to the already opened log file.
- emit(record)¶
Emit a record.
If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an ‘encoding’ attribute, it is used to determine how to do the output to the stream.
- pmb.helpers.logging.logfd: TextIO¶
- pmb.helpers.logging.verbose(msg: object, *args: str, **kwargs: Any) None ¶
- pmb.helpers.logging.warning(msg: object, *args: str, **kwargs: Any) None ¶
pmb.helpers.mount module¶
- pmb.helpers.mount.bind(source: Path | str, destination: Path, create_folders: bool = True, umount: bool = False) None ¶
Mount –bind a folder and create necessary directory structure.
- Parameters:
umount – when destination is already a mount point, umount it first.
- pmb.helpers.mount.bind_file(source: Path, destination: Path, create_folders: bool = False) None ¶
Mount a file with the –bind option, and create the destination file, if necessary.
- pmb.helpers.mount.ismount(folder: Path) bool ¶
Ismount() implementation that works for mount –bind.
Workaround for: https://bugs.python.org/issue29707
- pmb.helpers.mount.mount_device_rootfs(chroot_rootfs: ~pmb.core.chroot.Chroot, chroot_base: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>) PurePath ¶
Mount the device rootfs.
- Parameters:
chroot_rootfs – the chroot where the rootfs that will be installed on the device has been created (e.g. “rootfs_qemu-amd64”)
chroot_base – the chroot rootfs mounted to
- Returns:
the mountpoint (relative to the chroot)
- pmb.helpers.mount.umount_all(folder: Path) None ¶
Umount all folders that are mounted inside a given folder.
- pmb.helpers.mount.umount_all_list(prefix: Path, source: Path = PosixPath('/proc/mounts')) list[Path] ¶
Parse /proc/mounts for all folders beginning with a prefix.
- Source:
can be changed for testcases
- Returns:
a list of folders that need to be umounted
pmb.helpers.other module¶
- pmb.helpers.other.check_binfmt_misc() None ¶
Check if the ‘binfmt_misc’ module is loaded.
This is done by checking, if /proc/sys/fs/binfmt_misc/ exists. If it exists, then do nothing. Otherwise, load the module and mount binfmt_misc. If that fails as well, raise an exception pointing the user to the wiki.
- pmb.helpers.other.check_grsec() None ¶
Check if the current kernel is based on the grsec patchset.
Also check if the chroot_deny_chmod option is enabled. Raise an exception in that case, with a link to the issue. Otherwise, do nothing.
- pmb.helpers.other.folder_size(path: Path) int ¶
Run du to calculate the size of a folder.
(this is less code and faster than doing the same task in pure Python) This result is only approximatelly right, but good enough for pmbootstrap’s use case (#760).
- Returns:
folder size in kilobytes
- pmb.helpers.other.migrate_success(work: Path, version: int) None ¶
- pmb.helpers.other.migrate_work_folder() None ¶
- pmb.helpers.other.normalize_hostname(hostname: str) str ¶
Fixup default hostnames so that they don’t fail validate_hostname()
This should not be called on user-chosen hostnames as those should fail
- pmb.helpers.other.validate_hostname(hostname: str) bool ¶
Check whether the string is a valid hostname.
Check is performed according to <http://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names>
pmb.helpers.package module¶
Functions that work with both pmaports and binary package repos.
See also:
pmb/helpers/pmaports.py (work with pmaports)
pmb/helpers/repo.py (work with binary package repos)
- pmb.helpers.package.check_arch(pkgname: str, arch: Arch, binary: bool = True) bool ¶
Check if a package be built for a certain architecture, or is there a binary package for it.
- Parameters:
pkgname – name of the package
arch – architecture to check against
binary – set to False to only look at the pmaports, not at binary packages
- Returns:
True when the package can be built, or there is a binary package, False otherwise
- pmb.helpers.package.remove_operators(package)¶
pmb.helpers.pkgrel_bump module¶
- class pmb.helpers.pkgrel_bump.BumpType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)¶
Bases:
Enum
- PKGREL = 'pkgrel'¶
- PKGVER = 'pkgver'¶
- pmb.helpers.pkgrel_bump.auto(dry: bool = False) list[str] ¶
- Returns:
list of aport names, where the pkgrel needed to be changed
- pmb.helpers.pkgrel_bump.auto_apkindex_package(arch: Arch, aport: dict[str, Any], apk: ApkindexBlock, dry: bool = False) bool ¶
Bump the pkgrel of a specific package if it is outdated in the given APKINDEX.
- Parameters:
arch – the architecture, e.g. “armhf”
aport – parsed APKBUILD of the binary package’s origin: {“pkgname”: …, “pkgver”: …, “pkgrel”: …, …}
apk – information about the binary package from the APKINDEX: {“version”: …, “depends”: […], …}
dry – don’t modify the APKBUILD, just print the message
- Returns:
True when there was an APKBUILD that needed to be changed.
- pmb.helpers.pkgrel_bump.package(pkgname: str, reason: str = '', dry: bool = False, bump_type: BumpType = BumpType.PKGREL) None ¶
Increase the pkgrel or pkgver in the APKBUILD of a specific package.
- Parameters:
pkgname – name of the package
reason – string to display as reason why it was increased
dry – don’t modify the APKBUILD, just print the message
bump_type – whether to bump pkgrel or pkgver
pmb.helpers.pmaports module¶
Functions that work with pmaports.
See also: - pmb/helpers/repo.py (work with binary package repos) - pmb/helpers/package.py (work with both)
- pmb.helpers.pmaports.check_arches(arches: list[str], arch: Arch) bool ¶
Check if building for a certain arch is allowed.
- Parameters:
arches – list of all supported arches, as it can be found in the arch=”” line of APKBUILDS (including all, noarch, !arch, …). For example: [“x86_64”, “x86”, “!armhf”]
arch – the architecture to check for
- Returns:
True when building is allowed, False otherwise
- pmb.helpers.pmaports.find_optional(package: str) Path | None ¶
- pmb.helpers.pmaports.find_providers(provide: str, default: list[str]) list[tuple[Any, Any]] ¶
Search for providers of the specified (virtual) package in pmaports.
Note: Currently only providers from a single APKBUILD are returned.
- Parameters:
provide – the (virtual) package to search providers for
default – the _pmb_default to look through for defaults
- Returns:
tuple list (pkgname, apkbuild_pkg) with providers, sorted by provider_priority. The provider with the highest priority (which would be selected by default) comes first.
- pmb.helpers.pmaports.get(pkgname: str, must_exist: bool = True, subpackages: bool = True, with_extra_repos: Literal['default', 'enabled', 'disabled'] = 'default') dict[str, Any] ¶
- pmb.helpers.pmaports.get_channel_new(channel: str) str ¶
Translate legacy channel names to the new ones.
Legacy names are still supported for compatibility with old branches (pmb#2015). :param channel: name as read from pmaports.cfg or channels.cfg, like “edge”, “v21.03” etc., or potentially a legacy name like “stable”.
- Returns:
name in the new format, e.g. “edge” or “v21.03”
- pmb.helpers.pmaports.get_list() list[str] ¶
- Returns:
list of all pmaport pkgnames ([“hello-world”, …])
- pmb.helpers.pmaports.get_repo(pkgname: str) str | None ¶
Get the repository folder of an aport.
- Pkgname:
package name
- Returns:
None if pkgname is not in extra-repos/
”systemd” if the pkgname is in extra-repos/systemd/
- pmb.helpers.pmaports.guess_main(subpkgname: str) Path | None ¶
Find the main package by assuming it is a prefix of the subpkgname.
We do that, because in some APKBUILDs the subpkgname=”” variable gets filled with a shell loop and the APKBUILD parser in pmbootstrap can’t parse this right. (Intentionally, we don’t want to implement a full shell parser.)
- Parameters:
subpkgname – subpackage name (e.g. “u-boot-some-device”)
- Returns:
full path to the aport, e.g.: “/home/user/code/pmbootstrap/aports/main/u-boot”
None when we couldn’t find a main package
- pmb.helpers.pmaports.guess_main_dev(subpkgname: str) Path | None ¶
Check if a package without “-dev” at the end exists in pmaports or not, and log the appropriate message.
Don’t call this function directly, use guess_main() instead.
- Parameters:
subpkgname – subpackage name, must end in “-dev”
- Returns:
full path to the pmaport or None
- pmb.helpers.pmaports.require_bootstrap(arch, trigger_str)¶
Check if repo_bootstrap was done, if any is needed.
- Parameters:
arch – for which architecture
trigger_str – message for the user to understand what caused this
- pmb.helpers.pmaports.require_bootstrap_error(repo, arch, trigger_str)¶
Tell the user that they need to do repo_bootstrap, with some context.
- Parameters:
repo – which repository
arch – for which architecture
trigger_str – message for the user to understand what caused this
- pmb.helpers.pmaports.show_pkg_not_found_systemd_hint(package: str, with_extra_repos: Literal['default', 'enabled', 'disabled']) None ¶
Check if a package would be found if systemd was enabled and display a hint about it.
pmb.helpers.repo module¶
Functions that work with binary package repos.
See also: - pmb/helpers/pmaports.py (work with pmaports) - pmb/helpers/package.py (work with both)
- pmb.helpers.repo.alpine_apkindex_path(repo: str = 'main', arch: Arch | None = None) Path ¶
Get the path to a specific Alpine APKINDEX file on disk and download it if necessary.
- Parameters:
repo – Alpine repository name (e.g. “main”)
arch – Alpine architecture (e.g. “armhf”), defaults to native arch.
- Returns:
full path to the APKINDEX file
- pmb.helpers.repo.apkindex_files(arch: Arch | None = None, user_repository: bool = True, exclude_mirrors: list[str] = []) list[Path] ¶
Get a list of outside paths to all resolved APKINDEX.tar.gz files for a specific arch.
- Parameters:
arch – defaults to native
user_repository – add path to index of locally built packages
exclude_mirrors – list of mirrors to exclude (e.g. [“alpine”, “pmaports”])
- Returns:
list of absolute APKINDEX.tar.gz file paths
- pmb.helpers.repo.apkindex_hash(url: str, length: int = 8) Path ¶
Generate the hash that APK adds to the APKINDEX and apk packages in its apk cache folder.
It is the “12345678” part in this example: “APKINDEX.12345678.tar.gz”.
- Parameters:
length – The length of the hash in the output file.
See also: official implementation in apk-tools: <https://git.alpinelinux.org/cgit/apk-tools/>
blob.c: apk_blob_push_hexdump(), “const char \*xd” apk_defines.h: APK_CACHE_CSUM_BYTES database.c: apk_repo_format_cache_index()
pmb.helpers.repo_missing module¶
- pmb.helpers.repo_missing.filter_aport_packages(pkgnames)¶
Create a subset of pkgnames where each one has an aport.
- Parameters:
arch – architecture (e.g. “armhf”)
pkgnames – list of package names (e.g. [“hello-world”, “test12”])
- Returns:
subset of pkgnames (e.g. [“hello-world”])
- pmb.helpers.repo_missing.filter_arch_packages(arch, pkgnames)¶
Create a subset of pkgnames with packages removed that can not be built for a certain arch.
- Parameters:
arch – architecture (e.g. “armhf”)
pkgnames – list of package names (e.g. [“hello-world”, “test12”])
- Returns:
subset of pkgnames (e.g. [“hello-world”])
- pmb.helpers.repo_missing.filter_missing_packages(arch, pkgnames)¶
Create a subset of pkgnames with missing or outdated binary packages.
- Parameters:
arch – architecture (e.g. “armhf”)
pkgnames – list of package names (e.g. [“hello-world”, “test12”])
- Returns:
subset of pkgnames (e.g. [“hello-world”])
- pmb.helpers.repo_missing.generate(arch, overview, pkgname=None, built=False)¶
Get packages that need to be built, with all their dependencies.
- Parameters:
arch – architecture (e.g. “armhf”)
pkgname – only look at a specific package
built – include packages that have already been built
- Returns:
a list like the following: [{“pkgname”: “hello-world”, “repo”: “main”, “version”: “1-r4”}, {“pkgname”: “package-depending-on-hello-world”, “version”: “0.5-r0”, “repo”: “main”}]
- pmb.helpers.repo_missing.generate_output_format(arch: Arch, pkgnames: list[str]) list[dict[str, Any]] ¶
Generate the detailed output format.
- Parameters:
arch – architecture
pkgnames – list of package names that should be in the output, e.g.: [“hello-world”, “pkg-depending-on-hello-world”] :returns: a list like the following: [{“pkgname”: “hello-world”, “repo”: “main”, “version”: “1-r4”, “depends”: []}, {“pkgname”: “pkg-depending-on-hello-world”, “version”: “0.5-r0”, “repo”: “main”, “depends”: [“hello-world”]}]
- pmb.helpers.repo_missing.get_relevant_packages(arch, pkgname=None, built=False)¶
Get all packages that can be built for the architecture in question.
- Parameters:
arch – architecture (e.g. “armhf”)
pkgname – only look at a specific package (and its dependencies)
built – include packages that have already been built
- Returns:
an alphabetically sorted list of pkgnames, e.g.: [“devicepkg-dev”, “hello-world”, “osk-sdl”]
pmb.helpers.run module¶
- pmb.helpers.run.root(cmd: Sequence[PathString], working_dir: Path | None = None, output: RunOutputTypePopen = 'log', output_return: Literal[False] = False, check: bool | None = None, env: Env = {}) subprocess.Popen ¶
- pmb.helpers.run.root(cmd: Sequence[PathString], working_dir: Path | None = None, output: RunOutputTypeDefault = 'log', output_return: Literal[False] = False, check: bool | None = None, env: Env = {}) int
- pmb.helpers.run.root(cmd: Sequence[PathString], working_dir: Path | None = None, output: RunOutputType = 'log', output_return: Literal[True] = False, check: bool | None = None, env: Env = {}) str
Run a command on the host system as root, with sudo or doas.
- 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.helpers.run.user(cmd: Sequence[Path | str], working_dir: Path | None = None, output: Literal['log', 'stdout', 'interactive', 'tui', 'null'] | Literal['background', 'pipe'] = 'log', output_return: bool = False, check: bool | None = None, env: dict[str, Path | str] = {}, sudo: bool = False) str | int | Popen ¶
Run a command on the host system as user.
- 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.helpers.run.user_output(cmd: Sequence[Path | str], working_dir: Path | None = None, output: Literal['log', 'stdout', 'interactive', 'tui', 'null'] | Literal['background', 'pipe'] = 'log', check: bool | None = None, env: dict[str, Path | str] = {}, sudo: bool = False) str ¶
pmb.helpers.run_core module¶
- pmb.helpers.run_core.add_proxy_env_vars(env)¶
Add proxy environment variables from host to the environment of the command we are running.
- Parameters:
env – dict of environment variables, it will be extended with all of the proxy env vars that are set on the host
- pmb.helpers.run_core.background(cmd, working_dir=None)¶
Run a subprocess in background and redirect its output to the log.
- pmb.helpers.run_core.check_return_code(code, log_message)¶
Check the return code of a command.
- Parameters:
code – exit code to check
log_message – simplified and more readable form of the command, e.g. “(native) % echo test” instead of the full command with entering the chroot and more escaping
- Raises:
RuntimeError – when the code indicates that the command failed
- pmb.helpers.run_core.core(log_message, cmd, working_dir=None, output='log', output_return=False, check=None, sudo=False, disable_timeout=False)¶
Run a command and create a log entry.
This is a low level function not meant to be used directly. Use one of the following instead: pmb.helpers.run.user(), pmb.helpers.run.root(), pmb.chroot.user(), pmb.chroot.root()
- Parameters:
log_message – simplified and more readable form of the command, e.g. “(native) % echo test” instead of the full command with entering the chroot and more escaping
cmd – command as list, e.g. [“echo”, “string with spaces”]
working_dir – path in host system where the command should run
output –
- where to write the output (stdout and stderr) of the
process. We almost always write to the log file, which can be read with “pmbootstrap log” (output values: “log”, “stdout”, “interactive”, “background”), so it’s easy to trace what pmbootstrap does.
The exceptions are “tui” (text-based user interface), where it does not make sense to write to the log file (think of ncurses UIs, such as “menuconfig”) and “pipe” where the output is written to a pipe for manual asynchronous consumption by the caller.
When the output is not set to “interactive”, “tui”, “background” or “pipe”, we kill the process if it does not output anything for 5 minutes (time can be set with “pmbootstrap –timeout”).
The table below shows all possible values along with their properties. “wait” indicates that we wait for the process to complete.
output value
timeout
out to log
out to stdout
wait
pass stdin
”log”
x
x
x
”stdout”
x
x
x
x
”interactive”
x
x
x
x
”tui”
x
x
x
”background”
x
”pipe”
”null”
output_return – in addition to writing the program’s output to the destinations above in real time, write to a buffer and return it as string when the command has completed. This is not possible when output is “background”, “pipe” or “tui”.
check – an exception will be raised when the command’s return code is not 0. Set this to False to disable the check. This parameter can not be used when the output is “background” or “pipe”.
sudo – use sudo to kill the process when it hits the timeout.
- Returns:
program’s return code (default)
subprocess.Popen instance (output is “background” or “pipe”)
the program’s entire output (output_return is True)
- pmb.helpers.run_core.flat_cmd(cmds: Sequence[Sequence[Path | str]], working_dir: Path | None = None, env: dict[str, Path | str] = {}) str ¶
Convert a shell command passed as list into a flat shell string with proper escaping.
- Parameters:
cmds – list of commands as list, e.g. [“echo”, “string with spaces”]
working_dir – when set, prepend “cd …;” to execute the command in the given working directory
env – dict of environment variables to be passed to the command, e.g. {“JOBS”: “5”}
- Returns:
the flat string, e.g. echo ‘string with spaces’ cd /home/pmos;echo ‘string with spaces’
- pmb.helpers.run_core.foreground_pipe(cmd, working_dir=None, output_to_stdout=False, output_return=False, output_log=True, output_timeout=True, sudo=False, stdin=None)¶
Run a subprocess in foreground with redirected output.
Optionally kill it after being silent for too long.
- Parameters:
cmd – command as list, e.g. [“echo”, “string with spaces”]
working_dir – path in host system where the command should run
output_to_stdout – copy all output to pmbootstrap’s stdout
output_return – return the output of the whole program
output_timeout – kill the process when it doesn’t print any output after a certain time (configured with –timeout) and raise a RuntimeError exception
sudo – use sudo to kill the process when it hits the timeout
- Returns:
(code, output) * code: return code of the program * output: “” * output: full program output string (output_return is True)
- pmb.helpers.run_core.foreground_tui(cmd, working_dir=None)¶
Run a subprocess in foreground without redirecting any of its output.
This is the only way text-based user interfaces (ncurses programs like vim, nano or the kernel’s menuconfig) work properly.
- pmb.helpers.run_core.kill_command(pid, sudo)¶
Kill a command process and recursively kill its child processes.
- Parameters:
pid – process id that will be killed
sudo – use sudo to kill the process
- pmb.helpers.run_core.kill_process_tree(pid, ppids, sudo)¶
Recursively kill a pid and its child processes.
- Parameters:
pid – process id that will be killed
ppids – list of process id and parent process id tuples (pid, ppid)
sudo – use sudo to kill the process
- pmb.helpers.run_core.pipe(cmd, working_dir=None)¶
Run a subprocess in background and redirect its output to a pipe.
- pmb.helpers.run_core.pipe_read(process: subprocess.Popen, output_to_stdout: bool = False, output_log: bool = True, output_return: Literal[False] = False, output_return_buffer: None = None) None ¶
- pmb.helpers.run_core.pipe_read(process: subprocess.Popen, output_to_stdout: bool = False, output_log: bool = True, output_return: Literal[True] = False, output_return_buffer: list[bytes] = None) None
Read all output from a subprocess, copy it to the log and optionally stdout and a buffer variable.
This is only meant to be called by foreground_pipe() below.
- Parameters:
process – subprocess.Popen instance
output_to_stdout – copy all output to pmbootstrap’s stdout
output_return – when set to True, output_return_buffer will be extended
output_return_buffer – list of bytes that gets extended with the current output in case output_return is True.
- pmb.helpers.run_core.sanity_checks(output: Literal['log', 'stdout', 'interactive', 'tui', 'null'] | Literal['background', 'pipe'] = 'log', output_return: bool = False, check: bool | None = None) None ¶
Raise an exception if the parameters passed to core() don’t make sense.
(all parameters are described in core() below).
- pmb.helpers.run_core.sudo_timer_iterate()¶
Run sudo -v and schedule a new timer to repeat the same.
- pmb.helpers.run_core.sudo_timer_start()¶
Start a timer to call sudo -v periodically, so that the password is only needed once.
pmb.helpers.status module¶
- pmb.helpers.status.print_status() None ¶
- Parameters:
details – if True, print each passing check instead of a summary
- Returns:
True if all checks passed, False otherwise
- pmb.helpers.status.print_status_line(key: str, value: str) None ¶
pmb.helpers.toml module¶
pmb.helpers.ui module¶
- pmb.helpers.ui.check_option(ui: str, option: str, with_extra_repos: Literal['default', 'enabled', 'disabled'] = 'default') bool ¶
Check if an option, such as pmb:systemd, is inside an UI’s APKBUILD.
- pmb.helpers.ui.list_ui(arch)¶
Get all UIs, for which aports are available with their description.
- Parameters:
arch – device architecture, for which the UIs must be available
- Returns:
[(“none”, “No graphical…”), (“weston”, “Wayland reference…”)]