Compare commits

...

11 Commits

Author SHA1 Message Date
Martijn Braam ea70d3205e
pmb/config: add rkdeveloptool support (MR 2103)
Needed for flashing some rockchip platforms
2021-10-17 18:41:52 +02:00
Caleb Connolly 8bc5366e60
parse: deviceinfo: arch is required (MR 2124)
The deviceinfo_arch property is required but not checked, this leads to
weird errors if not caught.
2021-10-17 17:44:18 +02:00
Pablo Correa Gómez 4f793125d1
Allow to set mirror_alpine with pmbootstrap config command (MR 2129)
There is a double reason for this:
 * Better performance when developers/users choose local mirrors
 * Allows to continue developing if a mirror is down
2021-10-17 14:40:37 +02:00
Oliver Smith a676bdef0c
pmb.install.partition: fix mb_reserved calculation (MR 2123)
Calculate the end of the reserved space properly. Instead of:
	from size_boot to size_reserve
it is:
	from size_boot to (size_reserve + size_boot)

The reserved space is used by the on-device installer. Without this
patch, the reserved space could easily end up being too small, resulting
in no space left errors during the installation.
2021-10-17 14:27:44 +02:00
Alexey Min 97f59ffe93
pmb/config: fixup zram check options (MR 2126)
The main option - CONFIG_ZRAM - was not checked.
Add it and its direct requirement - CONFIG_ZSMALLOC.

The other two (ZSMALLOC_STAT, ZRAM_MEMORY_TRACKING) are
for debugging information only.
2021-10-15 21:48:18 +03:00
BO41 58922142ac
pmb.qemu.run.which_qemu: remove args argument (MR 2114)
Drop the argument, as it is not used.
2021-10-10 16:59:21 +02:00
BO41 944f539dd6
args.logfd: remove (MR 2114)
Replace "args.logfd" with "pmb.helpers.logging.logfd" in order to avoid
passing "args" to all functions that only use it to write to logfd. This
is the first step to get rid of this args-passed-to-all-functions
pattern in pmbootstrap.
2021-10-10 16:59:17 +02:00
Oliver Smith 313c9611c8
Prepare 1.38.0 release 2021-10-10 16:31:58 +02:00
Alexey Min ad491bc121
pmb.chroot.initfs: adapt to new mkinitfs (MR 2112)
Follow-up to 09794ef832 -
initfs file does not have flavor now, too.

Without this 'pmbootstrap initfs extract' fails with:

 (rootfs_samsung-klte) % cp /boot/initramfs-postmarketos-qcom-msm8974 /tmp/initfs-extracted/_initfs.gz
 cp: cannot stat '/boot/initramfs-postmarketos-qcom-msm8974': No such file or directory
2021-10-10 16:09:29 +02:00
Alexey Min 48c85cdc1f
kconfig migrate: new option to migrate kernel configs (MR 2111)
With this option you can run

$ pmbootstrap kconfig migrate --arch <arch> linux-postmarketos-xxx-xxx

to perform safe kconfig upgrades between kernel releases.

"make oldconfig" will ask question for every new/renamed kconfig option,
so you have no chance to miss anything.
2021-10-10 15:38:45 +02:00
Bart Ribbers 37c390aeed
pmb/parse/arguments: add aportupgrade to --help (MR 2121)
I keep forgetting this command exists, for one because it doesn't appear
(besides in a big, hard-to-read, one-line list) in the --help output
2021-10-10 13:55:02 +02:00
51 changed files with 194 additions and 144 deletions

View File

@ -9,13 +9,13 @@ import pmb.parse.apkindex
import pmb.parse.bootimg import pmb.parse.bootimg
def ask_for_architecture(args): def ask_for_architecture():
architectures = pmb.config.build_device_architectures architectures = pmb.config.build_device_architectures
# Don't show armhf, new ports shouldn't use this architecture # Don't show armhf, new ports shouldn't use this architecture
if "armhf" in architectures: if "armhf" in architectures:
architectures.remove("armhf") architectures.remove("armhf")
while True: while True:
ret = pmb.helpers.cli.ask(args, "Device architecture", architectures, ret = pmb.helpers.cli.ask("Device architecture", architectures,
architectures[0], complete=architectures) architectures[0], complete=architectures)
if ret in architectures: if ret in architectures:
return ret return ret
@ -25,14 +25,14 @@ def ask_for_architecture(args):
" pmb/config/__init__.py.") " pmb/config/__init__.py.")
def ask_for_manufacturer(args): def ask_for_manufacturer():
logging.info("Who produced the device (e.g. LG)?") logging.info("Who produced the device (e.g. LG)?")
return pmb.helpers.cli.ask(args, "Manufacturer", None, None, False) return pmb.helpers.cli.ask("Manufacturer", None, None, False)
def ask_for_name(args, manufacturer): def ask_for_name(manufacturer):
logging.info("What is the official name (e.g. Google Nexus 5)?") logging.info("What is the official name (e.g. Google Nexus 5)?")
ret = pmb.helpers.cli.ask(args, "Name", None, None, False) ret = pmb.helpers.cli.ask("Name", None, None, False)
# Always add the manufacturer # Always add the manufacturer
if not ret.startswith(manufacturer) and \ if not ret.startswith(manufacturer) and \
@ -41,19 +41,19 @@ def ask_for_name(args, manufacturer):
return ret return ret
def ask_for_year(args): def ask_for_year():
# Regex from https://stackoverflow.com/a/12240826 # Regex from https://stackoverflow.com/a/12240826
logging.info("In what year was the device released (e.g. 2012)?") logging.info("In what year was the device released (e.g. 2012)?")
return pmb.helpers.cli.ask(args, "Year", None, None, False, return pmb.helpers.cli.ask("Year", None, None, False,
validation_regex=r'^[1-9]\d{3,}$') validation_regex=r'^[1-9]\d{3,}$')
def ask_for_chassis(args): def ask_for_chassis():
types = pmb.config.deviceinfo_chassis_types types = pmb.config.deviceinfo_chassis_types
logging.info("What type of device is it?") logging.info("What type of device is it?")
logging.info("Valid types are: " + ", ".join(types)) logging.info("Valid types are: " + ", ".join(types))
return pmb.helpers.cli.ask(args, "Chassis", None, None, True, return pmb.helpers.cli.ask("Chassis", None, None, True,
validation_regex='|'.join(types), validation_regex='|'.join(types),
complete=types) complete=types)
@ -68,10 +68,10 @@ def ask_for_external_storage(args):
" other external storage medium?") " other external storage medium?")
def ask_for_flash_method(args): def ask_for_flash_method():
while True: while True:
logging.info("Which flash method does the device support?") logging.info("Which flash method does the device support?")
method = pmb.helpers.cli.ask(args, "Flash method", method = pmb.helpers.cli.ask("Flash method",
pmb.config.flash_methods, pmb.config.flash_methods,
pmb.config.flash_methods[0]) pmb.config.flash_methods[0])
@ -84,7 +84,7 @@ def ask_for_flash_method(args):
logging.info("<https://wiki.postmarketos.org/wiki" logging.info("<https://wiki.postmarketos.org/wiki"
"/Deviceinfo_flash_methods#Isorec_or_bootimg" "/Deviceinfo_flash_methods#Isorec_or_bootimg"
".3F>") ".3F>")
heimdall_type = pmb.helpers.cli.ask(args, "Type", heimdall_type = pmb.helpers.cli.ask("Type",
heimdall_types, heimdall_types,
heimdall_types[0]) heimdall_types[0])
if heimdall_type in heimdall_types: if heimdall_type in heimdall_types:
@ -106,7 +106,7 @@ def ask_for_bootimg(args):
" 'pmbootstrap bootimg_analyze').") " 'pmbootstrap bootimg_analyze').")
while True: while True:
response = pmb.helpers.cli.ask(args, "Path", None, "", False) response = pmb.helpers.cli.ask("Path", None, "", False)
path = os.path.expanduser(response) path = os.path.expanduser(response)
if not path: if not path:
return None return None
@ -116,7 +116,7 @@ def ask_for_bootimg(args):
logging.fatal("ERROR: " + str(e) + ". Please try again.") logging.fatal("ERROR: " + str(e) + ". Please try again.")
def generate_deviceinfo_fastboot_content(args, bootimg=None): def generate_deviceinfo_fastboot_content(bootimg=None):
if bootimg is None: if bootimg is None:
bootimg = {"cmdline": "", bootimg = {"cmdline": "",
"qcdt": "false", "qcdt": "false",
@ -205,9 +205,9 @@ def generate_deviceinfo(args, pkgname, name, manufacturer, year, arch,
""" """
if flash_method == "fastboot": if flash_method == "fastboot":
content += generate_deviceinfo_fastboot_content(args, bootimg) content += generate_deviceinfo_fastboot_content(bootimg)
elif flash_method == "heimdall-bootimg": elif flash_method == "heimdall-bootimg":
content += generate_deviceinfo_fastboot_content(args, bootimg) content += generate_deviceinfo_fastboot_content(bootimg)
content += content_heimdall_bootimg content += content_heimdall_bootimg
elif flash_method == "heimdall-isorec": elif flash_method == "heimdall-isorec":
content += content_heimdall_isorec content += content_heimdall_isorec
@ -273,14 +273,14 @@ def generate_apkbuild(args, pkgname, name, arch, flash_method):
def generate(args, pkgname): def generate(args, pkgname):
arch = ask_for_architecture(args) arch = ask_for_architecture()
manufacturer = ask_for_manufacturer(args) manufacturer = ask_for_manufacturer()
name = ask_for_name(args, manufacturer) name = ask_for_name(manufacturer)
year = ask_for_year(args) year = ask_for_year()
chassis = ask_for_chassis(args) chassis = ask_for_chassis()
has_keyboard = ask_for_keyboard(args) has_keyboard = ask_for_keyboard(args)
has_external_storage = ask_for_external_storage(args) has_external_storage = ask_for_external_storage(args)
flash_method = ask_for_flash_method(args) flash_method = ask_for_flash_method()
bootimg = None bootimg = None
if flash_method in ["fastboot", "heimdall-bootimg"]: if flash_method in ["fastboot", "heimdall-bootimg"]:
bootimg = ask_for_bootimg(args) bootimg = ask_for_bootimg(args)

View File

@ -26,7 +26,7 @@ def generate_apkbuild(args, pkgname, deviceinfo, patches):
build += """\n build += """\n
# Master DTB (deviceinfo_bootimg_qcdt)""" # Master DTB (deviceinfo_bootimg_qcdt)"""
vendors = ["spreadtrum", "exynos", "other"] vendors = ["spreadtrum", "exynos", "other"]
soc_vendor = pmb.helpers.cli.ask(args, "SoC vendor", vendors, soc_vendor = pmb.helpers.cli.ask("SoC vendor", vendors,
vendors[-1], complete=vendors) vendors[-1], complete=vendors)
if soc_vendor == "spreadtrum": if soc_vendor == "spreadtrum":
makedepends.append("dtbtool-sprd") makedepends.append("dtbtool-sprd")

View File

@ -78,12 +78,12 @@ def get_outputdir(args, pkgname, apkbuild):
" template with: pmbootstrap aportgen " + pkgname) " template with: pmbootstrap aportgen " + pkgname)
def menuconfig(args, pkgname): def menuconfig(args, pkgname, use_oldconfig):
# Pkgname: allow omitting "linux-" prefix # Pkgname: allow omitting "linux-" prefix
if pkgname.startswith("linux-"): if pkgname.startswith("linux-"):
pkgname_ = pkgname.split("linux-")[1] pkgname_ = pkgname.split("linux-")[1]
logging.info("PROTIP: You can simply do 'pmbootstrap kconfig edit " + logging.info(f"PROTIP: You can simply do 'pmbootstrap kconfig "
pkgname_ + "'") f"{args.action_kconfig} {pkgname_}'")
else: else:
pkgname = "linux-" + pkgname pkgname = "linux-" + pkgname
@ -99,9 +99,14 @@ def menuconfig(args, pkgname):
pmb.build.init(args, suffix) pmb.build.init(args, suffix)
if cross: if cross:
pmb.build.init_compiler(args, [], cross, arch) pmb.build.init_compiler(args, [], cross, arch)
depends = apkbuild["makedepends"] depends = apkbuild["makedepends"]
kopt = "menuconfig"
copy_xauth = False copy_xauth = False
if use_oldconfig:
kopt = "oldconfig"
else:
kopt = "menuconfig"
if args.xconfig: if args.xconfig:
depends += ["qt5-qtbase-dev", "font-noto"] depends += ["qt5-qtbase-dev", "font-noto"]
kopt = "xconfig" kopt = "xconfig"
@ -111,6 +116,7 @@ def menuconfig(args, pkgname):
depends += ["ncurses-dev"] depends += ["ncurses-dev"]
else: else:
depends += ["ncurses-dev"] depends += ["ncurses-dev"]
pmb.chroot.apk.install(args, depends) pmb.chroot.apk.install(args, depends)
# Copy host's .xauthority into native # Copy host's .xauthority into native

View File

@ -5,6 +5,7 @@ import logging
import pmb.chroot.initfs_hooks import pmb.chroot.initfs_hooks
import pmb.chroot.other import pmb.chroot.other
import pmb.chroot.apk import pmb.chroot.apk
import pmb.config.pmaports
import pmb.helpers.cli import pmb.helpers.cli
@ -35,9 +36,16 @@ def extract(args, flavor, suffix, extra=False):
""" """
# Extraction folder # Extraction folder
inside = "/tmp/initfs-extracted" inside = "/tmp/initfs-extracted"
pmaports_cfg = pmb.config.pmaports.read_config(args)
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
initfs_file = "/boot/initramfs"
else:
initfs_file = f"/boot/initramfs-${flavor}"
if extra: if extra:
inside = "/tmp/initfs-extra-extracted" inside = "/tmp/initfs-extra-extracted"
flavor += "-extra" initfs_file += "-extra"
outside = f"{args.work}/chroot_{suffix}{inside}" outside = f"{args.work}/chroot_{suffix}{inside}"
if os.path.exists(outside): if os.path.exists(outside):
if not pmb.helpers.cli.confirm(args, f"Extraction folder {outside}" if not pmb.helpers.cli.confirm(args, f"Extraction folder {outside}"
@ -55,7 +63,7 @@ def extract(args, flavor, suffix, extra=False):
# Extract # Extract
commands = [["mkdir", "-p", inside], commands = [["mkdir", "-p", inside],
["cp", f"/boot/initramfs-{flavor}", f"{inside}/_initfs.gz"], ["cp", initfs_file, f"{inside}/_initfs.gz"],
["gzip", "-d", f"{inside}/_initfs.gz"], ["gzip", "-d", f"{inside}/_initfs.gz"],
["cat", "/tmp/_extract.sh"], # for the log ["cat", "/tmp/_extract.sh"], # for the log
["sh", "/tmp/_extract.sh"], ["sh", "/tmp/_extract.sh"],

View File

@ -15,7 +15,7 @@ from pmb.config.merge_with_args import merge_with_args
# #
# Exported variables (internal configuration) # Exported variables (internal configuration)
# #
version = "1.37.0" version = "1.38.0"
pmb_src = os.path.normpath(os.path.realpath(__file__) + "/../../..") pmb_src = os.path.normpath(os.path.realpath(__file__) + "/../../..")
apk_keys_path = pmb_src + "/pmb/data/keys" apk_keys_path = pmb_src + "/pmb/data/keys"
@ -24,7 +24,7 @@ apk_keys_path = pmb_src + "/pmb/data/keys"
# Update this frequently to prevent a MITM attack with an outdated version # Update this frequently to prevent a MITM attack with an outdated version
# (which may contain a vulnerable apk/openssl, and allows an attacker to # (which may contain a vulnerable apk/openssl, and allows an attacker to
# exploit the system!) # exploit the system!)
apk_tools_min_version = {"edge": "2.12.7-r0", apk_tools_min_version = {"edge": "2.12.7-r3",
"v3.14": "2.12.7-r0", "v3.14": "2.12.7-r0",
"v3.13": "2.12.7-r0", "v3.13": "2.12.7-r0",
"v3.12": "2.10.8-r0"} "v3.12": "2.10.8-r0"}
@ -60,6 +60,7 @@ config_keys = ["aports",
"kernel", "kernel",
"keymap", "keymap",
"locale", "locale",
"mirror_alpine",
"mirrors_postmarketos", "mirrors_postmarketos",
"nonfree_firmware", "nonfree_firmware",
"nonfree_userland", "nonfree_userland",
@ -472,8 +473,8 @@ necessary_kconfig_options_containers = {
necessary_kconfig_options_zram = { necessary_kconfig_options_zram = {
">=3.14.0": { # zram support introduced here ">=3.14.0": { # zram support introduced here
"all": { # all arches "all": { # all arches
"ZSMALLOC_STAT": True, "ZRAM": True,
"ZRAM_MEMORY_TRACKING": True, "ZSMALLOC": True,
"CRYPTO_LZ4": True, "CRYPTO_LZ4": True,
"LZ4_COMPRESS": True, "LZ4_COMPRESS": True,
"SWAP": True, "SWAP": True,
@ -658,7 +659,14 @@ install_user_groups = ["wheel", "video", "audio", "input", "plugdev", "netdev"]
# FLASH # FLASH
# #
flash_methods = ["fastboot", "heimdall", "0xffff", "uuu", "none"] flash_methods = [
"0xffff",
"fastboot",
"heimdall",
"none"
"rkdeveloptool",
"uuu",
]
# These folders will be mounted at the same location into the native # These folders will be mounted at the same location into the native
# chroot, before the flash programs get started. # chroot, before the flash programs get started.
@ -785,6 +793,15 @@ flashers = {
["uuu", "flash_script.lst"], ["uuu", "flash_script.lst"],
], ],
}, },
},
"rkdeveloptool": {
"depends": ["rkdeveloptool"],
"actions": {
"list_devices": [["rkdeveloptool", "ld"]],
"flash_rootfs": [
["rkdeveloptool", "wl", "0", "$IMAGE"]
],
},
} }
} }

View File

@ -47,7 +47,7 @@ def ask_for_work_path(args):
while True: while True:
try: try:
work = os.path.expanduser(pmb.helpers.cli.ask( work = os.path.expanduser(pmb.helpers.cli.ask(
args, "Work path", None, args.work, False)) "Work path", None, args.work, False))
work = os.path.realpath(work) work = os.path.realpath(work)
exists = os.path.exists(work) exists = os.path.exists(work)
@ -103,7 +103,7 @@ def ask_for_channel(args):
# Ask until user gives valid channel # Ask until user gives valid channel
while True: while True:
ret = pmb.helpers.cli.ask(args, "Channel", None, default, ret = pmb.helpers.cli.ask("Channel", None, default,
complete=choices) complete=choices)
if ret in choices: if ret in choices:
return ret return ret
@ -138,7 +138,7 @@ def ask_for_ui(args, device):
" available. See: <https://wiki.postmarketos.org/wiki/" " available. See: <https://wiki.postmarketos.org/wiki/"
"Deviceinfo_reference") "Deviceinfo_reference")
while True: while True:
ret = pmb.helpers.cli.ask(args, "User interface", None, args.ui, True, ret = pmb.helpers.cli.ask("User interface", None, args.ui, True,
complete=ui_completion_list) complete=ui_completion_list)
if ret in dict(ui_list).keys(): if ret in dict(ui_list).keys():
return ret return ret
@ -174,7 +174,7 @@ def ask_for_keymaps(args, device):
args.keymap = options[0] args.keymap = options[0]
while True: while True:
ret = pmb.helpers.cli.ask(args, "Keymap", None, args.keymap, ret = pmb.helpers.cli.ask("Keymap", None, args.keymap,
True, complete=options) True, complete=options)
if ret in options: if ret in options:
return ret return ret
@ -241,7 +241,7 @@ def ask_for_device_kernel(args, device):
for type in sorted(kernels.keys()): for type in sorted(kernels.keys()):
logging.info(f"* {type}: {kernels[type]}") logging.info(f"* {type}: {kernels[type]}")
while True: while True:
ret = pmb.helpers.cli.ask(args, "Kernel", None, default, True, ret = pmb.helpers.cli.ask("Kernel", None, default, True,
complete=kernels) complete=kernels)
if ret in kernels.keys(): if ret in kernels.keys():
return ret return ret
@ -310,7 +310,7 @@ def ask_for_device(args):
current_codename = args.device.split("-", 1)[1] current_codename = args.device.split("-", 1)[1]
while True: while True:
vendor = pmb.helpers.cli.ask(args, "Vendor", None, current_vendor, vendor = pmb.helpers.cli.ask("Vendor", None, current_vendor,
False, r"[a-z0-9]+", vendors) False, r"[a-z0-9]+", vendors)
new_vendor = vendor not in vendors new_vendor = vendor not in vendors
@ -332,7 +332,7 @@ def ask_for_device(args):
if current_vendor != vendor: if current_vendor != vendor:
current_codename = '' current_codename = ''
codename = pmb.helpers.cli.ask(args, "Device codename", None, codename = pmb.helpers.cli.ask("Device codename", None,
current_codename, False, r"[a-z0-9]+", current_codename, False, r"[a-z0-9]+",
codenames) codenames)
@ -390,20 +390,20 @@ def ask_for_additional_options(args, cfg):
" enough to fit the rootfs (pmbootstrap#1904)." " enough to fit the rootfs (pmbootstrap#1904)."
" How much extra free space do you want to add to the image" " How much extra free space do you want to add to the image"
" (in MB)?") " (in MB)?")
answer = pmb.helpers.cli.ask(args, "Extra space size", None, answer = pmb.helpers.cli.ask("Extra space size", None,
args.extra_space, validation_regex="^[0-9]+$") args.extra_space, validation_regex="^[0-9]+$")
cfg["pmbootstrap"]["extra_space"] = answer cfg["pmbootstrap"]["extra_space"] = answer
# Boot size # Boot size
logging.info("What should be the boot partition size (in MB)?") logging.info("What should be the boot partition size (in MB)?")
answer = pmb.helpers.cli.ask(args, "Boot size", None, args.boot_size, answer = pmb.helpers.cli.ask("Boot size", None, args.boot_size,
validation_regex="^[1-9][0-9]*$") validation_regex="^[1-9][0-9]*$")
cfg["pmbootstrap"]["boot_size"] = answer cfg["pmbootstrap"]["boot_size"] = answer
# Parallel job count # Parallel job count
logging.info("How many jobs should run parallel on this machine, when" logging.info("How many jobs should run parallel on this machine, when"
" compiling?") " compiling?")
answer = pmb.helpers.cli.ask(args, "Jobs", None, args.jobs, answer = pmb.helpers.cli.ask("Jobs", None, args.jobs,
validation_regex="^[1-9][0-9]*$") validation_regex="^[1-9][0-9]*$")
cfg["pmbootstrap"]["jobs"] = answer cfg["pmbootstrap"]["jobs"] = answer
@ -414,7 +414,7 @@ def ask_for_additional_options(args, cfg):
" current usage with 'pmbootstrap stats'. Answer with 0 for" " current usage with 'pmbootstrap stats'. Answer with 0 for"
" infinite.") " infinite.")
regex = "0|[0-9]+(k|M|G|T|Ki|Mi|Gi|Ti)" regex = "0|[0-9]+(k|M|G|T|Ki|Mi|Gi|Ti)"
answer = pmb.helpers.cli.ask(args, "Ccache size", None, args.ccache_size, answer = pmb.helpers.cli.ask("Ccache size", None, args.ccache_size,
lowercase_answer=False, lowercase_answer=False,
validation_regex=regex) validation_regex=regex)
cfg["pmbootstrap"]["ccache_size"] = answer cfg["pmbootstrap"]["ccache_size"] = answer
@ -483,7 +483,7 @@ def ask_for_mirror(args):
mirrors_list = [] mirrors_list = []
# require one valid mirror index selected by user # require one valid mirror index selected by user
while len(mirrors_list) != 1: while len(mirrors_list) != 1:
answer = pmb.helpers.cli.ask(args, "Select a mirror", None, answer = pmb.helpers.cli.ask("Select a mirror", None,
",".join(mirror_indexes), ",".join(mirror_indexes),
validation_regex=regex) validation_regex=regex)
mirrors_list = [] mirrors_list = []
@ -499,8 +499,7 @@ def ask_for_mirror(args):
def ask_for_hostname(args, device): def ask_for_hostname(args, device):
while True: while True:
ret = pmb.helpers.cli.ask(args, ret = pmb.helpers.cli.ask("Device hostname (short form, e.g. 'foo')",
"Device hostname (short form, e.g. 'foo')",
None, (args.hostname or device), True) None, (args.hostname or device), True)
if not pmb.helpers.other.validate_hostname(ret): if not pmb.helpers.other.validate_hostname(ret):
continue continue
@ -531,7 +530,7 @@ def ask_build_pkgs_on_install(args):
def ask_for_locale(args): def ask_for_locale(args):
locales = pmb.config.locales locales = pmb.config.locales
logging.info(f"Available locales ({len(locales)}): {', '.join(locales)}") logging.info(f"Available locales ({len(locales)}): {', '.join(locales)}")
return pmb.helpers.cli.ask(args, "Choose default locale for installation", return pmb.helpers.cli.ask("Choose default locale for installation",
choices=None, choices=None,
default=args.locale, default=args.locale,
lowercase_answer=False, lowercase_answer=False,
@ -574,7 +573,7 @@ def frontend(args):
cfg["pmbootstrap"]["keymap"] = ask_for_keymaps(args, device) cfg["pmbootstrap"]["keymap"] = ask_for_keymaps(args, device)
# Username # Username
cfg["pmbootstrap"]["user"] = pmb.helpers.cli.ask(args, "Username", None, cfg["pmbootstrap"]["user"] = pmb.helpers.cli.ask("Username", None,
args.user, False, args.user, False,
"[a-z_][a-z0-9_-]*") "[a-z_][a-z0-9_-]*")
# UI and various build options # UI and various build options
@ -587,7 +586,7 @@ def frontend(args):
logging.info("Additional packages that will be installed to rootfs." logging.info("Additional packages that will be installed to rootfs."
" Specify them in a comma separated list (e.g.: vim,file)" " Specify them in a comma separated list (e.g.: vim,file)"
" or \"none\"") " or \"none\"")
extra = pmb.helpers.cli.ask(args, "Extra packages", None, extra = pmb.helpers.cli.ask("Extra packages", None,
args.extra_packages, args.extra_packages,
validation_regex=r"^([-.+\w]+)(,[-.+\w]+)*$") validation_regex=r"^([-.+\w]+)(,[-.+\w]+)*$")
cfg["pmbootstrap"]["extra_packages"] = extra cfg["pmbootstrap"]["extra_packages"] = extra

View File

@ -177,9 +177,7 @@ def update_work(args, work):
args_new = copy.deepcopy(args.from_argparse) args_new = copy.deepcopy(args.from_argparse)
# Keep from the modified args: # Keep from the modified args:
# * the old log file descriptor (so we can close it)
# * the unmodified args from argparse (to check if --aports was specified) # * the unmodified args from argparse (to check if --aports was specified)
args_new.logfd = args.logfd
args_new.from_argparse = args.from_argparse args_new.from_argparse = args.from_argparse
# Generate modified args again, replacing $WORK with the new work folder # Generate modified args again, replacing $WORK with the new work folder

View File

@ -38,7 +38,7 @@ class ReadlineTabCompleter:
return None return None
def ask(args, question="Continue?", choices=["y", "n"], default="n", def ask(question="Continue?", choices=["y", "n"], default="n",
lowercase_answer=True, validation_regex=None, complete=None): lowercase_answer=True, validation_regex=None, complete=None):
""" """
Ask a question on the terminal. Ask a question on the terminal.
@ -83,8 +83,8 @@ def ask(args, question="Continue?", choices=["y", "n"], default="n",
if ret == "": if ret == "":
ret = str(default) ret = str(default)
args.logfd.write(f"{line}: {ret}\n") pmb.helpers.logging.logfd.write(f"{line}: {ret}\n")
args.logfd.flush() pmb.helpers.logging.logfd.flush()
# Validate with regex # Validate with regex
if not validation_regex: if not validation_regex:
@ -110,7 +110,7 @@ def confirm(args, question="Continue?", default=False, no_assumptions=False):
if args.assume_yes and not no_assumptions: if args.assume_yes and not no_assumptions:
logging.info(question + " (y/n) [" + default_str + "]: y") logging.info(question + " (y/n) [" + default_str + "]: y")
return True return True
answer = ask(args, question, ["y", "n"], default_str, True, "(y|n)") answer = ask(question, ["y", "n"], default_str, True, "(y|n)")
return answer == "y" return answer == "y"

View File

@ -417,12 +417,13 @@ def kconfig(args):
logging.info("NOTE: " + str(skipped) + " kernel(s) was skipped" logging.info("NOTE: " + str(skipped) + " kernel(s) was skipped"
" (consider 'pmbootstrap kconfig check -f')") " (consider 'pmbootstrap kconfig check -f')")
logging.info("kconfig check succeeded!") logging.info("kconfig check succeeded!")
elif args.action_kconfig == "edit": elif args.action_kconfig in ["edit", "migrate"]:
if args.package: if args.package:
pkgname = args.package pkgname = args.package
else: else:
pkgname = args.deviceinfo["codename"] pkgname = args.deviceinfo["codename"]
pmb.build.menuconfig(args, pkgname) use_oldconfig = args.action_kconfig == "migrate"
pmb.build.menuconfig(args, pkgname, use_oldconfig)
def deviceinfo_parse(args): def deviceinfo_parse(args):
@ -550,7 +551,7 @@ def bootimg_analyze(args):
bootimg = pmb.parse.bootimg(args, args.path) bootimg = pmb.parse.bootimg(args, args.path)
tmp_output = "Put these variables in the deviceinfo file of your device:\n" tmp_output = "Put these variables in the deviceinfo file of your device:\n"
for line in pmb.aportgen.device.\ for line in pmb.aportgen.device.\
generate_deviceinfo_fastboot_content(args, bootimg).split("\n"): generate_deviceinfo_fastboot_content(bootimg).split("\n"):
tmp_output += "\n" + line.lstrip() tmp_output += "\n" + line.lstrip()
logging.info(tmp_output) logging.info(tmp_output)

View File

@ -5,6 +5,8 @@ import os
import sys import sys
import pmb.config import pmb.config
logfd = None
class log_handler(logging.StreamHandler): class log_handler(logging.StreamHandler):
""" """
@ -53,8 +55,8 @@ class log_handler(logging.StreamHandler):
# Everything: Write to logfd # Everything: Write to logfd
msg = "(" + str(os.getpid()).zfill(6) + ") " + msg msg = "(" + str(os.getpid()).zfill(6) + ") " + msg
self._args.logfd.write(msg + "\n") logfd.write(msg + "\n")
self._args.logfd.flush() logfd.flush()
except (KeyboardInterrupt, SystemExit): except (KeyboardInterrupt, SystemExit):
raise raise
@ -83,23 +85,24 @@ def add_verbose_log_level():
def init(args): def init(args):
""" """
Set log format and add the log file descriptor to args.logfd, add the Set log format and add the log file descriptor to logfd, add the
verbose log level. verbose log level.
""" """
global logfd
# Set log file descriptor (logfd) # Set log file descriptor (logfd)
if args.details_to_stdout: if args.details_to_stdout:
setattr(args, "logfd", sys.stdout) logfd = sys.stdout
else: else:
# Require containing directory to exist (so we don't create the work # Require containing directory to exist (so we don't create the work
# folder and break the folder migration logic, which needs to set the # folder and break the folder migration logic, which needs to set the
# version upon creation) # version upon creation)
dir = os.path.dirname(args.log) dir = os.path.dirname(args.log)
if os.path.exists(dir): if os.path.exists(dir):
setattr(args, "logfd", open(args.log, "a+")) logfd = open(args.log, "a+")
else: else:
setattr(args, "logfd", open(os.devnull, "a+")) logfd = open(os.devnull, "a+")
if args.action != "init": if args.action != "init":
print("WARNING: Can't create log file in '" + dir + "', path" print(f"WARNING: Can't create log file in '{dir}', path"
" does not exist!") " does not exist!")
# Set log format # Set log format

View File

@ -35,23 +35,23 @@ def sanity_checks(output="log", output_return=False, check=None):
raise RuntimeError("Can't use output_return with output: " + output) raise RuntimeError("Can't use output_return with output: " + output)
def background(args, cmd, working_dir=None): def background(cmd, working_dir=None):
""" Run a subprocess in background and redirect its output to the log. """ """ Run a subprocess in background and redirect its output to the log. """
ret = subprocess.Popen(cmd, stdout=args.logfd, stderr=args.logfd, ret = subprocess.Popen(cmd, stdout=pmb.helpers.logging.logfd,
cwd=working_dir) stderr=pmb.helpers.logging.logfd, cwd=working_dir)
logging.debug(f"New background process: pid={ret.pid}, output=background") logging.debug(f"New background process: pid={ret.pid}, output=background")
return ret return ret
def pipe(args, cmd, working_dir=None): def pipe(cmd, working_dir=None):
""" Run a subprocess in background and redirect its output to a pipe. """ """ Run a subprocess in background and redirect its output to a pipe. """
ret = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=args.logfd, ret = subprocess.Popen(cmd, stdout=subprocess.PIPE,
cwd=working_dir) stderr=pmb.helpers.logging.logfd, cwd=working_dir)
logging.verbose(f"New background process: pid={ret.pid}, output=pipe") logging.verbose(f"New background process: pid={ret.pid}, output=pipe")
return ret return ret
def pipe_read(args, process, output_to_stdout=False, output_return=False, def pipe_read(process, output_to_stdout=False, output_return=False,
output_return_buffer=False): output_return_buffer=False):
""" """
Read all available output from a subprocess and copy it to the log and Read all available output from a subprocess and copy it to the log and
@ -69,7 +69,7 @@ def pipe_read(args, process, output_to_stdout=False, output_return=False,
# Copy available output # Copy available output
out = process.stdout.readline() out = process.stdout.readline()
if len(out): if len(out):
args.logfd.buffer.write(out) pmb.helpers.logging.logfd.buffer.write(out)
if output_to_stdout: if output_to_stdout:
sys.stdout.buffer.write(out) sys.stdout.buffer.write(out)
if output_return: if output_return:
@ -77,7 +77,7 @@ def pipe_read(args, process, output_to_stdout=False, output_return=False,
continue continue
# No more output (flush buffers) # No more output (flush buffers)
args.logfd.flush() pmb.helpers.logging.logfd.flush()
if output_to_stdout: if output_to_stdout:
sys.stdout.flush() sys.stdout.flush()
return return
@ -175,11 +175,11 @@ def foreground_pipe(args, cmd, working_dir=None, output_to_stdout=False,
continue continue
# Read all currently available output # Read all currently available output
pipe_read(args, process, output_to_stdout, output_return, pipe_read(process, output_to_stdout, output_return,
output_buffer) output_buffer)
# There may still be output after the process quit # There may still be output after the process quit
pipe_read(args, process, output_to_stdout, output_return, output_buffer) pipe_read(process, output_to_stdout, output_return, output_buffer)
# Return the return code and output (the output gets built as list of # Return the return code and output (the output gets built as list of
# output chunks and combined at the end, this is faster than extending the # output chunks and combined at the end, this is faster than extending the
@ -313,11 +313,11 @@ def core(args, log_message, cmd, working_dir=None, output="log",
# Background # Background
if output == "background": if output == "background":
return background(args, cmd, working_dir) return background(cmd, working_dir)
# Pipe # Pipe
if output == "pipe": if output == "pipe":
return pipe(args, cmd, working_dir) return pipe(cmd, working_dir)
# Foreground # Foreground
output_after_run = "" output_after_run = ""

View File

@ -77,7 +77,8 @@ def partition(args, size_boot, size_reserve):
] ]
if size_reserve: if size_reserve:
commands += [["mkpart", "primary", mb_boot, mb_reserved]] mb_reserved_end = f"{round(size_reserve + size_boot)}M"
commands += [["mkpart", "primary", mb_boot, mb_reserved_end]]
commands += [ commands += [
["mkpart", "primary", mb_root_start, "100%"], ["mkpart", "primary", mb_root_start, "100%"],

View File

@ -355,7 +355,8 @@ def arguments_pkgrel_bump(subparser):
def arguments_aportupgrade(subparser): def arguments_aportupgrade(subparser):
ret = subparser.add_parser("aportupgrade") ret = subparser.add_parser("aportupgrade", help="check for outdated"
" packages that need upgrading")
ret.add_argument("--dry", action="store_true", help="instead of modifying" ret.add_argument("--dry", action="store_true", help="instead of modifying"
" APKBUILDs, print the changes that would be made") " APKBUILDs, print the changes that would be made")
ret.add_argument("--ref", help="git ref (tag, commit, etc) to use") ret.add_argument("--ref", help="git ref (tag, commit, etc) to use")
@ -456,6 +457,17 @@ def arguments_kconfig(subparser):
if argcomplete: if argcomplete:
edit_package.completer = kernel_completer edit_package.completer = kernel_completer
# "pmbootstrap kconfig migrate"
migrate = sub.add_parser("migrate",
help="Migrate kconfig from older version to "
"newer. Internally runs 'make oldconfig', "
"which asks question for every new kernel "
"config option.")
migrate.add_argument("--arch", choices=arch_choices, dest="arch")
migrate_package = migrate.add_argument("package", nargs='?')
if argcomplete:
migrate_package.completer = kernel_completer
def arguments_repo_missing(subparser): def arguments_repo_missing(subparser):
ret = subparser.add_parser("repo_missing") ret = subparser.add_parser("repo_missing")

View File

@ -58,6 +58,10 @@ def sanity_check(info, path):
" postmarketOS are 'handset' (for phones) and 'tablet'.") " postmarketOS are 'handset' (for phones) and 'tablet'.")
raise RuntimeError(f"Please add 'deviceinfo_chassis' to: {path}") raise RuntimeError(f"Please add 'deviceinfo_chassis' to: {path}")
# "arch" is required
if "arch" not in info or not info["arch"]:
raise RuntimeError(f"Please add 'deviceinfo_arch' to: {path}")
# "chassis" validation # "chassis" validation
chassis_type = info["chassis"] chassis_type = info["chassis"]
if chassis_type not in chassis_types: if chassis_type not in chassis_types:

View File

@ -44,7 +44,7 @@ def create_second_storage(args):
return path return path
def which_qemu(args, arch): def which_qemu(arch):
""" """
Finds the qemu executable or raises an exception otherwise Finds the qemu executable or raises an exception otherwise
""" """
@ -112,7 +112,7 @@ def command_qemu(args, arch, img_path, img_path_2nd=None):
ncpus = 8 ncpus = 8
if args.host_qemu: if args.host_qemu:
qemu_bin = which_qemu(args, arch) qemu_bin = which_qemu(arch)
env = {} env = {}
command = [qemu_bin] command = [qemu_bin]
else: else:

View File

@ -21,7 +21,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -23,7 +23,7 @@ def args(tmpdir, request):
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
args.fork_alpine = False args.fork_alpine = False
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -21,7 +21,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
# Fake aports folder: # Fake aports folder:
tmpdir = str(tmpdir) tmpdir = str(tmpdir)
@ -55,7 +55,7 @@ def generate(args, monkeypatch, answers):
pmb.parse.deviceinfo(). pmb.parse.deviceinfo().
""" """
# Patched function # Patched function
def fake_ask(args, question="Continue?", choices=["y", "n"], default="n", def fake_ask(question="Continue?", choices=["y", "n"], default="n",
lowercase_answer=True, validation_regex=None, complete=None): lowercase_answer=True, validation_regex=None, complete=None):
for substr, answer in answers.items(): for substr, answer in answers.items():
if substr in question: if substr in question:

View File

@ -18,7 +18,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -16,7 +16,7 @@ def args(request, tmpdir):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
# Create an empty APKINDEX.tar.gz file, so we can use its path and # Create an empty APKINDEX.tar.gz file, so we can use its path and
# timestamp to put test information in the cache. # timestamp to put test information in the cache.

View File

@ -23,7 +23,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -20,7 +20,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -18,7 +18,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -19,7 +19,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -17,7 +17,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -19,7 +19,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -20,7 +20,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -18,7 +18,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -22,7 +22,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -18,7 +18,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -15,7 +15,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -15,7 +15,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -17,7 +17,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -14,7 +14,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -19,7 +19,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -17,7 +17,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -21,7 +21,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -16,7 +16,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -19,7 +19,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -22,7 +22,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -15,7 +15,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -19,7 +19,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -19,7 +19,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -14,7 +14,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -19,7 +19,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -28,7 +28,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -21,7 +21,7 @@ def args(tmpdir, request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args
@ -34,7 +34,7 @@ def fake_answers(monkeypatch, answers):
In this example, the first question is answered with "y", In this example, the first question is answered with "y",
the second question with "n" and so on. the second question with "n" and so on.
""" """
def fake_ask(args, question="Continue?", choices=["y", "n"], default="n", def fake_ask(question="Continue?", choices=["y", "n"], default="n",
lowercase_answer=True, validation_regex=None, complete=None): lowercase_answer=True, validation_regex=None, complete=None):
answer = answers.pop(0) answer = answers.pop(0)
logging.info("pmb.helpers.cli.ask() fake answer: " + answer) logging.info("pmb.helpers.cli.ask() fake answer: " + answer)
@ -44,8 +44,8 @@ def fake_answers(monkeypatch, answers):
def test_fake_answers_selftest(monkeypatch): def test_fake_answers_selftest(monkeypatch):
fake_answers(monkeypatch, ["first", "second"]) fake_answers(monkeypatch, ["first", "second"])
assert pmb.helpers.cli.ask(args) == "first" assert pmb.helpers.cli.ask() == "first"
assert pmb.helpers.cli.ask(args) == "second" assert pmb.helpers.cli.ask() == "second"
def test_questions_booleans(args, monkeypatch): def test_questions_booleans(args, monkeypatch):
@ -61,7 +61,7 @@ def test_questions_strings(args, monkeypatch):
functions = [pmb.aportgen.device.ask_for_manufacturer] functions = [pmb.aportgen.device.ask_for_manufacturer]
for func in functions: for func in functions:
fake_answers(monkeypatch, ["Simple string answer"]) fake_answers(monkeypatch, ["Simple string answer"])
assert func(args) == "Simple string answer" assert func() == "Simple string answer"
def test_questions_name(args, monkeypatch): def test_questions_name(args, monkeypatch):
@ -69,18 +69,18 @@ def test_questions_name(args, monkeypatch):
# Manufacturer should get added automatically, but not twice # Manufacturer should get added automatically, but not twice
fake_answers(monkeypatch, ["Amazon Thor"]) fake_answers(monkeypatch, ["Amazon Thor"])
assert func(args, "Amazon") == "Amazon Thor" assert func("Amazon") == "Amazon Thor"
fake_answers(monkeypatch, ["Thor"]) fake_answers(monkeypatch, ["Thor"])
assert func(args, "Amazon") == "Amazon Thor" assert func("Amazon") == "Amazon Thor"
# Don't add the manufacturer when it starts with "Google" # Don't add the manufacturer when it starts with "Google"
fake_answers(monkeypatch, ["Google Nexus 12345"]) fake_answers(monkeypatch, ["Google Nexus 12345"])
assert func(args, "Amazon") == "Google Nexus 12345" assert func("Amazon") == "Google Nexus 12345"
def test_questions_arch(args, monkeypatch): def test_questions_arch(args, monkeypatch):
fake_answers(monkeypatch, ["invalid_arch", "aarch64"]) fake_answers(monkeypatch, ["invalid_arch", "aarch64"])
assert pmb.aportgen.device.ask_for_architecture(args) == "aarch64" assert pmb.aportgen.device.ask_for_architecture() == "aarch64"
def test_questions_bootimg(args, monkeypatch): def test_questions_bootimg(args, monkeypatch):
@ -196,16 +196,16 @@ def test_questions_device_nonfree(args, monkeypatch):
def test_questions_flash_methods(args, monkeypatch): def test_questions_flash_methods(args, monkeypatch):
func = pmb.aportgen.device.ask_for_flash_method func = pmb.aportgen.device.ask_for_flash_method
fake_answers(monkeypatch, ["invalid_flash_method", "fastboot"]) fake_answers(monkeypatch, ["invalid_flash_method", "fastboot"])
assert func(args) == "fastboot" assert func() == "fastboot"
fake_answers(monkeypatch, ["0xffff"]) fake_answers(monkeypatch, ["0xffff"])
assert func(args) == "0xffff" assert func() == "0xffff"
fake_answers(monkeypatch, ["heimdall", "invalid_type", "isorec"]) fake_answers(monkeypatch, ["heimdall", "invalid_type", "isorec"])
assert func(args) == "heimdall-isorec" assert func() == "heimdall-isorec"
fake_answers(monkeypatch, ["heimdall", "bootimg"]) fake_answers(monkeypatch, ["heimdall", "bootimg"])
assert func(args) == "heimdall-bootimg" assert func() == "heimdall-bootimg"
def test_questions_keymaps(args, monkeypatch): def test_questions_keymaps(args, monkeypatch):

View File

@ -16,7 +16,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args
@ -44,7 +44,7 @@ def test_sanity_checks():
def test_background(args): def test_background(args):
# Sleep in background # Sleep in background
process = pmb.helpers.run_core.background(args, ["sleep", "1"], "/") process = pmb.helpers.run_core.background(["sleep", "1"], "/")
# Check if it is still running # Check if it is still running
assert process.poll() is None assert process.poll() is None
@ -52,13 +52,13 @@ def test_background(args):
def test_pipe(args): def test_pipe(args):
# Sleep in background # Sleep in background
process = pmb.helpers.run_core.pipe(args, ["sleep", "1"], "/") process = pmb.helpers.run_core.pipe(["sleep", "1"], "/")
# Check if it is still running # Check if it is still running
assert process.poll() is None assert process.poll() is None
# Print output in background # Print output in background
process = pmb.helpers.run_core.pipe(args, ["echo", "-n", "hello"], "/") process = pmb.helpers.run_core.pipe(["echo", "-n", "hello"], "/")
# Read output # Read output
assert process.communicate()[0].decode('utf-8') == "hello" assert process.communicate()[0].decode('utf-8') == "hello"

View File

@ -17,7 +17,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -17,7 +17,7 @@ def args(request):
args = pmb.parse.arguments() args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt" args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args) pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close) request.addfinalizer(pmb.helpers.logging.logfd.close)
return args return args

View File

@ -1,5 +1,6 @@
deviceinfo_codename="multiple-kernels" deviceinfo_codename="multiple-kernels"
deviceinfo_chassis="handset" deviceinfo_chassis="handset"
deviceinfo_arch="aarch64"
deviceinfo_append_dtb="yes" deviceinfo_append_dtb="yes"
deviceinfo_dtb_mainline="mainline-dtb" deviceinfo_dtb_mainline="mainline-dtb"
deviceinfo_dtb_mainline_modem="mainline-modem-dtb" deviceinfo_dtb_mainline_modem="mainline-modem-dtb"