config: find required programs every time pmbootstrap is run (MR 2475)

On debian systems in particular special handling is needed for
/usr/sbin. Let's do this once and then provide the host deps we use in a
nice accessible dictionary.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Tweaked-by: Oliver Smith <ollieparanoid@postmarketos.org>
This commit is contained in:
Caleb Connolly 2024-11-04 07:53:34 +01:00 committed by Oliver Smith
parent c4194759f5
commit 585c477239
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
3 changed files with 20 additions and 13 deletions

View file

@ -14,7 +14,7 @@ if TYPE_CHECKING:
from . import config
from . import parse
from .config import init as config_init
from .config import init as config_init, require_programs
from .helpers import frontend
from .helpers import logging
from .helpers import mount
@ -76,6 +76,9 @@ def main() -> int:
if not args.as_root and os.geteuid() == 0:
raise RuntimeError("Do not run pmbootstrap as root!")
# Check for required programs (and find their absolute paths)
require_programs()
# Initialize or require config
if args.action == "init":
config_init.frontend(args)

View file

@ -14,6 +14,7 @@ from collections.abc import Sequence
from pmb.config.file import load, save, serialize
from pmb.config.sudo import which_sudo
from pmb.config.other import is_systemd_selected
from .init import require_programs
from . import workdir
@ -58,14 +59,16 @@ ondev_min_version = "0.2.0"
# Programs that pmbootstrap expects to be available from the host system. Keep
# in sync with README.md, and try to keep the list as small as possible. The
# idea is to run almost everything in Alpine chroots.
required_programs = [
"git",
"kpartx",
"losetup",
"openssl",
"ps",
"tar",
]
required_programs: dict[str, str] = {
"git": "",
"kpartx": "",
"losetup": "",
"openssl": "",
"ps": "",
"tar": "",
"chroot": "",
"sh": "",
}
def sudo(cmd: Sequence[PathString]) -> Sequence[PathString]:

View file

@ -36,11 +36,14 @@ import pmb.parse._apkbuild
def require_programs() -> None:
missing = []
for program in pmb.config.required_programs:
for program in pmb.config.required_programs.keys():
# Debian: some programs are in /usr/sbin, which is not in PATH
# unless using sudo
if not shutil.which(program) and not os.path.exists(os.path.join("/usr/sbin", program)):
prog = shutil.which(program, path=pmb.config.host_path)
if not prog:
missing.append(program)
else:
pmb.config.required_programs[program] = prog
losetup_missing_json = False
@ -694,8 +697,6 @@ def ask_for_locale(current_locale: str) -> str:
def frontend(args: PmbArgs) -> None:
require_programs()
# Work folder (needs to be first, so we can create chroots early)
config = get_context().config