pmb.core package

Submodules

pmb.core.apk_package module

class pmb.core.apk_package.ApkPackage(arch: Arch, depends: list[str], origin: str | None, pkgname: str, provides: list[str], provider_priority: int | None, timestamp: str | None, version: str, pkgdesc: str | None = None, from_pmaports: bool = False)

Bases: object

Representation of a package as parsed from e.g. an APKINDEX file or an APKBUILD.

property arch: Arch

The architecture of the package.

property depends: list[str]

Dependencies for the package.

classmethod from_apkbuild(apkbuild: dict[str, Any], arch: Arch) → ApkPackage
classmethod from_apkindex_block(block_lines: list[str]) → ApkPackage
property from_pmaports: bool

Whether the object was created from an APKBUILD from pmaports.

False in every other case.

property origin: str | None

The origin name of the package.

This is unset in virtual packages.

property pkgdesc: str | None

The description of the package

property pkgname: str

The package name.

property provider_priority: int | None

The provider priority for the package.

property provides: list[str]

The package providers.

property timestamp: str | None

The unix timestamp of the package build date/time.

This is unset in virtual packages.

property version: str

The package version.

class pmb.core.apk_package.ApkPackageEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)

Bases: JSONEncoder

default(o: object) → dict[str, Any]

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return super().default(o)

pmb.core.apkindex module

class pmb.core.apkindex.Apkindex(*args, **kwargs)

Bases: PosixPath

An APKINDEX file.

classmethod from_installed_db(chroot: Chroot) → Apkindex

Get the db of apk installed packages as an Apkindex.

The db of apk installed packages has basically the same format as APKINDEX files, and it is possible to parse it with the same code.

Parameters:

chroot – the Chroot where to find the db at.

Returns:

all blocks in the APKINDEX, without restructuring them by pkgname or removing duplicates with lower versions.

get_apk_packages() → list[ApkPackage]

Read all blocks from the APKINDEX a list.

Returns:

all blocks in the APKINDEX, without restructuring them by pkgname or removing duplicates with lower versions.

classmethod iter_package_indexes_for_channel(channel: str) → Generator[Apkindex]

Iterate over local package indexes for all arches of a channel.

read_lines() → list[str]

pmb.core.arch module

class pmb.core.arch.Arch(*values)

Bases: Enum

Supported architectures according to the Alpine APKBUILD format.

aarch64 = 'aarch64'
alpine_triple() → str

Get the cross compiler triple for this architecture on Alpine.

armel = 'armel'
armhf = 'armhf'
armv7 = 'armv7'
cpu_emulation_required() → bool
static from_arch_field(arch_field: Sequence[str]) → set[Arch]
static from_machine_type(machine_type: str) → Arch
static from_str(arch: str) → Arch
go() → str
is_native() → bool
kernel_arch() → str

Value to use for ARCH= when building the Linux kernel.

kernel_dir() → str

Name of the architecture-specific directory in the Linux kernel (in arch/).

linux32_required() → bool
loongarch32 = 'loongarch32'
loongarch64 = 'loongarch64'
loongarchx32 = 'loongarchx32'
mips = 'mips'
mips64 = 'mips64'
mips64el = 'mips64el'
mipsel = 'mipsel'
static native() → Arch
noarch = 'noarch'
ppc = 'ppc'
ppc64 = 'ppc64'
ppc64le = 'ppc64le'
qemu_system() → str
qemu_user() → str
riscv32 = 'riscv32'
riscv64 = 'riscv64'
s390x = 's390x'
static supported() → set[Arch]

Officially supported host/target architectures for postmarketOS. Only specify architectures supported by Alpine here. For cross-compiling, we need to generate the “musl-$ARCH” and “gcc-$ARCH” packages (use “pmbootstrap aportgen musl-armhf” etc.).

static supported_binary() → set[Arch]

Officially supported architectures that have a binary repository

x86 = 'x86'
x86_64 = 'x86_64'
pmb.core.arch.cp15_barriers_supported() → bool

Check whether the kernel is configured to emulate or execute cp15 barriers in hardware for aarch32.

pmb.core.arch.cpu_is_32_bit_capable() → bool

Check whether the host CPU is capable of executing 32-bit binaries.

This is done by calling personality(PER_LINUX32), similar to how util-linux does it

pmb.core.chroot module

class pmb.core.chroot.Chroot(suffix_type: ChrootType, name: str | Arch | None = '')

Bases: object

property arch: Arch
static buildroot(arch: Arch) → Chroot
property dirname: str
exists() → bool
static from_str(s: str) → Chroot

Generate a Suffix from a suffix string like “buildroot_aarch64”.

static glob() → Generator[Path, None, None]

Glob all initialized chroot directories

is_mounted() → bool
static iter_patterns() → Generator[str, None, None]

Generate suffix patterns for all valid suffix types

property name: str
static native() → Chroot
property path: Path
static rootfs(device: str) → Chroot
property type: ChrootType
class pmb.core.chroot.ChrootType(*values)

Bases: Enum

BUILDROOT = 'buildroot'
IMAGE = 'image'
INSTALLER = 'installer'
NATIVE = 'native'
ROOTFS = 'rootfs'

pmb.core.config module

class pmb.core.config.AutoZapConfig(*values)

Bases: Enum

NO = 'no'
SILENTLY = 'silently'
YES = 'yes'
enabled() → bool
noisy() → bool
class pmb.core.config.Config

Bases: object

aports: Path = PosixPath('/root/.local/var/pmbootstrap/cache_git/pmaports')
auto_zap_misconfigured_chroots: AutoZapConfig = 'no'
boot_size: int = 512
build_default_device_arch: bool = False
build_pkgs_on_install: bool = True
ccache_size: str = '5G'
device: str = 'qemu-amd64'
extra_packages: str = 'none'
extra_space: int = 0
static get_default(dotted_key: str) → Any

Get the default value for a config option, supporting nested dictionaries (e.g. “mirrors.alpine”).

hostname: str = ''
is_default_channel: bool = True
jobs: int = 112
kernel: str = 'stable'
keymap: str = ''
static keys() → list[str]
locale: str = 'en_US.UTF-8'
mirrors: ClassVar[Mirrors] = {'alpine': 'http://dl-cdn.alpinelinux.org/alpine/', 'alpine_custom': 'none', 'pmaports': 'http://mirror.postmarketos.org/postmarketos/', 'pmaports_custom': 'none', 'systemd': 'http://mirror.postmarketos.org/postmarketos/extra-repos/systemd/', 'systemd_custom': 'none'}
providers: ClassVar[dict[str, str]] = {}
qemu_redir_stdio: bool = False
service_manager: ServiceManagerConfig = 'default'
ssh_key_glob: str = '~/.ssh/*.pub'
ssh_keys: bool = False
sudo_timer: bool = False
timezone: str = 'GMT'
ui: str = 'console'
ui_extras: bool = False
user: str = 'user'
work: Path = PosixPath('/root/.local/var/pmbootstrap')
class pmb.core.config.Mirrors

Bases: TypedDict

alpine: str
alpine_custom: str
pmaports: str
pmaports_custom: str
systemd: str
systemd_custom: str
class pmb.core.config.ServiceManagerConfig(*values)

Bases: Enum

DEFAULT = 'default'
OPENRC = 'openrc'
SYSTEMD = 'systemd'
static choices() → list[str]

pmb.core.context module

Global runtime context

class pmb.core.context.CommandTimeout(length: float, reason: pmb.core.context.TimeoutReason)

Bases: object

length: float
reason: TimeoutReason
class pmb.core.context.Context(config: Config)

Bases: object

assume_yes: bool = False
ccache: bool = True
command: str = ''
command_timeout: CommandTimeout | None = None
config: Config
cross: bool = False
details_to_stdout: bool = False
force: bool = False
go_mod_cache: bool = False
ignore_depends: bool = False
log: Path
no_depends: bool = False
offline: bool = False
quiet: bool = False
sudo_timer: bool = False
class pmb.core.context.TimeoutReason(*values)

Bases: Enum

CI_DETECTED = "running in CI based on autodetection (environment variable 'CI' set)"
TIMEOUT_ARG = 'timeout was explicitly set via the --timeout or -t argument'
pmb.core.context.get_context(allow_failure: Literal[False] = False) → Context
pmb.core.context.get_context(allow_failure: Literal[True] = False) → Context | None

Get immutable global runtime context.

pmb.core.context.set_context(context: Context) → None

Set global runtime context.

pmb.core.dps module

pmb.core.pkgrepo module

pmb.core.pkgrepo.pkgrepo_glob_one(path: str) → Path | None

Search for the file denoted by path in all aports repositories. path can be a glob.

pmb.core.pkgrepo.pkgrepo_iglob(path: str, recursive: bool = False) → Generator[Path, None, None]

Yield each matching glob over each aports repository.

pmb.core.pkgrepo.pkgrepo_iter_package_dirs(with_extra_repos: WithExtraRepos = WithExtraRepos.DEFAULT) → Generator[Path, None, None]

Yield each matching glob over each aports repository. Detect duplicates within the same aports repository but otherwise ignore all but the first. This allows for overriding packages.

pmb.core.pkgrepo.pkgrepo_name(path: Path) → str

Return the name of the package repository with the given path. This MUST be used instead of “path.name” as we need special handling for the pmaports repository.

pmb.core.pkgrepo.pkgrepo_name_from_subdir(subdir: Path) → str

Return the name of the package repository for the given directory. e.g. “pmaports” for “$WORKDIR/pmaports/main/foobar”

pmb.core.pkgrepo.pkgrepo_names(with_extra_repos: WithExtraRepos = WithExtraRepos.DEFAULT) → list[str]

Return a list of all the package repository names. We REQUIRE that the last repository is “pmaports”, though the directory may be named differently. So we hardcode the name here.

pmb.core.pkgrepo.pkgrepo_path(name: str) → Path

Return the absolute path to the package repository with the given name.

pmb.core.pkgrepo.pkgrepo_relative_path(path: Path) → tuple[Path, Path]

Return the path relative to the first aports repository.

Module contents