more wip (MR 2252)

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
This commit is contained in:
Caleb Connolly 2024-05-27 00:39:50 +02:00 committed by Oliver Smith
parent 34dd9d42ba
commit 48cd886401
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
34 changed files with 237 additions and 228 deletions

View file

@ -4,6 +4,7 @@ import os
from pmb.core import get_context
from pmb.helpers import logging
import pmb.aportgen.busybox_static
import pmb.aportgen.core
import pmb.aportgen.device
import pmb.aportgen.gcc
import pmb.aportgen.linux
@ -53,8 +54,8 @@ def properties(pkgname):
raise ValueError("No generator available for " + pkgname + "!")
def generate(args: PmbArgs, pkgname):
if args.fork_alpine:
def generate(args: PmbArgs, pkgname, fork_alpine=False):
if fork_alpine:
prefix, folder, options = (pkgname, "temp",
{"confirm_overwrite": True})
else:
@ -66,21 +67,22 @@ def generate(args: PmbArgs, pkgname):
if options["confirm_overwrite"] and os.path.exists(path_target):
logging.warning("WARNING: Target folder already exists: "
f"{path_target}")
if not pmb.helpers.cli.confirm(args, "Continue and overwrite?"):
if not pmb.helpers.cli.confirm("Continue and overwrite?"):
raise RuntimeError("Aborted.")
aportgen = config.work / "aportgen"
if os.path.exists(aportgen):
pmb.helpers.run.user(["rm", "-r", aportgen])
if args.fork_alpine:
upstream = pmb.aportgen.core.get_upstream_aport(args, pkgname)
if fork_alpine:
upstream = pmb.aportgen.core.get_upstream_aport(pkgname)
pmb.helpers.run.user(["cp", "-r", upstream,
aportgen])
pmb.aportgen.core.rewrite(args, pkgname, replace_simple={
pmb.aportgen.core.rewrite(pkgname, replace_simple={
"# Contributor:*": None, "# Maintainer:*": None})
else:
# Run pmb.aportgen.PREFIX.generate()
# FIXME: this is really bad and hacky let's not do this please
getattr(pmb.aportgen, prefix.replace("-", "_")).generate(args, pkgname)
# Move to the aports folder

View file

@ -6,6 +6,7 @@ import re
from pmb.types import PmbArgs
import pmb.helpers.git
import pmb.helpers.run
import pmb.helpers.args
from pmb.core import get_context
@ -155,7 +156,7 @@ def rewrite(pkgname, path_original="", fields={}, replace_pkgname=None,
handle.truncate()
def get_upstream_aport(args: PmbArgs, pkgname, arch=None):
def get_upstream_aport(pkgname, arch=None):
"""
Perform a git checkout of Alpine's aports and get the path to the aport.
@ -168,6 +169,8 @@ def get_upstream_aport(args: PmbArgs, pkgname, arch=None):
pmb.helpers.git.clone("aports_upstream")
aports_upstream_path = get_context().config.work / "cache_git/aports_upstream"
args = pmb.helpers.args.please_i_really_need_args()
if getattr(args, "fork_alpine_retain_branch", False):
logging.info("Not changing aports branch as --fork-alpine-retain-branch was "
"used.")

View file

@ -8,7 +8,7 @@ import pmb.helpers.cli
import pmb.helpers.run
import pmb.aportgen.core
import pmb.parse.apkindex
import pmb.parse.bootimg
import pmb.parse
def ask_for_architecture():
@ -60,13 +60,13 @@ def ask_for_chassis():
complete=types)
def ask_for_keyboard(args: PmbArgs):
return pmb.helpers.cli.confirm(args, "Does the device have a hardware"
def ask_for_keyboard():
return pmb.helpers.cli.confirm("Does the device have a hardware"
" keyboard?")
def ask_for_external_storage(args: PmbArgs):
return pmb.helpers.cli.confirm(args, "Does the device have a sdcard or"
def ask_for_external_storage():
return pmb.helpers.cli.confirm("Does the device have a sdcard or"
" other external storage medium?")
@ -178,7 +178,7 @@ def generate_deviceinfo_fastboot_content(bootimg=None):
return content
def generate_deviceinfo(args: PmbArgs, pkgname, name, manufacturer, year, arch,
def generate_deviceinfo(pkgname, name, manufacturer, year, arch,
chassis, has_keyboard, has_external_storage,
flash_method, bootimg=None):
codename = "-".join(pkgname.split("-")[1:])
@ -246,7 +246,7 @@ def generate_deviceinfo(args: PmbArgs, pkgname, name, manufacturer, year, arch,
handle.write(line.lstrip() + "\n")
def generate_modules_initfs(args: PmbArgs):
def generate_modules_initfs():
content = """\
# Remove this file if unnecessary (CHANGEME!)
# This file shall contain a list of modules to be included in the initramfs,
@ -268,7 +268,7 @@ def generate_modules_initfs(args: PmbArgs):
handle.write(line.lstrip() + "\n")
def generate_apkbuild(args: PmbArgs, pkgname, name, arch, flash_method):
def generate_apkbuild(pkgname, name, arch, flash_method):
# Dependencies
depends = ["postmarketos-base",
"linux-" + "-".join(pkgname.split("-")[1:])]
@ -325,15 +325,15 @@ def generate(args: PmbArgs, pkgname):
name = ask_for_name(manufacturer)
year = ask_for_year()
chassis = ask_for_chassis()
has_keyboard = ask_for_keyboard(args)
has_external_storage = ask_for_external_storage(args)
has_keyboard = ask_for_keyboard()
has_external_storage = ask_for_external_storage()
flash_method = ask_for_flash_method()
bootimg = None
if flash_method in ["fastboot", "heimdall-bootimg"]:
bootimg = ask_for_bootimg(args)
generate_deviceinfo(args, pkgname, name, manufacturer, year, arch,
generate_deviceinfo(pkgname, name, manufacturer, year, arch,
chassis, has_keyboard, has_external_storage,
flash_method, bootimg)
generate_modules_initfs(args)
generate_apkbuild(args, pkgname, name, arch, flash_method)
generate_modules_initfs()
generate_apkbuild(pkgname, name, arch, flash_method)

View file

@ -1,6 +1,7 @@
# Copyright 2023 Robert Yang
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import List
from pmb.core.context import Context
from pmb.helpers import logging
import os
from pathlib import Path
@ -113,7 +114,7 @@ def modify_apkbuild(pkgname: str, aport: Path):
pmb.aportgen.core.rewrite(pkgname, apkbuild_path, fields=fields)
def run_abuild(args: PmbArgs, pkgname: str, arch: str, apkbuild_path: Path, kbuild_out):
def run_abuild(context: Context, pkgname: str, arch: str, apkbuild_path: Path, kbuild_out):
"""
Prepare build environment and run abuild.
@ -135,7 +136,7 @@ def run_abuild(args: PmbArgs, pkgname: str, arch: str, apkbuild_path: Path, kbui
if not os.path.exists(chroot / kbuild_out_source):
raise RuntimeError("No '.output' dir found in your kernel source dir. "
"Compile the " + args.device + " kernel first and "
"Compile the " + context.config.device + " kernel first and "
"then try again. See https://postmarketos.org/envkernel"
"for details. If building on your host and only using "
"--envkernel for packaging, make sure you have O=.output "
@ -184,9 +185,10 @@ def package_kernel(args: PmbArgs):
"argument.")
aport = pmb.helpers.pmaports.find(pkgname)
context = get_context()
modify_apkbuild(pkgname, aport)
apkbuild_path = get_context().config.work / "aportgen/APKBUILD"
apkbuild_path = context.config.work / "aportgen/APKBUILD"
arch = args.deviceinfo["arch"]
apkbuild = pmb.parse.apkbuild(apkbuild_path, check_pkgname=False)
@ -199,8 +201,8 @@ def package_kernel(args: PmbArgs):
# Install package dependencies
depends, _ = pmb.build._package.build_depends(
args, apkbuild, pmb.config.arch_native, strict=False)
pmb.build.init(args, chroot)
context, apkbuild, pmb.config.arch_native, strict=False)
pmb.build.init(chroot)
if pmb.parse.arch.cpu_emulation_required(arch):
depends.append("binutils-" + arch)
pmb.chroot.apk.install(depends, chroot)
@ -211,7 +213,7 @@ def package_kernel(args: PmbArgs):
logging.info(message)
try:
run_abuild(args, pkgname, arch, apkbuild_path, kbuild_out)
run_abuild(context, pkgname, arch, apkbuild_path, kbuild_out)
except Exception as e:
pmb.helpers.mount.umount_all(Chroot.native() / "mnt/linux")
raise e

View file

@ -14,7 +14,7 @@ from pmb.core import Chroot, get_context
def newapkbuild(args: PmbArgs, folder, args_passed, force=False):
# Initialize build environment and build folder
pmb.build.init(args)
pmb.build.init()
build = Path("/home/pmos/build")
build_outside = Chroot.native() / build
if build_outside.exists():
@ -42,7 +42,7 @@ def newapkbuild(args: PmbArgs, folder, args_passed, force=False):
if os.path.exists(target):
logging.warning("WARNING: Folder already exists: " + target)
question = "Continue and delete its contents?"
if not force and not pmb.helpers.cli.confirm(args, question):
if not force and not pmb.helpers.cli.confirm(question):
raise RuntimeError("Aborted.")
pmb.helpers.run.user(["rm", "-r", target])

View file

@ -58,7 +58,7 @@ def register(arch):
pmb.helpers.run.root(["sh", "-c", 'echo "' + code + '" > ' + register])
def unregister(args: PmbArgs, arch):
def unregister(arch):
arch_qemu = pmb.parse.arch.alpine_to_qemu(arch)
binfmt_file = "/proc/sys/fs/binfmt_misc/qemu-" + arch_qemu
if not os.path.exists(binfmt_file):

View file

@ -8,7 +8,7 @@ import pmb.chroot.apk
import pmb.config.pmaports
from pmb.types import PmbArgs
import pmb.helpers.cli
from pmb.core import Chroot
from pmb.core import Chroot, get_context
def build(args: PmbArgs, flavor, chroot: Chroot):
@ -49,7 +49,7 @@ def extract(args: PmbArgs, flavor, chroot: Chroot, extra=False):
outside = chroot / inside
if outside.exists():
if not pmb.helpers.cli.confirm(args, f"Extraction folder {outside}"
if not pmb.helpers.cli.confirm(f"Extraction folder {outside}"
" already exists."
" Do you want to overwrite it?"):
raise RuntimeError("Aborted!")
@ -88,8 +88,9 @@ def ls(args: PmbArgs, flavor, suffix, extra=False):
def frontend(args: PmbArgs):
# Find the appropriate kernel flavor
chroot = Chroot.rootfs(args.device)
flavor = pmb.chroot.other.kernel_flavor_installed(args, chroot)
context = get_context()
chroot = Chroot.rootfs(context.config.device)
flavor = pmb.chroot.other.kernel_flavor_installed(chroot)
# Handle initfs actions
action = args.action_initfs

View file

@ -1,6 +1,7 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import os
from pmb.core.context import get_context
from pmb.helpers import logging
from pathlib import Path
import pmb.chroot.apk
@ -9,7 +10,7 @@ import pmb.install
from pmb.core import Chroot
def kernel_flavor_installed(args: PmbArgs, chroot: Chroot, autoinstall=True):
def kernel_flavor_installed(chroot: Chroot, autoinstall=True):
"""
Get installed kernel flavor. Optionally install the device's kernel
beforehand.
@ -22,8 +23,9 @@ def kernel_flavor_installed(args: PmbArgs, chroot: Chroot, autoinstall=True):
"""
# Automatically install the selected kernel
if autoinstall:
packages = ([f"device-{args.device}"] +
pmb.install.get_kernel_package(args, args.device))
config = get_context().config
packages = ([f"device-{config.device}"] +
pmb.install.get_kernel_package(config))
pmb.chroot.apk.install(packages, chroot)
glob_result = list((chroot / "usr/share/kernel").glob("*"))
@ -32,7 +34,8 @@ def kernel_flavor_installed(args: PmbArgs, chroot: Chroot, autoinstall=True):
return glob_result[0].name if glob_result else None
def tempfolder(args: PmbArgs, path: Path, chroot: Chroot=Chroot.native()):
# FIXME: this function has ONE user, does it need to exist?
def tempfolder(path: Path, chroot: Chroot=Chroot.native()):
"""
Create a temporary folder inside the chroot that belongs to "user".
The folder gets deleted, if it already exists.

View file

@ -77,7 +77,7 @@ def shutdown(args: PmbArgs, only_install_related=False):
# Umount device rootfs and installer chroots
for chroot_type in [ChrootType.ROOTFS, ChrootType.INSTALLER]:
chroot = Chroot(chroot_type, args.device)
chroot = Chroot(chroot_type, get_context().config.device)
if chroot.path.exists():
pmb.helpers.mount.umount_all(chroot.path)
@ -99,5 +99,5 @@ def shutdown(args: PmbArgs, only_install_related=False):
# Clean up the rest
for arch in pmb.config.build_device_architectures:
if pmb.parse.arch.cpu_emulation_required(arch):
pmb.chroot.binfmt.unregister(args, arch)
pmb.chroot.binfmt.unregister(arch)
logging.debug("Shutdown complete")

View file

@ -70,7 +70,7 @@ def zap(args: PmbArgs, confirm=True, dry=False, pkgs_local=False, http=False,
matches = glob.glob(pattern)
for match in matches:
if (not confirm or
pmb.helpers.cli.confirm(args, f"Remove {match}?")):
pmb.helpers.cli.confirm(f"Remove {match}?")):
logging.info(f"% rm -rf {match}")
if not dry:
pmb.helpers.run.root(["rm", "-rf", match])
@ -93,7 +93,7 @@ def zap_pkgs_local_mismatch(args: PmbArgs, confirm=True, dry=False):
question = "Remove binary packages that are newer than the corresponding" \
f" pmaports (channel '{channel}')?"
if confirm and not pmb.helpers.cli.confirm(args, question):
if confirm and not pmb.helpers.cli.confirm(question):
return
reindex = False
@ -143,8 +143,7 @@ def zap_pkgs_online_mismatch(args: PmbArgs, confirm=True, dry=False):
paths = glob.glob(f"{get_context().config.work}/cache_apk_*")
if not len(paths):
return
if (confirm and not pmb.helpers.cli.confirm(args,
"Remove outdated"
if (confirm and not pmb.helpers.cli.confirm("Remove outdated"
" binary packages?")):
return

View file

@ -12,7 +12,7 @@ from typing import Any, List
import pmb.aportgen
import pmb.config
import pmb.config.pmaports
from pmb.types import PmbArgs
from pmb.types import Config, PmbArgs
import pmb.helpers.cli
import pmb.helpers.devices
import pmb.helpers.git
@ -189,7 +189,7 @@ def ask_for_ui_extras(args: PmbArgs, ui):
logging.info("This user interface has an extra package:"
f" {extra['pkgdesc']}")
return pmb.helpers.cli.confirm(args, "Enable this package?",
return pmb.helpers.cli.confirm("Enable this package?",
default=args.ui_extras)
@ -234,7 +234,7 @@ def ask_for_keymaps(args: PmbArgs, info):
" one from the list above.")
def ask_for_timezone(args: PmbArgs):
def ask_for_timezone():
localtimes = ["/etc/zoneinfo/localtime", "/etc/localtime"]
zoneinfo_path = "/usr/share/zoneinfo/"
for localtime in localtimes:
@ -251,8 +251,7 @@ def ask_for_timezone(args: PmbArgs):
pass
if tz:
logging.info(f"Your host timezone: {tz}")
if pmb.helpers.cli.confirm(args,
"Use this timezone instead of GMT?",
if pmb.helpers.cli.confirm("Use this timezone instead of GMT?",
default="y"):
return tz
logging.info("WARNING: Unable to determine timezone configuration on host,"
@ -260,7 +259,7 @@ def ask_for_timezone(args: PmbArgs):
return "GMT"
def ask_for_provider_select(args: PmbArgs, apkbuild, providers_cfg):
def ask_for_provider_select(apkbuild, providers_cfg):
"""Ask for selectable providers that are specified using "_pmb_select" in a APKBUILD.
:param apkbuild: the APKBUILD with the _pmb_select
@ -375,7 +374,7 @@ def ask_for_device_kernel(args: PmbArgs, device: str):
return ret
def ask_for_device(args: PmbArgs):
def ask_for_device(config: Config):
"""
Prompt for the device vendor, model, and kernel.
@ -391,9 +390,9 @@ def ask_for_device(args: PmbArgs):
current_vendor = None
current_codename = None
if args.device:
current_vendor = args.device.split("-", 1)[0]
current_codename = args.device.split("-", 1)[1]
if config.device:
current_vendor = config.device.split("-", 1)[0]
current_codename = config.device.split("-", 1)[1]
while True:
vendor = pmb.helpers.cli.ask("Vendor", None, current_vendor,
@ -405,7 +404,7 @@ def ask_for_device(args: PmbArgs):
logging.info("The specified vendor ({}) could not be found in"
" existing ports, do you want to start a new"
" port?".format(vendor))
if not pmb.helpers.cli.confirm(args, default=True):
if not pmb.helpers.cli.confirm(default=True):
continue
else:
# Archived devices can be selected, but are not displayed
@ -425,21 +424,21 @@ def ask_for_device(args: PmbArgs):
device = f"{vendor}-{codename}"
device_path = pmb.helpers.devices.find_path(device, 'deviceinfo')
if device_path is None:
if device == args.device:
if device == args.devicesdhbfvhubsud:
raise RuntimeError(
"This device does not exist anymore, check"
" <https://postmarketos.org/renamed>"
" to see if it was renamed")
logging.info("You are about to do"
f" a new device port for '{device}'.")
if not pmb.helpers.cli.confirm(args, default=True):
if not pmb.helpers.cli.confirm(default=True):
current_vendor = vendor
continue
# New port creation confirmed
logging.info("Generating new aports for: {}...".format(device))
pmb.aportgen.generate(args, f"device-{device}")
pmb.aportgen.generate(args, f"linux-{device}")
pmb.aportgen.generate(f"device-{device}")
pmb.aportgen.generate(f"linux-{device}")
elif any("archived" == x for x in device_path.parts):
apkbuild = f"{device_path[:-len('deviceinfo')]}APKBUILD"
archived = pmb.parse._apkbuild.archived(apkbuild)
@ -463,7 +462,7 @@ def ask_for_additional_options(args: PmbArgs, cfg):
f" sudo timer: {context.sudo_timer},"
f" mirror: {','.join(context.config.mirrors_postmarketos)}")
if not pmb.helpers.cli.confirm(args, "Change them?",
if not pmb.helpers.cli.confirm("Change them?",
default=False):
return
@ -510,7 +509,7 @@ def ask_for_additional_options(args: PmbArgs, cfg):
" work with these chroots, pmbootstrap calls 'sudo'"
" internally. For long running operations, it is possible"
" that you'll have to authorize sudo more than once.")
answer = pmb.helpers.cli.confirm(args, "Enable background timer to prevent"
answer = pmb.helpers.cli.confirm("Enable background timer to prevent"
" repeated sudo authorization?",
default=context.sudo_timer)
cfg["pmbootstrap"]["sudo_timer"] = str(answer)
@ -519,7 +518,7 @@ def ask_for_additional_options(args: PmbArgs, cfg):
# prompt for mirror change
logging.info("Selected mirror:"
f" {','.join(context.config.mirrors_postmarketos)}")
if pmb.helpers.cli.confirm(args, "Change mirror?", default=False):
if pmb.helpers.cli.confirm("Change mirror?", default=False):
mirrors = ask_for_mirror(args)
cfg["pmbootstrap"]["mirrors_postmarketos"] = ",".join(mirrors)
@ -597,8 +596,7 @@ def ask_for_hostname(args: PmbArgs, device):
def ask_for_ssh_keys(args: PmbArgs):
if not len(glob.glob(os.path.expanduser("~/.ssh/id_*.pub"))):
return False
return pmb.helpers.cli.confirm(args,
"Would you like to copy your SSH public"
return pmb.helpers.cli.confirm("Would you like to copy your SSH public"
" keys to the device?",
default=args.ssh_keys)
@ -607,7 +605,7 @@ def ask_build_pkgs_on_install(args: PmbArgs):
logging.info("After pmaports are changed, the binary packages may be"
" outdated. If you want to install postmarketOS without"
" changes, reply 'n' for a faster installation.")
return pmb.helpers.cli.confirm(args, "Build outdated packages during"
return pmb.helpers.cli.confirm("Build outdated packages during"
" 'pmbootstrap install'?",
default=args.build_pkgs_on_install)
@ -677,7 +675,7 @@ def frontend(args: PmbArgs):
pmb.config.pmaports.install_githooks()
# Device
device, device_exists, kernel = ask_for_device(args)
device, device_exists, kernel = ask_for_device(config)
config.device = device
config.kernel = kernel
@ -685,7 +683,7 @@ def frontend(args: PmbArgs):
apkbuild_path = pmb.helpers.devices.find_path(device, 'APKBUILD')
if apkbuild_path:
apkbuild = pmb.parse.apkbuild(apkbuild_path)
ask_for_provider_select(args, apkbuild, config.providers)
ask_for_provider_select(apkbuild, config.providers)
# Device keymap
if device_exists:
@ -712,12 +710,12 @@ def frontend(args: PmbArgs):
" Specify them in a comma separated list (e.g.: vim,file)"
" or \"none\"")
extra = pmb.helpers.cli.ask("Extra packages", None,
args.extra_packages,
config.extra_packages,
validation_regex=r"^([-.+\w]+)(,[-.+\w]+)*$")
config.extra_packages = extra
# Configure timezone info
config.timezone = ask_for_timezone(args)
config.timezone = ask_for_timezone()
# Locale
config.locale = ask_for_locale(args)
@ -741,7 +739,7 @@ def frontend(args: PmbArgs):
if (work_exists and device_exists and
len(list(Chroot.iter_patterns())) and
pmb.helpers.cli.confirm(
args, "Zap existing chroots to apply configuration?",
"Zap existing chroots to apply configuration?",
default=True)):
setattr(args, "deviceinfo", info)

View file

@ -9,47 +9,34 @@ from pmb.types import Config
class Context():
details_to_stdout: bool
quiet: bool
command_timeout: float
sudo_timer: bool
details_to_stdout: bool = False
quiet: bool = False
command_timeout: float = 900
sudo_timer: bool = False
log: Path
# The architecture of the selected device
device_arch: Optional[str]
offline: bool
device_arch: Optional[str] = None
offline: bool = False
# Never build packages
sdnfivnsifdvsbdf: bool
# assume yes to prompts
assume_yes: bool = False
# The pmbootstrap subcommand
command: str
command: str = ""
## FIXME: build options, should not be here ##
# disable cross compilation and use QEMU
cross: bool
no_depends: bool
ignore_depends: bool
ccache: bool
go_mod_cache: bool
cross: bool = False
no_depends: bool = False
ignore_depends: bool = False
ccache: bool = False
go_mod_cache: bool = False
config: Config
def __init__(self, config: Config):
self.details_to_stdout = False
self.command_timeout = 0
self.sudo_timer = False
self.log = config.work / "log.txt"
self.quiet = False
self.device_arch = None
self.offline = False
self.config = config
self.sdnfivnsifdvsbdf = False
self.command = ""
self.cross = False
self.no_depends = False
self.ignore_depends = False
self.ccache = False
self.go_mod_cache = False
__context: Context

View file

@ -17,7 +17,7 @@ def frontend(args: PmbArgs):
# Rootfs image note
chroot = Chroot.native()
rootfs_dir = chroot / "home/pmos/rootfs" / args.device
rootfs_dir = chroot / "home/pmos/rootfs" / args.devicesdhbfvhubsud
if not rootfs_dir.glob("*.img"):
logging.info("NOTE: To export the rootfs image, run 'pmbootstrap"
" install' first (without the 'disk' parameter).")
@ -25,7 +25,7 @@ def frontend(args: PmbArgs):
# Rebuild the initramfs, just to make sure (see #69)
flavor = pmb.helpers.frontend._parse_flavor(args, args.autoinstall)
if args.autoinstall:
pmb.chroot.initfs.build(args, flavor, Chroot(ChrootType.ROOTFS, args.device))
pmb.chroot.initfs.build(args, flavor, Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud))
# Do the export, print all files
logging.info(f"Export symlinks to: {target}")

View file

@ -19,7 +19,7 @@ def odin(args: PmbArgs, flavor, folder: Path):
and with boot.img for devices with 'heimdall-bootimg'
"""
pmb.flasher.init(args)
suffix = Chroot(ChrootType.ROOTFS, args.device)
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
# Backwards compatibility with old mkinitfs (pma#660)
suffix_flavor = f"-{flavor}"
@ -49,12 +49,12 @@ def odin(args: PmbArgs, flavor, folder: Path):
# Odin flashable tar generation script
# (because redirecting stdin/stdout is not allowed
# in pmbootstrap's chroot/shell functions for security reasons)
odin_script = Chroot(ChrootType.ROOTFS, args.device) / "tmp/_odin.sh"
odin_script = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud) / "tmp/_odin.sh"
with odin_script.open("w") as handle:
odin_kernel_md5 = f"{partition_kernel}.bin.md5"
odin_initfs_md5 = f"{partition_initfs}.bin.md5"
odin_device_tar = f"{args.device}.tar"
odin_device_tar_md5 = f"{args.device}.tar.md5"
odin_device_tar = f"{args.devicesdhbfvhubsud}.tar"
odin_device_tar_md5 = f"{args.devicesdhbfvhubsud}.tar.md5"
handle.write(
"#!/bin/sh\n"
@ -90,7 +90,7 @@ def odin(args: PmbArgs, flavor, folder: Path):
# Move Odin flashable tar to native chroot and cleanup temp folder
pmb.chroot.user(["mkdir", "-p", "/home/pmos/rootfs"])
pmb.chroot.root(["mv", f"/mnt/rootfs_{args.device}{temp_folder}"
pmb.chroot.root(["mv", f"/mnt/rootfs_{args.devicesdhbfvhubsud}{temp_folder}"
f"/{odin_device_tar_md5}", "/home/pmos/rootfs/"]),
pmb.chroot.root(["chown", "pmos:pmos",
f"/home/pmos/rootfs/{odin_device_tar_md5}"])

View file

@ -35,16 +35,16 @@ def symlinks(args: PmbArgs, flavor, folder: Path):
f"uInitrd{suffix}": "Initramfs, legacy u-boot image format",
f"uImage{suffix}": "Kernel, legacy u-boot image format",
f"vmlinuz{suffix}": "Linux kernel",
f"{args.device}.img": "Rootfs with partitions for /boot and /",
f"{args.device}-boot.img": "Boot partition image",
f"{args.device}-root.img": "Root partition image",
f"pmos-{args.device}.zip": "Android recovery flashable zip",
f"{args.devicesdhbfvhubsud}.img": "Rootfs with partitions for /boot and /",
f"{args.devicesdhbfvhubsud}-boot.img": "Boot partition image",
f"{args.devicesdhbfvhubsud}-root.img": "Root partition image",
f"pmos-{args.devicesdhbfvhubsud}.zip": "Android recovery flashable zip",
"lk2nd.img": "Secondary Android bootloader",
}
# Generate a list of patterns
chroot_native = Chroot.native()
path_boot = Chroot(ChrootType.ROOTFS, args.device) / "boot"
path_boot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud) / "boot"
chroot_buildroot = Chroot.buildroot(args.deviceinfo['arch'])
files: List[Path] = [
path_boot / f"boot.img{suffix}",
@ -52,11 +52,11 @@ def symlinks(args: PmbArgs, flavor, folder: Path):
path_boot / f"uImage{suffix}",
path_boot / f"vmlinuz{suffix}",
path_boot / "dtbo.img",
chroot_native / "home/pmos/rootfs" / f"{args.device}.img",
chroot_native / "home/pmos/rootfs" / f"{args.device}-boot.img",
chroot_native / "home/pmos/rootfs" / f"{args.device}-root.img",
chroot_native / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}.img",
chroot_native / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}-boot.img",
chroot_native / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}-root.img",
chroot_buildroot / "var/libpostmarketos-android-recovery-installer" /
f"pmos-{args.device}.zip",
f"pmos-{args.devicesdhbfvhubsud}.zip",
path_boot / "lk2nd.img"
]

View file

@ -19,7 +19,7 @@ def kernel(args: PmbArgs):
# Rebuild the initramfs, just to make sure (see #69)
flavor = pmb.helpers.frontend._parse_flavor(args, args.autoinstall)
if args.autoinstall:
pmb.chroot.initfs.build(args, flavor, Chroot(ChrootType.ROOTFS, args.device))
pmb.chroot.initfs.build(args, flavor, Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud))
# Check kernel config
pmb.parse.kconfig.check(args, flavor, must_exist=False)
@ -42,9 +42,9 @@ def kernel(args: PmbArgs):
def list_flavors(args: PmbArgs):
suffix = Chroot(ChrootType.ROOTFS, args.device)
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
logging.info(f"({suffix}) installed kernel flavors:")
logging.info("* " + pmb.chroot.other.kernel_flavor_installed(args, suffix))
logging.info("* " + pmb.chroot.other.kernel_flavor_installed(suffix))
def rootfs(args: PmbArgs):
@ -55,7 +55,7 @@ def rootfs(args: PmbArgs):
if pmb.config.flashers.get(method, {}).get("split", False):
suffix = "-root.img"
img_path = Chroot.native() / "home/pmos/rootfs" / f"{args.device}{suffix}"
img_path = Chroot.native() / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}{suffix}"
if not img_path.exists():
raise RuntimeError("The rootfs has not been generated yet, please run"
" 'pmbootstrap install' first.")
@ -100,7 +100,7 @@ def sideload(args: PmbArgs):
# Missing recovery zip error
if not (Chroot.native() / mountpoint / "/var/lib/postmarketos-android-recovery-installer"
/ f"pmos-{args.device}.zip").exists():
/ f"pmos-{args.devicesdhbfvhubsud}.zip").exists():
raise RuntimeError("The recovery zip has not been generated yet,"
" please run 'pmbootstrap install' with the"
" '--android-recovery-zip' parameter first!")
@ -125,7 +125,7 @@ def flash_lk2nd(args: PmbArgs):
" bootloader mode to re-flash lk2nd.")
# Get the lk2nd package (which is a dependency of the device package)
device_pkg = f"device-{args.device}"
device_pkg = f"device-{args.devicesdhbfvhubsud}"
apkbuild = pmb.helpers.pmaports.get(device_pkg)
lk2nd_pkg = None
for dep in apkbuild["depends"]:
@ -136,7 +136,7 @@ def flash_lk2nd(args: PmbArgs):
if not lk2nd_pkg:
raise RuntimeError(f"{device_pkg} does not depend on any lk2nd package")
suffix = Chroot(ChrootType.ROOTFS, args.device)
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
pmb.chroot.apk.install([lk2nd_pkg], suffix)
logging.info("(native) flash lk2nd image")

View file

@ -51,4 +51,4 @@ def init(args: PmbArgs):
pmb.helpers.mount.bind(folder, Chroot.native() / folder)
# Mount device chroot inside native chroot (required for kernel/ramdisk)
mount_device_rootfs(args, Chroot(ChrootType.ROOTFS, args.device))
mount_device_rootfs(args, Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud))

View file

@ -76,11 +76,11 @@ def variables(args: PmbArgs, flavor, method):
_resume = "--resume"
vars = {
"$BOOT": "/mnt/rootfs_" + args.device + "/boot",
"$BOOT": "/mnt/rootfs_" + args.devicesdhbfvhubsud + "/boot",
"$DTB": _dtb,
"$IMAGE_SPLIT_BOOT": "/home/pmos/rootfs/" + args.device + "-boot.img",
"$IMAGE_SPLIT_ROOT": "/home/pmos/rootfs/" + args.device + "-root.img",
"$IMAGE": "/home/pmos/rootfs/" + args.device + ".img",
"$IMAGE_SPLIT_BOOT": "/home/pmos/rootfs/" + args.devicesdhbfvhubsud + "-boot.img",
"$IMAGE_SPLIT_ROOT": "/home/pmos/rootfs/" + args.devicesdhbfvhubsud + "-root.img",
"$IMAGE": "/home/pmos/rootfs/" + args.devicesdhbfvhubsud + ".img",
"$KERNEL_CMDLINE": _cmdline,
"$PARTITION_KERNEL": _partition_kernel,
"$PARTITION_INITFS": args.deviceinfo[
@ -91,7 +91,7 @@ def variables(args: PmbArgs, flavor, method):
"$FLASH_PAGESIZE": flash_pagesize,
"$RECOVERY_ZIP": "/mnt/buildroot_" + args.deviceinfo["arch"] +
"/var/lib/postmarketos-android-recovery-installer"
"/pmos-" + args.device + ".zip",
"/pmos-" + args.devicesdhbfvhubsud + ".zip",
"$UUU_SCRIPT": "/mnt/rootfs_" + args.deviceinfo["codename"] +
"/usr/share/uuu/flash_script.lst",
"$NO_REBOOT": _no_reboot,

View file

@ -1,14 +1,19 @@
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from argparse import Namespace
import copy
import json
import os
from pathlib import Path
import sys
import pmb.config
from pmb.core.context import Context
from pmb.types import PmbArgs
import pmb.helpers.git
import pmb.helpers.args
__args: PmbArgs = PmbArgs()
"""This file constructs the args variable, which is passed to almost all
functions in the pmbootstrap code base. Here's a listing of the kind of
information it stores.
@ -89,6 +94,7 @@ def add_deviceinfo(args: PmbArgs):
def init(args: PmbArgs) -> PmbArgs:
global __args
# Basic initialization
config = pmb.config.load(args)
# pmb.config.merge_with_args(args)
@ -137,7 +143,16 @@ def init(args: PmbArgs) -> PmbArgs:
# args.work is deprecated!
delattr(args, "work")
return args
# Copy all properties from args to out that don't start with underscores
for key, value in vars(args).items():
if not key.startswith("_") and not key == "from_argparse":
setattr(__args, key, value)
print(json.dumps(__args.__dict__))
#sys.exit(0)
return __args
def update_work(args: PmbArgs, work):
@ -157,3 +172,7 @@ def update_work(args: PmbArgs, work):
# Overwrite old attributes of args with the new attributes
for key in vars(args_new):
setattr(args, key, getattr(args_new, key))
def please_i_really_need_args() -> PmbArgs:
print("FIXME: retrieved args where it shouldn't be needed!")
return __args

View file

@ -98,14 +98,14 @@ def ask(question="Continue?", choices=["y", "n"], default="n",
validation_regex + "). Please try again.")
def confirm(args: PmbArgs, question="Continue?", default=False, no_assumptions=False):
def confirm(question="Continue?", default=False, no_assumptions=False):
"""Convenience wrapper around ask for simple yes-no questions with validation.
:param no_assumptions: ask for confirmation, even if "pmbootstrap -y' is set
:returns: True for "y", False for "n"
"""
default_str = "y" if default else "n"
if args.assume_yes and not no_assumptions:
if get_context().assume_yes and not no_assumptions:
logging.info(question + " (y/n) [" + default_str + "]: y")
return True
answer = ask(question, ["y", "n"], default_str, True, "(y|n)")

View file

@ -49,9 +49,9 @@ def _parse_flavor(args: PmbArgs, autoinstall=True):
# identifier that is typically in the form
# "postmarketos-<manufacturer>-<device/chip>", e.g.
# "postmarketos-qcom-sdm845"
chroot = Chroot(ChrootType.ROOTFS, args.device)
chroot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
flavor = pmb.chroot.other.kernel_flavor_installed(
args, chroot, autoinstall)
chroot, autoinstall)
if not flavor:
raise RuntimeError(
@ -78,7 +78,7 @@ def _parse_suffix(args: PmbArgs) -> Chroot:
def _install_ondev_verify_no_rootfs(args: PmbArgs):
chroot_dest = "/var/lib/rootfs.img"
dest = Chroot(ChrootType.INSTALLER, args.device) / chroot_dest
dest = Chroot(ChrootType.INSTALLER, args.devicesdhbfvhubsud) / chroot_dest
if dest.exists():
return

View file

@ -79,7 +79,7 @@ def get_nonfree_packages(device):
return ret
def get_kernel_package(args: PmbArgs, device):
def get_kernel_package(config: Config):
"""
Get the device's kernel subpackage based on the user's choice in
"pmbootstrap init".
@ -89,18 +89,18 @@ def get_kernel_package(args: PmbArgs, device):
["device-sony-amami-kernel-mainline"]
"""
# Empty list: single kernel devices / "none" selected
kernels = pmb.parse._apkbuild.kernels(args, device)
if not kernels or args.kernel == "none":
kernels = pmb.parse._apkbuild.kernels(config.device)
if not kernels or config.kernel == "none":
return []
# Sanity check
if args.kernel not in kernels:
raise RuntimeError("Selected kernel (" + args.kernel + ") is not"
" valid for device " + device + ". Please"
if config.kernel not in kernels:
raise RuntimeError("Selected kernel (" + config.kernel + ") is not"
" valid for device " + config.device + ". Please"
" run 'pmbootstrap init' to select a valid kernel.")
# Selected kernel subpackage
return ["device-" + device + "-kernel-" + args.kernel]
return ["device-" + config.device + "-kernel-" + config.kernel]
def copy_files_from_chroot(args: PmbArgs, chroot: Chroot):
@ -245,7 +245,7 @@ def setup_login_chpasswd_user_from_arg(args: PmbArgs, chroot: Chroot):
os.unlink(path_outside)
def is_root_locked(args: PmbArgs, chroot: Chroot):
def is_root_locked(chroot: Chroot):
"""
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
@ -282,7 +282,7 @@ def setup_login(args: PmbArgs, chroot: Chroot):
" one more time.")
# Disable root login
if is_root_locked(args, chroot):
if is_root_locked(chroot):
logging.debug(f"({chroot}) root is already locked")
else:
logging.debug(f"({chroot}) locking root")
@ -391,7 +391,7 @@ def setup_hostname(args: PmbArgs):
# default to a static default.
hostname = args.hostname
if not hostname:
hostname = args.device
hostname = args.devicesdhbfvhubsud
if not pmb.helpers.other.validate_hostname(hostname):
# A valid host name, see:
# https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.1
@ -402,7 +402,7 @@ def setup_hostname(args: PmbArgs):
raise RuntimeError("Hostname '" + hostname + "' is not valid, please"
" run 'pmbootstrap init' to configure it.")
suffix = Chroot(ChrootType.ROOTFS, args.device)
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
# Generate /etc/hostname
pmb.chroot.root(["sh", "-c", "echo " + shlex.quote(hostname) +
" > /etc/hostname"], suffix)
@ -417,7 +417,7 @@ def setup_appstream(args: PmbArgs):
If alpine-appstream-downloader has been downloaded, execute it to have
update AppStream data on new installs
"""
suffix = Chroot(ChrootType.ROOTFS, args.device)
suffix = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
installed_pkgs = pmb.chroot.apk.installed(args, suffix)
if "alpine-appstream-downloader" not in installed_pkgs or args.offline:
@ -436,7 +436,7 @@ def disable_sshd(args: PmbArgs):
return
# check=False: rc-update doesn't exit with 0 if already disabled
chroot = Chroot(ChrootType.ROOTFS, args.device)
chroot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
pmb.chroot.root(["rc-update", "del", "sshd", "default"], chroot,
check=False)
@ -474,7 +474,7 @@ def disable_firewall(args: PmbArgs):
return
# check=False: rc-update doesn't exit with 0 if already disabled
chroot = Chroot(ChrootType.ROOTFS, args.device)
chroot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
pmb.chroot.root(["rc-update", "del", "nftables", "default"], chroot,
check=False)
@ -495,7 +495,7 @@ def print_firewall_info(args: PmbArgs):
apkbuild_has_opt = False
arch = args.deviceinfo["arch"]
kernel = get_kernel_package(args, args.device)
kernel = get_kernel_package(get_context().config)
if kernel:
kernel_apkbuild = pmb.build._package.get_apkbuild(kernel[0], arch)
if kernel_apkbuild:
@ -671,8 +671,7 @@ def sanity_check_disk_size(args: PmbArgs):
# Warn if the size is larger than 100GiB
if not args.assume_yes and size > (100 * 2 * 1024 * 1024):
if not pmb.helpers.cli.confirm(args,
f"WARNING: The target disk ({devpath}) "
if not pmb.helpers.cli.confirm(f"WARNING: The target disk ({devpath}) "
"is larger than a usual SD card "
"(>100GiB). Are you sure you want to "
f"overwrite this {human} disk?",
@ -885,8 +884,8 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
workdir = Path("/home/pmos/rootfs")
logging.info("(native) make sparse rootfs")
pmb.chroot.apk.install(["android-tools"], Chroot.native())
sys_image = args.device + ".img"
sys_image_sparse = args.device + "-sparse.img"
sys_image = args.devicesdhbfvhubsud + ".img"
sys_image_sparse = args.devicesdhbfvhubsud + "-sparse.img"
pmb.chroot.user(["img2simg", sys_image, sys_image_sparse],
working_dir=workdir)
pmb.chroot.user(["mv", "-f", sys_image_sparse, sys_image],
@ -897,8 +896,8 @@ def install_system_image(args: PmbArgs, size_reserve, chroot: Chroot, step, step
if samsungify_strategy:
logging.info("(native) convert sparse image into Samsung's sparse image format")
pmb.chroot.apk.install(["sm-sparse-image-tool"], Chroot.native())
sys_image = f"{args.device}.img"
sys_image_patched = f"{args.device}-patched.img"
sys_image = f"{args.devicesdhbfvhubsud}.img"
sys_image_patched = f"{args.devicesdhbfvhubsud}-patched.img"
pmb.chroot.user(["sm_sparse_image_tool", "samsungify", "--strategy",
samsungify_strategy, sys_image, sys_image_patched],
working_dir=workdir)
@ -935,9 +934,9 @@ def print_flash_info(args: PmbArgs):
logging.info("* pmbootstrap flasher flash_rootfs")
logging.info(" Flashes the generated rootfs image to your device:")
if args.split:
logging.info(f" {Chroot.native() / 'home/pmos/rootfs' / args.device}-rootfs.img")
logging.info(f" {Chroot.native() / 'home/pmos/rootfs' / args.devicesdhbfvhubsud}-rootfs.img")
else:
logging.info(f" {Chroot.native() / 'home/pmos/rootfs' / args.device}.img")
logging.info(f" {Chroot.native() / 'home/pmos/rootfs' / args.devicesdhbfvhubsud}.img")
logging.info(" (NOTE: This file has a partition table, which"
" contains /boot and / subpartitions. That way we"
" don't need to change the partition layout on your"
@ -969,9 +968,9 @@ def print_flash_info(args: PmbArgs):
logging.info(" Flashes the kernel + initramfs to your device:")
if requires_split:
logging.info(f" {Chroot.native()}/home/pmos/rootfs/"
f"{args.device}-boot.img")
f"{args.devicesdhbfvhubsud}-boot.img")
else:
logging.info(f" {Chroot(ChrootType.ROOTFS, args.device)}/boot")
logging.info(f" {Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)}/boot")
if "boot" in flasher_actions:
logging.info(" (NOTE: " + method + " also supports booting"
@ -979,7 +978,7 @@ def print_flash_info(args: PmbArgs):
" Use 'pmbootstrap flasher boot' to do that.)")
if "flash_lk2nd" in flasher_actions and \
(Chroot(ChrootType.ROOTFS, args.device) / "/boot/lk2nd.img").exists():
(Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud) / "/boot/lk2nd.img").exists():
logging.info("* Your device supports and may even require"
" flashing lk2nd. You should flash it before"
" flashing anything else. Use 'pmbootstrap flasher"
@ -994,7 +993,7 @@ def print_flash_info(args: PmbArgs):
def install_recovery_zip(args: PmbArgs, steps):
logging.info(f"*** ({steps}/{steps}) CREATING RECOVERY-FLASHABLE ZIP ***")
suffix = "buildroot_" + args.deviceinfo["arch"]
mount_device_rootfs(args, Chroot.rootfs(args.device))
mount_device_rootfs(args, Chroot.rootfs(args.devicesdhbfvhubsud))
pmb.install.recovery.create_zip(args, suffix)
# Flash information
@ -1005,8 +1004,9 @@ def install_recovery_zip(args: PmbArgs, steps):
def install_on_device_installer(args: PmbArgs, step, steps):
# Generate the rootfs image
config = get_context().config
if not args.ondev_no_rootfs:
suffix_rootfs = Chroot.rootfs(args.device)
suffix_rootfs = Chroot.rootfs(config.device)
install_system_image(args, 0, suffix_rootfs, step=step, steps=steps,
split=True)
step += 2
@ -1014,21 +1014,21 @@ def install_on_device_installer(args: PmbArgs, step, steps):
# Prepare the installer chroot
logging.info(f"*** ({step}/{steps}) CREATE ON-DEVICE INSTALLER ROOTFS ***")
step += 1
packages = ([f"device-{args.device}",
packages = ([f"device-{config.device}",
"postmarketos-ondev"] +
get_kernel_package(args, args.device) +
get_nonfree_packages(args.device))
get_kernel_package(config) +
get_nonfree_packages(config.device))
chroot_installer = Chroot(ChrootType.INSTALLER, args.device)
chroot_installer = Chroot(ChrootType.INSTALLER, config.device)
pmb.chroot.apk.install(packages, chroot_installer)
# Move rootfs image into installer chroot
img_path_dest = chroot_installer / "var/lib/rootfs.img"
if not args.ondev_no_rootfs:
img = f"{args.device}-root.img"
img = f"{config.device}-root.img"
img_path_src = Chroot.native() / "home/pmos/rootfs" / img
logging.info(f"({chroot_installer}) add {img} as /var/lib/rootfs.img")
pmb.install.losetup.umount(args, img_path_src)
pmb.install.losetup.umount(img_path_src)
pmb.helpers.run.root(["mv", img_path_src, img_path_dest])
# Run ondev-prepare, so it may generate nice configs from the channel
@ -1037,7 +1037,7 @@ def install_on_device_installer(args: PmbArgs, step, steps):
# changes in the postmarketos-ondev package.
logging.info(f"({chroot_installer}) ondev-prepare")
channel = pmb.config.pmaports.read_config()["channel"]
channel_cfg = pmb.config.pmaports.read_config_channel(args)
channel_cfg = pmb.config.pmaports.read_config_channel()
env = {"ONDEV_CHANNEL": channel,
"ONDEV_CHANNEL_BRANCH_APORTS": channel_cfg["branch_aports"],
"ONDEV_CHANNEL_BRANCH_PMAPORTS": channel_cfg["branch_pmaports"],
@ -1045,7 +1045,7 @@ def install_on_device_installer(args: PmbArgs, step, steps):
"ONDEV_CHANNEL_MIRRORDIR_ALPINE": channel_cfg["mirrordir_alpine"],
"ONDEV_CIPHER": args.cipher,
"ONDEV_PMBOOTSTRAP_VERSION": pmb.__version__,
"ONDEV_UI": args.ui}
"ONDEV_UI": config.ui}
pmb.chroot.root(["ondev-prepare"], chroot_installer, env=env)
# Copy files specified with 'pmbootstrap install --ondev --cp'
@ -1060,7 +1060,7 @@ def install_on_device_installer(args: PmbArgs, step, steps):
# Remove $DEVICE-boot.img (we will generate a new one if --split was
# specified, otherwise the separate boot image is not needed)
if not args.ondev_no_rootfs:
img_boot = f"{args.device}-boot.img"
img_boot = f"{args.devicesdhbfvhubsud}-boot.img"
logging.info(f"(native) rm {img_boot}")
pmb.chroot.root(["rm", f"/home/pmos/rootfs/{img_boot}"])
@ -1206,7 +1206,7 @@ def create_device_rootfs(args: PmbArgs, step, steps):
# Add additional providers of base/device/UI package
install_packages += get_selected_providers(args, install_packages)
install_packages += get_kernel_package(args, device)
install_packages += get_kernel_package(config)
install_packages += get_nonfree_packages(device)
if context.config.ui.lower() != "none":
if context.config.ui_extras:
@ -1231,7 +1231,7 @@ def create_device_rootfs(args: PmbArgs, step, steps):
# Pick the most suitable unlocker depending on the packages
# selected for installation
unlocker = pmb.parse.depends.package_provider(
args, "postmarketos-fde-unlocker", install_packages, suffix)
"postmarketos-fde-unlocker", install_packages, suffix)
if unlocker["pkgname"] not in install_packages:
install_packages += [unlocker["pkgname"]]
else:
@ -1246,23 +1246,23 @@ def create_device_rootfs(args: PmbArgs, step, steps):
# dependency, in case the version increased
if args.build_pkgs_on_install:
for pkgname in install_packages:
pmb.build.package(pkgname, args.deviceinfo["arch"])
pmb.build.package(context, pkgname, args.deviceinfo["arch"])
# Install all packages to device rootfs chroot (and rebuild the initramfs,
# because that doesn't always happen automatically yet, e.g. when the user
# installed a hook without pmbootstrap - see #69 for more info)
pmb.chroot.apk.install(install_packages, suffix)
flavor = pmb.chroot.other.kernel_flavor_installed(args, suffix)
flavor = pmb.chroot.other.kernel_flavor_installed(suffix)
pmb.chroot.initfs.build(args, flavor, suffix)
# Set the user password
setup_login(args, suffix)
# Set the keymap if the device requires it
setup_keymap(args)
setup_keymap(config)
# Set timezone
setup_timezone(args)
setup_timezone(config)
# Set locale
if locale_is_set:
@ -1325,7 +1325,7 @@ def install(args: PmbArgs):
# Runs install_system_image twice
install_on_device_installer(args, step, steps)
else:
install_system_image(args, 0, Chroot(ChrootType.ROOTFS, args.device), step, steps,
install_system_image(args, 0, Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud), step, steps,
split=args.split, disk=args.disk)
print_flash_info(args)

View file

@ -13,7 +13,7 @@ import pmb.config
from pmb.core import Chroot, get_context
def previous_install(args: PmbArgs, path: Path):
def previous_install(path: Path):
"""
Search the disk for possible existence of a previous installation of
pmOS. We temporarily mount the possible pmOS_boot partition as
@ -40,7 +40,7 @@ def previous_install(args: PmbArgs, path: Path):
return "pmOS_boot" in label
def mount_disk(args: PmbArgs, path: Path):
def mount_disk( path: Path):
"""
:param path: path to disk block device (e.g. /dev/mmcblk0)
"""
@ -53,13 +53,13 @@ def mount_disk(args: PmbArgs, path: Path):
" format this!")
logging.info(f"(native) mount /dev/install (host: {path})")
pmb.helpers.mount.bind_file(path, Chroot.native() / "dev/install")
if previous_install(args, path):
if not pmb.helpers.cli.confirm(args, "WARNING: This device has a"
if previous_install(path):
if not pmb.helpers.cli.confirm("WARNING: This device has a"
" previous installation of pmOS."
" CONTINUE?"):
raise RuntimeError("Aborted.")
else:
if not pmb.helpers.cli.confirm(args, f"EVERYTHING ON {path} WILL BE"
if not pmb.helpers.cli.confirm(f"EVERYTHING ON {path} WILL BE"
" ERASED! CONTINUE?"):
raise RuntimeError("Aborted.")
@ -77,10 +77,11 @@ def create_and_mount_image(args: PmbArgs, size_boot, size_root, size_reserve,
# Short variables for paths
chroot = Chroot.native()
config = get_context().config
img_path_prefix = Path("/home/pmos/rootfs")
img_path_full = img_path_prefix / f"{args.device}.img"
img_path_boot = img_path_prefix / f"{args.device}-boot.img"
img_path_root = img_path_prefix / f"{args.device}-root.img"
img_path_full = img_path_prefix / f"{config.device}.img"
img_path_boot = img_path_prefix / f"{config.device}-boot.img"
img_path_root = img_path_prefix / f"{config.device}-root.img"
# Umount and delete existing images
for img_path in [img_path_full, img_path_boot, img_path_root]:
@ -121,7 +122,7 @@ def create_and_mount_image(args: PmbArgs, size_boot, size_root, size_reserve,
for img_path, mount_point in mount_image_paths.items():
logging.info(f"(native) mount {mount_point} ({img_path.name})")
pmb.install.losetup.mount(args, img_path)
device = pmb.install.losetup.device_by_back_file(args, img_path)
device = pmb.install.losetup.device_by_back_file(img_path)
pmb.helpers.mount.bind_file(device, Chroot.native() / mount_point)
@ -137,7 +138,7 @@ def create(args: PmbArgs, size_boot, size_root, size_reserve, split, disk: Optio
"""
pmb.helpers.mount.umount_all(Chroot.native() / "dev/install")
if disk:
mount_disk(args, disk)
mount_disk(disk)
else:
create_and_mount_image(args, size_boot, size_root, size_reserve,
split)

View file

@ -6,12 +6,12 @@ from pmb.core import Chroot
from pmb.types import PmbArgs
def install_fsprogs(args: PmbArgs, filesystem):
def install_fsprogs(filesystem):
""" Install the package required to format a specific filesystem. """
fsprogs = pmb.config.filesystems.get(filesystem)
if not fsprogs:
raise RuntimeError(f"Unsupported filesystem: {filesystem}")
pmb.chroot.apk.install([fsprogs])
pmb.chroot.apk.install([fsprogs], Chroot.native())
def format_and_mount_boot(args: PmbArgs, device, boot_label):
@ -24,7 +24,7 @@ def format_and_mount_boot(args: PmbArgs, device, boot_label):
"""
mountpoint = "/mnt/install/boot"
filesystem = args.deviceinfo["boot_filesystem"] or "ext2"
install_fsprogs(args, filesystem)
install_fsprogs(filesystem)
logging.info(f"(native) format {device} (boot, {filesystem}), mount to"
f" {mountpoint}")
if filesystem == "fat16":
@ -99,8 +99,7 @@ def prepare_btrfs_subvolumes(args: PmbArgs, device, mountpoint):
/snapshots should be a separate subvol so that changing the root subvol
doesn't affect snapshots
"""
pmb.chroot.root(args,
["btrfs", "subvol", "create",
pmb.chroot.root(["btrfs", "subvol", "create",
f"{mountpoint}/@",
f"{mountpoint}/@home",
f"{mountpoint}/@root",
@ -112,8 +111,7 @@ def prepare_btrfs_subvolumes(args: PmbArgs, device, mountpoint):
# Set the default root subvolume to be separate from top level btrfs
# subvol. This lets us easily swap out current root subvol with an
# earlier snapshot.
pmb.chroot.root(args,
["btrfs", "subvol", "set-default", f"{mountpoint}/@"])
pmb.chroot.root(["btrfs", "subvol", "set-default", f"{mountpoint}/@"])
# Make directories to mount subvols onto
pmb.chroot.root(["umount", mountpoint])
@ -131,20 +129,15 @@ def prepare_btrfs_subvolumes(args: PmbArgs, device, mountpoint):
pmb.chroot.root(["chmod", "700", f"{mountpoint}/.snapshots"])
# Mount subvols
pmb.chroot.root(args,
["mount", "-o", "subvol=@var",
pmb.chroot.root(["mount", "-o", "subvol=@var",
device, f"{mountpoint}/var"])
pmb.chroot.root(args,
["mount", "-o", "subvol=@home",
pmb.chroot.root(["mount", "-o", "subvol=@home",
device, f"{mountpoint}/home"])
pmb.chroot.root(args,
["mount", "-o", "subvol=@root",
pmb.chroot.root(["mount", "-o", "subvol=@root",
device, f"{mountpoint}/root"])
pmb.chroot.root(args,
["mount", "-o", "subvol=@srv",
pmb.chroot.root(["mount", "-o", "subvol=@srv",
device, f"{mountpoint}/srv"])
pmb.chroot.root(args,
["mount", "-o", "subvol=@snapshots",
pmb.chroot.root(["mount", "-o", "subvol=@snapshots",
device, f"{mountpoint}/.snapshots"])
# Disable CoW for /var, to avoid write multiplication
@ -180,7 +173,7 @@ def format_and_mount_root(args: PmbArgs, device, root_label, disk):
else:
raise RuntimeError(f"Don't know how to format {filesystem}!")
install_fsprogs(args, filesystem)
install_fsprogs(filesystem)
logging.info(f"(native) format {device} (root, {filesystem})")
pmb.chroot.root(mkfs_root_args + [device])

View file

@ -15,7 +15,7 @@ import pmb.chroot
from pmb.core import Chroot
def init(args: PmbArgs):
def init():
if not Path("/sys/module/loop").is_dir():
pmb.helpers.run.root(["modprobe", "loop"])
for loopdevice in Path("/dev/").glob("loop*"):
@ -39,7 +39,7 @@ def mount(args: PmbArgs, img_path: Path):
time.sleep(1)
# Mount and return on success
init(args)
init()
losetup_cmd: List[PathString] = ["losetup", "-f", img_path]
sector_size = args.deviceinfo["rootfs_image_sector_size"]
@ -48,7 +48,7 @@ def mount(args: PmbArgs, img_path: Path):
pmb.chroot.root(losetup_cmd, check=False)
try:
device_by_back_file(args, img_path)
device_by_back_file(img_path)
return
except RuntimeError:
pass

View file

@ -21,7 +21,7 @@ def partitions_mount(args: PmbArgs, layout, disk: Optional[Path]):
:param disk: path to disk block device (e.g. /dev/mmcblk0) or None
"""
if not disk:
img_path = Path("/home/pmos/rootfs") / f"{args.device}.img"
img_path = Path("/home/pmos/rootfs") / f"{args.devicesdhbfvhubsud}.img"
disk = pmb.install.losetup.device_by_back_file(args, img_path)
logging.info(f"Mounting partitions of {disk} inside the chroot")

View file

@ -15,7 +15,7 @@ def create_zip(args: PmbArgs, suffix):
Create android recovery compatible installer zip.
"""
zip_root = Path("/var/lib/postmarketos-android-recovery-installer/")
rootfs = "/mnt/rootfs_" + args.device
rootfs = "/mnt/rootfs_" + args.devicesdhbfvhubsud
flavor = pmb.helpers.frontend._parse_flavor(args)
method = args.deviceinfo["flash_method"]
vars = pmb.flasher.variables(args, flavor, method)
@ -32,7 +32,7 @@ def create_zip(args: PmbArgs, suffix):
# Create config file for the recovery installer
options = {
"DEVICE": args.device,
"DEVICE": args.devicesdhbfvhubsud,
"FLASH_KERNEL": args.recovery_flash_kernel,
"ISOREC": method == "heimdall-isorec",
"KERNEL_PARTLABEL": vars["$PARTITION_KERNEL"],
@ -69,6 +69,6 @@ def create_zip(args: PmbArgs, suffix):
["tar", "-prf", "rootfs.tar", "-C", "/", "./etc/apk/keys"],
# Compress with -1 for speed improvement
["gzip", "-f1", "rootfs.tar"],
["build-recovery-zip", args.device]]
["build-recovery-zip", args.devicesdhbfvhubsud]]
for command in commands:
pmb.chroot.root(command, suffix, working_dir=zip_root)

View file

@ -22,16 +22,16 @@ def start_nbd_server(args: PmbArgs, ip="172.16.42.2", port=9999):
chroot = Chroot.native()
rootfs_path = Path("/mnt/pmbootstrap/netboot") / f"{args.device}.img"
rootfs_path = Path("/mnt/pmbootstrap/netboot") / f"{args.devicesdhbfvhubsud}.img"
if not (chroot / rootfs_path).exists() or args.replace:
rootfs_path2 = Path("/home/pmos/rootfs") / f"{args.device}.img"
rootfs_path2 = Path("/home/pmos/rootfs") / f"{args.devicesdhbfvhubsud}.img"
if not (chroot / rootfs_path2).exists():
raise RuntimeError("The rootfs has not been generated yet, please "
"run 'pmbootstrap install' first.")
if args.replace and not \
pmb.helpers.cli.confirm(args, f"Are you sure you want to "
pmb.helpers.cli.confirm(f"Are you sure you want to "
f"replace the rootfs for "
f"{args.device}?"):
f"{args.devicesdhbfvhubsud}?"):
return
pmb.chroot.run(args, ["cp", rootfs_path2, rootfs_path])
logging.info(f"NOTE: Copied device image to {get_context().config.work}"
@ -39,7 +39,7 @@ def start_nbd_server(args: PmbArgs, ip="172.16.42.2", port=9999):
f"zap\" for your convenience. Use \"pmbootstrap netboot "
f"serve --help\" for more options.")
logging.info(f"Running nbd server for {args.device} on {ip} port {port}.")
logging.info(f"Running nbd server for {args.devicesdhbfvhubsud} on {ip} port {port}.")
while True:
logging.info("Waiting for postmarketOS device to appear...")

View file

@ -81,7 +81,7 @@ def bootimg(args: PmbArgs, path: Path):
" boot.img file")
pmb.chroot.apk.install(["file", "unpackbootimg"], Chroot.native())
temp_path = pmb.chroot.other.tempfolder(args, Path("/tmp/bootimg_parser"))
temp_path = pmb.chroot.other.tempfolder(Path("/tmp/bootimg_parser"))
bootimg_path = Chroot.native() / temp_path / "boot.img"
# Copy the boot.img into the chroot temporary folder
@ -166,6 +166,6 @@ def bootimg(args: PmbArgs, path: Path):
output["cmdline"] = f.read().replace('\n', '')
# Cleanup
pmb.chroot.run(args, ["rm", "-r", temp_path])
pmb.chroot.run.user(["rm", "-r", temp_path])
return output

View file

@ -29,7 +29,7 @@ def system_image(args: PmbArgs):
Returns path to rootfs for specified device. In case that it doesn't
exist, raise and exception explaining how to generate it.
"""
path = Chroot.native() / "home/pmos/rootfs" / f"{args.device}.img"
path = Chroot.native() / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}.img"
if not path.exists():
logging.debug(f"Could not find rootfs: {path}")
raise RuntimeError("The rootfs has not been generated yet, please "
@ -44,7 +44,7 @@ def create_second_storage(args: PmbArgs):
:returns: path to the image or None
"""
path = Chroot.native() / "home/pmos/rootfs" / f"{args.device}-2nd.img"
path = Chroot.native() / "home/pmos/rootfs" / f"{args.devicesdhbfvhubsud}-2nd.img"
pmb.helpers.run.root(["touch", path])
pmb.helpers.run.root(["chmod", "a+w", path])
resize_image(args, args.second_storage, path)
@ -102,7 +102,7 @@ def command_qemu(args: PmbArgs, arch, img_path, img_path_2nd=None):
port_ssh = str(args.port)
chroot = Chroot(ChrootType.ROOTFS, args.device)
chroot = Chroot(ChrootType.ROOTFS, args.devicesdhbfvhubsud)
chroot_native = Chroot.native()
flavor = pmb.chroot.other.kernel_flavor_installed(args, chroot)
flavor_suffix = f"-{flavor}"
@ -332,7 +332,7 @@ def run(args: PmbArgs):
"""
Run a postmarketOS image in qemu
"""
if not args.device.startswith("qemu-"):
if not args.devicesdhbfvhubsud.startswith("qemu-"):
raise RuntimeError("'pmbootstrap qemu' can be only used with one of "
"the QEMU device packages. Run 'pmbootstrap init' "
"and select the 'qemu' vendor.")

View file

@ -26,7 +26,8 @@ class AportGenEntry(TypedDict):
# Property list generated with:
# $ rg --vimgrep "((^|\s)args\.\w+)" --only-matching | cut -d"." -f3 | sort | uniq
class PmbArgs():
class PmbArgs(Namespace):
devicesdhbfvhubsud: str
action_flasher: str
action_initfs: str
action_kconfig: str

View file

@ -384,9 +384,9 @@ def test_build_local_source_high_level(args: PmbArgs, tmpdir):
# aports: Add deviceinfo (required by pmbootstrap to start)
tmpdir = str(tmpdir)
aports = tmpdir + "/aports"
aport = aports + "/device/testing/device-" + args.device
aport = aports + "/device/testing/device-" + args.devicesdhbfvhubsud
os.makedirs(aport)
path_original = pmb.helpers.pmaports.find(f"device-{args.device}")
path_original = pmb.helpers.pmaports.find(f"device-{args.devicesdhbfvhubsud}")
shutil.copy(f"{path_original}/deviceinfo", aport)
# aports: Add modified hello-world aport (source="", uses $builddir)
@ -447,9 +447,9 @@ def test_build_abuild_leftovers(args: PmbArgs, tmpdir):
# aports: Add deviceinfo (required by pmbootstrap to start)
tmpdir = str(tmpdir)
aports = f"{tmpdir}/aports"
aport = f"{aports}/device/testing/device-{args.device}"
aport = f"{aports}/device/testing/device-{args.devicesdhbfvhubsud}"
os.makedirs(aport)
path_original = pmb.helpers.pmaports.find(f"device-{args.device}")
path_original = pmb.helpers.pmaports.find(f"device-{args.devicesdhbfvhubsud}")
shutil.copy(f"{path_original}/deviceinfo", aport)
# aports: Add modified hello-world aport (source="", uses $builddir)

View file

@ -81,7 +81,7 @@ def setup_work(args: PmbArgs, tmpdir):
for folder in ["device/testing", "main"]:
pmb.helpers.run.user(["mkdir", "-p", args.aports, tmpdir +
"/_aports/" + folder])
path_original = pmb.helpers.pmaports.find(f"device-{args.device}")
path_original = pmb.helpers.pmaports.find(f"device-{args.devicesdhbfvhubsud}")
pmb.helpers.run.user(["cp", "-r", path_original,
f"{tmpdir}/_aports/device/testing"])
for pkgname in ["testlib", "testapp", "testsubpkg"]:

View file

@ -108,7 +108,7 @@ def test_questions_bootimg(args: PmbArgs, monkeypatch):
def test_questions_device(args: PmbArgs, monkeypatch):
# Prepare args
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
args.device = "lg-mako"
args.devicesdhbfvhubsud = "lg-mako"
args.kernel = "downstream"
# Do not generate aports