Files
euri-mklive/euri_mklive/distros/base.py
T

65 lines
2.1 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"
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', '')}"
return subprocess.run(cmd, check=True, env=env, **kw)
@staticmethod
def _run_chroot(rootfs: Path, cmd: list[str], **kw) -> subprocess.CompletedProcess:
full = ["sudo", "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)