forked from Mirror/pmbootstrap
more n more (MR 2252)
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
This commit is contained in:
parent
de4c912692
commit
d9e1da98b2
8 changed files with 52 additions and 203 deletions
|
@ -772,87 +772,6 @@ apkbuild_custom_valid_options = [
|
||||||
"pmb:systemd-never",
|
"pmb:systemd-never",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Variables from deviceinfo. Reference: <https://postmarketos.org/deviceinfo>
|
|
||||||
deviceinfo_attributes = [
|
|
||||||
# general
|
|
||||||
"format_version",
|
|
||||||
"name",
|
|
||||||
"manufacturer",
|
|
||||||
"codename",
|
|
||||||
"year",
|
|
||||||
"dtb",
|
|
||||||
"arch",
|
|
||||||
|
|
||||||
# device
|
|
||||||
"chassis",
|
|
||||||
"keyboard",
|
|
||||||
"external_storage",
|
|
||||||
"dev_touchscreen",
|
|
||||||
"dev_touchscreen_calibration",
|
|
||||||
"append_dtb",
|
|
||||||
|
|
||||||
# bootloader
|
|
||||||
"flash_method",
|
|
||||||
"boot_filesystem",
|
|
||||||
|
|
||||||
# flash
|
|
||||||
"flash_heimdall_partition_kernel",
|
|
||||||
"flash_heimdall_partition_initfs",
|
|
||||||
"flash_heimdall_partition_rootfs",
|
|
||||||
"flash_heimdall_partition_system", # deprecated
|
|
||||||
"flash_heimdall_partition_vbmeta",
|
|
||||||
"flash_heimdall_partition_dtbo",
|
|
||||||
"flash_fastboot_partition_kernel",
|
|
||||||
"flash_fastboot_partition_rootfs",
|
|
||||||
"flash_fastboot_partition_system", # deprecated
|
|
||||||
"flash_fastboot_partition_vbmeta",
|
|
||||||
"flash_fastboot_partition_dtbo",
|
|
||||||
"flash_rk_partition_kernel",
|
|
||||||
"flash_rk_partition_rootfs",
|
|
||||||
"flash_rk_partition_system", # deprecated
|
|
||||||
"flash_mtkclient_partition_kernel",
|
|
||||||
"flash_mtkclient_partition_rootfs",
|
|
||||||
"flash_mtkclient_partition_vbmeta",
|
|
||||||
"flash_mtkclient_partition_dtbo",
|
|
||||||
"generate_legacy_uboot_initfs",
|
|
||||||
"kernel_cmdline",
|
|
||||||
"generate_bootimg",
|
|
||||||
"header_version",
|
|
||||||
"bootimg_qcdt",
|
|
||||||
"bootimg_mtk_mkimage", # deprecated
|
|
||||||
"bootimg_mtk_label_kernel",
|
|
||||||
"bootimg_mtk_label_ramdisk",
|
|
||||||
"bootimg_dtb_second",
|
|
||||||
"bootimg_custom_args",
|
|
||||||
"flash_offset_base",
|
|
||||||
"flash_offset_dtb",
|
|
||||||
"flash_offset_kernel",
|
|
||||||
"flash_offset_ramdisk",
|
|
||||||
"flash_offset_second",
|
|
||||||
"flash_offset_tags",
|
|
||||||
"flash_pagesize",
|
|
||||||
"flash_fastboot_max_size",
|
|
||||||
"flash_sparse",
|
|
||||||
"flash_sparse_samsung_format",
|
|
||||||
"rootfs_image_sector_size",
|
|
||||||
"sd_embed_firmware",
|
|
||||||
"sd_embed_firmware_step_size",
|
|
||||||
"partition_blacklist",
|
|
||||||
"boot_part_start",
|
|
||||||
"partition_type",
|
|
||||||
"root_filesystem",
|
|
||||||
"flash_kernel_on_update",
|
|
||||||
"cgpt_kpart",
|
|
||||||
"cgpt_kpart_start",
|
|
||||||
"cgpt_kpart_size",
|
|
||||||
|
|
||||||
# weston
|
|
||||||
"weston_pixman_type",
|
|
||||||
|
|
||||||
# keymaps
|
|
||||||
"keymaps",
|
|
||||||
]
|
|
||||||
|
|
||||||
# Valid types for the 'chassis' attribute in deviceinfo
|
# Valid types for the 'chassis' attribute in deviceinfo
|
||||||
# See https://www.freedesktop.org/software/systemd/man/machine-info.html
|
# See https://www.freedesktop.org/software/systemd/man/machine-info.html
|
||||||
deviceinfo_chassis_types = [
|
deviceinfo_chassis_types = [
|
||||||
|
|
|
@ -647,11 +647,11 @@ def frontend(args: PmbArgs):
|
||||||
require_programs()
|
require_programs()
|
||||||
|
|
||||||
# Work folder (needs to be first, so we can create chroots early)
|
# Work folder (needs to be first, so we can create chroots early)
|
||||||
config = pmb.config.load(args)
|
config = pmb.config.load(args.config)
|
||||||
config.work, work_exists = ask_for_work_path(args)
|
config.work, work_exists = ask_for_work_path(args)
|
||||||
|
|
||||||
# Update args and save config (so chroots and 'pmbootstrap log' work)
|
# Update args and save config (so chroots and 'pmbootstrap log' work)
|
||||||
pmb.helpers.args.update_work(args, config.work)
|
#pmb.helpers.args.update_work(args, config.work)
|
||||||
pmb.config.save(args.config, config)
|
pmb.config.save(args.config, config)
|
||||||
|
|
||||||
# Migrate work dir if necessary
|
# Migrate work dir if necessary
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright 2023 Oliver Smith
|
# Copyright 2023 Oliver Smith
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
from pathlib import Path, PosixPath
|
from pathlib import Path, PosixPath
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
from pmb.helpers import logging
|
from pmb.helpers import logging
|
||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
|
@ -11,7 +11,7 @@ from pmb.types import Config
|
||||||
from pmb.types import PmbArgs
|
from pmb.types import PmbArgs
|
||||||
|
|
||||||
|
|
||||||
def sanity_check(args: PmbArgs, cfg: Config, key, allowed, print_path):
|
def sanity_check(cfg: Config, key, allowed, path: Optional[Path] = None):
|
||||||
value = getattr(cfg, key)
|
value = getattr(cfg, key)
|
||||||
|
|
||||||
if value in allowed:
|
if value in allowed:
|
||||||
|
@ -20,23 +20,23 @@ def sanity_check(args: PmbArgs, cfg: Config, key, allowed, print_path):
|
||||||
logging.error(f"pmbootstrap.cfg: invalid value for {key}: '{value}'")
|
logging.error(f"pmbootstrap.cfg: invalid value for {key}: '{value}'")
|
||||||
logging.error(f"Allowed: {', '.join(allowed)}")
|
logging.error(f"Allowed: {', '.join(allowed)}")
|
||||||
|
|
||||||
if print_path:
|
if path:
|
||||||
logging.error(f"Fix it here and try again: {args.config}")
|
logging.error(f"Fix it here and try again: {path}")
|
||||||
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def sanity_checks(args: PmbArgs, cfg: Config, print_path=True):
|
def sanity_checks(cfg: Config, path: Optional[Path] = None):
|
||||||
for key, allowed in pmb.config.allowed_values.items():
|
for key, allowed in pmb.config.allowed_values.items():
|
||||||
sanity_check(args, cfg, key, allowed, print_path)
|
sanity_check(cfg, key, allowed, path)
|
||||||
|
|
||||||
|
|
||||||
def load(args: PmbArgs) -> Config:
|
def load(path: Path) -> Config:
|
||||||
config = Config()
|
config = Config()
|
||||||
|
|
||||||
cfg = configparser.ConfigParser()
|
cfg = configparser.ConfigParser()
|
||||||
if os.path.isfile(args.config):
|
if os.path.isfile(path):
|
||||||
cfg.read(args.config)
|
cfg.read(path)
|
||||||
|
|
||||||
if "pmbootstrap" not in cfg:
|
if "pmbootstrap" not in cfg:
|
||||||
cfg["pmbootstrap"] = {}
|
cfg["pmbootstrap"] = {}
|
||||||
|
@ -57,7 +57,7 @@ def load(args: PmbArgs) -> Config:
|
||||||
elif key in cfg["pmbootstrap"]:
|
elif key in cfg["pmbootstrap"]:
|
||||||
setattr(config, key, cfg["pmbootstrap"][key])
|
setattr(config, key, cfg["pmbootstrap"][key])
|
||||||
|
|
||||||
sanity_checks(args, config)
|
sanity_checks(config, path)
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
# Copyright 2023 Oliver Smith
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
from pathlib import Path
|
|
||||||
import pmb.config
|
|
||||||
from pmb.types import PmbArgs
|
|
||||||
|
|
||||||
|
|
||||||
# def merge_with_args(args: PmbArgs):
|
|
||||||
# """We have the internal config (pmb/config/__init__.py) and the user config
|
|
||||||
# (usually ~/.config/pmbootstrap.cfg, can be changed with the '-c'
|
|
||||||
# parameter).
|
|
||||||
|
|
||||||
# Args holds the variables parsed from the commandline (e.g. -j fills out
|
|
||||||
# args.jobs), and values specified on the commandline count the most.
|
|
||||||
|
|
||||||
# In case it is not specified on the commandline, for the keys in
|
|
||||||
# pmb.config.config_keys, we look into the value set in the the user config.
|
|
||||||
|
|
||||||
# When that is empty as well (e.g. just before pmbootstrap init), or the key
|
|
||||||
# is not in pmb.config_keys, we use the default value from the internal
|
|
||||||
# config.
|
|
||||||
# """
|
|
||||||
# # Use defaults from the user's config file
|
|
||||||
# cfg = pmb.config.load(args)
|
|
||||||
# for key in cfg["pmbootstrap"]:
|
|
||||||
# if key not in args or getattr(args, key) is None:
|
|
||||||
# value = cfg["pmbootstrap"][key]
|
|
||||||
# if key in pmb.config.defaults:
|
|
||||||
# default = pmb.config.defaults[key]
|
|
||||||
# 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():
|
|
||||||
# if key not in args or getattr(args, key) is None:
|
|
||||||
# setattr(args, key, value)
|
|
||||||
|
|
||||||
# pmb.config.work_dir(Path(cfg["pmbootstrap"]["work"]))
|
|
||||||
|
|
||||||
# # Make sure args.aports is a Path object
|
|
||||||
# setattr(args, "aports", Path(args.aports))
|
|
|
@ -52,48 +52,30 @@ __args: PmbArgs = PmbArgs()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def check_pmaports_path(args: PmbArgs):
|
|
||||||
"""Make sure that args.aports exists when it was overridden by --aports.
|
|
||||||
|
|
||||||
Without this check, 'pmbootstrap init' would start cloning the
|
|
||||||
pmaports into the default folder when args.aports does not exist.
|
|
||||||
"""
|
|
||||||
if args.from_argparse.aports and not os.path.exists(args.aports):
|
|
||||||
raise ValueError("pmaports path (specified with --aports) does"
|
|
||||||
f" not exist: {args.aports}")
|
|
||||||
|
|
||||||
|
|
||||||
# def replace_placeholders(args: PmbArgs):
|
|
||||||
# """Replace $WORK and ~ (for path variables) in variables from any config.
|
|
||||||
|
|
||||||
# (user's config file, default config settings or config parameters specified on commandline)
|
|
||||||
# """
|
|
||||||
# # Replace $WORK
|
|
||||||
# for key, value in pmb.config.defaults.items():
|
|
||||||
# if key not in args:
|
|
||||||
# continue
|
|
||||||
# old = getattr(args, key)
|
|
||||||
# if isinstance(old, str):
|
|
||||||
# setattr(args, key, old.replace("$WORK", str(get_context().config.work)))
|
|
||||||
|
|
||||||
# # Replace ~ (path variables only)
|
|
||||||
# for key in ["aports", "config", "work"]:
|
|
||||||
# if key in args:
|
|
||||||
# setattr(args, key, Path(getattr(args, key)).expanduser())
|
|
||||||
|
|
||||||
|
|
||||||
def init(args: PmbArgs) -> PmbArgs:
|
def init(args: PmbArgs) -> PmbArgs:
|
||||||
global __args
|
global __args
|
||||||
# Basic initialization
|
# Basic initialization
|
||||||
config = pmb.config.load(args)
|
# print(json.dumps(args.__dict__))
|
||||||
|
# sys.exit(0)
|
||||||
|
config = pmb.config.load(args.config)
|
||||||
|
|
||||||
for key, value in vars(args).items():
|
if args.aports and not args.aports.exists():
|
||||||
|
raise ValueError("pmaports path (specified with --aports) does"
|
||||||
|
f" not exist: {args.aports}")
|
||||||
|
|
||||||
|
# Override config at runtime with command line arguments
|
||||||
|
for key, _ in vars(config).items():
|
||||||
if key.startswith("_"):
|
if key.startswith("_"):
|
||||||
continue
|
continue
|
||||||
if getattr(args, key, None) and hasattr(config, key):
|
value = getattr(args, key, None)
|
||||||
|
if value:
|
||||||
print(f"Overriding config.{key} with {value}")
|
print(f"Overriding config.{key} with {value}")
|
||||||
setattr(config, key, value)
|
setattr(config, key, value)
|
||||||
|
|
||||||
|
# Deny accessing the attribute via args
|
||||||
|
if hasattr(args, key):
|
||||||
|
delattr(args, key)
|
||||||
|
|
||||||
# Configure runtime context
|
# Configure runtime context
|
||||||
context = Context(config)
|
context = Context(config)
|
||||||
context.command_timeout = args.timeout
|
context.command_timeout = args.timeout
|
||||||
|
@ -104,13 +86,6 @@ def init(args: PmbArgs) -> PmbArgs:
|
||||||
context.cross = args.cross
|
context.cross = args.cross
|
||||||
context.assume_yes = getattr(args, "assume_yes", False)
|
context.assume_yes = getattr(args, "assume_yes", False)
|
||||||
context.force = getattr(args, "force", False)
|
context.force = getattr(args, "force", False)
|
||||||
if args.mirrors_postmarketos:
|
|
||||||
context.config.mirrors_postmarketos = args.mirrors_postmarketos
|
|
||||||
if args.mirror_alpine:
|
|
||||||
context.config.mirror_alpine = args.mirror_alpine
|
|
||||||
if args.aports:
|
|
||||||
print(f"Using pmaports from: {args.aports}")
|
|
||||||
context.config.aports = args.aports
|
|
||||||
|
|
||||||
# Initialize context
|
# Initialize context
|
||||||
pmb.core.set_context(context)
|
pmb.core.set_context(context)
|
||||||
|
@ -119,7 +94,6 @@ def init(args: PmbArgs) -> PmbArgs:
|
||||||
pmb.helpers.logging.init(args)
|
pmb.helpers.logging.init(args)
|
||||||
|
|
||||||
# Initialization code which may raise errors
|
# Initialization code which may raise errors
|
||||||
check_pmaports_path(args)
|
|
||||||
if args.action not in ["init", "checksum", "config", "bootimg_analyze", "log",
|
if args.action not in ["init", "checksum", "config", "bootimg_analyze", "log",
|
||||||
"pull", "shutdown", "zap"]:
|
"pull", "shutdown", "zap"]:
|
||||||
pmb.config.pmaports.read_config()
|
pmb.config.pmaports.read_config()
|
||||||
|
@ -133,15 +107,10 @@ def init(args: PmbArgs) -> PmbArgs:
|
||||||
delattr(args, "log")
|
delattr(args, "log")
|
||||||
delattr(args, "quiet")
|
delattr(args, "quiet")
|
||||||
delattr(args, "offline")
|
delattr(args, "offline")
|
||||||
delattr(args, "aports")
|
|
||||||
delattr(args, "mirrors_postmarketos")
|
|
||||||
delattr(args, "mirror_alpine")
|
|
||||||
if hasattr(args, "force"):
|
if hasattr(args, "force"):
|
||||||
delattr(args, "force")
|
delattr(args, "force")
|
||||||
if hasattr(args, "device"):
|
if hasattr(args, "device"):
|
||||||
delattr(args, "device")
|
delattr(args, "device")
|
||||||
# args.work is deprecated!
|
|
||||||
delattr(args, "work")
|
|
||||||
|
|
||||||
# Copy all properties from args to out that don't start with underscores
|
# Copy all properties from args to out that don't start with underscores
|
||||||
for key, value in vars(args).items():
|
for key, value in vars(args).items():
|
||||||
|
@ -155,24 +124,26 @@ def init(args: PmbArgs) -> PmbArgs:
|
||||||
return __args
|
return __args
|
||||||
|
|
||||||
|
|
||||||
def update_work(args: PmbArgs, work):
|
# def update_work(args: PmbArgs, work):
|
||||||
"""Update the work path in args.work and wherever $WORK was used."""
|
# """Update the work path in args.work and wherever $WORK was used."""
|
||||||
# Start with the unmodified args from argparse
|
# # Start with the unmodified args from argparse
|
||||||
args_new = copy.deepcopy(args.from_argparse)
|
# args_new = copy.deepcopy(args.from_argparse)
|
||||||
|
|
||||||
# Keep from the modified args:
|
# # Keep from the modified args:
|
||||||
# * the unmodified args from argparse (to check if --aports was specified)
|
# # * the unmodified args from argparse (to check if --aports was specified)
|
||||||
args_new.from_argparse = args.from_argparse
|
# args_new.from_argparse = args.from_argparse
|
||||||
|
|
||||||
# Generate modified args again, replacing $WORK with the new work folder
|
# # Generate modified args again, replacing $WORK with the new work folder
|
||||||
# When args.log is different, this also opens the log in the new location
|
# # When args.log is different, this also opens the log in the new location
|
||||||
args_new.work = work
|
# args_new.work = work
|
||||||
args_new = pmb.helpers.args.init(args_new)
|
# args_new = pmb.helpers.args.init(args_new)
|
||||||
|
|
||||||
# Overwrite old attributes of args with the new attributes
|
# # Overwrite old attributes of args with the new attributes
|
||||||
for key in vars(args_new):
|
# for key in vars(args_new):
|
||||||
setattr(args, key, getattr(args_new, key))
|
# setattr(args, key, getattr(args_new, key))
|
||||||
|
|
||||||
def please_i_really_need_args() -> PmbArgs:
|
def please_i_really_need_args() -> PmbArgs:
|
||||||
|
import traceback
|
||||||
|
traceback.print_stack()
|
||||||
print("FIXME: retrieved args where it shouldn't be needed!")
|
print("FIXME: retrieved args where it shouldn't be needed!")
|
||||||
return __args
|
return __args
|
||||||
|
|
|
@ -225,7 +225,7 @@ def config(args: PmbArgs):
|
||||||
pmb.config.save(args.config, config)
|
pmb.config.save(args.config, config)
|
||||||
elif args.value is not None:
|
elif args.value is not None:
|
||||||
setattr(config, args.name, args.value)
|
setattr(config, args.name, args.value)
|
||||||
pmb.config.sanity_checks(args, config, False)
|
pmb.config.sanity_checks(config)
|
||||||
logging.info("Config changed: " + args.name + "='" + args.value + "'")
|
logging.info("Config changed: " + args.name + "='" + args.value + "'")
|
||||||
pmb.config.save(args.config, config)
|
pmb.config.save(args.config, config)
|
||||||
elif args.name:
|
elif args.name:
|
||||||
|
|
|
@ -143,10 +143,11 @@ def arguments_install(subparser):
|
||||||
group.add_argument("--no-fde", help=argparse.SUPPRESS,
|
group.add_argument("--no-fde", help=argparse.SUPPRESS,
|
||||||
action="store_true", dest="no_fde")
|
action="store_true", dest="no_fde")
|
||||||
group.add_argument("--cipher", help="cryptsetup cipher used to encrypt the"
|
group.add_argument("--cipher", help="cryptsetup cipher used to encrypt the"
|
||||||
" the rootfs (e.g. 'aes-xts-plain64')")
|
" the rootfs (e.g. 'aes-xts-plain64')",
|
||||||
|
default=pmb.config.defaults["cipher"])
|
||||||
group.add_argument("--iter-time", help="cryptsetup iteration time (in"
|
group.add_argument("--iter-time", help="cryptsetup iteration time (in"
|
||||||
" milliseconds) to use when encrypting the system"
|
" milliseconds) to use when encrypting the system"
|
||||||
" partition")
|
" partition", default=pmb.config.defaults["iter_time"])
|
||||||
|
|
||||||
# Packages
|
# Packages
|
||||||
group = ret.add_argument_group(
|
group = ret.add_argument_group(
|
||||||
|
@ -663,7 +664,8 @@ def get_parser():
|
||||||
"partition size on target machine in MB (default"
|
"partition size on target machine in MB (default"
|
||||||
" 128)")
|
" 128)")
|
||||||
parser.add_argument("-p", "--aports",
|
parser.add_argument("-p", "--aports",
|
||||||
help="postmarketos aports (pmaports) path")
|
help="postmarketos aports (pmaports) path",
|
||||||
|
type=lambda x: Path(x))
|
||||||
parser.add_argument("-t", "--timeout", help="seconds after which processes"
|
parser.add_argument("-t", "--timeout", help="seconds after which processes"
|
||||||
" get killed that stopped writing any output (default:"
|
" get killed that stopped writing any output (default:"
|
||||||
" 900)", default=900, type=float)
|
" 900)", default=900, type=float)
|
||||||
|
@ -942,8 +944,8 @@ def arguments():
|
||||||
# Parse and extend arguments (also backup unmodified result from argparse)
|
# Parse and extend arguments (also backup unmodified result from argparse)
|
||||||
args: PmbArgs = get_parser().parse_args() # type: ignore
|
args: PmbArgs = get_parser().parse_args() # type: ignore
|
||||||
|
|
||||||
setattr(args, "from_argparse", copy.deepcopy(args))
|
# setattr(args, "from_argparse", copy.deepcopy(args))
|
||||||
setattr(args.from_argparse, "from_argparse", args.from_argparse)
|
# setattr(args.from_argparse, "from_argparse", args.from_argparse)
|
||||||
|
|
||||||
if getattr(args, "fork_alpine_retain_branch", False):
|
if getattr(args, "fork_alpine_retain_branch", False):
|
||||||
# fork_alpine_retain_branch largely matches the behaviour of fork_alpine, so
|
# fork_alpine_retain_branch largely matches the behaviour of fork_alpine, so
|
||||||
|
|
|
@ -37,7 +37,7 @@ class PmbArgs(Namespace):
|
||||||
all_git: str
|
all_git: str
|
||||||
all_stable: str
|
all_stable: str
|
||||||
android_recovery_zip: str
|
android_recovery_zip: str
|
||||||
aports: Path
|
aports: Optional[Path]
|
||||||
_aports_real: str
|
_aports_real: str
|
||||||
arch: str
|
arch: str
|
||||||
as_root: str
|
as_root: str
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue