config: fixes + handle mirrors migration (MR 2252)

Get rid of config.mirror_alpine and mirrors_postmarketos and make sure
they get migrated over for existing users.

mirrors_postmarketos being a list was always a bit off, but now we have
per-aports mirrors which make a lot more sense for what we're trying to
do with systemd.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
This commit is contained in:
Caleb Connolly 2024-06-10 05:46:26 +02:00 committed by Oliver Smith
parent aedab4df73
commit fc010bc7c8
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
7 changed files with 44 additions and 72 deletions

View file

@ -143,7 +143,7 @@ def download(file):
"""
channel_cfg = pmb.config.pmaports.read_config_channel()
mirrordir = channel_cfg["mirrordir_alpine"]
base_url = f"{get_context().config.mirror_alpine}{mirrordir}/main/{Arch.native()}"
base_url = f"{get_context().config.mirrors["alpine"]}{mirrordir}/main/{Arch.native()}"
return pmb.helpers.http.download(f"{base_url}/{file}", file)

View file

@ -72,36 +72,6 @@ def sudo(cmd: Sequence[PathString]) -> Sequence[PathString]:
return cmd
# Keys saved in the config file (mostly what we ask in 'pmbootstrap init')
config_keys = [
"aports",
"boot_size",
"build_default_device_arch",
"build_pkgs_on_install",
"ccache_size",
"device",
"extra_packages",
"extra_space",
"hostname",
"is_default_channel",
"jobs",
"kernel",
"keymap",
"locale",
"mirror_alpine",
"mirrors_postmarketos",
"qemu_redir_stdio",
"ssh_key_glob",
"ssh_keys",
"sudo_timer",
"systemd",
"timezone",
"ui",
"ui_extras",
"user",
"work",
]
defaults = {
"cipher": "aes-xts-plain64",
"config": Path((os.environ.get('XDG_CONFIG_HOME') or

View file

@ -456,9 +456,8 @@ def ask_for_device(context: Context):
return (device, device_path is not None, kernel)
def ask_for_additional_options(args: PmbArgs, cfg):
def ask_for_additional_options(config):
context = pmb.core.get_context()
config = context.config
# Allow to skip additional options
logging.info("Additional options:"
f" extra free space: {config.extra_space} MB,"
@ -466,7 +465,7 @@ def ask_for_additional_options(args: PmbArgs, cfg):
f" parallel jobs: {config.jobs},"
f" ccache per arch: {config.ccache_size},"
f" sudo timer: {context.sudo_timer},"
f" mirror: {','.join(config.mirrors_postmarketos)}")
f" mirror: {config.mirrors["pmaports"]}")
if not pmb.helpers.cli.confirm("Change them?",
default=False):
@ -481,21 +480,21 @@ def ask_for_additional_options(args: PmbArgs, cfg):
" How much extra free space do you want to add to the image"
" (in MB)?")
answer = pmb.helpers.cli.ask("Extra space size", None,
args.extra_space, validation_regex="^[0-9]+$")
cfg["pmbootstrap"]["extra_space"] = answer
config.extra_space, validation_regex="^[0-9]+$")
config.extra_space = answer
# Boot size
logging.info("What should be the boot partition size (in MB)?")
answer = pmb.helpers.cli.ask("Boot size", None, args.boot_size,
answer = pmb.helpers.cli.ask("Boot size", None, config.boot_size,
validation_regex="^[1-9][0-9]*$")
cfg["pmbootstrap"]["boot_size"] = answer
config.boot_size = int(answer)
# Parallel job count
logging.info("How many jobs should run parallel on this machine, when"
" compiling?")
answer = pmb.helpers.cli.ask("Jobs", None, args.jobs,
answer = pmb.helpers.cli.ask("Jobs", None, config.jobs,
validation_regex="^[1-9][0-9]*$")
cfg["pmbootstrap"]["jobs"] = answer
config.jobs = int(answer)
# Ccache size
logging.info("We use ccache to speed up building the same code multiple"
@ -504,10 +503,10 @@ def ask_for_additional_options(args: PmbArgs, cfg):
" current usage with 'pmbootstrap stats'. Answer with 0 for"
" infinite.")
regex = "0|[0-9]+(k|M|G|T|Ki|Mi|Gi|Ti)"
answer = pmb.helpers.cli.ask("Ccache size", None, args.ccache_size,
answer = pmb.helpers.cli.ask("Ccache size", None, config.ccache_size,
lowercase_answer=False,
validation_regex=regex)
cfg["pmbootstrap"]["ccache_size"] = answer
config.ccache_size = answer
# Sudo timer
logging.info("pmbootstrap does everything in Alpine Linux chroots, so"
@ -518,18 +517,18 @@ def ask_for_additional_options(args: PmbArgs, cfg):
answer = pmb.helpers.cli.confirm("Enable background timer to prevent"
" repeated sudo authorization?",
default=context.sudo_timer)
cfg["pmbootstrap"]["sudo_timer"] = str(answer)
config.sudo_timer = str(answer)
# Mirrors
# prompt for mirror change
logging.info("Selected mirror:"
f" {','.join(context.config.mirrors_postmarketos)}")
if pmb.helpers.cli.confirm("Change mirror?", default=False):
mirrors = ask_for_mirror(args)
cfg["pmbootstrap"]["mirrors_postmarketos"] = ",".join(mirrors)
mirror = ask_for_mirror()
config.mirrors["pmaports"] = mirror
def ask_for_mirror(args: PmbArgs):
def ask_for_mirror():
regex = "^[1-9][0-9]*$" # single non-zero number only
json_path = pmb.helpers.http.download(
@ -564,27 +563,24 @@ def ask_for_mirror(args: PmbArgs):
urls.append(link_list[0])
mirror_indexes = []
for mirror in get_context().config.mirrors_postmarketos:
mirror = get_context().config.mirrors["pmaports"]
for i in range(len(urls)):
if urls[i] == mirror:
mirror_indexes.append(str(i + 1))
break
mirrors_list: List[str] = []
mirror = ""
# require one valid mirror index selected by user
while len(mirrors_list) != 1:
while len(mirror) == 0:
answer = pmb.helpers.cli.ask("Select a mirror", None,
",".join(mirror_indexes),
validation_regex=regex)
mirrors_list = []
for i in answer.split(","):
idx = int(i) - 1
if 0 <= idx < len(urls):
mirrors_list.append(urls[idx])
if len(mirrors_list) != 1:
i = int(answer)
if i < 1 or i > len(urls):
logging.info("You must select one valid mirror!")
mirror = urls[i - 1]
return mirrors_list
return mirror
def ask_for_hostname(default: Optional[str], device):
@ -709,7 +705,7 @@ def frontend(args: PmbArgs):
ask_for_provider_select_pkg(f"postmarketos-ui-{ui}",
config.providers)
ask_for_additional_options(args, config)
ask_for_additional_options(config)
# Extra packages to be installed to rootfs
logging.info("Additional packages that will be installed to rootfs."

View file

@ -31,14 +31,15 @@ def load(path: Path) -> Config:
if key not in cfg["pmbootstrap"]:
continue
elif key == "mirror_alpine":
# DEPRCATED: We have special handling for this below.
# DEPRCATED
config.mirrors["alpine"] = cfg["pmbootstrap"]["mirror_alpine"]
continue
# Handle whacky type conversions
elif key == "mirrors_postmarketos":
mirrors = cfg["pmbootstrap"]["mirrors_postmarketos"].split(",")
if len(mirrors) > 1:
logging.warning("Multiple mirrors are not supported, using the last one")
config.mirrors_postmarketos = [mirrors[-1].strip("/master")]
config.mirrors["pmaports"] = mirrors[-1].strip("/master")
# Convert strings to paths
elif type(getattr(Config, key)) == PosixPath:
setattr(config, key, Path(cfg["pmbootstrap"][key]))
@ -52,8 +53,7 @@ def load(path: Path) -> Config:
setattr(config, key, cfg["pmbootstrap"][key])
# One time migration "mirror_alpine" -> mirrors.alpine
if "mirror_alpine" in cfg["pmbootstrap"]:
config.mirrors["alpine"] = cfg["pmbootstrap"]["mirror_alpine"]
if "mirror_alpine" in cfg["pmbootstrap"] or "mirrors_postmarketos" in cfg["pmbootstrap"]:
save(path, config)
return config
@ -87,9 +87,6 @@ def serialize(config: Config, skip_defaults=True) -> configparser.ConfigParser:
elif key.startswith("mirrors."):
_key = key.split(".")[1]
cfg["mirrors"][_key] = getattr(config, key)
# Handle whacky type conversions
elif key == "mirrors_postmarketos":
cfg["pmbootstrap"]["mirrors_postmarketos"] = ",".join(config.mirrors_postmarketos)
# Convert strings to paths
elif type(getattr(Config, key)) == PosixPath:
cfg["pmbootstrap"][key] = str(getattr(config, key))

View file

@ -77,6 +77,14 @@ def init(args: PmbArgs) -> PmbArgs:
if hasattr(args, key):
delattr(args, key)
# Handle --mirror-alpine and --mirror-pmos
value = getattr(args, "mirror_alpine", None)
if value:
config.mirrors["alpine"] = value
value = getattr(args, "mirror_postmarketos", None)
if value:
config.mirrors["pmaports"] = value
# Configure runtime context
context = Context(config)
context.command_timeout = args.timeout

View file

@ -639,8 +639,9 @@ def get_parser():
parser = argparse.ArgumentParser(prog="pmbootstrap")
arch_native = Arch.native()
arch_choices = Arch.supported()
# FIXME: we should load the real config instead here
default_config = Config()
mirrors_pmos_default = ",".join(default_config.mirrors_postmarketos)
mirrors_pmos_default = default_config.mirrors["pmaports"]
# Other
parser.add_argument("-V", "--version", action="version",
@ -649,14 +650,14 @@ def get_parser():
default=pmb.config.defaults["config"],
help="path to pmbootstrap.cfg file (default in"
" ~/.config/)")
parser.add_argument("-mp", "--mirror-pmOS", dest="mirrors_postmarketos",
parser.add_argument("-mp", "--mirror-pmOS", dest="mirror_postmarketos",
help="postmarketOS mirror, disable with: -mp='',"
" specify multiple with: -mp='one' -mp='two',"
f" default: {mirrors_pmos_default}",
metavar="URL", action="append", default=[])
parser.add_argument("-m", "--mirror-alpine", dest="mirror_alpine",
help="Alpine Linux mirror, default: "
f"{default_config.mirror_alpine}",
f"{default_config.mirrors["alpine"]}",
metavar="URL")
parser.add_argument("-j", "--jobs", help="parallel jobs when compiling")
parser.add_argument("-E", "--extra-space",

View file

@ -94,7 +94,7 @@ class PmbArgs(Namespace):
lines: str
log: Path
mirror_alpine: str
mirrors_postmarketos: List[str]
mirror_postmarketos: str
name: str
no_depends: str
no_fde: str