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; use crate::generation::Generation;
/// Paths to the boot files that are not specific to a generation.
pub struct EspPaths { pub struct EspPaths {
pub esp: PathBuf, pub esp: PathBuf,
pub efi: PathBuf, pub efi: PathBuf,
pub nixos: PathBuf, pub nixos: PathBuf,
pub kernel: PathBuf,
pub initrd: PathBuf,
pub linux: PathBuf, pub linux: PathBuf,
pub lanzaboote_image: PathBuf,
pub efi_fallback_dir: PathBuf, pub efi_fallback_dir: PathBuf,
pub efi_fallback: PathBuf, pub efi_fallback: PathBuf,
pub systemd: PathBuf, pub systemd: PathBuf,
@ -20,7 +18,7 @@ pub struct EspPaths {
} }
impl 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 esp = esp.as_ref();
let efi = esp.join("EFI"); let efi = esp.join("EFI");
let efi_nixos = efi.join("nixos"); let efi_nixos = efi.join("nixos");
@ -28,39 +26,25 @@ impl EspPaths {
let efi_systemd = efi.join("systemd"); let efi_systemd = efi.join("systemd");
let efi_efi_fallback_dir = efi.join("BOOT"); let efi_efi_fallback_dir = efi.join("BOOT");
let bootspec = &generation.spec.bootspec; Self {
Ok(Self {
esp: esp.to_path_buf(), esp: esp.to_path_buf(),
efi, efi,
nixos: efi_nixos.clone(), nixos: efi_nixos,
kernel: efi_nixos.join(nixos_path(&bootspec.kernel, "bzImage")?), linux: efi_linux,
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)),
efi_fallback_dir: efi_efi_fallback_dir.clone(), efi_fallback_dir: efi_efi_fallback_dir.clone(),
efi_fallback: efi_efi_fallback_dir.join("BOOTX64.EFI"), efi_fallback: efi_efi_fallback_dir.join("BOOTX64.EFI"),
systemd: efi_systemd.clone(), systemd: efi_systemd.clone(),
systemd_boot: efi_systemd.join("systemd-bootx64.efi"), systemd_boot: efi_systemd.join("systemd-bootx64.efi"),
}) }
} }
/// Return the used file paths to store as garbage collection roots. /// 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.esp,
&self.efi, &self.efi,
&self.nixos, &self.nixos,
&self.kernel,
&self.initrd,
&self.linux, &self.linux,
&self.lanzaboote_image,
&self.efi_fallback_dir, &self.efi_fallback_dir,
&self.efi_fallback, &self.efi_fallback,
&self.systemd, &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> { fn nixos_path(path: impl AsRef<Path>, name: &str) -> Result<PathBuf> {
let resolved = path let resolved = path
.as_ref() .as_ref()

View File

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