Compare commits
27 Commits
ea70d3205e
...
4c4bd77c87
Author | SHA1 | Date |
---|---|---|
Caleb Connolly | 4c4bd77c87 | |
Oliver Smith | 498738abcc | |
Ultracoolguy | 54afa35d70 | |
Luca Weiss | f4990cfc7a | |
Luca Weiss | f996f3ed5a | |
Oliver Smith | 6557e6892a | |
Oliver Smith | 152bd6753c | |
Minecrell | 8ace36113c | |
Minecrell | 47645f41b1 | |
Minecrell | 19b232969d | |
Minecrell | 5ed807c064 | |
Minecrell | eb3e38d15c | |
Minecrell | 7246c32539 | |
Minecrell | 9d724d5d3d | |
Oliver Smith | 05f257295d | |
Oliver Smith | aead36d5ac | |
Oliver Smith | d856e21673 | |
Oliver Smith | 93e7a1d876 | |
Oliver Smith | dcedc4bc1f | |
Oliver Smith | 6b8fa93d37 | |
Alexey Min | 0664a38190 | |
博麗霊夢 | 7541a0ca36 | |
Jami Kettunen | 931675450d | |
bo41 | caf7973e24 | |
Oliver Smith | f2966e62ae | |
bo41 | a8d425554c | |
Martijn Braam | 896879e89a |
|
@ -120,7 +120,8 @@ initialize_chroot() {
|
|||
# shellcheck disable=SC3057
|
||||
arch_substr="${host_arch:0:3}"
|
||||
if [ "$arch" = "$host_arch" ] || \
|
||||
{ [ "$arch_substr" = "arm" ] && [ "$arch_substr" = "$arch" ]; }; then
|
||||
{ [ "$arch_substr" = "arm" ] && [ "$arch_substr" = "$arch" ]; } || \
|
||||
{ [ "$arch" = "arm64" ] && [ "$host_arch" = "aarch64" ]; }; then
|
||||
need_cross_compiler=0
|
||||
fi
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ def main():
|
|||
os.umask(0o22)
|
||||
|
||||
# Sanity checks
|
||||
other.check_grsec(args)
|
||||
other.check_grsec()
|
||||
if not args.as_root and os.geteuid() == 0:
|
||||
raise RuntimeError("Do not run pmbootstrap as root!")
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ def generate(args, pkgname):
|
|||
fields = {
|
||||
"pkgname": pkgname,
|
||||
"pkgdesc": f"Tools necessary to build programs for {arch} targets",
|
||||
"arch": args.arch_native,
|
||||
"arch": pmb.config.arch_native,
|
||||
"makedepends_build": "",
|
||||
"makedepends_host": "",
|
||||
"makedepends": "gettext libtool autoconf automake bison texinfo",
|
||||
|
|
|
@ -47,7 +47,7 @@ def generate(args, pkgname):
|
|||
|
||||
url="http://busybox.net"
|
||||
license="GPL2"
|
||||
arch="{args.arch_native}"
|
||||
arch="{pmb.config.arch_native}"
|
||||
options="!check !strip"
|
||||
pkgdesc="Statically linked Busybox for $_arch"
|
||||
_target="$(arch_to_hostspec $_arch)"
|
||||
|
|
|
@ -28,7 +28,7 @@ def generate(args, pkgname):
|
|||
fields = {
|
||||
"pkgname": pkgname,
|
||||
"pkgdesc": f"Stage2 cross-compiler for {arch}",
|
||||
"arch": args.arch_native,
|
||||
"arch": pmb.config.arch_native,
|
||||
"depends": f"isl binutils-{arch} mpc1",
|
||||
"makedepends_build": "gcc g++ bison flex texinfo gawk zip"
|
||||
" gmp-dev mpfr-dev mpc1-dev zlib-dev",
|
||||
|
|
|
@ -43,7 +43,7 @@ def generate(args, pkgname):
|
|||
pkgdesc="GRUB $_arch EFI files for every architecture"
|
||||
url="https://www.gnu.org/software/grub/"
|
||||
license="GPL-3.0-or-later"
|
||||
arch="{args.arch_native}"
|
||||
arch="{pmb.config.arch_native}"
|
||||
source="grub-efi-$pkgver-r$pkgrel-$_arch-{mirrordir}.apk::$_mirror/{mirrordir}/main/$_arch/grub-efi-$pkgver-r$pkgrel.apk"
|
||||
|
||||
package() {{
|
||||
|
|
|
@ -42,7 +42,7 @@ def generate(args, pkgname):
|
|||
pkgname={pkgname}
|
||||
pkgver={pkgver}
|
||||
pkgrel={pkgrel}
|
||||
arch="{args.arch_native}"
|
||||
arch="{pmb.config.arch_native}"
|
||||
subpackages="musl-dev-{arch}:package_dev"
|
||||
|
||||
_arch="{arch}"
|
||||
|
|
|
@ -196,7 +196,7 @@ def init_buildenv(args, apkbuild, arch, strict=False, force=False, cross=None,
|
|||
|
||||
depends_arch = arch
|
||||
if cross == "native":
|
||||
depends_arch = args.arch_native
|
||||
depends_arch = pmb.config.arch_native
|
||||
|
||||
# Build dependencies
|
||||
depends, built = build_depends(args, apkbuild, depends_arch, strict)
|
||||
|
@ -236,7 +236,7 @@ def get_gcc_version(args, arch):
|
|||
:returns: a string like "6.4.0-r5"
|
||||
"""
|
||||
return pmb.parse.apkindex.package(args, "gcc-" + arch,
|
||||
args.arch_native)["version"]
|
||||
pmb.config.arch_native)["version"]
|
||||
|
||||
|
||||
def get_pkgver(original_pkgver, original_source=False, now=None):
|
||||
|
@ -493,7 +493,7 @@ def package(args, pkgname, arch=None, force=False, strict=False,
|
|||
output path relative to the packages folder ("armhf/ab-1-r2.apk")
|
||||
"""
|
||||
# Once per session is enough
|
||||
arch = arch or args.arch_native
|
||||
arch = arch or pmb.config.arch_native
|
||||
if skip_already_built(args, pkgname, arch):
|
||||
return
|
||||
|
||||
|
@ -505,7 +505,7 @@ def package(args, pkgname, arch=None, force=False, strict=False,
|
|||
# Detect the build environment (skip unnecessary builds)
|
||||
if not check_build_for_arch(args, pkgname, arch):
|
||||
return
|
||||
suffix = pmb.build.autodetect.suffix(args, apkbuild, arch)
|
||||
suffix = pmb.build.autodetect.suffix(apkbuild, arch)
|
||||
cross = pmb.build.autodetect.crosscompile(args, apkbuild, arch, suffix)
|
||||
if not init_buildenv(args, apkbuild, arch, strict, force, cross, suffix,
|
||||
skip_init_buildenv, src):
|
||||
|
|
|
@ -50,8 +50,10 @@ def arch(args, pkgname):
|
|||
|
||||
apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD")
|
||||
arches = apkbuild["arch"]
|
||||
if "noarch" in arches or "all" in arches or args.arch_native in arches:
|
||||
return args.arch_native
|
||||
if ("noarch" in arches or
|
||||
"all" in arches or
|
||||
pmb.config.arch_native in arches):
|
||||
return pmb.config.arch_native
|
||||
|
||||
arch_device = args.deviceinfo["arch"]
|
||||
if arch_device in arches:
|
||||
|
@ -63,8 +65,8 @@ def arch(args, pkgname):
|
|||
return None
|
||||
|
||||
|
||||
def suffix(args, apkbuild, arch):
|
||||
if arch == args.arch_native:
|
||||
def suffix(apkbuild, arch):
|
||||
if arch == pmb.config.arch_native:
|
||||
return "native"
|
||||
|
||||
if "pmb:cross-native" in apkbuild["options"]:
|
||||
|
@ -79,7 +81,7 @@ def crosscompile(args, apkbuild, arch, suffix):
|
|||
"""
|
||||
if not args.cross:
|
||||
return None
|
||||
if not pmb.parse.arch.cpu_emulation_required(args, arch):
|
||||
if not pmb.parse.arch.cpu_emulation_required(arch):
|
||||
return None
|
||||
if suffix == "native":
|
||||
return "native"
|
||||
|
|
|
@ -12,7 +12,7 @@ import pmb.helpers.pmaports
|
|||
import pmb.parse
|
||||
|
||||
|
||||
def match_kbuild_out(args, word):
|
||||
def match_kbuild_out(word):
|
||||
"""
|
||||
Look for paths in the following formats:
|
||||
"<prefix>/<kbuild_out>/arch/<arch>/boot"
|
||||
|
@ -47,7 +47,7 @@ def match_kbuild_out(args, word):
|
|||
return "" if out_dir is None else out_dir.strip("/")
|
||||
|
||||
|
||||
def find_kbuild_output_dir(args, function_body):
|
||||
def find_kbuild_output_dir(function_body):
|
||||
"""
|
||||
Guess what the kernel build output directory is. Parses each line of the
|
||||
function word by word, looking for paths which contain the kbuild output
|
||||
|
@ -61,7 +61,7 @@ def find_kbuild_output_dir(args, function_body):
|
|||
guesses = []
|
||||
for line in function_body:
|
||||
for item in line.split():
|
||||
kbuild_out = match_kbuild_out(args, item)
|
||||
kbuild_out = match_kbuild_out(item)
|
||||
if kbuild_out is not None:
|
||||
guesses.append(kbuild_out)
|
||||
break
|
||||
|
@ -142,7 +142,7 @@ def run_abuild(args, pkgname, arch, apkbuild_path, kbuild_out):
|
|||
# Create the apk package
|
||||
env = {"CARCH": arch,
|
||||
"CHOST": arch,
|
||||
"CBUILD": args.arch_native,
|
||||
"CBUILD": pmb.config.arch_native,
|
||||
"SUDO_APK": "abuild-apk --no-progress"}
|
||||
cmd = ["abuild", "rootpkg"]
|
||||
pmb.chroot.user(args, cmd, working_dir=build_path, env=env)
|
||||
|
@ -176,12 +176,12 @@ def package_kernel(args):
|
|||
kbuild_out = apkbuild["_outdir"]
|
||||
else:
|
||||
function_body = pmb.parse.function_body(aport + "/APKBUILD", "package")
|
||||
kbuild_out = find_kbuild_output_dir(args, function_body)
|
||||
suffix = pmb.build.autodetect.suffix(args, apkbuild, arch)
|
||||
kbuild_out = find_kbuild_output_dir(function_body)
|
||||
suffix = pmb.build.autodetect.suffix(apkbuild, arch)
|
||||
|
||||
# Install package dependencies
|
||||
depends, _ = pmb.build._package.build_depends(
|
||||
args, apkbuild, args.arch_native, strict=False)
|
||||
args, apkbuild, pmb.config.arch_native, strict=False)
|
||||
pmb.build.init(args, suffix)
|
||||
pmb.chroot.apk.install(args, depends, suffix)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import pmb.helpers.run
|
|||
import pmb.parse
|
||||
|
||||
|
||||
def get_arch(args, apkbuild):
|
||||
def get_arch(apkbuild):
|
||||
"""
|
||||
Take the architecture from the APKBUILD or complain if it's ambiguous. This
|
||||
function only gets called if --arch is not set.
|
||||
|
@ -81,17 +81,15 @@ def get_outputdir(args, pkgname, apkbuild):
|
|||
def menuconfig(args, pkgname, use_oldconfig):
|
||||
# Pkgname: allow omitting "linux-" prefix
|
||||
if pkgname.startswith("linux-"):
|
||||
pkgname_ = pkgname.split("linux-")[1]
|
||||
logging.info(f"PROTIP: You can simply do 'pmbootstrap kconfig "
|
||||
f"{args.action_kconfig} {pkgname_}'")
|
||||
pkgname = pkgname.split("linux-")[1]
|
||||
else:
|
||||
pkgname = "linux-" + pkgname
|
||||
|
||||
# Read apkbuild
|
||||
aport = pmb.helpers.pmaports.find(args, pkgname)
|
||||
apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD")
|
||||
arch = args.arch or get_arch(args, apkbuild)
|
||||
suffix = pmb.build.autodetect.suffix(args, apkbuild, arch)
|
||||
arch = args.arch or get_arch(apkbuild)
|
||||
suffix = pmb.build.autodetect.suffix(apkbuild, arch)
|
||||
cross = pmb.build.autodetect.crosscompile(args, apkbuild, arch, suffix)
|
||||
hostspec = pmb.parse.arch.alpine_to_hostspec(arch)
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ def download(args, file):
|
|||
"""
|
||||
channel_cfg = pmb.config.pmaports.read_config_channel(args)
|
||||
mirrordir = channel_cfg["mirrordir_alpine"]
|
||||
base_url = f"{args.mirror_alpine}{mirrordir}/main/{args.arch_native}"
|
||||
base_url = f"{args.mirror_alpine}{mirrordir}/main/{pmb.config.arch_native}"
|
||||
return pmb.helpers.http.download(args, f"{base_url}/{file}", file)
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ def register(args, arch):
|
|||
if is_registered(arch_qemu):
|
||||
return
|
||||
|
||||
info = pmb.parse.binfmt_info(args, arch_qemu)
|
||||
info = pmb.parse.binfmt_info(arch_qemu)
|
||||
|
||||
# Build registration string
|
||||
# https://en.wikipedia.org/wiki/Binfmt_misc
|
||||
|
|
|
@ -43,7 +43,7 @@ def mark_in_chroot(args, suffix="native"):
|
|||
|
||||
def setup_qemu_emulation(args, suffix):
|
||||
arch = pmb.parse.arch.from_chroot_suffix(args, suffix)
|
||||
if not pmb.parse.arch.cpu_emulation_required(args, arch):
|
||||
if not pmb.parse.arch.cpu_emulation_required(arch):
|
||||
return
|
||||
|
||||
chroot = f"{args.work}/chroot_{suffix}"
|
||||
|
|
|
@ -90,6 +90,6 @@ def shutdown(args, only_install_related=False):
|
|||
|
||||
# Clean up the rest
|
||||
for arch in pmb.config.build_device_architectures:
|
||||
if pmb.parse.arch.cpu_emulation_required(args, arch):
|
||||
if pmb.parse.arch.cpu_emulation_required(arch):
|
||||
pmb.chroot.binfmt.unregister(args, arch)
|
||||
logging.debug("Shutdown complete")
|
||||
|
|
|
@ -106,7 +106,7 @@ def zap_pkgs_local_mismatch(args, confirm=True, dry=False):
|
|||
pattern = f"{args.work}/packages/{channel}/*/APKINDEX.tar.gz"
|
||||
for apkindex_path in glob.glob(pattern):
|
||||
# Delete packages without same version in aports
|
||||
blocks = pmb.parse.apkindex.parse_blocks(args, apkindex_path)
|
||||
blocks = pmb.parse.apkindex.parse_blocks(apkindex_path)
|
||||
for block in blocks:
|
||||
pkgname = block["pkgname"]
|
||||
origin = block["origin"]
|
||||
|
@ -158,7 +158,9 @@ def zap_pkgs_online_mismatch(args, confirm=True, dry=False):
|
|||
# Iterate over existing apk caches
|
||||
for path in paths:
|
||||
arch = os.path.basename(path).split("_", 2)[2]
|
||||
suffix = "native" if arch == args.arch_native else f"buildroot_{arch}"
|
||||
suffix = f"buildroot_{arch}"
|
||||
if arch == pmb.config.arch_native:
|
||||
suffix = "native"
|
||||
|
||||
# Clean the cache with apk
|
||||
logging.info(f"({suffix}) apk -v cache clean")
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import multiprocessing
|
||||
import os
|
||||
import pmb.parse.arch
|
||||
import sys
|
||||
|
||||
#
|
||||
|
@ -15,9 +16,10 @@ from pmb.config.merge_with_args import merge_with_args
|
|||
#
|
||||
# Exported variables (internal configuration)
|
||||
#
|
||||
version = "1.38.0"
|
||||
version = "1.39.0"
|
||||
pmb_src = os.path.normpath(os.path.realpath(__file__) + "/../../..")
|
||||
apk_keys_path = pmb_src + "/pmb/data/keys"
|
||||
arch_native = pmb.parse.arch.alpine_native()
|
||||
|
||||
# apk-tools minimum version
|
||||
# https://pkgs.alpinelinux.org/packages?name=apk-tools&branch=edge
|
||||
|
@ -256,6 +258,21 @@ build_device_architectures = ["armhf", "armv7", "aarch64", "x86_64", "x86"]
|
|||
# for the first time
|
||||
build_packages = ["abuild", "build-base", "ccache", "git"]
|
||||
|
||||
#
|
||||
# KCONFIG CHECK
|
||||
#
|
||||
# Implemented value types:
|
||||
# - boolean (e.g. '"ANDROID_PARANOID_NETWORK": False'):
|
||||
# - False: disabled
|
||||
# - True: enabled, either as module or built-in
|
||||
# - array (e.g. '"ANDROID_BINDER_DEVICES": ["binder", "hwbinder"]'):
|
||||
# - each element of the array must be contained in the kernel config string,
|
||||
# in any order. The example above would accept the following in the config:
|
||||
# CONFIG_ANDROID_BINDER_DEVICES="hwbinder,vndbinder,binder"
|
||||
# - string (e.g. '"LSM": "lockdown,yama,loadpin,safesetid,integrity"'):
|
||||
# - the value in the kernel config must be the same as the given string. Use
|
||||
# this e.g. if the order of the elements is important.
|
||||
|
||||
# Necessary kernel config options
|
||||
necessary_kconfig_options = {
|
||||
">=0.0.0": { # all versions
|
||||
|
@ -263,9 +280,11 @@ necessary_kconfig_options = {
|
|||
"ANDROID_PARANOID_NETWORK": False,
|
||||
"BLK_DEV_INITRD": True,
|
||||
"CGROUPS": True,
|
||||
"CRYPTO_AES": True,
|
||||
"CRYPTO_XTS": True,
|
||||
"DEVTMPFS": True,
|
||||
"DM_CRYPT": True,
|
||||
"INPUT_EVDEV": True,
|
||||
"EXT4_FS": True,
|
||||
"KINETO_GAN": False,
|
||||
"PFT": False,
|
||||
|
@ -296,7 +315,7 @@ necessary_kconfig_options = {
|
|||
}
|
||||
}
|
||||
|
||||
# Necessary anbox kernel config options
|
||||
# Necessary anbox/waydroid kernel config options (android app support)
|
||||
necessary_kconfig_options_anbox = {
|
||||
">=0.0.0": { # all versions
|
||||
"all": { # all arches
|
||||
|
@ -328,7 +347,55 @@ necessary_kconfig_options_anbox = {
|
|||
}
|
||||
}
|
||||
|
||||
# Necessary nftables kernel config options
|
||||
# Necessary apparmor kernel config options (mandatory access control)
|
||||
# LSM: the value that "config LSM" sets in security/Kconfig, if
|
||||
# DEFAULT_SECURITY_APPARMOR is set (and other DEFAULT_SECURITY_* are unset).
|
||||
necessary_kconfig_options_apparmor = {
|
||||
">=0.0.0": { # all versions
|
||||
"all": { # all arches
|
||||
"AUDIT": True,
|
||||
"DEFAULT_SECURITY_APPARMOR": True,
|
||||
"LSM": "landlock,lockdown,yama,loadpin,safesetid,integrity,"
|
||||
"apparmor,selinux,smack,tomoyo,bpf",
|
||||
"SECURITY_APPARMOR": True,
|
||||
},
|
||||
},
|
||||
"<5.1": {
|
||||
"all": {
|
||||
"SECURITY_APPARMOR_BOOTPARAM_VALUE": True,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# Necessary iwd kernel config options (inet wireless daemon)
|
||||
# Obtained from 'grep ADD_MISSING src/main.c' in iwd.git
|
||||
necessary_kconfig_options_iwd = {
|
||||
">=0.0.0": { # all versions
|
||||
"all": { # all arches
|
||||
"ASYMMETRIC_KEY_TYPE": True,
|
||||
"ASYMMETRIC_PUBLIC_KEY_SUBTYPE": True,
|
||||
"CRYPTO_AES": True,
|
||||
"CRYPTO_CBC": True,
|
||||
"CRYPTO_CMAC": True,
|
||||
"CRYPTO_DES": True,
|
||||
"CRYPTO_ECB": True,
|
||||
"CRYPTO_HMAC": True,
|
||||
"CRYPTO_MD5": True,
|
||||
"CRYPTO_SHA1": True,
|
||||
"CRYPTO_SHA256": True,
|
||||
"CRYPTO_SHA512": True,
|
||||
"CRYPTO_USER_API_HASH": True,
|
||||
"CRYPTO_USER_API_SKCIPHER": True,
|
||||
"KEYS": True,
|
||||
"KEY_DH_OPERATIONS": True,
|
||||
"PKCS7_MESSAGE_PARSER": True,
|
||||
"PKCS8_PRIVATE_KEY_PARSER": True,
|
||||
"X509_CERTIFICATE_PARSER": True,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# Necessary nftables kernel config options (firewall)
|
||||
necessary_kconfig_options_nftables = {
|
||||
">=3.13.0": { # nftables support introduced here
|
||||
"all": { # all arches
|
||||
|
@ -470,6 +537,7 @@ necessary_kconfig_options_containers = {
|
|||
},
|
||||
}
|
||||
|
||||
# Necessary zram kernel config options (RAM disk with on-the-fly compression)
|
||||
necessary_kconfig_options_zram = {
|
||||
">=3.14.0": { # zram support introduced here
|
||||
"all": { # all arches
|
||||
|
@ -491,6 +559,7 @@ apkbuild_package_attributes = {
|
|||
"pkgdesc": {},
|
||||
"depends": {"array": True},
|
||||
"provides": {"array": True},
|
||||
"provider_priority": {"int": True},
|
||||
"install": {"array": True},
|
||||
|
||||
# UI meta-packages can specify apps in "_pmb_recommends" to be explicitly
|
||||
|
@ -503,6 +572,11 @@ apkbuild_package_attributes = {
|
|||
# UI meta-packages can specify groups to which the user must be added
|
||||
# to access specific hardware such as LED indicators.
|
||||
"_pmb_groups": {"array": True},
|
||||
|
||||
# postmarketos-base, UI and device packages can use _pmb_select to provide
|
||||
# additional configuration options in "pmbootstrap init" that allow
|
||||
# selecting alternative providers for a virtual APK package.
|
||||
"_pmb_select": {"array": True},
|
||||
}
|
||||
|
||||
# Variables in APKBUILD files that get parsed
|
||||
|
@ -714,6 +788,8 @@ flashers = {
|
|||
"$BOOT/dtbo.img"]],
|
||||
"boot": [["fastboot", "--cmdline", "$KERNEL_CMDLINE",
|
||||
"boot", "$BOOT/boot.img$FLAVOR"]],
|
||||
"flash_lk2nd": [["fastboot", "flash", "$PARTITION_KERNEL",
|
||||
"$BOOT/lk2nd.img"]]
|
||||
},
|
||||
},
|
||||
# Some devices provide Fastboot but using Android boot images is not
|
||||
|
|
|
@ -14,6 +14,7 @@ import pmb.helpers.devices
|
|||
import pmb.helpers.http
|
||||
import pmb.helpers.logging
|
||||
import pmb.helpers.other
|
||||
import pmb.helpers.pmaports
|
||||
import pmb.helpers.run
|
||||
import pmb.helpers.ui
|
||||
import pmb.chroot.zap
|
||||
|
@ -111,8 +112,7 @@ def ask_for_channel(args):
|
|||
" from the list above.")
|
||||
|
||||
|
||||
def ask_for_ui(args, device):
|
||||
info = pmb.parse.deviceinfo(args, device)
|
||||
def ask_for_ui(args, info):
|
||||
ui_list = pmb.helpers.ui.list(args, info["arch"])
|
||||
hidden_ui_count = 0
|
||||
device_is_accelerated = info.get("gpu_accelerated") == "true"
|
||||
|
@ -163,8 +163,7 @@ def ask_for_ui_extras(args, ui):
|
|||
default=args.ui_extras)
|
||||
|
||||
|
||||
def ask_for_keymaps(args, device):
|
||||
info = pmb.parse.deviceinfo(args, device)
|
||||
def ask_for_keymaps(args, info):
|
||||
if "keymaps" not in info or info["keymaps"].strip() == "":
|
||||
return ""
|
||||
options = info["keymaps"].split(' ')
|
||||
|
@ -208,6 +207,80 @@ def ask_for_timezone(args):
|
|||
return "GMT"
|
||||
|
||||
|
||||
def ask_for_provider_select(args, apkbuild, providers_cfg):
|
||||
"""
|
||||
Ask for selectable providers that are specified using "_pmb_select"
|
||||
in a APKBUILD.
|
||||
|
||||
:param apkbuild: the APKBUILD with the _pmb_select
|
||||
:param providers_cfg: the configuration section with previously selected
|
||||
providers. Updated with new providers after selection
|
||||
"""
|
||||
for select in apkbuild["_pmb_select"]:
|
||||
providers = pmb.helpers.pmaports.find_providers(args, select)
|
||||
logging.info(f"Available providers for {select} ({len(providers)}):")
|
||||
|
||||
has_default = False
|
||||
providers_short = {}
|
||||
last_selected = providers_cfg.get(select, 'default')
|
||||
|
||||
for pkgname, pkg in providers:
|
||||
# Strip provider prefix if possible
|
||||
short = pkgname
|
||||
if short.startswith(f'{select}-'):
|
||||
short = short[len(f"{select}-"):]
|
||||
|
||||
# Allow selecting the package using both short and long name
|
||||
providers_short[pkgname] = pkgname
|
||||
providers_short[short] = pkgname
|
||||
|
||||
if pkgname == last_selected:
|
||||
last_selected = short
|
||||
|
||||
if not has_default and pkg.get('provider_priority', 0) != 0:
|
||||
# Display as default provider
|
||||
styles = pmb.config.styles
|
||||
logging.info(f"* {short}: {pkg['pkgdesc']} "
|
||||
f"{styles['BOLD']}(default){styles['END']}")
|
||||
has_default = True
|
||||
else:
|
||||
logging.info(f"* {short}: {pkg['pkgdesc']}")
|
||||
|
||||
while True:
|
||||
ret = pmb.helpers.cli.ask("Provider", None, last_selected, True,
|
||||
complete=providers_short.keys())
|
||||
|
||||
if has_default and ret == 'default':
|
||||
# Selecting default means to not select any provider explicitly
|
||||
# In other words, apk chooses it automatically based on
|
||||
# "provider_priority"
|
||||
if select in providers_cfg:
|
||||
del providers_cfg[select]
|
||||
break
|
||||
if ret in providers_short:
|
||||
providers_cfg[select] = providers_short[ret]
|
||||
break
|
||||
logging.fatal("ERROR: Invalid provider specified, please type in"
|
||||
" one from the list above.")
|
||||
|
||||
|
||||
def ask_for_provider_select_pkg(args, pkgname, providers_cfg):
|
||||
"""
|
||||
Look up the APKBUILD for the specified pkgname and ask for selectable
|
||||
providers that are specified using "_pmb_select".
|
||||
|
||||
:param pkgname: name of the package to search APKBUILD for
|
||||
:param providers_cfg: the configuration section with previously selected
|
||||
providers. Updated with new providers after selection
|
||||
"""
|
||||
apkbuild = pmb.helpers.pmaports.get(args, pkgname,
|
||||
subpackages=False, must_exist=False)
|
||||
if not apkbuild:
|
||||
return
|
||||
|
||||
ask_for_provider_select(args, apkbuild, providers_cfg)
|
||||
|
||||
|
||||
def ask_for_device_kernel(args, device):
|
||||
"""
|
||||
Ask for the kernel that should be used with the device.
|
||||
|
@ -568,18 +641,29 @@ def frontend(args):
|
|||
cfg["pmbootstrap"]["nonfree_firmware"] = str(nonfree["firmware"])
|
||||
cfg["pmbootstrap"]["nonfree_userland"] = str(nonfree["userland"])
|
||||
|
||||
info = pmb.parse.deviceinfo(args, device)
|
||||
apkbuild_path = pmb.helpers.devices.find_path(args, device, 'APKBUILD')
|
||||
if apkbuild_path:
|
||||
apkbuild = pmb.parse.apkbuild(args, apkbuild_path)
|
||||
ask_for_provider_select(args, apkbuild, cfg["providers"])
|
||||
|
||||
# Device keymap
|
||||
if device_exists:
|
||||
cfg["pmbootstrap"]["keymap"] = ask_for_keymaps(args, device)
|
||||
cfg["pmbootstrap"]["keymap"] = ask_for_keymaps(args, info)
|
||||
|
||||
# Username
|
||||
cfg["pmbootstrap"]["user"] = pmb.helpers.cli.ask("Username", None,
|
||||
args.user, False,
|
||||
"[a-z_][a-z0-9_-]*")
|
||||
|
||||
ask_for_provider_select_pkg(args, "postmarketos-base", cfg["providers"])
|
||||
|
||||
# UI and various build options
|
||||
ui = ask_for_ui(args, device)
|
||||
ui = ask_for_ui(args, info)
|
||||
cfg["pmbootstrap"]["ui"] = ui
|
||||
cfg["pmbootstrap"]["ui_extras"] = str(ask_for_ui_extras(args, ui))
|
||||
ask_for_provider_select_pkg(args, f"postmarketos-ui-{ui}",
|
||||
cfg["providers"])
|
||||
ask_for_additional_options(args, cfg)
|
||||
|
||||
# Extra packages to be installed to rootfs
|
||||
|
@ -619,7 +703,7 @@ def frontend(args):
|
|||
pmb.helpers.cli.confirm(
|
||||
args, "Zap existing chroots to apply configuration?",
|
||||
default=True)):
|
||||
setattr(args, "deviceinfo", pmb.parse.deviceinfo(args, device=device))
|
||||
setattr(args, "deviceinfo", info)
|
||||
|
||||
# Do not zap any existing packages or cache_http directories
|
||||
pmb.chroot.zap(args, confirm=False)
|
||||
|
|
|
@ -13,6 +13,8 @@ def load(args):
|
|||
|
||||
if "pmbootstrap" not in cfg:
|
||||
cfg["pmbootstrap"] = {}
|
||||
if "providers" not in cfg:
|
||||
cfg["providers"] = {}
|
||||
|
||||
for key in pmb.config.defaults:
|
||||
if key in pmb.config.config_keys and key not in cfg["pmbootstrap"]:
|
||||
|
|
|
@ -29,6 +29,7 @@ def merge_with_args(args):
|
|||
if isinstance(default, bool):
|
||||
value = (value.lower() == "true")
|
||||
setattr(args, key, value)
|
||||
setattr(args, 'selected_providers', cfg['providers'])
|
||||
|
||||
# Use defaults from pmb.config.defaults
|
||||
for key, value in pmb.config.defaults.items():
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXEJ8uVwJPODshTkf2BH
|
||||
pH5fVVDppOa974+IQJsZDmGd3Ny0dcd+WwYUhNFUW3bAfc3/egaMWCaprfaHn+oS
|
||||
4ddbOFgbX8JCHdru/QMAAU0aEWSMybfJGA569c38fNUF/puX6XK/y0lD2SS3YQ/a
|
||||
oJ5jb5eNrQGR1HHMAd0G9WC4JeZ6WkVTkrcOw55F00aUPGEjejreXBerhTyFdabo
|
||||
dSfc1TILWIYD742Lkm82UBOPsOSdSfOdsMOOkSXxhdCJuCQQ70DHkw7Epy9r+X33
|
||||
ybI4r1cARcV75OviyhD8CFhAlapLKaYnRFqFxlA515e6h8i8ih/v3MSEW17cCK0b
|
||||
QwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwR4uJVtJOnOFGchnMW5Y
|
||||
j5/waBdG1u5BTMlH+iQMcV5+VgWhmpZHJCBz3ocD+0IGk2I68S5TDOHec/GSC0lv
|
||||
6R9o6F7h429GmgPgVKQsc8mPTPtbjJMuLLs4xKc+viCplXc0Nc0ZoHmCH4da6fCV
|
||||
tdpHQjVe6F9zjdquZ4RjV6R6JTiN9v924dGMAkbW/xXmamtz51FzondKC52Gh8Mo
|
||||
/oA0/T0KsCMCi7tb4QNQUYrf+Xcha9uus4ww1kWNZyfXJB87a2kORLiWMfs2IBBJ
|
||||
TmZ2Fnk0JnHDb8Oknxd9PvJPT0mvyT8DA+KIAPqNvOjUXP4bnjEHJcoCP9S5HkGC
|
||||
IQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAutQkua2CAig4VFSJ7v54
|
||||
ALyu/J1WB3oni7qwCZD3veURw7HxpNAj9hR+S5N/pNeZgubQvJWyaPuQDm7PTs1+
|
||||
tFGiYNfAsiibX6Rv0wci3M+z2XEVAeR9Vzg6v4qoofDyoTbovn2LztaNEjTkB+oK
|
||||
tlvpNhg1zhou0jDVYFniEXvzjckxswHVb8cT0OMTKHALyLPrPOJzVtM9C1ew2Nnc
|
||||
3848xLiApMu3NBk0JqfcS3Bo5Y2b1FRVBvdt+2gFoKZix1MnZdAEZ8xQzL/a0YS5
|
||||
Hd0wj5+EEKHfOd3A75uPa/WQmA+o0cBFfrzm69QDcSJSwGpzWrD1ScH3AK8nWvoj
|
||||
v7e9gukK/9yl1b4fQQ00vttwJPSgm9EnfPHLAtgXkRloI27H6/PuLoNvSAMQwuCD
|
||||
hQRlyGLPBETKkHeodfLoULjhDi1K2gKJTMhtbnUcAA7nEphkMhPWkBpgFdrH+5z4
|
||||
Lxy+3ek0cqcI7K68EtrffU8jtUj9LFTUC8dERaIBs7NgQ/LfDbDfGh9g6qVj1hZl
|
||||
k9aaIPTm/xsi8v3u+0qaq7KzIBc9s59JOoA8TlpOaYdVgSQhHHLBaahOuAigH+VI
|
||||
isbC9vmqsThF2QdDtQt37keuqoda2E6sL7PUvIyVXDRfwX7uMDjlzTxHTymvq2Ck
|
||||
htBqojBnThmjJQFgZXocHG8CAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlEyxkHggKCXC2Wf5Mzx4
|
||||
nZLFZvU2bgcA3exfNPO/g1YunKfQY+Jg4fr6tJUUTZ3XZUrhmLNWvpvSwDS19ZmC
|
||||
IXOu0+V94aNgnhMsk9rr59I8qcbsQGIBoHzuAl8NzZCgdbEXkiY90w1skUw8J57z
|
||||
qCsMBydAueMXuWqF5nGtYbi5vHwK42PffpiZ7G5Kjwn8nYMW5IZdL6ZnMEVJUWC9
|
||||
I4waeKg0yskczYDmZUEAtrn3laX9677ToCpiKrvmZYjlGl0BaGp3cxggP2xaDbUq
|
||||
qfFxWNgvUAb3pXD09JM6Mt6HSIJaFc9vQbrKB9KT515y763j5CC2KUsilszKi3mB
|
||||
HYe5PoebdjS7D1Oh+tRqfegU2IImzSwW3iwA7PJvefFuc/kNIijfS/gH/cAqAK6z
|
||||
bhdOtE/zc7TtqW2Wn5Y03jIZdtm12CxSxwgtCF1NPyEWyIxAQUX9ACb3M0FAZ61n
|
||||
fpPrvwTaIIxxZ01L3IzPLpbc44x/DhJIEU+iDt6IMTrHOphD9MCG4631eIdB0H1b
|
||||
6zbNX1CXTsafqHRFV9XmYYIeOMggmd90s3xIbEujA6HKNP/gwzO6CDJ+nHFDEqoF
|
||||
SkxRdTkEqjTjVKieURW7Swv7zpfu5PrsrrkyGnsRrBJJzXlm2FOOxnbI2iSL1B5F
|
||||
rO5kbUxFeZUIDq+7Yv4kLWcCAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnC+bR4bHf/L6QdU4puhQ
|
||||
gl1MHePszRC38bzvVFDUJsmCaMCL2suCs2A2yxAgGb9pu9AJYLAmxQC4mM3jNqhg
|
||||
/E7yuaBbek3O02zN/ctvflJ250wZCy+z0ZGIp1ak6pu1j14IwHokl9j36zNfGtfv
|
||||
ADVOcdpWITFFlPqwq1qt/H3UsKVmtiF3BNWWTeUEQwKvlU8ymxgS99yn0+4OPyNT
|
||||
L3EUeS+NQJtDS01unau0t7LnjUXn+XIneWny8bIYOQCuVR6s/gpIGuhBaUqwaJOw
|
||||
7jkJZYF2Ij7uPb4b5/R3vX2FfxxqEHqssFSg8FFUNTZz3qNZs0CRVyfA972g9WkJ
|
||||
hPfn31pQYil4QGRibCMIeU27YAEjXoqfJKEPh4UWMQsQLrEfdGfb8VgwrPbniGfU
|
||||
L3jKJR3VAafL9330iawzVQDlIlwGl6u77gEXMl9K0pfazunYhAp+BMP+9ot5ckK+
|
||||
osmrqj11qMESsAj083GeFdfV3pXEIwUytaB0AKEht9DbqUfiE/oeZ/LAXgySMtVC
|
||||
sbC4ESmgVeY2xSBIJdDyUap7FR49GGrw0W49NUv9gRgQtGGaNVQQO9oGL2PBC41P
|
||||
iWF9GLoX30HIz1P8PF/cZvicSSPkQf2Z6TV+t0ebdGNS5DjapdnCrq8m9Z0pyKsQ
|
||||
uxAL2a7zX8l5i1CZh1ycUGsCAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0MfCDrhODRCIxR9Dep1s
|
||||
eXafh5CE5BrF4WbCgCsevyPIdvTeyIaW4vmO3bbG4VzhogDZju+R3IQYFuhoXP5v
|
||||
Y+zYJGnwrgz3r5wYAvPnLEs1+dtDKYOgJXQj+wLJBW1mzRDL8FoRXOe5iRmn1EFS
|
||||
wZ1DoUvyu7/J5r0itKicZp3QKED6YoilXed+1vnS4Sk0mzN4smuMR9eO1mMCqNp9
|
||||
9KTfRDHTbakIHwasECCXCp50uXdoW6ig/xUAFanpm9LtK6jctNDbXDhQmgvAaLXZ
|
||||
LvFqoaYJ/CvWkyYCgL6qxvMvVmPoRv7OPcyni4xR/WgWa0MSaEWjgPx3+yj9fiMA
|
||||
1S02pFWFDOr5OUF/O4YhFJvUCOtVsUPPfA/Lj6faL0h5QI9mQhy5Zb9TTaS9jB6p
|
||||
Lw7u0dJlrjFedk8KTJdFCcaGYHP6kNPnOxMylcB/5WcztXZVQD5WpCicGNBxCGMm
|
||||
W64SgrV7M07gQfL/32QLsdqPUf0i8hoVD8wfQ3EpbQzv6Fk1Cn90bZqZafg8XWGY
|
||||
wddhkXk7egrr23Djv37V2okjzdqoyLBYBxMz63qQzFoAVv5VoY2NDTbXYUYytOvG
|
||||
GJ1afYDRVWrExCech1mX5ZVUB1br6WM+psFLJFoBFl6mDmiYt0vMYBddKISsvwLl
|
||||
IJQkzDwtXzT2cSjoj3T5QekCAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvaaoSLab+IluixwKV5Od
|
||||
0gib2YurjPatGIbn5Ov2DLUFYiebj2oJINXJSwUOO+4WcuHFEqiL/1rya+k5hLZt
|
||||
hnPL1tn6QD4rESznvGSasRCQNT2vS/oyZbTYJRyAtFkEYLlq0t3S3xBxxHWuvIf0
|
||||
qVxVNYpQWyM3N9RIeYBR/euXKJXileSHk/uq1I5wTC0XBIHWcthczGN0m9wBEiWS
|
||||
0m3cnPk4q0Ea8mUJ91Rqob19qETz6VbSPYYpZk3qOycjKosuwcuzoMpwU8KRiMFd
|
||||
5LHtX0Hx85ghGsWDVtS0c0+aJa4lOMGvJCAOvDfqvODv7gKlCXUpgumGpLdTmaZ8
|
||||
1RwqspAe3IqBcdKTqRD4m2mSg23nVx2FAY3cjFvZQtfooT7q1ItRV5RgH6FhQSl7
|
||||
+6YIMJ1Bf8AAlLdRLpg+doOUGcEn+pkDiHFgI8ylH1LKyFKw+eXaAml/7DaWZk1d
|
||||
dqggwhXOhc/UUZFQuQQ8A8zpA13PcbC05XxN2hyP93tCEtyynMLVPtrRwDnHxFKa
|
||||
qKzs3rMDXPSXRn3ZZTdKH3069ApkEjQdpcwUh+EmJ1Ve/5cdtzT6kKWCjKBFZP/s
|
||||
91MlRrX2BTRdHaU5QJkUheUtakwxuHrdah2F94lRmsnQlpPr2YseJu6sIE+Dnx4M
|
||||
CfhdVbQL2w54R645nlnohu8CAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq0BFD1D4lIxQcsqEpQzU
|
||||
pNCYM3aP1V/fxxVdT4DWvSI53JHTwHQamKdMWtEXetWVbP5zSROniYKFXd/xrD9X
|
||||
0jiGHey3lEtylXRIPxe5s+wXoCmNLcJVnvTcDtwx/ne2NLHxp76lyc25At+6RgE6
|
||||
ADjLVuoD7M4IFDkAsd8UQ8zM0Dww9SylIk/wgV3ZkifecvgUQRagrNUdUjR56EBZ
|
||||
raQrev4hhzOgwelT0kXCu3snbUuNY/lU53CoTzfBJ5UfEJ5pMw1ij6X0r5S9IVsy
|
||||
KLWH1hiO0NzU2c8ViUYCly4Fe9xMTFc6u2dy/dxf6FwERfGzETQxqZvSfrRX+GLj
|
||||
/QZAXiPg5178hT/m0Y3z5IGenIC/80Z9NCi+byF1WuJlzKjDcF/TU72zk0+PNM/H
|
||||
Kuppf3JT4DyjiVzNC5YoWJT2QRMS9KLP5iKCSThwVceEEg5HfhQBRT9M6KIcFLSs
|
||||
mFjx9kNEEmc1E8hl5IR3+3Ry8G5/bTIIruz14jgeY9u5jhL8Vyyvo41jgt9sLHR1
|
||||
/J1TxKfkgksYev7PoX6/ZzJ1ksWKZY5NFoDXTNYUgzFUTOoEaOg3BAQKadb3Qbbq
|
||||
XIrxmPBdgrn9QI7NCgfnAY3Tb4EEjs3ON/BNyEhUENcXOH6I1NbcuBQ7g9P73kE4
|
||||
VORdoc8MdJ5eoKBpO8Ww8HECAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyduVzi1mWm+lYo2Tqt/0
|
||||
XkCIWrDNP1QBMVPrE0/ZlU2bCGSoo2Z9FHQKz/mTyMRlhNqTfhJ5qU3U9XlyGOPJ
|
||||
piM+b91g26pnpXJ2Q2kOypSgOMOPA4cQ42PkHBEqhuzssfj9t7x47ppS94bboh46
|
||||
xLSDRff/NAbtwTpvhStV3URYkxFG++cKGGa5MPXBrxIp+iZf9GnuxVdST5PGiVGP
|
||||
ODL/b69sPJQNbJHVquqUTOh5Ry8uuD2WZuXfKf7/C0jC/ie9m2+0CttNu9tMciGM
|
||||
EyKG1/Xhk5iIWO43m4SrrT2WkFlcZ1z2JSf9Pjm4C2+HovYpihwwdM/OdP8Xmsnr
|
||||
DzVB4YvQiW+IHBjStHVuyiZWc+JsgEPJzisNY0Wyc/kNyNtqVKpX6dRhMLanLmy+
|
||||
f53cCSI05KPQAcGj6tdL+D60uKDkt+FsDa0BTAobZ31OsFVid0vCXtsbplNhW1IF
|
||||
HwsGXBTVcfXg44RLyL8Lk/2dQxDHNHzAUslJXzPxaHBLmt++2COa2EI1iWlvtznk
|
||||
Ok9WP8SOAIj+xdqoiHcC4j72BOVVgiITIJNHrbppZCq6qPR+fgXmXa+sDcGh30m6
|
||||
9Wpbr28kLMSHiENCWTdsFij+NQTd5S47H7XTROHnalYDuF1RpS+DpQidT5tUimaT
|
||||
JZDr++FjKrnnijbyNF8b98UCAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,14 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpUpyWDWjlUk3smlWeA0
|
||||
lIMW+oJ38t92CRLHH3IqRhyECBRW0d0aRGtq7TY8PmxjjvBZrxTNDpJT6KUk4LRm
|
||||
a6A6IuAI7QnNK8SJqM0DLzlpygd7GJf8ZL9SoHSH+gFsYF67Cpooz/YDqWrlN7Vw
|
||||
tO00s0B+eXy+PCXYU7VSfuWFGK8TGEv6HfGMALLjhqMManyvfp8hz3ubN1rK3c8C
|
||||
US/ilRh1qckdbtPvoDPhSbTDmfU1g/EfRSIEXBrIMLg9ka/XB9PvWRrekrppnQzP
|
||||
hP9YE3x/wbFc5QqQWiRCYyQl/rgIMOXvIxhkfe8H5n1Et4VAorkpEAXdsfN8KSVv
|
||||
LSMazVlLp9GYq5SUpqYX3KnxdWBgN7BJoZ4sltsTpHQ/34SXWfu3UmyUveWj7wp0
|
||||
x9hwsPirVI00EEea9AbP7NM2rAyu6ukcm4m6ATd2DZJIViq2es6m60AE6SMCmrQF
|
||||
wmk4H/kdQgeAELVfGOm2VyJ3z69fQuywz7xu27S6zTKi05Qlnohxol4wVb6OB7qG
|
||||
LPRtK9ObgzRo/OPumyXqlzAi/Yvyd1ZQk8labZps3e16bQp8+pVPiumWioMFJDWV
|
||||
GZjCmyMSU8V6MB6njbgLHoyg2LCukCAeSjbPGGGYhnKLm1AKSoJh3IpZuqcKCk5C
|
||||
8CM1S15HxV78s9dFntEqIokCAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
|
@ -37,6 +37,7 @@ def symlinks(args, flavor, folder):
|
|||
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",
|
||||
"lk2nd.img": "Secondary Android bootloader",
|
||||
}
|
||||
|
||||
# Generate a list of patterns
|
||||
|
@ -53,7 +54,8 @@ def symlinks(args, flavor, folder):
|
|||
f"{path_native}/home/pmos/rootfs/{args.device}-boot.img",
|
||||
f"{path_native}/home/pmos/rootfs/{args.device}-root.img",
|
||||
f"{path_buildroot}/var/lib/postmarketos-android-recovery-" +
|
||||
f"installer/pmos-{args.device}.zip"]
|
||||
f"installer/pmos-{args.device}.zip",
|
||||
f"{path_boot}/lk2nd.img"]
|
||||
|
||||
# Generate a list of files from the patterns
|
||||
files = []
|
||||
|
|
|
@ -112,6 +112,19 @@ def sideload(args):
|
|||
pmb.flasher.run(args, "sideload")
|
||||
|
||||
|
||||
def flash_lk2nd(args):
|
||||
chroot_path = args.work + "/chroot_rootfs_" + args.device
|
||||
lk2nd_path = "/boot/lk2nd.img"
|
||||
if not os.path.exists(chroot_path + lk2nd_path):
|
||||
raise RuntimeError(f"{chroot_path+lk2nd_path} doesn't exist. Your"
|
||||
" device may not support lk2nd.")
|
||||
|
||||
logging.info(lk2nd_path)
|
||||
logging.info("It's normal if fastboot warns"
|
||||
" \"Image not signed or corrupt\" or a similar warning")
|
||||
pmb.flasher.run(args, "flash_lk2nd")
|
||||
|
||||
|
||||
def frontend(args):
|
||||
action = args.action_flasher
|
||||
method = args.flash_method or args.deviceinfo["flash_method"]
|
||||
|
@ -120,7 +133,8 @@ def frontend(args):
|
|||
if action == "flash_system":
|
||||
action = "flash_rootfs"
|
||||
|
||||
if method == "none" and action in ["boot", "flash_kernel", "flash_rootfs"]:
|
||||
if method == "none" and action in ["boot", "flash_kernel", "flash_rootfs",
|
||||
"flash_lk2nd"]:
|
||||
logging.info("This device doesn't support any flash method.")
|
||||
return
|
||||
|
||||
|
@ -138,3 +152,5 @@ def frontend(args):
|
|||
list_devices(args)
|
||||
if action == "sideload":
|
||||
sideload(args)
|
||||
if action in ["flash_lk2nd"]:
|
||||
flash_lk2nd(args)
|
||||
|
|
|
@ -19,9 +19,10 @@ ANITYA_API_BASE = "https://release-monitoring.org/api/v2"
|
|||
GITHUB_API_BASE = "https://api.github.com"
|
||||
GITLAB_HOSTS = [
|
||||
"https://gitlab.com",
|
||||
"https://gitlab.freedesktop.org",
|
||||
"https://gitlab.gnome.org",
|
||||
"https://invent.kde.org",
|
||||
"https://source.puri.sm",
|
||||
"https://gitlab.freedesktop.org",
|
||||
]
|
||||
|
||||
|
||||
|
@ -169,38 +170,52 @@ def upgrade_stable_package(args, pkgname: str, package) -> bool:
|
|||
:param package: a dict containing package information
|
||||
:returns: if something (would have) been changed
|
||||
"""
|
||||
projects = pmb.helpers.http.retrieve_json(
|
||||
f"{ANITYA_API_BASE}/projects/?name={pkgname}", headers=req_headers)
|
||||
if projects["total_items"] < 1:
|
||||
# There is no Anitya project with the package name.
|
||||
# Looking up if there's a custom mapping from postmarketOS package name
|
||||
# to Anitya project name.
|
||||
mappings = pmb.helpers.http.retrieve_json(
|
||||
f"{ANITYA_API_BASE}/packages/?distribution=postmarketOS"
|
||||
f"&name={pkgname}", headers=req_headers)
|
||||
if mappings["total_items"] < 1:
|
||||
logging.warning("{}: failed to get Anitya project".format(pkgname))
|
||||
return False
|
||||
project_name = mappings["items"][0]["project"]
|
||||
|
||||
# Looking up if there's a custom mapping from postmarketOS package name
|
||||
# to Anitya project name.
|
||||
mappings = pmb.helpers.http.retrieve_json(
|
||||
f"{ANITYA_API_BASE}/packages/?distribution=postmarketOS"
|
||||
f"&name={pkgname}", headers=req_headers)
|
||||
if mappings["total_items"] < 1:
|
||||
projects = pmb.helpers.http.retrieve_json(
|
||||
f"{ANITYA_API_BASE}/projects/?name={project_name}",
|
||||
f"{ANITYA_API_BASE}/projects/?name={pkgname}", headers=req_headers)
|
||||
if projects["total_items"] < 1:
|
||||
logging.warning(f"{pkgname}: failed to get Anitya project")
|
||||
return False
|
||||
else:
|
||||
project_name = mappings["items"][0]["project"]
|
||||
ecosystem = mappings["items"][0]["ecosystem"]
|
||||
projects = pmb.helpers.http.retrieve_json(
|
||||
f"{ANITYA_API_BASE}/projects/?name={project_name}&"
|
||||
f"ecosystem={ecosystem}",
|
||||
headers=req_headers)
|
||||
|
||||
if projects["total_items"] < 1:
|
||||
logging.warning(f"{pkgname}: didn't find any projects, can't upgrade!")
|
||||
return False
|
||||
if projects["total_items"] > 1:
|
||||
logging.warning(f"{pkgname}: found more than one project, can't "
|
||||
f"upgrade! Please create an explicit mapping of "
|
||||
f"\"project\" to the package name.")
|
||||
return False
|
||||
|
||||
# Get the first, best-matching item
|
||||
project = projects["items"][0]
|
||||
|
||||
# Check that we got a version number
|
||||
if project["version"] is None:
|
||||
if len(project["stable_versions"]) < 1:
|
||||
logging.warning("{}: got no version number, ignoring".format(pkgname))
|
||||
return False
|
||||
|
||||
version = project["stable_versions"][0]
|
||||
|
||||
# Compare the pmaports version with the project version
|
||||
if package["pkgver"] == project["version"]:
|
||||
if package["pkgver"] == version:
|
||||
logging.info("{}: up-to-date".format(pkgname))
|
||||
return False
|
||||
|
||||
pkgver = package["pkgver"]
|
||||
pkgver_new = project["version"]
|
||||
pkgver_new = version
|
||||
|
||||
pkgrel = package["pkgrel"]
|
||||
pkgrel_new = 0
|
||||
|
|
|
@ -31,15 +31,7 @@ import pmb.helpers.git
|
|||
args.device ("samsung-i9100", "qemu-amd64" etc.)
|
||||
args.work ("/home/user/.local/var/pmbootstrap", override with --work)
|
||||
|
||||
3. Shortcuts
|
||||
Long variables or function calls that always return the same information
|
||||
may have a shortcut defined, to make the code more readable (see
|
||||
add_shortcuts() below).
|
||||
|
||||
Example:
|
||||
args.arch_native ("x86_64" etc.)
|
||||
|
||||
4. Cache
|
||||
3. Cache
|
||||
pmbootstrap uses this dictionary to save the result of expensive
|
||||
results, so they work a lot faster the next time they are needed in the
|
||||
same session. Usually the cache is written to and read from in the same
|
||||
|
@ -54,7 +46,7 @@ import pmb.helpers.git
|
|||
|
||||
See add_cache() below for details.
|
||||
|
||||
5. Parsed configs
|
||||
4. Parsed configs
|
||||
Similar to the cache above, specific config files get parsed and added
|
||||
to args, so they can get accessed quickly (without parsing the configs
|
||||
over and over). These configs are not only used in one specific
|
||||
|
@ -116,11 +108,6 @@ def replace_placeholders(args):
|
|||
setattr(args, key, os.path.expanduser(getattr(args, key)))
|
||||
|
||||
|
||||
def add_shortcuts(args):
|
||||
""" Add convenience shortcuts """
|
||||
setattr(args, "arch_native", pmb.parse.arch.alpine_native())
|
||||
|
||||
|
||||
def add_cache(args):
|
||||
""" Add a caching dict (caches parsing of files etc. for the current
|
||||
session) """
|
||||
|
@ -142,7 +129,7 @@ def add_deviceinfo(args):
|
|||
""" Add and verify the deviceinfo (only after initialization) """
|
||||
setattr(args, "deviceinfo", pmb.parse.deviceinfo(args))
|
||||
arch = args.deviceinfo["arch"]
|
||||
if (arch != args.arch_native and
|
||||
if (arch != pmb.config.arch_native and
|
||||
arch not in pmb.config.build_device_architectures):
|
||||
raise ValueError("Arch '" + arch + "' is not available in"
|
||||
" postmarketOS. If you would like to add it, see:"
|
||||
|
@ -154,7 +141,6 @@ def init(args):
|
|||
fix_mirrors_postmarketos(args)
|
||||
pmb.config.merge_with_args(args)
|
||||
replace_placeholders(args)
|
||||
add_shortcuts(args)
|
||||
add_cache(args)
|
||||
|
||||
# Initialize logs (we could raise errors below)
|
||||
|
|
|
@ -368,7 +368,7 @@ def kconfig(args):
|
|||
if args.action_kconfig == "check":
|
||||
# Handle passing a file directly
|
||||
if args.file:
|
||||
if pmb.parse.kconfig.check_file(args, args.package,
|
||||
if pmb.parse.kconfig.check_file(args.package,
|
||||
anbox=args.anbox,
|
||||
nftables=args.nftables,
|
||||
containers=args.containers,
|
||||
|
@ -403,6 +403,8 @@ def kconfig(args):
|
|||
if not pmb.parse.kconfig.check(
|
||||
args, package,
|
||||
force_anbox_check=args.anbox,
|
||||
force_apparmor_check=args.apparmor,
|
||||
force_iwd_check=args.iwd,
|
||||
force_nftables_check=args.nftables,
|
||||
force_containers_check=args.containers,
|
||||
force_zram_check=args.zram,
|
||||
|
@ -507,7 +509,7 @@ def shutdown(args):
|
|||
def stats(args):
|
||||
# Chroot suffix
|
||||
suffix = "native"
|
||||
if args.arch != args.arch_native:
|
||||
if args.arch != pmb.config.arch_native:
|
||||
suffix = "buildroot_" + args.arch
|
||||
|
||||
# Install ccache and display stats
|
||||
|
|
|
@ -229,7 +229,7 @@ def pull(args, name_repo):
|
|||
return 0
|
||||
|
||||
|
||||
def is_outdated(args, path):
|
||||
def is_outdated(path):
|
||||
# FETCH_HEAD always exists in repositories cloned by pmbootstrap.
|
||||
# Usually it does not (before first git fetch/pull), but there is no good
|
||||
# fallback. For exampe, getting the _creation_ date of .git/HEAD is non-
|
||||
|
|
|
@ -29,7 +29,7 @@ def folder_size(args, path):
|
|||
return ret
|
||||
|
||||
|
||||
def check_grsec(args):
|
||||
def check_grsec():
|
||||
"""
|
||||
Check if the current kernel is based on the grsec patchset, and if
|
||||
the chroot_deny_chmod option is enabled. Raise an exception in that
|
||||
|
|
|
@ -100,6 +100,41 @@ def guess_main(args, subpkgname):
|
|||
return os.path.dirname(path)
|
||||
|
||||
|
||||
def _find_package_in_apkbuild(args, package, path):
|
||||
"""
|
||||
Look through subpackages and all provides to see if the APKBUILD at the
|
||||
specified path contains (or provides) the specified package.
|
||||
|
||||
:param package: The package to search for
|
||||
:param path: The path to the apkbuild
|
||||
:return: True if the APKBUILD contains or provides the package
|
||||
"""
|
||||
apkbuild = pmb.parse.apkbuild(args, path)
|
||||
|
||||
# Subpackages
|
||||
if package in apkbuild["subpackages"]:
|
||||
return True
|
||||
|
||||
# Search for provides in both package and subpackages
|
||||
apkbuild_pkgs = [apkbuild, *apkbuild["subpackages"].values()]
|
||||
for apkbuild_pkg in apkbuild_pkgs:
|
||||
if not apkbuild_pkg:
|
||||
continue
|
||||
|
||||
# Provides (cut off before equals sign for entries like
|
||||
# "mkbootimg=0.0.1")
|
||||
for provides_i in apkbuild_pkg["provides"]:
|
||||
# Ignore provides without version, they shall never be
|
||||
# automatically selected
|
||||
if "=" not in provides_i:
|
||||
continue
|
||||
|
||||
if package == provides_i.split("=", 1)[0]:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def find(args, package, must_exist=True):
|
||||
"""
|
||||
Find the aport path that provides a certain subpackage.
|
||||
|
@ -123,36 +158,23 @@ def find(args, package, must_exist=True):
|
|||
if path:
|
||||
ret = os.path.dirname(path)
|
||||
|
||||
# Try to guess based on the subpackage name
|
||||
guess = guess_main(args, package)
|
||||
if guess:
|
||||
# ... but see if we were right
|
||||
if _find_package_in_apkbuild(args, package, f'{guess}/APKBUILD'):
|
||||
ret = guess
|
||||
|
||||
# Search in subpackages and provides
|
||||
if not ret:
|
||||
for path_current in _find_apkbuilds(args).values():
|
||||
apkbuild = pmb.parse.apkbuild(args, path_current)
|
||||
found = False
|
||||
|
||||
# Subpackages
|
||||
if package in apkbuild["subpackages"]:
|
||||
found = True
|
||||
|
||||
# Provides (cut off before equals sign for entries like
|
||||
# "mkbootimg=0.0.1")
|
||||
if not found:
|
||||
for provides_i in apkbuild["provides"]:
|
||||
# Ignore provides without version, they shall never be
|
||||
# automatically selected
|
||||
if "=" not in provides_i:
|
||||
continue
|
||||
|
||||
if package == provides_i.split("=", 1)[0]:
|
||||
found = True
|
||||
break
|
||||
|
||||
if found:
|
||||
if _find_package_in_apkbuild(args, package, path_current):
|
||||
ret = os.path.dirname(path_current)
|
||||
break
|
||||
|
||||
# Guess a main package
|
||||
# Use the guess otherwise
|
||||
if not ret:
|
||||
ret = guess_main(args, package)
|
||||
ret = guess
|
||||
|
||||
# Crash when necessary
|
||||
if ret is None and must_exist:
|
||||
|
@ -197,6 +219,30 @@ def get(args, pkgname, must_exist=True, subpackages=True):
|
|||
return None
|
||||
|
||||
|
||||
def find_providers(args, provide):
|
||||
"""
|
||||
Search for providers of the specified (virtual) package in pmaports.
|
||||
Note: Currently only providers from a single APKBUILD are returned.
|
||||
|
||||
:param provide: the (virtual) package to search providers for
|
||||
:returns: tuple list (pkgname, apkbuild_pkg) with providers, sorted by
|
||||
provider_priority. The provider with the highest priority
|
||||
(which would be selected by default) comes first.
|
||||
"""
|
||||
|
||||
providers = {}
|
||||
|
||||
apkbuild = get(args, provide)
|
||||
for subpkgname, subpkg in apkbuild["subpackages"].items():
|
||||
for provides in subpkg["provides"]:
|
||||
# Strip provides version (=$pkgver-r$pkgrel)
|
||||
if provides.split("=", 1)[0] == provide:
|
||||
providers[subpkgname] = subpkg
|
||||
|
||||
return sorted(providers.items(), reverse=True,
|
||||
key=lambda p: p[1].get('provider_priority', 0))
|
||||
|
||||
|
||||
def get_repo(args, pkgname, must_exist=True):
|
||||
""" Get the repository folder of an aport.
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ def apkindex_files(args, arch=None, user_repository=True, pmos=True,
|
|||
:returns: list of absolute APKINDEX.tar.gz file paths
|
||||
"""
|
||||
if not arch:
|
||||
arch = args.arch_native
|
||||
arch = pmb.config.arch_native
|
||||
|
||||
ret = []
|
||||
# Local user repository (for packages compiled with pmbootstrap)
|
||||
|
@ -209,7 +209,7 @@ def alpine_apkindex_path(args, repo="main", arch=None):
|
|||
raise RuntimeError("Invalid Alpine repository: " + repo)
|
||||
|
||||
# Download the file
|
||||
arch = arch or args.arch_native
|
||||
arch = arch or pmb.config.arch_native
|
||||
update(args, arch)
|
||||
|
||||
# Find it on disk
|
||||
|
|
|
@ -92,7 +92,7 @@ def print_checks_git_repo(args, repo, details=True):
|
|||
log_ok("up to date with remote branch")
|
||||
|
||||
# Outdated remote information
|
||||
if pmb.helpers.git.is_outdated(args, path):
|
||||
if pmb.helpers.git.is_outdated(path):
|
||||
return log_nok_ret(-5, "outdated remote information",
|
||||
"update with 'pmbootstrap pull'")
|
||||
log_ok("remote information updated recently (via git fetch/pull)")
|
||||
|
|
|
@ -204,6 +204,30 @@ def set_user(args):
|
|||
pmb.chroot.root(args, ["addgroup", args.user, group], suffix)
|
||||
|
||||
|
||||
def setup_login_chpasswd_user_from_arg(args, suffix):
|
||||
"""
|
||||
Set the user's password from what the user passed as --password. Make an
|
||||
effort to not have the password end up in the log file by writing it to
|
||||
a temp file, instead of "echo user:$pass | chpasswd". The user should of
|
||||
course only use this with a test password anyway, but let's be nice and try
|
||||
to have the user protected from accidentally posting their password in
|
||||
any case.
|
||||
|
||||
:param suffix: of the chroot, where passwd will be execute (either the
|
||||
f"rootfs_{args.device}", or f"installer_{args.device}")
|
||||
"""
|
||||
path = "/tmp/pmbootstrap_chpasswd_in"
|
||||
path_outside = f"{args.work}/chroot_{suffix}{path}"
|
||||
|
||||
with open(path_outside, "w", encoding="utf-8") as handle:
|
||||
handle.write(f"{args.user}:{args.password}")
|
||||
|
||||
pmb.chroot.root(args, ["sh", "-c", f"cat {shlex.quote(path)} | chpasswd"],
|
||||
suffix)
|
||||
|
||||
os.unlink(path_outside)
|
||||
|
||||
|
||||
def setup_login(args, suffix):
|
||||
"""
|
||||
Loop until the password for user has been set successfully, and disable
|
||||
|
@ -214,16 +238,19 @@ def setup_login(args, suffix):
|
|||
"""
|
||||
if not args.on_device_installer:
|
||||
# User password
|
||||
logging.info(" *** SET LOGIN PASSWORD FOR: '" + args.user + "' ***")
|
||||
while True:
|
||||
try:
|
||||
pmb.chroot.root(args, ["passwd", args.user], suffix,
|
||||
output="interactive")
|
||||
break
|
||||
except RuntimeError:
|
||||
logging.info("WARNING: Failed to set the password. Try it"
|
||||
" one more time.")
|
||||
pass
|
||||
logging.info(f" *** SET LOGIN PASSWORD FOR: '{args.user}' ***")
|
||||
if args.password:
|
||||
setup_login_chpasswd_user_from_arg(args, suffix)
|
||||
else:
|
||||
while True:
|
||||
try:
|
||||
pmb.chroot.root(args, ["passwd", args.user], suffix,
|
||||
output="interactive")
|
||||
break
|
||||
except RuntimeError:
|
||||
logging.info("WARNING: Failed to set the password. Try it"
|
||||
" one more time.")
|
||||
pass
|
||||
|
||||
# Disable root login
|
||||
pmb.chroot.root(args, ["passwd", "-l", "root"], suffix)
|
||||
|
@ -698,6 +725,14 @@ def print_flash_info(args):
|
|||
" the kernel/initramfs directly without flashing."
|
||||
" Use 'pmbootstrap flasher boot' to do that.)")
|
||||
|
||||
if "flash_lk2nd" in flasher_actions and \
|
||||
os.path.exists(args.work + "/chroot_rootfs_" + args.device +
|
||||
"/boot/lk2nd.img"):
|
||||
logging.info(" * Your device supports and may even require"
|
||||
" flashing lk2nd. You should flash it before"
|
||||
" flashing anything else. Use 'pmbootstrap flasher"
|
||||
" flash_lk2nd' to do that.")
|
||||
|
||||
# Export information
|
||||
logging.info("* If the above steps do not work, you can also create"
|
||||
" symlinks to the generated files with 'pmbootstrap export'"
|
||||
|
@ -789,6 +824,24 @@ def install_on_device_installer(args, step, steps):
|
|||
boot_label, "pmOS_install", args.split, args.sdcard)
|
||||
|
||||
|
||||
def get_selected_providers(args, packages):
|
||||
"""
|
||||
Look through the specified packages and see which providers were selected
|
||||
in "pmbootstrap init". Install those as extra packages to select them
|
||||
instead of the default provider.
|
||||
|
||||
:param packages: the packages that have selectable providers (_pmb_select)
|
||||
:return: additional provider packages to install
|
||||
"""
|
||||
providers = []
|
||||
for p in packages:
|
||||
apkbuild = pmb.helpers.pmaports.get(args, p, subpackages=False)
|
||||
for select in apkbuild['_pmb_select']:
|
||||
if select in args.selected_providers:
|
||||
providers.append(args.selected_providers[select])
|
||||
return providers
|
||||
|
||||
|
||||
def create_device_rootfs(args, step, steps):
|
||||
# List all packages to be installed (including the ones specified by --add)
|
||||
# and upgrade the installed packages/apkindexes
|
||||
|
@ -802,17 +855,23 @@ def create_device_rootfs(args, step, steps):
|
|||
|
||||
# Fill install_packages
|
||||
install_packages = (pmb.config.install_device_packages +
|
||||
["device-" + args.device] +
|
||||
get_kernel_package(args, args.device) +
|
||||
get_nonfree_packages(args, args.device) +
|
||||
pmb.install.ui.get_recommends(args))
|
||||
["device-" + args.device])
|
||||
if not args.install_base:
|
||||
install_packages = [p for p in install_packages
|
||||
if p != "postmarketos-base"]
|
||||
if args.ui.lower() != "none":
|
||||
install_packages += ["postmarketos-ui-" + args.ui]
|
||||
|
||||
# Add additional providers of base/device/UI package
|
||||
install_packages += get_selected_providers(args, install_packages)
|
||||
|
||||
install_packages += get_kernel_package(args, args.device)
|
||||
install_packages += get_nonfree_packages(args, args.device)
|
||||
if args.ui.lower() != "none":
|
||||
if args.ui_extras:
|
||||
install_packages += ["postmarketos-ui-" + args.ui + "-extras"]
|
||||
if args.install_recommends:
|
||||
install_packages += pmb.install.ui.get_recommends(args)
|
||||
if args.extra_packages.lower() != "none":
|
||||
install_packages += args.extra_packages.split(",")
|
||||
if args.add:
|
||||
|
|
|
@ -209,6 +209,11 @@ def _parse_attributes(path, lines, apkbuild_attributes, ret):
|
|||
if options.get("array", False):
|
||||
# Split up arrays, delete empty strings inside the list
|
||||
ret[attribute] = list(filter(None, ret[attribute].split(" ")))
|
||||
if options.get("int", False):
|
||||
if ret[attribute]:
|
||||
ret[attribute] = int(ret[attribute])
|
||||
else:
|
||||
ret[attribute] = 0
|
||||
|
||||
|
||||
def _parse_subpackage(path, lines, apkbuild, subpackages, subpkg):
|
||||
|
|
|
@ -9,7 +9,7 @@ import pmb.helpers.repo
|
|||
import pmb.parse.version
|
||||
|
||||
|
||||
def parse_next_block(args, path, lines, start):
|
||||
def parse_next_block(path, lines, start):
|
||||
"""
|
||||
Parse the next block in an APKINDEX.
|
||||
|
||||
|
@ -200,7 +200,7 @@ def parse(args, path, multiple_providers=True):
|
|||
ret = collections.OrderedDict()
|
||||
start = [0]
|
||||
while True:
|
||||
block = parse_next_block(args, path, lines, start)
|
||||
block = parse_next_block(path, lines, start)
|
||||
if not block:
|
||||
break
|
||||
|
||||
|
@ -223,7 +223,7 @@ def parse(args, path, multiple_providers=True):
|
|||
return ret
|
||||
|
||||
|
||||
def parse_blocks(args, path):
|
||||
def parse_blocks(path):
|
||||
"""
|
||||
Read all blocks from an APKINDEX.tar.gz into a list.
|
||||
|
||||
|
@ -244,7 +244,7 @@ def parse_blocks(args, path):
|
|||
ret = []
|
||||
start = [0]
|
||||
while True:
|
||||
block = pmb.parse.apkindex.parse_next_block(args, path, lines, start)
|
||||
block = pmb.parse.apkindex.parse_next_block(path, lines, start)
|
||||
if not block:
|
||||
return ret
|
||||
ret.append(block)
|
||||
|
@ -282,7 +282,7 @@ def providers(args, package, arch=None, must_exist=True, indexes=None):
|
|||
"""
|
||||
|
||||
if not indexes:
|
||||
arch = arch or args.arch_native
|
||||
arch = arch or pmb.config.arch_native
|
||||
indexes = pmb.helpers.repo.apkindex_files(args, arch)
|
||||
|
||||
for operator in [">", ">=", "=", "<=", "<", "~"]:
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# Copyright 2021 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
import platform
|
||||
import fnmatch
|
||||
import platform
|
||||
import pmb.parse.arch
|
||||
|
||||
|
||||
def alpine_native():
|
||||
machine = platform.machine()
|
||||
ret = ""
|
||||
|
||||
mapping = {
|
||||
"i686": "x86",
|
||||
|
@ -19,12 +19,11 @@ def alpine_native():
|
|||
return mapping[machine]
|
||||
raise ValueError("Can not map platform.machine '" + machine + "'"
|
||||
" to the right Alpine Linux architecture")
|
||||
return ret
|
||||
|
||||
|
||||
def from_chroot_suffix(args, suffix):
|
||||
if suffix == "native":
|
||||
return args.arch_native
|
||||
return pmb.config.arch_native
|
||||
if suffix in [f"rootfs_{args.device}", f"installer_{args.device}"]:
|
||||
return args.deviceinfo["arch"]
|
||||
if suffix.startswith("buildroot_"):
|
||||
|
@ -97,9 +96,9 @@ def alpine_to_hostspec(arch):
|
|||
" to the right hostspec value")
|
||||
|
||||
|
||||
def cpu_emulation_required(args, arch):
|
||||
def cpu_emulation_required(arch):
|
||||
# Obvious case: host arch is target arch
|
||||
if args.arch_native == arch:
|
||||
if pmb.config.arch_native == arch:
|
||||
return False
|
||||
|
||||
# Other cases: host arch on the left, target archs on the right
|
||||
|
@ -108,8 +107,8 @@ def cpu_emulation_required(args, arch):
|
|||
"armv7": ["armel", "armhf"],
|
||||
"aarch64": ["armel", "armhf", "armv7"],
|
||||
}
|
||||
if args.arch_native in not_required:
|
||||
if arch in not_required[args.arch_native]:
|
||||
if pmb.config.arch_native in not_required:
|
||||
if arch in not_required[pmb.config.arch_native]:
|
||||
return False
|
||||
|
||||
# No match: then it's required
|
||||
|
|
|
@ -55,6 +55,10 @@ def arguments_install(subparser):
|
|||
help="do not enable the SSH daemon by default")
|
||||
ret.add_argument("--no-firewall", action="store_true",
|
||||
help="do not enable the firewall by default")
|
||||
ret.add_argument("--password", help="dummy password for automating the"
|
||||
" installation - will be handled in PLAIN TEXT during"
|
||||
" install and may be logged to the logfile, do not use an"
|
||||
" important password!")
|
||||
|
||||
# Image type
|
||||
group_desc = ret.add_argument_group(
|
||||
|
@ -217,6 +221,14 @@ def arguments_flasher(subparser):
|
|||
help="partition to flash the kernel to (defaults"
|
||||
" to deviceinfo_flash_*_partition_kernel)")
|
||||
|
||||
# Flash lk2nd
|
||||
flash_lk2nd = sub.add_parser("flash_lk2nd",
|
||||
help="flash lk2nd, a secondary bootloader"
|
||||
" needed for various Android devices")
|
||||
flash_lk2nd.add_argument("--partition", default=None,
|
||||
help="partition to flash lk2nd to (defaults to"
|
||||
" default boot image partition ")
|
||||
|
||||
# Flash rootfs
|
||||
flash_rootfs = sub.add_parser("flash_rootfs", aliases=["flash_system"],
|
||||
help="flash the rootfs to a partition on the"
|
||||
|
@ -416,7 +428,7 @@ def arguments_newapkbuild(subparser):
|
|||
|
||||
def arguments_kconfig(subparser):
|
||||
# Allowed architectures
|
||||
arch_native = pmb.parse.arch.alpine_native()
|
||||
arch_native = pmb.config.arch_native
|
||||
arch_choices = set(pmb.config.build_device_architectures + [arch_native])
|
||||
|
||||
# Kconfig subparser
|
||||
|
@ -434,15 +446,17 @@ def arguments_kconfig(subparser):
|
|||
" directly instead of a config in a package")
|
||||
check.add_argument("--anbox", action="store_true", help="check"
|
||||
" options needed for anbox too")
|
||||
check.add_argument("--apparmor", action="store_true", help="check"
|
||||
" options needed for apparmor too")
|
||||
check.add_argument("--iwd", action="store_true", help="check"
|
||||
" options needed for iwd too")
|
||||
check.add_argument("--nftables", action="store_true", help="check"
|
||||
" options needed for nftables too")
|
||||
check.add_argument("--containers", action="store_true",
|
||||
help="check options needed for containers too")
|
||||
check.add_argument("--zram", action="store_true", help="check"
|
||||
" options needed for zram support too")
|
||||
check_package = check.add_argument("package", default="", nargs='?')
|
||||
if argcomplete:
|
||||
check_package.completer = kernel_completer
|
||||
add_kernel_arg(check)
|
||||
|
||||
# "pmbootstrap kconfig edit"
|
||||
edit = sub.add_parser("edit", help="edit kernel aport config")
|
||||
|
@ -453,9 +467,7 @@ def arguments_kconfig(subparser):
|
|||
edit.add_argument("-n", dest="nconfig", action="store_true",
|
||||
help="use nconfig rather than menuconfig for kernel"
|
||||
" configuration")
|
||||
edit_package = edit.add_argument("package", nargs='?')
|
||||
if argcomplete:
|
||||
edit_package.completer = kernel_completer
|
||||
add_kernel_arg(edit)
|
||||
|
||||
# "pmbootstrap kconfig migrate"
|
||||
migrate = sub.add_parser("migrate",
|
||||
|
@ -464,9 +476,7 @@ def arguments_kconfig(subparser):
|
|||
"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
|
||||
add_kernel_arg(migrate)
|
||||
|
||||
|
||||
def arguments_repo_missing(subparser):
|
||||
|
@ -476,7 +486,7 @@ def arguments_repo_missing(subparser):
|
|||
if argcomplete:
|
||||
package.completer = package_completer
|
||||
ret.add_argument("--arch", choices=pmb.config.build_device_architectures,
|
||||
default=pmb.parse.arch.alpine_native())
|
||||
default=pmb.config.arch_native)
|
||||
ret.add_argument("--built", action="store_true",
|
||||
help="include packages which exist in the binary repos")
|
||||
ret.add_argument("--overview", action="store_true",
|
||||
|
@ -498,7 +508,7 @@ def arguments_status(subparser):
|
|||
return ret
|
||||
|
||||
|
||||
def package_completer(prefix, action, parser, parsed_args):
|
||||
def package_completer(prefix, action, parser=None, parsed_args=None):
|
||||
args = parsed_args
|
||||
pmb.config.merge_with_args(args)
|
||||
pmb.helpers.args.replace_placeholders(args)
|
||||
|
@ -509,10 +519,21 @@ def package_completer(prefix, action, parser, parsed_args):
|
|||
return packages
|
||||
|
||||
|
||||
def kernel_completer(prefix, action, parser, parsed_args):
|
||||
packages = package_completer("linux-" + prefix, action, parser,
|
||||
def kernel_completer(prefix, action, parser=None, parsed_args=None):
|
||||
""" :returns: matched linux-* packages, with linux-* prefix and without """
|
||||
ret = []
|
||||
|
||||
# Full package name, starting with "linux-"
|
||||
if (len("linux-") < len(prefix) and prefix.startswith("linux-") or
|
||||
"linux-".startswith(prefix)):
|
||||
ret += package_completer(prefix, action, parser, parsed_args)
|
||||
|
||||
# Kernel name without "linux-"
|
||||
packages = package_completer(f"linux-{prefix}", action, parser,
|
||||
parsed_args)
|
||||
return [package.replace("linux-", "", 1) for package in packages]
|
||||
ret += [package.replace("linux-", "", 1) for package in packages]
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def add_packages_arg(subparser, name="packages", *args, **kwargs):
|
||||
|
@ -521,9 +542,16 @@ def add_packages_arg(subparser, name="packages", *args, **kwargs):
|
|||
arg.completer = package_completer
|
||||
|
||||
|
||||
def add_kernel_arg(subparser, name="package", *args, **kwargs):
|
||||
arg = subparser.add_argument("package", nargs='?', help="kernel package"
|
||||
" (e.g. linux-postmarketos-allwinner)")
|
||||
if argcomplete:
|
||||
arg.completer = kernel_completer
|
||||
|
||||
|
||||
def arguments():
|
||||
parser = argparse.ArgumentParser(prog="pmbootstrap")
|
||||
arch_native = pmb.parse.arch.alpine_native()
|
||||
arch_native = pmb.config.arch_native
|
||||
arch_choices = set(pmb.config.build_device_architectures + [arch_native])
|
||||
mirrors_pmos_default = pmb.config.defaults["mirrors_postmarketos"]
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import pmb.config
|
|||
# Return: {magic: ..., mask: ...}
|
||||
|
||||
|
||||
def binfmt_info(args, arch_qemu):
|
||||
def binfmt_info(arch_qemu):
|
||||
# Parse the info file
|
||||
full = {}
|
||||
info = pmb.config.pmb_src + "/pmb/data/qemu-user-binfmt.txt"
|
||||
|
|
|
@ -19,6 +19,17 @@ def is_set(config, option):
|
|||
return re.search("^CONFIG_" + option + "=[ym]$", config, re.M) is not None
|
||||
|
||||
|
||||
def is_set_str(config, option, string):
|
||||
"""
|
||||
Check, whether a config option contains a string as value.
|
||||
"""
|
||||
match = re.search("^CONFIG_" + option + "=\"(.*)\"$", config, re.M)
|
||||
if match:
|
||||
return string == match.group(1)
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def is_in_array(config, option, string):
|
||||
"""
|
||||
Check, whether a config option contains string as an array element
|
||||
|
@ -47,6 +58,15 @@ def check_option(component, details, config, config_path_pretty, option,
|
|||
else:
|
||||
logging.warning(warning_no_details)
|
||||
return False
|
||||
elif isinstance(option_value, str):
|
||||
if not is_set_str(config, option, option_value):
|
||||
if details:
|
||||
logging.info(f"WARNING: {config_path_pretty}: CONFIG_{option}"
|
||||
f' should be set to "{option_value}".'
|
||||
f" See <{link}> for details.")
|
||||
else:
|
||||
logging.warning(warning_no_details)
|
||||
return False
|
||||
elif option_value in [True, False]:
|
||||
if option_value != is_set(config, option):
|
||||
if details:
|
||||
|
@ -57,15 +77,20 @@ def check_option(component, details, config, config_path_pretty, option,
|
|||
logging.warning(warning_no_details)
|
||||
return False
|
||||
else:
|
||||
raise RuntimeError("kconfig check code can only handle True/False and"
|
||||
" arrays now, given value '" + str(option_value) +
|
||||
"' is not supported. If you need this, please open"
|
||||
" an issue.")
|
||||
raise RuntimeError("kconfig check code can only handle booleans,"
|
||||
f" strings and arrays. Given value {option_value}"
|
||||
" is not supported. If you need this, please patch"
|
||||
" pmbootstrap or open an issue.")
|
||||
return True
|
||||
|
||||
|
||||
def check_config(config_path, config_path_pretty, config_arch, pkgver,
|
||||
anbox=False, nftables=False, containers=False, zram=False,
|
||||
anbox=False,
|
||||
apparmor=False,
|
||||
iwd=False,
|
||||
nftables=False,
|
||||
containers=False,
|
||||
zram=False,
|
||||
details=False):
|
||||
logging.debug(f"Check kconfig: {config_path}")
|
||||
with open(config_path) as handle:
|
||||
|
@ -74,6 +99,10 @@ def check_config(config_path, config_path_pretty, config_arch, pkgver,
|
|||
components = {"postmarketOS": pmb.config.necessary_kconfig_options}
|
||||
if anbox:
|
||||
components["anbox"] = pmb.config.necessary_kconfig_options_anbox
|
||||
if apparmor:
|
||||
components["apparmor"] = pmb.config.necessary_kconfig_options_apparmor
|
||||
if iwd:
|
||||
components["iwd"] = pmb.config.necessary_kconfig_options_iwd
|
||||
if nftables:
|
||||
components["nftables"] = pmb.config.necessary_kconfig_options_nftables
|
||||
if containers:
|
||||
|
@ -123,8 +152,14 @@ def check_config_options_set(config, config_path_pretty, config_arch, options,
|
|||
return ret
|
||||
|
||||
|
||||
def check(args, pkgname, force_anbox_check=False, force_nftables_check=False,
|
||||
force_containers_check=False, force_zram_check=False, details=False):
|
||||
def check(args, pkgname,
|
||||
force_anbox_check=False,
|
||||
force_apparmor_check=False,
|
||||
force_iwd_check=False,
|
||||
force_nftables_check=False,
|
||||
force_containers_check=False,
|
||||
force_zram_check=False,
|
||||
details=False):
|
||||
"""
|
||||
Check for necessary kernel config options in a package.
|
||||
|
||||
|
@ -133,8 +168,6 @@ def check(args, pkgname, force_anbox_check=False, force_nftables_check=False,
|
|||
# Pkgname: allow omitting "linux-" prefix
|
||||
if pkgname.startswith("linux-"):
|
||||
flavor = pkgname.split("linux-")[1]
|
||||
logging.info("PROTIP: You can simply do 'pmbootstrap kconfig check " +
|
||||
flavor + "'")
|
||||
else:
|
||||
flavor = pkgname
|
||||
|
||||
|
@ -145,6 +178,10 @@ def check(args, pkgname, force_anbox_check=False, force_nftables_check=False,
|
|||
pkgver = apkbuild["pkgver"]
|
||||
check_anbox = force_anbox_check or (
|
||||
"pmb:kconfigcheck-anbox" in apkbuild["options"])
|
||||
check_apparmor = force_apparmor_check or (
|
||||
"pmb:kconfigcheck-apparmor" in apkbuild["options"])
|
||||
check_iwd = force_iwd_check or (
|
||||
"pmb:kconfigcheck-iwd" in apkbuild["options"])
|
||||
check_nftables = force_nftables_check or (
|
||||
"pmb:kconfigcheck-nftables" in apkbuild["options"])
|
||||
check_containers = force_containers_check or (
|
||||
|
@ -159,6 +196,8 @@ def check(args, pkgname, force_anbox_check=False, force_nftables_check=False,
|
|||
ret &= check_config(config_path, config_path_pretty, config_arch,
|
||||
pkgver,
|
||||
anbox=check_anbox,
|
||||
apparmor=check_apparmor,
|
||||
iwd=check_iwd,
|
||||
nftables=check_nftables,
|
||||
containers=check_containers,
|
||||
zram=check_zram,
|
||||
|
@ -198,7 +237,7 @@ def extract_version(config_file):
|
|||
return "unknown"
|
||||
|
||||
|
||||
def check_file(args, config_file, anbox=False, nftables=False,
|
||||
def check_file(config_file, anbox=False, nftables=False,
|
||||
containers=False, zram=False, details=False):
|
||||
"""
|
||||
Check for necessary kernel config options in a kconfig file.
|
||||
|
|
|
@ -104,11 +104,18 @@ def command_qemu(args, arch, img_path, img_path_2nd=None):
|
|||
if pmaports_cfg.get("supported_mkinitfs_without_flavors", False):
|
||||
flavor_suffix = ""
|
||||
|
||||
# Alpine kernels always have the flavor appended to /boot/vmlinuz
|
||||
kernel = f"{rootfs}/boot/vmlinuz{flavor_suffix}"
|
||||
if not os.path.exists(kernel):
|
||||
kernel = f"{kernel}-{flavor}"
|
||||
if not os.path.exists(kernel):
|
||||
raise RuntimeError("failed to find the proper vmlinuz path")
|
||||
|
||||
ncpus = os.cpu_count()
|
||||
|
||||
# QEMU mach-virt's max CPU count is 8, limit it so it will work correctly
|
||||
# on systems with more than 8 CPUs
|
||||
if arch != args.arch_native and ncpus > 8:
|
||||
if arch != pmb.config.arch_native and ncpus > 8:
|
||||
ncpus = 8
|
||||
|
||||
if args.host_qemu:
|
||||
|
@ -130,7 +137,7 @@ def command_qemu(args, arch, img_path, img_path_2nd=None):
|
|||
rootfs_native + "/usr/share"})
|
||||
|
||||
command = []
|
||||
if args.arch_native in ["aarch64", "armv7"]:
|
||||
if pmb.config.arch_native in ["aarch64", "armv7"]:
|
||||
# Workaround for QEMU failing on aarch64 asymetric multiprocessor
|
||||
# arch (big/little architecture
|
||||
# https://en.wikipedia.org/wiki/ARM_big.LITTLE) see
|
||||
|
@ -141,12 +148,12 @@ def command_qemu(args, arch, img_path, img_path_2nd=None):
|
|||
logging.info("QEMU will run on big/little architecture on the"
|
||||
f" first {ncpus} cores (from /proc/cpuinfo)")
|
||||
command += [rootfs_native + "/lib/ld-musl-" +
|
||||
args.arch_native + ".so.1"]
|
||||
pmb.config.arch_native + ".so.1"]
|
||||
command += [rootfs_native + "/usr/bin/taskset"]
|
||||
command += ["-c", "0-" + str(ncpus - 1)]
|
||||
|
||||
command += [rootfs_native + "/lib/ld-musl-" +
|
||||
args.arch_native + ".so.1"]
|
||||
pmb.config.arch_native + ".so.1"]
|
||||
command += ["--library-path=" + rootfs_native + "/lib:" +
|
||||
rootfs_native + "/usr/lib:" +
|
||||
rootfs_native + "/usr/lib/pulseaudio"]
|
||||
|
@ -154,7 +161,7 @@ def command_qemu(args, arch, img_path, img_path_2nd=None):
|
|||
command += ["-L", rootfs_native + "/usr/share/qemu/"]
|
||||
|
||||
command += ["-nodefaults"]
|
||||
command += ["-kernel", rootfs + "/boot/vmlinuz" + flavor_suffix]
|
||||
command += ["-kernel", kernel]
|
||||
command += ["-initrd", rootfs + "/boot/initramfs" + flavor_suffix]
|
||||
command += ["-append", shlex.quote(cmdline)]
|
||||
|
||||
|
@ -189,7 +196,7 @@ def command_qemu(args, arch, img_path, img_path_2nd=None):
|
|||
" yet.")
|
||||
|
||||
# Kernel Virtual Machine (KVM) support
|
||||
native = args.arch_native == args.deviceinfo["arch"]
|
||||
native = pmb.config.arch_native == args.deviceinfo["arch"]
|
||||
if args.qemu_kvm and native and os.path.exists("/dev/kvm"):
|
||||
command += ["-enable-kvm"]
|
||||
command += ["-cpu", "host"]
|
||||
|
|
|
@ -315,7 +315,7 @@ def test_finish(args, monkeypatch):
|
|||
assert "Package not found" in str(e.value)
|
||||
|
||||
# Existing output path
|
||||
func(args, apkbuild, args.arch_native, output)
|
||||
func(args, apkbuild, pmb.config.arch_native, output)
|
||||
|
||||
|
||||
def test_package(args):
|
||||
|
@ -362,7 +362,7 @@ def test_build_depends_high_level(args, monkeypatch):
|
|||
|
||||
# Remove hello-world
|
||||
pmb.helpers.run.root(args, ["rm", output_hello_outside])
|
||||
pmb.build.index_repo(args, args.arch_native)
|
||||
pmb.build.index_repo(args, pmb.config.arch_native)
|
||||
args.cache["built"] = {}
|
||||
|
||||
# Ask to build the wrapper. It should not build the wrapper (it exists, not
|
||||
|
@ -414,7 +414,7 @@ def test_build_local_source_high_level(args, tmpdir):
|
|||
|
||||
# Test native arch and foreign arch chroot
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
for arch in [args.arch_native, "armhf"]:
|
||||
for arch in [pmb.config.arch_native, "armhf"]:
|
||||
# Delete all hello-world --src packages
|
||||
pattern = f"{args.work}/packages/{channel}/{arch}/hello-world-*_p*.apk"
|
||||
for path in glob.glob(pattern):
|
||||
|
@ -432,5 +432,5 @@ def test_build_local_source_high_level(args, tmpdir):
|
|||
pmb.helpers.run.root(args, ["rm", paths[0]])
|
||||
|
||||
# Clean up: update index, delete temp folder
|
||||
pmb.build.index_repo(args, args.arch_native)
|
||||
pmb.build.index_repo(args, pmb.config.arch_native)
|
||||
pmb.helpers.run.root(args, ["rm", "-r", tmpdir])
|
||||
|
|
|
@ -32,13 +32,12 @@ def test_package_kernel_args(args):
|
|||
str(e.value)
|
||||
|
||||
|
||||
def test_find_kbuild_output_dir(args):
|
||||
def test_find_kbuild_output_dir():
|
||||
# Test parsing an APKBUILD
|
||||
pkgname = "linux-envkernel-test"
|
||||
path = pmb_test.const.testdata + "/apkbuild/APKBUILD." + pkgname
|
||||
function_body = pmb.parse.function_body(path, "package")
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(args,
|
||||
function_body)
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
|
||||
assert kbuild_out == "build"
|
||||
|
||||
# Test full function body
|
||||
|
@ -59,8 +58,7 @@ def test_find_kbuild_output_dir(args):
|
|||
" KBUILD_BUILD_VERSION=\"$((pkgrel + 1))-Alpine\" ",
|
||||
" INSTALL_MOD_PATH=\"$pkgdir\" modules_install",
|
||||
]
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(args,
|
||||
function_body)
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
|
||||
assert kbuild_out == "build"
|
||||
|
||||
# Test no kbuild out dir
|
||||
|
@ -70,8 +68,7 @@ def test_find_kbuild_output_dir(args):
|
|||
" install -D \"$srcdir\"/include/config/kernel.release ",
|
||||
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
|
||||
]
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(args,
|
||||
function_body)
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
|
||||
assert kbuild_out == ""
|
||||
|
||||
# Test curly brackets around srcdir
|
||||
|
@ -81,8 +78,7 @@ def test_find_kbuild_output_dir(args):
|
|||
" install -D \"${srcdir}\"/build/include/config/kernel.release ",
|
||||
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
|
||||
]
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(args,
|
||||
function_body)
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
|
||||
assert kbuild_out == "build"
|
||||
|
||||
# Test multiple sub directories
|
||||
|
@ -92,8 +88,7 @@ def test_find_kbuild_output_dir(args):
|
|||
" install -D \"${srcdir}\"/sub/dir/include/config/kernel.release ",
|
||||
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
|
||||
]
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(args,
|
||||
function_body)
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
|
||||
assert kbuild_out == "sub/dir"
|
||||
|
||||
# Test no kbuild out dir found
|
||||
|
@ -104,8 +99,7 @@ def test_find_kbuild_output_dir(args):
|
|||
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
|
||||
]
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(args,
|
||||
function_body)
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
|
||||
assert ("Couldn't find a kbuild out directory. Is your APKBUILD messed up?"
|
||||
" If not, then consider adjusting the patterns in "
|
||||
"pmb/build/envkernel.py to work with your APKBUILD, or submit an "
|
||||
|
@ -119,8 +113,7 @@ def test_find_kbuild_output_dir(args):
|
|||
" \"$pkgdir\"/usr/share/kernel/$_flavor/kernel.release",
|
||||
]
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(args,
|
||||
function_body)
|
||||
kbuild_out = pmb.build.envkernel.find_kbuild_output_dir(function_body)
|
||||
assert ("Multiple kbuild out directories found. Can you modify your "
|
||||
"APKBUILD so it only has one output path? If you can't resolve it,"
|
||||
" please open an issue.") in str(e.value)
|
||||
|
|
|
@ -168,7 +168,7 @@ def test_pull(args, monkeypatch, tmpdir):
|
|||
assert func(args, name_repo) == 0
|
||||
|
||||
|
||||
def test_is_outdated(args, tmpdir, monkeypatch):
|
||||
def test_is_outdated(tmpdir, monkeypatch):
|
||||
func = pmb.helpers.git.is_outdated
|
||||
|
||||
# Override time.time(): now is "100"
|
||||
|
@ -187,8 +187,8 @@ def test_is_outdated(args, tmpdir, monkeypatch):
|
|||
|
||||
# Outdated (date_outdated: 90)
|
||||
monkeypatch.setattr(pmb.config, "git_repo_outdated", 10)
|
||||
assert func(args, path) is True
|
||||
assert func(path) is True
|
||||
|
||||
# Not outdated (date_outdated: 89)
|
||||
monkeypatch.setattr(pmb.config, "git_repo_outdated", 11)
|
||||
assert func(args, path) is False
|
||||
assert func(path) is False
|
||||
|
|
|
@ -85,7 +85,7 @@ def test_print_checks_git_repo(args, monkeypatch, tmpdir):
|
|||
assert status == 0
|
||||
|
||||
# Outdated remote information
|
||||
def is_outdated(args, path):
|
||||
def is_outdated(path):
|
||||
return True
|
||||
monkeypatch.setattr(pmb.helpers.git, "is_outdated", is_outdated)
|
||||
status, _ = func(args, name_repo)
|
||||
|
|
|
@ -23,20 +23,20 @@ def args(tmpdir, request):
|
|||
def test_kconfig_check(args):
|
||||
# basic checks, from easiers to hard-ish
|
||||
dir = f"{pmb_test.const.testdata}/kconfig_check/"
|
||||
assert not pmb.parse.kconfig.check_file(args, dir +
|
||||
assert not pmb.parse.kconfig.check_file(dir +
|
||||
"bad-missing-required-option")
|
||||
assert pmb.parse.kconfig.check_file(args, dir + "good")
|
||||
assert not pmb.parse.kconfig.check_file(args, dir + "bad-wrong-option-set")
|
||||
assert pmb.parse.kconfig.check_file(args, dir + "good-anbox",
|
||||
assert pmb.parse.kconfig.check_file(dir + "good")
|
||||
assert not pmb.parse.kconfig.check_file(dir + "bad-wrong-option-set")
|
||||
assert pmb.parse.kconfig.check_file(dir + "good-anbox",
|
||||
anbox=True)
|
||||
assert not pmb.parse.kconfig.check_file(args, dir +
|
||||
assert not pmb.parse.kconfig.check_file(dir +
|
||||
"bad-array-missing-some-options",
|
||||
anbox=True)
|
||||
assert pmb.parse.kconfig.check_file(args, dir + "good-nftables",
|
||||
assert pmb.parse.kconfig.check_file(dir + "good-nftables",
|
||||
nftables=True)
|
||||
assert not pmb.parse.kconfig.check_file(args, dir + "bad-nftables",
|
||||
assert not pmb.parse.kconfig.check_file(dir + "bad-nftables",
|
||||
nftables=True)
|
||||
assert pmb.parse.kconfig.check_file(args, dir + "good-zram",
|
||||
assert pmb.parse.kconfig.check_file(dir + "good-zram",
|
||||
zram=True)
|
||||
|
||||
# tests on real devices
|
||||
|
|
|
@ -27,8 +27,8 @@ def test_keys(args):
|
|||
# Get the alpine-keys apk filename
|
||||
pmb.chroot.init(args)
|
||||
version = pmb.parse.apkindex.package(args, "alpine-keys")["version"]
|
||||
pattern = (args.work + "/cache_apk_" + args.arch_native + "/alpine-keys-" +
|
||||
version + ".*.apk")
|
||||
pattern = (args.work + "/cache_apk_" + pmb.config.arch_native +
|
||||
"/alpine-keys-" + version + ".*.apk")
|
||||
filename = os.path.basename(glob.glob(pattern)[0])
|
||||
|
||||
# Extract it to a temporary folder
|
||||
|
|
|
@ -23,7 +23,7 @@ def args(tmpdir, request):
|
|||
return args
|
||||
|
||||
|
||||
def test_parse_next_block_exceptions(args):
|
||||
def test_parse_next_block_exceptions():
|
||||
# Mapping of input files (inside the /test/testdata/apkindex) to
|
||||
# error message substrings
|
||||
mapping = {"key_twice": "specified twice",
|
||||
|
@ -37,11 +37,11 @@ def test_parse_next_block_exceptions(args):
|
|||
lines = handle.readlines()
|
||||
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
pmb.parse.apkindex.parse_next_block(args, path, lines, [0])
|
||||
pmb.parse.apkindex.parse_next_block(path, lines, [0])
|
||||
assert error_substr in str(e.value)
|
||||
|
||||
|
||||
def test_parse_next_block_no_error(args):
|
||||
def test_parse_next_block_no_error():
|
||||
# Read the file
|
||||
func = pmb.parse.apkindex.parse_next_block
|
||||
path = pmb.config.pmb_src + "/test/testdata/apkindex/no_error"
|
||||
|
@ -57,7 +57,7 @@ def test_parse_next_block_no_error(args):
|
|||
'provides': ['so:libc.musl-x86_64.so.1'],
|
||||
'timestamp': '1515217616',
|
||||
'version': '1.1.18-r5'}
|
||||
assert func(args, path, lines, start) == block
|
||||
assert func(path, lines, start) == block
|
||||
assert start == [24]
|
||||
|
||||
# Second block
|
||||
|
@ -71,15 +71,15 @@ def test_parse_next_block_no_error(args):
|
|||
'provides': ['cmd:curl'],
|
||||
'timestamp': '1512030418',
|
||||
'version': '7.57.0-r0'}
|
||||
assert func(args, path, lines, start) == block
|
||||
assert func(path, lines, start) == block
|
||||
assert start == [45]
|
||||
|
||||
# No more blocks
|
||||
assert func(args, path, lines, start) is None
|
||||
assert func(path, lines, start) is None
|
||||
assert start == [45]
|
||||
|
||||
|
||||
def test_parse_next_block_virtual(args):
|
||||
def test_parse_next_block_virtual():
|
||||
"""
|
||||
Test parsing a virtual package from an APKINDEX.
|
||||
"""
|
||||
|
@ -98,7 +98,7 @@ def test_parse_next_block_virtual(args):
|
|||
'provides': ['cmd:hello-world'],
|
||||
'timestamp': '1500000000',
|
||||
'version': '2-r0'}
|
||||
assert func(args, path, lines, start) == block
|
||||
assert func(path, lines, start) == block
|
||||
assert start == [20]
|
||||
|
||||
# Second block: virtual package
|
||||
|
@ -107,11 +107,11 @@ def test_parse_next_block_virtual(args):
|
|||
'pkgname': '.pmbootstrap',
|
||||
'provides': [],
|
||||
'version': '0'}
|
||||
assert func(args, path, lines, start) == block
|
||||
assert func(path, lines, start) == block
|
||||
assert start == [31]
|
||||
|
||||
# No more blocks
|
||||
assert func(args, path, lines, start) is None
|
||||
assert func(path, lines, start) is None
|
||||
assert start == [31]
|
||||
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ def test_pkgrel_bump_high_level(args, tmpdir):
|
|||
|
||||
# Delete package with previous soname (--auto-dry exits with >0 now)
|
||||
channel = pmb.config.pmaports.read_config(args)["channel"]
|
||||
arch = args.arch_native
|
||||
arch = pmb.config.arch_native
|
||||
apk_path = f"{tmpdir}/packages/{channel}/{arch}/testlib-1.0-r0.apk"
|
||||
pmb.helpers.run.root(args, ["rm", apk_path])
|
||||
pmbootstrap(args, tmpdir, ["index"])
|
||||
|
|
|
@ -11,6 +11,7 @@ import pmb.aportgen.device
|
|||
import pmb.config
|
||||
import pmb.config.init
|
||||
import pmb.helpers.logging
|
||||
import pmb.parse.deviceinfo
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -211,19 +212,20 @@ def test_questions_flash_methods(args, monkeypatch):
|
|||
def test_questions_keymaps(args, monkeypatch):
|
||||
func = pmb.config.init.ask_for_keymaps
|
||||
fake_answers(monkeypatch, ["invalid_keymap", "us/rx51_us"])
|
||||
assert func(args, "nokia-n900") == "us/rx51_us"
|
||||
assert func(args, "lg-mako") == ""
|
||||
assert func(args, pmb.parse.deviceinfo(args, "nokia-n900")) == "us/rx51_us"
|
||||
assert func(args, pmb.parse.deviceinfo(args, "lg-mako")) == ""
|
||||
|
||||
|
||||
def test_questions_ui(args, monkeypatch):
|
||||
args.aports = pmb_test.const.testdata + "/init_questions_device/aports"
|
||||
device = "lg-mako"
|
||||
info = pmb.parse.deviceinfo(args, device)
|
||||
|
||||
fake_answers(monkeypatch, ["none"])
|
||||
assert pmb.config.init.ask_for_ui(args, device) == "none"
|
||||
assert pmb.config.init.ask_for_ui(args, info) == "none"
|
||||
|
||||
fake_answers(monkeypatch, ["invalid_UI", "weston"])
|
||||
assert pmb.config.init.ask_for_ui(args, device) == "weston"
|
||||
assert pmb.config.init.ask_for_ui(args, info) == "weston"
|
||||
|
||||
|
||||
def test_questions_ui_extras(args, monkeypatch):
|
||||
|
|
|
@ -25,10 +25,12 @@ CONFIG_BLK_DEV_INITRD=y
|
|||
CONFIG_CGROUPS=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_UEVENT_HELPER=y
|
||||
CONFIG_LBDAF=y
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_XTS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
### here's one explicitely disabled:
|
||||
|
|
|
@ -25,10 +25,12 @@ CONFIG_BLK_DEV_INITRD=y
|
|||
CONFIG_CGROUPS=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_UEVENT_HELPER=y
|
||||
CONFIG_LBDAF=y
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_XTS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS=y
|
||||
|
|
|
@ -8,10 +8,12 @@ CONFIG_BLK_DEV_INITRD=y
|
|||
CONFIG_CGROUPS=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_UEVENT_HELPER=y
|
||||
CONFIG_LBDAF=y
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_XTS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
### here's one explicitely disabled:
|
||||
|
|
|
@ -31,10 +31,12 @@ CONFIG_BLK_DEV_INITRD=y
|
|||
CONFIG_CGROUPS=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_UEVENT_HELPER=y
|
||||
CONFIG_LBDAF=y
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_XTS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
### here's one explicitely disabled:
|
||||
|
|
Loading…
Reference in New Issue