pmb.parse package

Submodules

pmb.parse.apkindex module

pmb.parse.apkindex.cache_key(path: Path)
pmb.parse.apkindex.clear_cache(path: Path)

Clear the APKINDEX parsing cache.

Returns:

True on successful deletion, False otherwise

pmb.parse.apkindex.package(package, arch: Arch | None = None, must_exist=True, indexes=None)

Get a specific package’s data from an apkindex.

Parameters:
  • package – of which you want to have the apkindex data

  • arch – defaults to native arch, only relevant for indexes=None

  • must_exist – When set to true, raise an exception when the package is not provided at all.

  • indexes – list of APKINDEX.tar.gz paths, defaults to all index files (depending on arch)

Returns:

a dictionary with the following structure: { “arch”: “noarch”, “depends”: [“busybox-extras”, “lddtree”, … ], “pkgname”: “postmarketos-mkinitfs”, “provides”: [“mkinitfs=0.0.1”], “version”: “0.0.4-r10” } or None when the package was not found.

pmb.parse.apkindex.parse(path: Path, multiple_providers=True)

Parse an APKINDEX.tar.gz file, and return its content as dictionary.

Parameters:
  • path – path to an APKINDEX.tar.gz file or apk package database (almost the same format, but not compressed).

  • multiple_providers – assume that there are more than one provider for the alias. This makes sense when parsing the APKINDEX files from a repository (#1122), but not when parsing apk’s installed packages DB.

Returns:

(without multiple_providers)

Generic format:

{ pkgname: block, ... }

Example:

{ "postmarketos-mkinitfs": block, "so:libGL.so.1": block, ...}

Returns:

(with multiple_providers)

Generic format:

{ provide: { pkgname: block, ... }, ... }

Example:

{ "postmarketos-mkinitfs": {"postmarketos-mkinitfs": block},"so:libGL.so.1": {"mesa-egl": block, "libhybris": block}, ...}

NOTE: block is the return value from parse_next_block() above.

pmb.parse.apkindex.parse_add_block(ret, block, alias=None, multiple_providers=True)

Add one block to the return dictionary of parse().

Parameters:
  • ret – dictionary of all packages in the APKINDEX that is getting built right now. This function will extend it.

  • block – return value from parse_next_block().

  • alias – defaults to the pkgname, could be an alias from the “provides” list.

  • multiple_providers – assume that there are more than one provider for the alias. This makes sense when parsing the APKINDEX files from a repository (#1122), but not when parsing apk’s installed packages DB.

pmb.parse.apkindex.parse_blocks(path: Path)

Read all blocks from an APKINDEX.tar.gz into a list.

Path:

full path to the APKINDEX.tar.gz file.

Returns:

all blocks in the APKINDEX, without restructuring them by pkgname or removing duplicates with lower versions (use parse() if you need these features). Structure: [block, block, ...]

NOTE: “block” is the return value from parse_next_block() above.

pmb.parse.apkindex.parse_next_block(path: Path, lines: list[str])

Parse the next block in an APKINDEX.

Parameters:
  • path – to the APKINDEX.tar.gz

  • start – current index in lines, gets increased in this function. Wrapped into a list, so it can be modified “by reference”. Example: [5]

  • lines – all lines from the “APKINDEX” file inside the archive

Returns:

dictionary with the following structure: { "arch": "noarch", "depends": ["busybox-extras", "lddtree", ... ], "origin": "postmarketos-mkinitfs", "pkgname": "postmarketos-mkinitfs", "provides": ["mkinitfs=0.0.1"], "timestamp": "1500000000", "version": "0.0.4-r10" }

NOTE: “depends” is not set for packages without any dependencies, e.g. musl.

NOTE: “timestamp” and “origin” are not set for virtual packages (#1273). We use that information to skip these virtual packages in parse().

Returns:

None, when there are no more blocks

pmb.parse.apkindex.provider_highest_priority(providers, pkgname)

Get the provider(s) with the highest provider_priority and log a message.

Parameters:
  • providers – returned dict from providers(), must not be empty

  • pkgname – the package name we are interested in (for the log message)

pmb.parse.apkindex.provider_shortest(providers, pkgname)

Get the provider with the shortest pkgname and log a message. In most cases this should be sufficient, e.g. ‘mesa-purism-gc7000-egl, mesa-egl’ or ‘gtk+2.0-maemo, gtk+2.0’.

Parameters:
  • providers – returned dict from providers(), must not be empty

  • pkgname – the package name we are interested in (for the log message)

pmb.parse.apkindex.providers(package, arch: Arch | None = None, must_exist=True, indexes=None)

Get all packages, which provide one package.

Parameters:
  • package – of which you want to have the providers

  • arch – defaults to native arch, only relevant for indexes=None

  • must_exist – When set to true, raise an exception when the package is not provided at all.

  • indexes – list of APKINDEX.tar.gz paths, defaults to all index files (depending on arch)

Returns:

list of parsed packages. Example for package=”so:libGL.so.1”: {"mesa-egl": block, "libhybris": block} block is the return value from parse_next_block() above.

pmb.parse.arch module

pmb.parse.arguments module

pmb.parse.arguments.add_kernel_arg(subparser, name='package', nargs='?', *args, **kwargs)
pmb.parse.arguments.add_packages_arg(subparser, name='packages', *args, **kwargs)
pmb.parse.arguments.arguments()
pmb.parse.arguments.arguments_aportupgrade(subparser)
pmb.parse.arguments.arguments_ci(subparser)
pmb.parse.arguments.arguments_export(subparser)
pmb.parse.arguments.arguments_flasher(subparser)
pmb.parse.arguments.arguments_initfs(subparser)
pmb.parse.arguments.arguments_install(subparser)
pmb.parse.arguments.arguments_kconfig(subparser)
pmb.parse.arguments.arguments_lint(subparser)
pmb.parse.arguments.arguments_netboot(subparser)
pmb.parse.arguments.arguments_newapkbuild(subparser)

Wrapper for Alpine’s “newapkbuild” command.

Most parameters will get directly passed through, and they are defined in “pmb/config/__init__.py”. That way they can be used here and when passing them through in “pmb/helpers/frontend.py”. The order of the parameters is kept the same as in “newapkbuild -h”.

pmb.parse.arguments.arguments_pkgrel_bump(subparser)
pmb.parse.arguments.arguments_qemu(subparser)
pmb.parse.arguments.arguments_repo_bootstrap(subparser)
pmb.parse.arguments.arguments_repo_missing(subparser)
pmb.parse.arguments.arguments_sideload(subparser)
pmb.parse.arguments.arguments_status(subparser)
pmb.parse.arguments.arguments_test(subparser)
pmb.parse.arguments.get_parser()
pmb.parse.arguments.kernel_completer(prefix, action, parser=None, parsed_args=None)
Returns:

matched linux-* packages, with linux-* prefix and without

pmb.parse.arguments.package_completer(prefix, action, parser=None, parsed_args=None)
pmb.parse.arguments.toggle_other_boolean_flags(*other_destinations, value=True)

Group several argparse flags to one.

Sets multiple other_destination to value.

Parameters:

other_destinations – ‘the other argument names’ str

:param value ‘the value to set the other_destinations to’ bool

:returns custom Action

pmb.parse.arguments.type_ondev_cp(val)

Parse and validate arguments to ‘pmbootstrap install –ondev –cp’.

Parameters:

val – ‘HOST_SRC:CHROOT_DEST’ string

Returns:

(HOST_SRC, CHROOT_DEST)

pmb.parse.binfmt_info module

pmb.parse.binfmt_info.binfmt_info(arch_qemu)

pmb.parse.bootimg module

pmb.parse.bootimg.bootimg(path: Path)
pmb.parse.bootimg.get_mtk_label(path)

Read the label from the MediaTek header of the kernel or ramdisk inside an extracted boot.img. :param path: to either the kernel or ramdisk extracted from boot.img :returns: * None: file does not exist or does not have MediaTek header * Label string (e.g. “ROOTFS”, “KERNEL”)

pmb.parse.bootimg.get_qcdt_type(path)

Get the dt.img type by reading the first four bytes of the file. :param path: to the qcdt image extracted from boot.img :returns: * None: dt.img is of unknown type * Type string (e.g. “qcom”, “sprd”, “exynos”)

pmb.parse.bootimg.is_dtb(path)

pmb.parse.cpuinfo module

pmb.parse.cpuinfo.arm_big_little_first_group_ncpus() int | None

Infer from /proc/cpuinfo on aarch64 if this is a big/little architecture (if there is different processor models) and the number of cores in the first model group. https://en.wikipedia.org/wiki/ARM_big.LITTLE

Returns:

the number of cores of the first model in the order given by linux or None if not big/little architecture

pmb.parse.depends module

pmb.parse.depends.package_from_aports(pkgname_depend)
Returns:

None when there is no aport, or a dict with the keys pkgname, depends, version. The version is the combined pkgver and pkgrel.

pmb.parse.depends.package_from_index(pkgname_depend, pkgnames_install, package_aport, suffix: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>)
Returns:

None when there is no aport and no binary package, or a dict with the keys pkgname, depends, version from either the aport or the binary package provider.

pmb.parse.depends.package_provider(pkgname, pkgnames_install, suffix: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>)
Parameters:

pkgnames_install – packages to be installed

Returns:

a block from the apkindex: {“pkgname”: “…”, …} or None (no provider found)

pmb.parse.deviceinfo module

class pmb.parse.deviceinfo.Deviceinfo(path: Path, kernel: str | None = None)

Bases: object

Variables from deviceinfo. Reference: <https://postmarketos.org/deviceinfo> Many of these are unused in pmbootstrap, and still more that are described on the wiki are missing. Eventually this class and associated code should be moved to a separate library and become the authoritative source of truth for the deviceinfo format.

append_dtb: str | None = ''
arch: Arch
boot_filesystem: str | None = ''
boot_part_start: str | None = ''
bootimg_custom_args: str | None = ''
bootimg_dtb_second: str | None = ''
bootimg_mtk_label_kernel: str | None = ''
bootimg_mtk_label_ramdisk: str | None = ''
bootimg_mtk_mkimage: str | None = ''
bootimg_qcdt: str | None = ''
cgpt_kpart: str | None = ''
cgpt_kpart_size: str | None = ''
cgpt_kpart_start: str | None = ''
chassis: str
codename: str
dev_touchscreen: str | None = ''
dev_touchscreen_calibration: str | None = ''
dtb: str
external_storage: str | None = ''
flash_fastboot_max_size: str | None = ''
flash_fastboot_partition_dtbo: str | None = ''
flash_fastboot_partition_kernel: str | None = ''
flash_fastboot_partition_rootfs: str | None = ''
flash_fastboot_partition_system: str | None = ''
flash_fastboot_partition_vbmeta: str | None = ''
flash_heimdall_partition_dtbo: str | None = ''
flash_heimdall_partition_initfs: str | None = ''
flash_heimdall_partition_kernel: str | None = ''
flash_heimdall_partition_rootfs: str | None = ''
flash_heimdall_partition_system: str | None = ''
flash_heimdall_partition_vbmeta: str | None = ''
flash_kernel_on_update: str | None = ''
flash_method: str = ''
flash_mtkclient_partition_dtbo: str | None = ''
flash_mtkclient_partition_kernel: str | None = ''
flash_mtkclient_partition_rootfs: str | None = ''
flash_mtkclient_partition_vbmeta: str | None = ''
flash_offset_base: str | None = ''
flash_offset_dtb: str | None = ''
flash_offset_kernel: str | None = ''
flash_offset_ramdisk: str | None = ''
flash_offset_second: str | None = ''
flash_offset_tags: str | None = ''
flash_pagesize: str | None = ''
flash_rk_partition_kernel: str | None = ''
flash_rk_partition_rootfs: str | None = ''
flash_rk_partition_system: str | None = ''
flash_sparse: str | None = ''
flash_sparse_samsung_format: str | None = ''
format_version: str
generate_bootimg: str | None = ''
generate_legacy_uboot_initfs: str | None = ''
gpu_accelerated: bool | None = False
header_version: str | None = ''
kernel_cmdline: str | None = ''
keyboard: str | None = ''
keymaps: str | None = ''
manufacturer: str
name: str
partition_blacklist: str | None = ''
partition_type: str | None = ''
path: Path
root_filesystem: str | None = ''
rootfs_image_sector_size: str | None = ''
sd_embed_firmware: str | None = ''
sd_embed_firmware_step_size: str | None = ''
weston_pixman_type: str | None = ''
year: str

pmb.parse.kconfig module

pmb.parse.kconfig.check(pkgname, components_list=[], details=False, must_exist=True)

Check for necessary kernel config options in a package.

Parameters:
  • pkgname – the package to check for, optionally without “linux-”

  • components_list – what to check for, e.g. [“waydroid”, “iwd”]

  • details – print all warnings if True, otherwise one generic warning

  • must_exist – if False, just return if the package does not exist

Returns:

True when the check was successful, False otherwise None if the aport cannot be found (only if must_exist=False)

pmb.parse.kconfig.check_config(config_path, config_arch, pkgver, categories: list, details=False)

Check, whether one kernel config passes the rules of multiple components.

Parameters:
  • config_path – full path to kernel config file

  • config_arch – architecture name (alpine format, e.g. aarch64, x86_64)

  • pkgver – kernel version

  • categories – what to check for, e.g. [“waydroid”, “iwd”]

  • details – print all warnings if True, otherwise one per component

Returns:

True if the check passed, False otherwise

pmb.parse.kconfig.check_config_options_set(config, config_path, config_arch, options, component, pkgver, details=False)

Check, whether all the kernel config passes all rules of one component.

Print a warning if any is missing.

Parameters:
  • config – full kernel config as string

  • config_path – full path to kernel config file

  • config_arch – architecture name (alpine format, e.g. aarch64, x86_64)

  • options – kconfig_options* var passed from pmb/config/__init__.py: kconfig_options_example = { “>=0.0.0”: { # all versions “all”: { # all arches “ANDROID_PARANOID_NETWORK”: False, }, }

  • component – name of the component to test (postmarketOS, waydroid, …)

  • pkgver – kernel version

  • details – print all warnings if True, otherwise one per component

Returns:

True if the check passed, False otherwise

pmb.parse.kconfig.check_file(config_path, components_list=[], details=False)

Check for necessary kernel config options in a kconfig file.

Parameters:
  • config_path – full path to kernel config file

  • components_list – what to check for, e.g. [“waydroid”, “iwd”]

  • details – print all warnings if True, otherwise one generic warning

Returns:

True when the check was successful, False otherwise

pmb.parse.kconfig.check_option(component, details, config, config_path, option, option_value)

Check, whether one kernel config option has a given value.

Parameters:
  • component – name of the component to test (postmarketOS, waydroid, …)

  • details – print all warnings if True, otherwise one per component

  • config – full kernel config as string

  • config_path – full path to kernel config file

  • option – name of the option to check, e.g. EXT4_FS

  • option_value – expected value, e.g. True, “str”, [“str1”, “str2”]

Returns:

True if the check passed, False otherwise

pmb.parse.kconfig.extract_arch(config_path)
pmb.parse.kconfig.extract_version(config_path)
pmb.parse.kconfig.is_in_array(config, option, string)

Check, whether a config option contains string as an array element

Parameters:
  • config – full kernel config as string

  • option – name of the option to check, e.g. EXT4_FS

  • string – the string expected to be an element of the array

Returns:

True if the check passed, False otherwise

pmb.parse.kconfig.is_set(config, option)

Check, whether a boolean or tristate option is enabled either as builtin or module.

Parameters:
  • config – full kernel config as string

  • option – name of the option to check, e.g. EXT4_FS

Returns:

True if the check passed, False otherwise

pmb.parse.kconfig.is_set_str(config, option, string)

Check, whether a config option contains a string as value.

Parameters:
  • config – full kernel config as string

  • option – name of the option to check, e.g. EXT4_FS

  • string – the expected string

Returns:

True if the check passed, False otherwise

pmb.parse.version module

pmb.parse.version.check_string(a_version, rule)

Compare a version against a check string. This is used in “pmbootstrap kconfig check”, to only require certain options if the pkgver is in a specified range (#1795).

Parameters:
  • a_version – “3.4.1”

  • rule – “>=1.0.0”

Returns:

True if a_version matches rule, false otherwise.

pmb.parse.version.compare(a_version: str, b_version: str, fuzzy=False)

Compare two versions A and B to find out which one is higher, or if both are equal.

Parameters:
  • a_version – full version string A

  • b_version – full version string B

  • fuzzy – treat version strings, which end in different token types as equal

Returns:

(a < b): -1 (a == b): 0 (a > b): 1

C equivalent: apk_version_compare_blob_fuzzy()

pmb.parse.version.get_token(previous, rest)

This function does three things: * get the next token * get the token value * cut-off the whole token from rest

Parameters:
  • previous – the token before

  • rest – of the version string

Returns:

(next, value, rest) next is the new token string, value is an integer for comparing, rest is the rest of the input string.

C equivalent: get_token()

pmb.parse.version.next_token(previous, rest)

Parse the next token in the rest of the version string, we’re currently looking at.

We do not get the value of the token, or advance the rest string beyond the whole token that is what the get_token() function does (see below).

Parameters:
  • previous – the token before

  • rest – of the version string

Returns:

(next, rest) next is the upcoming token, rest is the input “rest” string with one leading ‘.’, ‘_’ or ‘-’ character removed (if there was any).

C equivalent: next_token()

pmb.parse.version.parse_suffix(rest)

Cut off the suffix of rest (which is now at the beginning of the rest variable, but regarding the whole version string, it is a suffix), and return a value integer (so it can be compared later, “beta” > “alpha” etc).

Parameters:

rest – what is left of the version string that we are currently parsing, starts with a “suffix” value (see below for valid suffixes).

Returns:

(rest, value, invalid_suffix) - rest: is the input “rest” string without the suffix - value: is a signed integer (negative for pre-, positive for post-suffixes). - invalid_suffix: is true, when rest does not start with anything from the suffixes variable.

C equivalent: get_token(), case TOKEN_SUFFIX

pmb.parse.version.token_value(string)

Return the associated value for a given token string (we parse through the version string one token at a time).

Parameters:

string – a token string

Returns:

integer associated to the token (so we can compare them in functions further below, a digit (1) looses against a letter (2), because “letter” has a higher value).

C equivalent: enum PARTS

pmb.parse.version.validate(version)

Check whether one version string is valid.

Parameters:

version – full version string

Returns:

True when the version string is valid

C equivalent: apk_version_validate()

Module contents