Merge pull request #74 from nix-community/refactor-esp-paths

tool: split esp paths
This commit is contained in:
nikstur 2023-01-25 00:32:07 +01:00 committed by GitHub
commit a9bce14645
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 40 deletions

View File

@ -5,14 +5,12 @@ use anyhow::{Context, Result};
use crate::generation::Generation;
/// Paths to the boot files that are not specific to a generation.
pub struct EspPaths {
pub esp: PathBuf,
pub efi: PathBuf,
pub nixos: PathBuf,
pub kernel: PathBuf,
pub initrd: PathBuf,
pub linux: PathBuf,
pub lanzaboote_image: PathBuf,
pub efi_fallback_dir: PathBuf,
pub efi_fallback: PathBuf,
pub systemd: PathBuf,
@ -20,7 +18,7 @@ pub struct EspPaths {
}
impl EspPaths {
pub fn new(esp: impl AsRef<Path>, generation: &Generation) -> Result<Self> {
pub fn new(esp: impl AsRef<Path>) -> Self {
let esp = esp.as_ref();
let efi = esp.join("EFI");
let efi_nixos = efi.join("nixos");
@ -28,39 +26,25 @@ impl EspPaths {
let efi_systemd = efi.join("systemd");
let efi_efi_fallback_dir = efi.join("BOOT");
let bootspec = &generation.spec.bootspec;
Ok(Self {
Self {
esp: esp.to_path_buf(),
efi,
nixos: efi_nixos.clone(),
kernel: efi_nixos.join(nixos_path(&bootspec.kernel, "bzImage")?),
initrd: efi_nixos.join(nixos_path(
bootspec
.initrd
.as_ref()
.context("Lanzaboote does not support missing initrd yet")?,
"initrd",
)?),
linux: efi_linux.clone(),
lanzaboote_image: efi_linux.join(generation_path(generation)),
nixos: efi_nixos,
linux: efi_linux,
efi_fallback_dir: efi_efi_fallback_dir.clone(),
efi_fallback: efi_efi_fallback_dir.join("BOOTX64.EFI"),
systemd: efi_systemd.clone(),
systemd_boot: efi_systemd.join("systemd-bootx64.efi"),
})
}
}
/// Return the used file paths to store as garbage collection roots.
pub fn to_iter(&self) -> IntoIter<&PathBuf, 11> {
pub fn to_iter(&self) -> IntoIter<&PathBuf, 8> {
[
&self.esp,
&self.efi,
&self.nixos,
&self.kernel,
&self.initrd,
&self.linux,
&self.lanzaboote_image,
&self.efi_fallback_dir,
&self.efi_fallback,
&self.systemd,
@ -70,6 +54,38 @@ impl EspPaths {
}
}
/// Paths to the boot files of a specific generation.
pub struct EspGenerationPaths {
pub kernel: PathBuf,
pub initrd: PathBuf,
pub lanzaboote_image: PathBuf,
}
impl EspGenerationPaths {
pub fn new(esp_paths: &EspPaths, generation: &Generation) -> Result<Self> {
let bootspec = &generation.spec.bootspec;
Ok(Self {
kernel: esp_paths
.nixos
.join(nixos_path(&bootspec.kernel, "bzImage")?),
initrd: esp_paths.nixos.join(nixos_path(
bootspec
.initrd
.as_ref()
.context("Lanzaboote does not support missing initrd yet")?,
"initrd",
)?),
lanzaboote_image: esp_paths.linux.join(generation_path(generation)),
})
}
/// Return the used file paths to store as garbage collection roots.
pub fn to_iter(&self) -> IntoIter<&PathBuf, 3> {
[&self.kernel, &self.initrd, &self.lanzaboote_image].into_iter()
}
}
fn nixos_path(path: impl AsRef<Path>, name: &str) -> Result<PathBuf> {
let resolved = path
.as_ref()

View File

@ -6,7 +6,7 @@ use std::process::Command;
use anyhow::{Context, Result};
use nix::unistd::sync;
use crate::esp::EspPaths;
use crate::esp::{EspGenerationPaths, EspPaths};
use crate::gc::Roots;
use crate::generation::{Generation, GenerationLink};
use crate::os_release::OsRelease;
@ -19,7 +19,7 @@ pub struct Installer {
lanzaboote_stub: PathBuf,
key_pair: KeyPair,
configuration_limit: usize,
esp: PathBuf,
esp_paths: EspPaths,
generation_links: Vec<PathBuf>,
}
@ -31,12 +31,16 @@ impl Installer {
esp: PathBuf,
generation_links: Vec<PathBuf>,
) -> Self {
let mut gc_roots = Roots::new();
let esp_paths = EspPaths::new(esp);
gc_roots.extend(esp_paths.to_iter());
Self {
gc_roots: Roots::new(),
gc_roots,
lanzaboote_stub,
key_pair,
configuration_limit,
esp,
esp_paths,
generation_links,
}
}
@ -66,12 +70,12 @@ impl Installer {
// the NixOS installation are deleted. Lanzatool takes full control over the esp/EFI/nixos
// directory and deletes ALL files that it doesn't know about. Dual- or multiboot setups
// that need files in this directory will NOT work.
self.gc_roots.collect_garbage(self.esp.join("EFI/nixos"))?;
self.gc_roots.collect_garbage(&self.esp_paths.nixos)?;
// The esp/EFI/Linux directory is assumed to be potentially shared with other distros.
// Thus, only files that start with "nixos-" are garbage collected (i.e. potentially
// deleted).
self.gc_roots
.collect_garbage_with_filter(self.esp.join("EFI/Linux"), |p| {
.collect_garbage_with_filter(&self.esp_paths.linux, |p| {
p.file_name()
.and_then(|n| n.to_str())
.map_or(false, |n| n.starts_with("nixos-"))
@ -115,8 +119,8 @@ impl Installer {
fn install_generation(&mut self, generation: &Generation) -> Result<()> {
let bootspec = &generation.spec.bootspec;
let esp_paths = EspPaths::new(&self.esp, generation)?;
self.gc_roots.extend(esp_paths.to_iter());
let esp_gen_paths = EspGenerationPaths::new(&self.esp_paths, generation)?;
self.gc_roots.extend(esp_gen_paths.to_iter());
let kernel_cmdline =
assemble_kernel_cmdline(&bootspec.init, bootspec.kernel_params.clone());
@ -150,9 +154,9 @@ impl Installer {
.join("systemd/lib/systemd/boot/efi/systemd-bootx64.efi");
[
(&systemd_boot, &esp_paths.efi_fallback),
(&systemd_boot, &esp_paths.systemd_boot),
(&bootspec.kernel, &esp_paths.kernel),
(&systemd_boot, &self.esp_paths.efi_fallback),
(&systemd_boot, &self.esp_paths.systemd_boot),
(&bootspec.kernel, &esp_gen_paths.kernel),
]
.into_iter()
.try_for_each(|(from, to)| install_signed(&self.key_pair, from, to))?;
@ -160,23 +164,24 @@ impl Installer {
// The initrd doesn't need to be signed. Lanzaboote has its
// hash embedded and will refuse loading it when the hash
// mismatches.
install(&initrd_location, &esp_paths.initrd).context("Failed to install initrd to ESP")?;
install(&initrd_location, &esp_gen_paths.initrd)
.context("Failed to install initrd to ESP")?;
let lanzaboote_image = pe::lanzaboote_image(
&tempdir,
&self.lanzaboote_stub,
&os_release_path,
&kernel_cmdline,
&esp_paths.kernel,
&esp_paths.initrd,
&esp_paths.esp,
&esp_gen_paths.kernel,
&esp_gen_paths.initrd,
&self.esp_paths.esp,
)
.context("Failed to assemble stub")?;
install_signed(
&self.key_pair,
&lanzaboote_image,
&esp_paths.lanzaboote_image,
&esp_gen_paths.lanzaboote_image,
)
.context("Failed to install lanzaboote")?;
@ -187,7 +192,7 @@ impl Installer {
println!(
"Successfully installed lanzaboote to '{}'",
esp_paths.esp.display()
self.esp_paths.esp.display()
);
Ok(())