lanzaboote/rust/lanzatool/src/esp.rs

96 lines
2.9 KiB
Rust
Raw Normal View History

use anyhow::{Context, Result};
2022-11-23 09:26:26 -05:00
use std::path::{Path, PathBuf};
use crate::generation::Generation;
2022-11-23 09:26:26 -05:00
pub struct EspPaths {
pub esp: 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,
pub systemd_boot: PathBuf,
2022-11-23 09:26:26 -05:00
}
impl EspPaths {
pub fn new(esp: impl AsRef<Path>, generation: &Generation) -> Result<Self> {
let esp = esp.as_ref();
2022-11-23 09:26:26 -05:00
let esp_nixos = esp.join("EFI/nixos");
let esp_linux = esp.join("EFI/Linux");
let esp_systemd = esp.join("EFI/systemd");
let esp_efi_fallback_dir = esp.join("EFI/BOOT");
2022-11-23 09:26:26 -05:00
let bootspec = &generation.spec.bootspec;
Ok(Self {
esp: esp.to_path_buf(),
2022-11-23 09:26:26 -05:00
nixos: esp_nixos.clone(),
kernel: esp_nixos.join(nixos_path(&bootspec.kernel, "bzImage")?),
initrd: esp_nixos.join(nixos_path(
bootspec
.initrd
.as_ref()
.context("Lanzaboote does not support missing initrd yet")?,
"initrd",
)?),
linux: esp_linux.clone(),
2022-11-26 17:19:08 -05:00
lanzaboote_image: esp_linux.join(generation_path(generation)),
efi_fallback_dir: esp_efi_fallback_dir.clone(),
efi_fallback: esp_efi_fallback_dir.join("BOOTX64.EFI"),
systemd: esp_systemd.clone(),
systemd_boot: esp_systemd.join("systemd-bootx64.efi"),
})
2022-11-23 09:26:26 -05:00
}
}
fn nixos_path(path: impl AsRef<Path>, name: &str) -> Result<PathBuf> {
2022-11-26 17:19:08 -05:00
let resolved = path
.as_ref()
.read_link()
.unwrap_or_else(|_| path.as_ref().into());
let parent_final_component = resolved
.parent()
.and_then(|x| x.file_name())
.and_then(|x| x.to_str())
.with_context(|| format!("Failed to extract final component from: {:?}", resolved))?;
let nixos_filename = format!("{}-{}.efi", parent_final_component, name);
Ok(PathBuf::from(nixos_filename))
}
fn generation_path(generation: &Generation) -> PathBuf {
2022-11-27 05:19:02 -05:00
if let Some(specialisation_name) = generation.is_specialized() {
PathBuf::from(format!(
"nixos-generation-{}-specialisation-{}.efi",
generation, specialisation_name
))
} else {
PathBuf::from(format!("nixos-generation-{}.efi", generation))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nixos_path_creates_correct_filename_from_nix_store_path() -> Result<()> {
let path =
Path::new("/nix/store/xqplddjjjy1lhzyzbcv4dza11ccpcfds-initrd-linux-6.1.1/initrd");
let generated_filename = nixos_path(path, "initrd")?;
let expected_filename =
PathBuf::from("xqplddjjjy1lhzyzbcv4dza11ccpcfds-initrd-linux-6.1.1-initrd.efi");
assert_eq!(generated_filename, expected_filename);
Ok(())
}
}