Backends now resolve package managers from euri_mklive/bin/ first, falling back to system PATH. No more host_deps for package managers.
59 lines
1.8 KiB
Python
59 lines
1.8 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"
|
|
|
|
|
|
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:
|
|
print(f" \033[90m$\033[0m \033[1m{' '.join(cmd)}\033[0m")
|
|
return subprocess.run(cmd, check=True, **kw)
|
|
|
|
@staticmethod
|
|
def _run_chroot(rootfs: Path, cmd: list[str], **kw) -> subprocess.CompletedProcess:
|
|
full = ["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)
|