mirror of
https://git.launchpad.net/livecd-rootfs
synced 2026-02-23 02:13:32 +00:00
Package contents were being extracted into subdirectories of the boot tree (grub_dir, shim_dir), which meant the boot tree contained both the final boot files and the raw package extractions. Extract packages into scratch directories instead, copying only the needed files into the boot tree. This also removes the grub_dir/shim_dir instance variables and the create_dirs overrides, and moves copy_grub_modules to a standalone function in grub.py.
103 lines
3.2 KiB
Python
103 lines
3.2 KiB
Python
"""Base classes and helper functions for boot configuration."""
|
|
|
|
import pathlib
|
|
import subprocess
|
|
import tempfile
|
|
from abc import ABC, abstractmethod
|
|
|
|
from ..builder import Logger
|
|
from ..apt_state import AptStateManager
|
|
|
|
|
|
def default_kernel_params(project: str) -> str:
|
|
if project == "ubuntukylin":
|
|
return (
|
|
"file=/cdrom/preseed/ubuntu.seed locale=zh_CN "
|
|
"keyboard-configuration/layoutcode?=cn quiet splash --- "
|
|
)
|
|
if project == "ubuntu-server":
|
|
return " --- "
|
|
else:
|
|
return " --- quiet splash"
|
|
|
|
|
|
class BaseBootConfigurator(ABC):
|
|
"""Abstract base class for architecture-specific boot configurators.
|
|
|
|
Subclasses must implement:
|
|
- extract_files(): Download and extract bootloader packages
|
|
- mkisofs_opts(): Return mkisofs command-line options
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
logger: Logger,
|
|
apt_state: AptStateManager,
|
|
iso_root: pathlib.Path,
|
|
) -> None:
|
|
self.logger = logger
|
|
self.apt_state = apt_state
|
|
self.iso_root = iso_root
|
|
|
|
def create_dirs(self, workdir):
|
|
self.scratch = workdir.joinpath("boot-stuff")
|
|
self.scratch.mkdir(exist_ok=True)
|
|
self.boot_tree = self.scratch.joinpath("cd-boot-tree")
|
|
|
|
def download_and_extract_package(
|
|
self, pkg_name: str, target_dir: pathlib.Path
|
|
) -> None:
|
|
"""Download a Debian package and extract its contents to target directory."""
|
|
self.logger.log(f"downloading and extracting {pkg_name}")
|
|
target_dir.mkdir(exist_ok=True, parents=True)
|
|
with tempfile.TemporaryDirectory() as tdir_str:
|
|
tdir = pathlib.Path(tdir_str)
|
|
self.apt_state.download_direct(pkg_name, tdir)
|
|
[deb] = tdir.glob("*.deb")
|
|
dpkg_proc = subprocess.Popen(
|
|
["dpkg-deb", "--fsys-tarfile", deb], stdout=subprocess.PIPE
|
|
)
|
|
tar_proc = subprocess.Popen(
|
|
["tar", "xf", "-", "-C", target_dir], stdin=dpkg_proc.stdout
|
|
)
|
|
assert dpkg_proc.stdout is not None
|
|
dpkg_proc.stdout.close()
|
|
tar_proc.communicate()
|
|
|
|
@abstractmethod
|
|
def extract_files(self) -> None:
|
|
"""Download and extract bootloader packages to the boot tree.
|
|
|
|
Each architecture must implement this to set up its specific bootloader files.
|
|
"""
|
|
...
|
|
|
|
@abstractmethod
|
|
def mkisofs_opts(self) -> list[str | pathlib.Path]:
|
|
"""Return mkisofs command-line options for this architecture.
|
|
|
|
Returns:
|
|
List of command-line options to pass to mkisofs/xorriso.
|
|
"""
|
|
...
|
|
|
|
def post_process_iso(self, iso_path: pathlib.Path) -> None:
|
|
"""Post-process the ISO image after xorriso creates it."""
|
|
|
|
def make_bootable(
|
|
self,
|
|
workdir: pathlib.Path,
|
|
project: str,
|
|
capproject: str,
|
|
subarch: str,
|
|
hwe: bool,
|
|
) -> None:
|
|
"""Make the ISO bootable by extracting bootloader files."""
|
|
self.project = project
|
|
self.humanproject = capproject.replace("-", " ")
|
|
self.subarch = subarch
|
|
self.hwe = hwe
|
|
self.create_dirs(workdir)
|
|
with self.logger.logged("configuring boot"):
|
|
self.extract_files()
|