2022-12-11 20:09:19 -05:00
|
|
|
use std::array::IntoIter;
|
2022-11-23 09:26:26 -05:00
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
|
2022-12-11 20:09:19 -05:00
|
|
|
use anyhow::{Context, Result};
|
|
|
|
|
2022-12-17 18:31:09 -05:00
|
|
|
use crate::generation::Generation;
|
2022-11-25 21:14:21 -05:00
|
|
|
|
2022-11-23 09:26:26 -05:00
|
|
|
pub struct EspPaths {
|
|
|
|
pub esp: PathBuf,
|
2022-12-11 20:09:19 -05:00
|
|
|
pub efi: PathBuf,
|
2022-11-23 09:26:26 -05:00
|
|
|
pub nixos: PathBuf,
|
|
|
|
pub kernel: PathBuf,
|
|
|
|
pub initrd: PathBuf,
|
2022-11-23 11:26:56 -05:00
|
|
|
pub linux: PathBuf,
|
|
|
|
pub lanzaboote_image: PathBuf,
|
2022-11-24 05:10:19 -05:00
|
|
|
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 {
|
2022-12-17 18:31:09 -05:00
|
|
|
pub fn new(esp: impl AsRef<Path>, generation: &Generation) -> Result<Self> {
|
2022-11-26 16:23:00 -05:00
|
|
|
let esp = esp.as_ref();
|
2022-12-11 20:09:19 -05:00
|
|
|
let efi = esp.join("EFI");
|
|
|
|
let efi_nixos = efi.join("nixos");
|
|
|
|
let efi_linux = efi.join("Linux");
|
|
|
|
let efi_systemd = efi.join("systemd");
|
|
|
|
let efi_efi_fallback_dir = efi.join("BOOT");
|
2022-11-23 09:26:26 -05:00
|
|
|
|
2022-12-17 18:31:09 -05:00
|
|
|
let bootspec = &generation.spec.bootspec;
|
2022-11-26 16:23:00 -05:00
|
|
|
|
2022-11-25 21:14:21 -05:00
|
|
|
Ok(Self {
|
2022-11-26 16:23:00 -05:00
|
|
|
esp: esp.to_path_buf(),
|
2022-12-11 20:09:19 -05:00
|
|
|
efi,
|
|
|
|
nixos: efi_nixos.clone(),
|
|
|
|
kernel: efi_nixos.join(nixos_path(&bootspec.kernel, "bzImage")?),
|
|
|
|
initrd: efi_nixos.join(nixos_path(
|
2022-12-17 18:31:09 -05:00
|
|
|
bootspec
|
|
|
|
.initrd
|
|
|
|
.as_ref()
|
|
|
|
.context("Lanzaboote does not support missing initrd yet")?,
|
|
|
|
"initrd",
|
|
|
|
)?),
|
2022-12-11 20:09:19 -05:00
|
|
|
linux: efi_linux.clone(),
|
|
|
|
lanzaboote_image: efi_linux.join(generation_path(generation)),
|
|
|
|
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"),
|
2022-11-25 21:14:21 -05:00
|
|
|
})
|
2022-11-23 09:26:26 -05:00
|
|
|
}
|
2022-12-11 20:09:19 -05:00
|
|
|
|
|
|
|
/// Return the used file paths to store as garbage collection roots.
|
|
|
|
pub fn to_iter(&self) -> IntoIter<&PathBuf, 11> {
|
|
|
|
[
|
|
|
|
&self.esp,
|
|
|
|
&self.efi,
|
|
|
|
&self.nixos,
|
|
|
|
&self.kernel,
|
|
|
|
&self.initrd,
|
|
|
|
&self.linux,
|
|
|
|
&self.lanzaboote_image,
|
|
|
|
&self.efi_fallback_dir,
|
|
|
|
&self.efi_fallback,
|
|
|
|
&self.systemd,
|
|
|
|
&self.systemd_boot,
|
|
|
|
]
|
|
|
|
.into_iter()
|
|
|
|
}
|
2022-11-23 09:26:26 -05:00
|
|
|
}
|
2022-11-25 21:14:21 -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());
|
2022-11-25 21:14:21 -05:00
|
|
|
|
2022-12-29 19:40:22 -05:00
|
|
|
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))?;
|
2022-11-25 21:14:21 -05:00
|
|
|
|
2022-12-29 19:40:22 -05:00
|
|
|
let nixos_filename = format!("{}-{}.efi", parent_final_component, name);
|
2022-11-25 21:14:21 -05:00
|
|
|
|
|
|
|
Ok(PathBuf::from(nixos_filename))
|
|
|
|
}
|
|
|
|
|
2022-12-17 18:31:09 -05:00
|
|
|
fn generation_path(generation: &Generation) -> PathBuf {
|
2023-01-06 17:20:31 -05:00
|
|
|
if let Some(specialisation_name) = generation.is_specialised() {
|
2022-11-27 05:19:02 -05:00
|
|
|
PathBuf::from(format!(
|
|
|
|
"nixos-generation-{}-specialisation-{}.efi",
|
|
|
|
generation, specialisation_name
|
|
|
|
))
|
|
|
|
} else {
|
|
|
|
PathBuf::from(format!("nixos-generation-{}.efi", generation))
|
|
|
|
}
|
2022-11-25 21:14:21 -05:00
|
|
|
}
|
2022-12-29 19:40:22 -05:00
|
|
|
|
|
|
|
#[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(())
|
|
|
|
}
|
|
|
|
}
|