chroot: apk: safety net when chroot unitialized (MR 2252)

We recently changed how we manage chroots, requiring the user (of the
chroot) to initialize it before doing stuff like installing packages.

There are however still certain edgecases in pmbootstrap where this
doesn't get done (for example qemu/run.py would attempt to install the
kernel package for the device, but we don't initialize the rootfs chroot
in QEMU since that doesn't make sense to do). Check for and catch this
situation explicitly so we don't ruin someones day, but still be loud
about it so we can hopefully catch the remaining instances of this.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
This commit is contained in:
Caleb Connolly 2024-06-22 18:59:05 +02:00 committed by Oliver Smith
parent 794048e2d5
commit cb6cd3bc4c
No known key found for this signature in database
GPG key ID: 5AE7F5513E0885CB
3 changed files with 16 additions and 0 deletions

View file

@ -2,6 +2,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import os import os
from pathlib import Path from pathlib import Path
import traceback
import pmb.chroot.apk_static import pmb.chroot.apk_static
from pmb.core.arch import Arch from pmb.core.arch import Arch
from pmb.helpers import logging from pmb.helpers import logging
@ -204,6 +205,15 @@ def install_run_apk(to_add: List[str], to_add_local: List[Path], to_del: List[st
channel = pmb.config.pmaports.read_config()["channel"] channel = pmb.config.pmaports.read_config()["channel"]
user_repo = work / "packages" / channel user_repo = work / "packages" / channel
# There are still some edgecases where we manage to get here while the chroot is not
# initialized. To not break the build, we initialize it here but print a big warning
# and a stack trace so hopefully folks report it.
if not chroot.is_mounted():
logging.warning(f"({chroot}) chroot not initialized! This is a bug! Please report it.")
logging.warning(f"({chroot}) initializing the chroot for you...")
traceback.print_stack(file=logging.logfd)
pmb.chroot.init(chroot)
for (i, command) in enumerate(commands): for (i, command) in enumerate(commands):
# --no-interactive is a parameter to `add`, so it must be appended or apk # --no-interactive is a parameter to `add`, so it must be appended or apk
# gets confused # gets confused

View file

@ -23,6 +23,8 @@ def kernel_flavor_installed(chroot: Chroot, autoinstall=True):
""" """
# Automatically install the selected kernel # Automatically install the selected kernel
if autoinstall: if autoinstall:
if not chroot.is_mounted():
pmb.chroot.init(chroot)
config = get_context().config config = get_context().config
packages = ([f"device-{config.device}"] + packages = ([f"device-{config.device}"] +
pmb.install.get_kernel_package(config)) pmb.install.get_kernel_package(config))

View file

@ -91,6 +91,10 @@ class Chroot:
return (self / "bin/sh").is_symlink() return (self / "bin/sh").is_symlink()
def is_mounted(self) -> bool:
return self.exists() and pmb.helpers.mount.ismount(self.path / "etc/apk/keys")
@property @property
def arch(self) -> Arch: def arch(self) -> Arch:
if self.type == ChrootType.NATIVE: if self.type == ChrootType.NATIVE: