pmb.install package

Submodules

pmb.install.blockdevice module

pmb.install.blockdevice.create(args: PmbArgs, size_boot: int, size_root: int, size_reserve: int, split: bool, disk: Path | None) None

Create /dev/install (the “install blockdevice”).

Parameters:
  • size_boot – size of the boot partition in MiB

  • size_root – size of the root partition in MiB

  • size_reserve – empty partition between root and boot in MiB (pma#463)

  • split – create separate images for boot and root partitions

  • disk – path to disk block device (e.g. /dev/mmcblk0) or None

pmb.install.blockdevice.create_and_mount_image(args: PmbArgs, size_boot: int, size_root: int, size_reserve: int, split: bool = False) None

Create a new image file, and mount it as /dev/install.

Parameters:
  • size_boot – size of the boot partition in MiB

  • size_root – size of the root partition in MiB

  • size_reserve – empty partition between root and boot in MiB (pma#463)

  • split – create separate images for boot and root partitions

pmb.install.blockdevice.mount_disk(path: Path) None
Parameters:

path – path to disk block device (e.g. /dev/mmcblk0)

pmb.install.blockdevice.previous_install(path: Path) bool

Search the disk for possible existence of a previous installation of pmOS. We temporarily mount the possible pmOS_boot partition as /dev/diskp1 inside the native chroot to check the label from there. :param path: path to disk block device (e.g. /dev/mmcblk0)

pmb.install.format module

pmb.install.format.format(args: PmbArgs, layout: PartitionLayout, boot_label: str, root_label: str, disk: Path | str | None) None
Parameters:
  • layout – partition layout from get_partition_layout()

  • boot_label – label of the boot partition (e.g. “pmOS_boot”)

  • root_label – label of the root partition (e.g. “pmOS_root”)

  • disk – path to disk block device (e.g. /dev/mmcblk0) or None

pmb.install.format.format_and_mount_boot(args: PmbArgs, device: str, boot_label: str) None
Parameters:
  • device – boot partition on install block device (e.g. /dev/installp1)

  • boot_label – label of the root partition (e.g. “pmOS_boot”)

When adjusting this function, make sure to also adjust ondev-prepare-internal-storage.sh in postmarketos-ondev.git!

pmb.install.format.format_and_mount_root(args: PmbArgs, device: str, root_label: str, disk: Path | str | None) None
Parameters:
  • device – root partition on install block device (e.g. /dev/installp2)

  • root_label – label of the root partition (e.g. “pmOS_root”)

  • disk – path to disk block device (e.g. /dev/mmcblk0) or None

pmb.install.format.format_luks_root(args: PmbArgs, device: str) None
Parameters:

device – root partition on install block device (e.g. /dev/installp2)

pmb.install.format.get_root_filesystem(args: PmbArgs) str
pmb.install.format.install_fsprogs(filesystem)

Install the package required to format a specific filesystem.

pmb.install.format.prepare_btrfs_subvolumes(args: PmbArgs, device: str, mountpoint: str) None

Create separate subvolumes if root filesystem is btrfs. This lets us do snapshots and rollbacks of relevant parts of the filesystem. /var contains logs, VMs, containers, flatpaks; and shouldn’t roll back, /root is root’s home directory and shouldn’t roll back, /tmp has temporary files, snapshotting them is unnecessary, /srv contains data for web and FTP servers, and shouldn’t roll back, /snapshots should be a separate subvol so that changing the root subvol doesn’t affect snapshots

pmb.install.losetup module

pmb.install.losetup.detach_all() None

Detach all loop devices used by pmbootstrap

pmb.install.losetup.device_by_back_file(back_file: Path) Path

Get the /dev/loopX device that points to a specific image file.

pmb.install.losetup.init() None
pmb.install.losetup.mount(img_path: Path, _sector_size: int | None = None) Path
Parameters:

img_path – Path to the img file inside native chroot.

pmb.install.losetup.umount(img_path: Path) None
Parameters:

img_path – Path to the img file inside native chroot.

pmb.install.partition module

pmb.install.partition.partition(layout: PartitionLayout, size_boot: int, size_reserve: int) None

Partition /dev/install and create /dev/install{p1,p2,p3}: * /dev/installp1: boot * /dev/installp2: root (or reserved space) * /dev/installp3: (root, if reserved space > 0)

When adjusting this function, make sure to also adjust ondev-prepare-internal-storage.sh in postmarketos-ondev.git!

Parameters:
  • layout – partition layout from get_partition_layout()

  • size_boot – size of the boot partition in MiB

  • size_reserve – empty partition between root and boot in MiB (pma#463)

pmb.install.partition.partition_cgpt(layout: PartitionLayout, size_boot: int, size_reserve: int) None

This function does similar functionality to partition(), but this one is for ChromeOS devices which use special GPT. We don’t follow the Discoverable Partitions Specification here for that exact reason.

Parameters:
  • layout – partition layout from get_partition_layout()

  • size_boot – size of the boot partition in MiB

  • size_reserve – empty partition between root and boot in MiB (pma#463)

pmb.install.partition.partitions_mount(device: str, layout: PartitionLayout, disk: Path | None) None

Mount blockdevices of partitions inside native chroot :param layout: partition layout from get_partition_layout() :param disk: path to disk block device (e.g. /dev/mmcblk0) or None

pmb.install.recovery module

pmb.install.recovery.create_zip(args: PmbArgs, chroot: Chroot, device: str) None

Create android recovery compatible installer zip.

pmb.install.ui module

pmb.install.ui.get_groups(config: Config) list[str]

Get all groups to which the user additionally must be added. The list of groups are listed in _pmb_groups of the UI and UI-extras package.

Returns:

list of groups, e.g. [“feedbackd”, “udev”]

pmb.install._install module

pmb.install._install.configure_apk(args: PmbArgs) None

Copy over all official keys, and the keys used to compile local packages (unless –no-local-pkgs is set). Then copy the corresponding APKINDEX files and remove the /mnt/pmbootstrap/packages repository.

pmb.install._install.copy_files_from_chroot(args: PmbArgs, chroot: Chroot) None

Copy all files from the rootfs chroot to /mnt/install, except for the home folder (because /home will contain some empty mountpoint folders).

Parameters:

suffix – the chroot suffix, e.g. “rootfs_qemu-amd64”

pmb.install._install.copy_ssh_keys(config: Config) None

If requested, copy user’s SSH public keys to the device if they exist

pmb.install._install.create_crypttab(args: PmbArgs, layout: PartitionLayout, chroot: Chroot) None

Create /etc/crypttab config

Parameters:
  • layout – partition layout from get_partition_layout()

  • suffix – of the chroot, which crypttab will be created to

pmb.install._install.create_device_rootfs(args: PmbArgs, step: int, steps: int) None
pmb.install._install.create_fstab(args: PmbArgs, layout: PartitionLayout, chroot: Chroot) None

Create /etc/fstab config

Parameters:
  • layout – partition layout from get_partition_layout()

  • chroot – of the chroot, which fstab will be created to

pmb.install._install.create_home_from_skel(filesystem: str, user: str) None

Create /home/{user} from /etc/skel

pmb.install._install.disable_firewall(chroot: Chroot) None
pmb.install._install.disable_sshd(chroot: Chroot) None
pmb.install._install.embed_firmware(args: PmbArgs, suffix: Chroot) None

This method will embed firmware, located at /usr/share, that are specified by the “sd_embed_firmware” deviceinfo parameter into the SD card image (e.g. u-boot). Binaries that would overwrite the first partition are not accepted, and if multiple binaries are specified then they will be checked for collisions with each other.

Parameters:

suffix – of the chroot, which holds the firmware files (either the rootfs_{args.device} or installer_{args.device}

pmb.install._install.generate_binary_list(args: PmbArgs, chroot: Chroot, step: int) list[tuple[str, int]]

Perform three checks prior to writing binaries to disk: 1) that binaries exist, 2) that binaries do not extend into the first partition, 3) that binaries do not overlap each other.

Parameters:
  • suffix – of the chroot, which holds the firmware files (either the rootfs_{args.device} or installer_{args.device}

  • step – partition step size in bytes

pmb.install._install.get_kernel_package(config: Config) list[str]

Get the device’s kernel subpackage based on the user’s choice in “pmbootstrap init”.

Parameters:

device – code name, e.g. “sony-amami”

Returns:

[] or the package in a list, e.g. [“device-sony-amami-kernel-mainline”]

pmb.install._install.get_nonfree_packages(device)

Get any legacy non-free subpackages in the APKBUILD. Also see: https://postmarketos.org/edge/2024/02/15/default-nonfree-fw/

Returns:

list of non-free packages to be installed. Example: [“device-nokia-n900-nonfree-firmware”]

pmb.install._install.get_ondev_pkgver(args: PmbArgs) str
pmb.install._install.get_partition_layout(reserve: bool | int, kernel: bool) PartitionLayout
Parameters:
  • reserve – create an empty partition between root and boot (pma#463)

  • kernel – create a separate kernel partition before all other partitions, e.g. for the ChromeOS devices with cgpt

Returns:

the partition layout, e.g. without reserve and kernel: {“kernel”: None, “boot”: 1, “reserve”: None, “root”: 2}

pmb.install._install.get_recommends(args: PmbArgs, packages: list[str]) Sequence[str]

Look through the specified packages and collect additional packages specified under _pmb_recommends in them. This is recursive, so it will dive into packages that are listed under recommends to collect any packages they might also have listed under their own _pmb_recommends.

Recursion is only done into packages found in pmaports.

If running with pmbootstrap install –no-recommends, this function returns an empty list.

Parameters:
  • packages – list of packages of which we want to get the recommends

  • initial – used internally when the function calls itself

Returns:

list of pkgnames, e.g. [“chatty”, “gnome-contacts”]

pmb.install._install.get_selected_providers(args: PmbArgs, packages: list[str]) list[str]

Look through the specified packages and see which providers were selected in “pmbootstrap init”. Install those as extra packages to select them instead of the default provider. This function is called recursively on the dependencies of the given packages.

Parameters:
  • packages – the packages that have selectable providers (_pmb_select)

  • initial – used internally when the function calls itself

Returns:

additional provider packages to install

pmb.install._install.get_subpartitions_size(chroot: Chroot) tuple[int, int]

Calculate the size of the boot and root subpartition.

Parameters:

suffix – the chroot suffix, e.g. “rootfs_qemu-amd64”

Returns:

(boot, root) the size of the boot and root partition as integer in MiB

pmb.install._install.get_uuid(args: PmbArgs, partition: Path) str

Get UUID of a partition

Parameters:

partition – block device for getting UUID from

pmb.install._install.install(args: PmbArgs) None
pmb.install._install.install_on_device_installer(args: PmbArgs, step: int, steps: int) None
pmb.install._install.install_recovery_zip(args: PmbArgs, device: str, arch: Arch, steps: int) None
pmb.install._install.install_system_image(args: PmbArgs, size_reserve: int, chroot: Chroot, step: int, steps: int, boot_label: str = 'pmOS_boot', root_label: str = 'pmOS_root', split: bool = False, disk: Path | None = None) None
Parameters:
  • size_reserve – empty partition between root and boot in MiB (pma#463)

  • suffix – the chroot suffix, where the rootfs that will be installed on the device has been created (e.g. “rootfs_qemu-amd64”)

  • step – next installation step

  • steps – total installation steps

  • boot_label – label of the boot partition (e.g. “pmOS_boot”)

  • root_label – label of the root partition (e.g. “pmOS_root”)

  • split – create separate images for boot and root partitions

  • disk – path to disk block device (e.g. /dev/mmcblk0) or None

pmb.install._install.is_root_locked(chroot: Chroot) bool

Figure out from /etc/shadow if root is already locked. The output of this is stored in the log, so use grep to only log the line for root, not the line for the user which contains a hash of the user’s password.

Parameters:

suffix – either rootfs_{args.device} or installer_{args.device}

pmb.install._install.print_firewall_info(disabled: bool, arch: Arch) None
pmb.install._install.print_flash_info(device: str, deviceinfo: Deviceinfo, split: bool, have_disk: bool) None

Print flashing information, based on the deviceinfo data and the pmbootstrap arguments.

pmb.install._install.print_sshd_info(args: PmbArgs) None
pmb.install._install.sanity_check_boot_size()
pmb.install._install.sanity_check_disk(args: PmbArgs) None
pmb.install._install.sanity_check_disk_size(args: PmbArgs) None
pmb.install._install.sanity_check_ondev_version(args: PmbArgs) None
pmb.install._install.set_user(config: Config) None

Create user with UID 10000 if it doesn’t exist. Usually the ID for the first user created is 1000, but higher ID is chosen here to not cause issues with existing installations. Historically, this was done to avoid conflict with Android UIDs/GIDs, but pmOS has since dropped support for hybris/Halium.

pmb.install._install.setup_appstream(offline: bool, chroot: Chroot) None

If alpine-appstream-downloader has been downloaded, execute it to have update AppStream data on new installs

pmb.install._install.setup_hostname(device: str, hostname: str | None) None

Set the hostname and update localhost address in /etc/hosts

pmb.install._install.setup_keymap(config: Config) None

Set the keymap with the setup-keymap utility if the device requires it

pmb.install._install.setup_login(args: PmbArgs, config: Config, chroot: Chroot) None

Loop until the password for user has been set successfully, and disable root login.

Parameters:

suffix – of the chroot, where passwd will be execute (either the rootfs_{args.device} or installer_{args.device}

pmb.install._install.setup_login_chpasswd_user_from_arg(args: PmbArgs, user: str, chroot: Chroot) None

Set the user’s password from what the user passed as –password. Make an effort to not have the password end up in the log file by writing it to a temp file, instead of “echo user:$pass | chpasswd”. The user should of course only use this with a test password anyway, but let’s be nice and try to have the user protected from accidentally posting their password in any case.

Parameters:

suffix – of the chroot, where passwd will be execute (either the rootfs_{args.device} or installer_{args.device}

pmb.install._install.setup_timezone(chroot: Chroot, timezone: str) None
pmb.install._install.write_cgpt_kpart(args: PmbArgs, layout: PartitionLayout, suffix: Chroot) None

Write the kernel to the ChromeOS kernel partition.

Parameters:
  • layout – partition layout from get_partition_layout()

  • suffix – of the chroot, which holds the image file to be flashed

Module contents