pmbootstrap init: Add mirror choice (MR 2035)

Allows user to choose one of the mirrors from
https://mirrors.postmarketos.org.

Example:
[1] Mirror 1 (Location 1)
[2] Mirror 2 (Location 2)
[3] Mirror 3 (Location 3)
Select a mirror [1]: 2

Co-Authored-By: Alexey Min <alexey.min@gmail.com>
This commit is contained in:
Anri Dellal 2021-03-17 20:09:59 +03:00 committed by Oliver Smith
parent c5bd07e3ae
commit 5c1da79634
No known key found for this signature in database
GPG Key ID: 5AE7F5513E0885CB
4 changed files with 82 additions and 5 deletions

View File

@ -60,6 +60,7 @@ config_keys = ["aports",
"kernel",
"keymap",
"locale",
"mirrors_postmarketos",
"nonfree_firmware",
"nonfree_userland",
"ssh_keys",
@ -97,7 +98,9 @@ defaults = {
"locale": "C.UTF-8",
"log": "$WORK/log.txt",
"mirror_alpine": "http://dl-cdn.alpinelinux.org/alpine/",
"mirrors_postmarketos": ["http://mirror.postmarketos.org/postmarketos/"],
# NOTE: mirrors_postmarketos variable type is supposed to be
# comma-separated string, not a python list or any other type!
"mirrors_postmarketos": "http://mirror.postmarketos.org/postmarketos/",
"nonfree_firmware": True,
"nonfree_userland": False,
"port_distccd": "33632",

View File

@ -2,6 +2,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later
import logging
import glob
import json
import os
import shutil
@ -10,6 +11,7 @@ import pmb.config
import pmb.config.pmaports
import pmb.helpers.cli
import pmb.helpers.devices
import pmb.helpers.http
import pmb.helpers.logging
import pmb.helpers.other
import pmb.helpers.run
@ -357,7 +359,8 @@ def ask_for_additional_options(args, cfg):
f" boot partition size: {args.boot_size} MB,"
f" parallel jobs: {args.jobs},"
f" ccache per arch: {args.ccache_size},"
f" sudo timer: {args.sudo_timer}")
f" sudo timer: {args.sudo_timer},"
f" mirror: {','.join(args.mirrors_postmarketos)}")
if not pmb.helpers.cli.confirm(args, "Change them?",
default=False):
@ -411,6 +414,72 @@ def ask_for_additional_options(args, cfg):
default=args.sudo_timer)
cfg["pmbootstrap"]["sudo_timer"] = str(answer)
# Mirrors
# prompt for mirror change
logging.info("Selected mirror:"
f" {','.join(args.mirrors_postmarketos)}")
if pmb.helpers.cli.confirm(args, "Change mirror?", default=False):
mirrors = ask_for_mirror(args)
cfg["pmbootstrap"]["mirrors_postmarketos"] = ",".join(mirrors)
def ask_for_mirror(args):
regex = "^[1-9][0-9]*$" # single non-zero number only
json_path = pmb.helpers.http.download(
args, "https://postmarketos.org/mirrors.json", "pmos_mirrors",
cache=False)
with open(json_path, "rt") as handle:
s = handle.read()
logging.info("List of available mirrors:")
mirrors = json.loads(s)
keys = mirrors.keys()
i = 1
for key in keys:
logging.info(f"[{i}]\t{key} ({mirrors[key]['location']})")
i += 1
urls = []
for key in keys:
# accept only http:// or https:// urls
http_count = 0 # remember if we saw any http:// only URLs
link_list = []
for k in mirrors[key]["urls"]:
if k.startswith("http"):
link_list.append(k)
if k.startswith("http://"):
http_count += 1
# remove all https urls if there is more that one URL and one of
# them was http://
if http_count > 0 and len(link_list) > 1:
link_list = [k for k in link_list if not k.startswith("https")]
if len(link_list) > 0:
urls.append(link_list[0])
mirror_indexes = []
for mirror in args.mirrors_postmarketos:
for i in range(len(urls)):
if urls[i] == mirror:
mirror_indexes.append(str(i + 1))
break
mirrors_list = []
# require one valid mirror index selected by user
while len(mirrors_list) != 1:
answer = pmb.helpers.cli.ask(args, "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:
logging.info("You must select one valid mirror!")
return mirrors_list
def ask_for_hostname(args, device):
while True:

View File

@ -79,7 +79,9 @@ def fix_mirrors_postmarketos(args):
subparsers: <https://bugs.python.org/issue9338> """
# -mp not specified: use default mirrors
if not args.mirrors_postmarketos:
args.mirrors_postmarketos = pmb.config.defaults["mirrors_postmarketos"]
cfg = pmb.config.load(args)
args.mirrors_postmarketos = \
cfg["pmbootstrap"]["mirrors_postmarketos"].split(",")
# -mp="": use no postmarketOS mirrors (build everything locally)
if args.mirrors_postmarketos == [""]:

View File

@ -261,13 +261,16 @@ def test_questions_additional_options(args, monkeypatch):
assert cfg == {"pmbootstrap": {}}
# Answer everything
fake_answers(monkeypatch, ["y", "128", "64", "5", "2G", "n", "n"])
fake_answers(monkeypatch, ["y", "128", "64", "5", "2G", "n", "y", "1",
"n"])
func(args, cfg)
mirror = pmb.config.defaults["mirrors_postmarketos"]
assert cfg == {"pmbootstrap": {"extra_space": "128",
"boot_size": "64",
"jobs": "5",
"ccache_size": "2G",
"sudo_timer": "False"}}
"sudo_timer": "False",
"mirrors_postmarketos": mirror}}
def test_questions_hostname(args, monkeypatch):