Files
euri-mklive/euri_mklive/distros/base.py
T
c-ludenberg 131e84bb3f feat: interactive TUI with rich/questionary, fakeroot mode, failsafes
- Interactive TUI: distro/init/libc/arch/package selection, ISO config
- Root vs fakeroot mode detection with warnings
- Disk space check before build
- Confirmation prompts with build summary
- Fakeroot support via set_mode() in base.py
2026-08-27 20:18:30 +02:00

79 lines
2.4 KiB
Python

"""Base class for distro backends."""
from __future__ import annotations
import shutil
import subprocess
from abc import ABC, abstractmethod
from pathlib import Path
_BUNDLED = Path(__file__).resolve().parent.parent / "bin"
_LIB = Path(__file__).resolve().parent.parent / "lib"
_mode = "root"
def set_mode(m: str) -> None:
global _mode
_mode = m
class Distro(ABC):
"""Base class every distro backend must implement."""
name: str
host_deps: list[str]
@abstractmethod
def bootstrap(self, rootfs: Path, config: dict) -> None:
"""Create the rootfs by installing the base system."""
@abstractmethod
def install_packages(self, rootfs: Path, packages: list[str]) -> None:
"""Install packages into an existing rootfs."""
@abstractmethod
def configure_base(self, rootfs: Path, config: dict) -> None:
"""Write hostname, fstab, locale, users, services, etc."""
@abstractmethod
def install_bootloader(self, rootfs: Path, config: dict) -> None:
"""Install and configure the bootloader inside the rootfs."""
@staticmethod
def _tool(name: str) -> str:
bundled = _BUNDLED / name
if bundled.is_file():
return str(bundled)
if bundled.is_dir():
script = bundled / name
if script.is_file():
return str(script)
path = shutil.which(name)
if path:
return path
return name
@staticmethod
def _run(cmd: list[str], **kw) -> subprocess.CompletedProcess:
import os
print(f" \033[90m$\033[0m \033[1m{' '.join(cmd)}\033[0m")
env = kw.pop("env", None) or os.environ.copy()
lib_str = str(_LIB)
env["LD_LIBRARY_PATH"] = f"{lib_str}:{env.get('LD_LIBRARY_PATH', '')}"
kw.setdefault("input", b"Y\n")
return subprocess.run(cmd, check=True, env=env, **kw)
@staticmethod
def _run_chroot(rootfs: Path, cmd: list[str], **kw) -> subprocess.CompletedProcess:
prefix = []
if _mode == "fakeroot" and shutil.which("fakeroot"):
prefix = ["fakeroot"]
elif _mode == "root":
prefix = ["sudo"]
full = [*prefix, "chroot", str(rootfs), "/bin/sh", "-c", " ".join(cmd)]
print(f" \033[90m$\033[0m \033[33m[chroot]\033[0m \033[1m{' '.join(cmd)}\033[0m")
return subprocess.run(full, check=True, **kw)