kconfig check: remove redundant component lists

Components are the sets of kernel config options in
pmb/config/__init__.py, such as the ones for waydroid, nftables, etc.

Generate the list of components dynamically and refactor the code, so we
can add/remove components in just one place.

Reviewed-by: Clayton Craft <clayton@craftyguy.net>
Link: https://lists.sr.ht/~postmarketos/pmbootstrap-devel/%3C20230312151325.1968-4-ollieparanoid@postmarketos.org%3E
This commit is contained in:
Oliver Smith 2023-03-12 16:13:10 +01:00
parent d14dbd49de
commit 1a124ec2b6
No known key found for this signature in database
GPG Key ID: 5AE7F5513E0885CB
5 changed files with 96 additions and 150 deletions

View File

@ -153,12 +153,4 @@ def menuconfig(args, pkgname, use_oldconfig):
pmb.build.checksum.update(args, pkgname)
# Check config
pmb.parse.kconfig.check(args, apkbuild["_flavor"],
force_waydroid_check=False,
force_nftables_check=False,
force_containers_check=False,
force_zram_check=False,
force_netboot_check=False,
force_community_check=False,
force_uefi_check=False,
details=True)
pmb.parse.kconfig.check(args, apkbuild["_flavor"], details=True)

View File

@ -377,16 +377,15 @@ def newapkbuild(args):
def kconfig(args):
if args.action_kconfig == "check":
# Build the components list from cli arguments (--waydroid etc.)
components_list = []
for name in pmb.parse.kconfig.get_all_component_names():
if getattr(args, f"kconfig_check_{name}"):
components_list += [name]
# Handle passing a file directly
if args.file:
if pmb.parse.kconfig.check_file(args.package,
waydroid=args.waydroid,
nftables=args.nftables,
containers=args.containers,
zram=args.zram,
netboot=args.netboot,
community=args.community,
uefi=args.uefi,
if pmb.parse.kconfig.check_file(args.package, components_list,
details=True):
logging.info("kconfig check succeeded!")
return
@ -414,17 +413,8 @@ def kconfig(args):
if "!pmb:kconfigcheck" in apkbuild["options"]:
skipped += 1
continue
if not pmb.parse.kconfig.check(
args, package,
force_waydroid_check=args.waydroid,
force_iwd_check=args.iwd,
force_nftables_check=args.nftables,
force_containers_check=args.containers,
force_zram_check=args.zram,
force_netboot_check=args.netboot,
force_community_check=args.community,
force_uefi_check=args.uefi,
details=True):
if not pmb.parse.kconfig.check(args, package, components_list,
details=True):
error = True
# At least one failure

View File

@ -464,23 +464,10 @@ def arguments_kconfig(subparser):
check.add_argument("--arch", choices=arch_choices, dest="arch")
check.add_argument("--file", action="store_true", help="check a file"
" directly instead of a config in a package")
check.add_argument("--waydroid", action="store_true", help="check"
" options needed for waydroid 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.add_argument("--netboot", action="store_true", help="check"
" options needed for netbooting too")
check.add_argument("--community", action="store_true", help="check"
" options needed for various features, required for"
" community/main devices")
check.add_argument("--uefi", action="store_true", help="check"
" options needed for uefi too")
for name in pmb.parse.kconfig.get_all_component_names():
check.add_argument(f"--{name}", action="store_true",
dest=f"kconfig_check_{name}",
help=f"check options needed for {name} too")
add_kernel_arg(check)
# "pmbootstrap kconfig edit"

View File

@ -11,6 +11,23 @@ import pmb.parse
import pmb.helpers.pmaports
def get_all_component_names():
"""
Get the component names from kconfig_options variables in
pmb/config/__init__.py. This does not include the base options.
:returns: a list of component names, e.g. ["waydroid", "iwd", "nftables"]
"""
prefix = "necessary_kconfig_options_"
ret = []
for key in pmb.config.__dict__.keys():
if key.startswith(prefix):
ret += [key.split(prefix, 1)[1]]
return ret
def is_set(config, option):
"""
Check, whether a boolean or tristate option is enabled
@ -74,48 +91,49 @@ def check_option(component, details, config, config_path, option,
return True
def check_config(config_path, config_arch, pkgver,
waydroid=False,
iwd=False,
nftables=False,
containers=False,
zram=False,
netboot=False,
community=False,
uefi=False,
details=False,
enforce_check=True):
def check_config(config_path, config_arch, pkgver, components_list=[],
details=False, enforce_check=True):
"""
:param config_path: full path to kernel config file
:param config_arch: architecture name (alpine format, e.g. aarch64, x86_64)
:param pkgver: kernel version
:param components_list: what to check for, e.g. ["waydroid", "iwd"]
:param details: print all warnings if True, otherwise one generic warning
:param enforce_check: set to False to not fail kconfig check as long as
everything in necessary_kconfig_options is set
correctly, even if additional components are checked
:returns: True if the check passed, False otherwise
"""
logging.debug(f"Check kconfig: {config_path}")
with open(config_path) as handle:
config = handle.read()
components = {"postmarketOS": pmb.config.necessary_kconfig_options}
if waydroid:
components["waydroid"] = pmb.config.necessary_kconfig_options_waydroid
if iwd:
components["iwd"] = pmb.config.necessary_kconfig_options_iwd
if nftables:
components["nftables"] = pmb.config.necessary_kconfig_options_nftables
if containers:
components["containers"] = \
pmb.config.necessary_kconfig_options_containers
if zram:
components["zram"] = pmb.config.necessary_kconfig_options_zram
if netboot:
components["netboot"] = pmb.config.necessary_kconfig_options_netboot
if community:
components["waydroid"] = pmb.config.necessary_kconfig_options_waydroid
components["iwd"] = pmb.config.necessary_kconfig_options_iwd
components["nftables"] = pmb.config.necessary_kconfig_options_nftables
components["containers"] = \
pmb.config.necessary_kconfig_options_containers
components["zram"] = pmb.config.necessary_kconfig_options_zram
components["netboot"] = pmb.config.necessary_kconfig_options_netboot
components["wireguard"] = pmb.config.necessary_kconfig_options_wireguard
components["filesystems"] = pmb.config.necessary_kconfig_options_filesystems
components["community"] = pmb.config.necessary_kconfig_options_community
if uefi:
components["uefi"] = pmb.config.necessary_kconfig_options_uefi
# Devices in all categories need basic options
# https://wiki.postmarketos.org/wiki/Device_categorization
components_list = ["postmarketOS"] + components_list
# Devices in "community" or "main" need additional options
if "community" in components_list:
components_list += [
"containers",
"filesystems",
"iwd",
"netboot",
"nftables",
"waydroid",
"wireguard",
"zram",
]
components = {}
for name in components_list:
if name == "postmarketOS":
pmb_config_var = "necessary_kconfig_options"
else:
pmb_config_var = f"necessary_kconfig_options_{name}"
components[name] = getattr(pmb.config, pmb_config_var, None)
assert components[name], f"invalid kconfig component name: {name}"
results = []
for component, options in components.items():
@ -163,20 +181,14 @@ def check_config_options_set(config, config_path, config_arch, options,
return ret
def check(args, pkgname,
force_waydroid_check=False,
force_iwd_check=False,
force_nftables_check=False,
force_containers_check=False,
force_zram_check=False,
force_netboot_check=False,
force_community_check=False,
force_uefi_check=False,
details=False,
must_exist=True):
def check(args, pkgname, components_list=[], details=False, must_exist=True):
"""
Check for necessary kernel config options in a package.
:param pkgname: the package to check for, optionally without "linux-"
:param components_list: what to check for, e.g. ["waydroid", "iwd"]
:param details: print all warnings if True, otherwise one generic warning
:param must_exist: if False, just return if the package does not exist
:returns: True when the check was successful, False otherwise
None if the aport cannot be found (only if must_exist=False)
"""
@ -197,22 +209,11 @@ def check(args, pkgname,
# We only enforce optional checks for community & main devices
enforce_check = aport.split("/")[-2] in ["community", "main"]
check_waydroid = force_waydroid_check or (
"pmb:kconfigcheck-waydroid" 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 (
"pmb:kconfigcheck-containers" in apkbuild["options"])
check_zram = force_zram_check or (
"pmb:kconfigcheck-zram" in apkbuild["options"])
check_netboot = force_netboot_check or (
"pmb:kconfigcheck-netboot" in apkbuild["options"])
check_community = force_community_check or (
"pmb:kconfigcheck-community" in apkbuild["options"])
check_uefi = force_uefi_check or (
"pmb:kconfigcheck-uefi" in apkbuild["options"])
for name in get_all_component_names():
if f"pmb:kconfigcheck-{name}" in apkbuild["options"] and \
name not in components_list:
components_list += [name]
for config_path in glob.glob(aport + "/config-*"):
# The architecture of the config is in the name, so it just needs to be
# extracted
@ -228,18 +229,8 @@ def check(args, pkgname,
"elsewhere in the name.")
config_arch = config_name_split[1]
ret &= check_config(config_path, config_arch,
pkgver,
waydroid=check_waydroid,
iwd=check_iwd,
nftables=check_nftables,
containers=check_containers,
zram=check_zram,
netboot=check_netboot,
community=check_community,
uefi=check_uefi,
details=details,
enforce_check=enforce_check)
ret &= check_config(config_path, config_arch, pkgver, components_list,
details=details, enforce_check=enforce_check)
return ret
@ -275,24 +266,18 @@ def extract_version(config_file):
return "unknown"
def check_file(config_file, waydroid=False, nftables=False,
containers=False, zram=False, netboot=False,
community=False, uefi=False, details=False):
def check_file(config_file, components_list=[], details=False):
"""
Check for necessary kernel config options in a kconfig file.
:param config_file: full path to kernel config file
:param components_list: what to check for, e.g. ["waydroid", "iwd"]
:param details: print all warnings if True, otherwise one generic warning
:returns: True when the check was successful, False otherwise
"""
arch = extract_arch(config_file)
version = extract_version(config_file)
logging.debug(f"Check kconfig: parsed arch={arch}, version={version} from "
f"file: {config_file}")
return check_config(config_file, arch, version,
waydroid=waydroid,
nftables=nftables,
containers=containers,
zram=zram,
netboot=netboot,
community=community,
uefi=uefi,
return check_config(config_file, arch, version, components_list,
details=details)

View File

@ -31,21 +31,14 @@ def test_kconfig_check(args):
"bad-missing-required-option")
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-waydroid",
waydroid=True)
assert not pmb.parse.kconfig.check_file(dir +
"bad-array-missing-some-options",
waydroid=True)
assert pmb.parse.kconfig.check_file(dir + "good-nftables",
nftables=True)
assert not pmb.parse.kconfig.check_file(dir + "bad-nftables",
nftables=True)
assert pmb.parse.kconfig.check_file(dir + "good-zram",
zram=True)
assert pmb.parse.kconfig.check_file(dir + "good-uefi",
uefi=True)
assert not pmb.parse.kconfig.check_file(dir + "bad-uefi",
uefi=True)
assert pmb.parse.kconfig.check_file(dir + "good-waydroid", ["waydroid"])
assert not pmb.parse.kconfig.check_file(f"{dir}/bad-array-missing-some-options",
["waydroid"])
assert pmb.parse.kconfig.check_file(dir + "good-nftables", ["nftables"])
assert not pmb.parse.kconfig.check_file(dir + "bad-nftables", ["nftables"])
assert pmb.parse.kconfig.check_file(dir + "good-zram", ["zram"])
assert pmb.parse.kconfig.check_file(dir + "good-uefi", ["uefi"])
assert not pmb.parse.kconfig.check_file(dir + "bad-uefi", ["uefi"])
# tests on real devices
# *** do not add more of these! ***
@ -60,8 +53,7 @@ def test_kconfig_check(args):
assert pmb.parse.kconfig.check(args, "postmarketos-allwinner")
# testing the force param: nokia-n900 will never need the uefi options
assert not pmb.parse.kconfig.check(args, "nokia-n900",
force_uefi_check=True)
assert not pmb.parse.kconfig.check(args, "nokia-n900", ["uefi"])
# supports zram (with pmb:kconfigcheck-zram), nftables
assert pmb.parse.kconfig.check(args, "linux-purism-librem5")