lzbt: abstraction for multiple backends
This generates `lzbt-systemd` binary instead of `lzbt` which is using a special systemd-specific entrypoint. This is part of the effort to enable multiple backends.
This commit is contained in:
parent
7ef2b13780
commit
efe7b40f5c
|
@ -4,8 +4,8 @@ version = "0.3.0"
|
|||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "lzbt"
|
||||
path = "src/main.rs"
|
||||
name = "lzbt-systemd"
|
||||
path = "src/systemd-main.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
|
@ -1,65 +1,29 @@
|
|||
use std::array::IntoIter;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{path::{PathBuf, Path}, array::IntoIter};
|
||||
|
||||
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 linux: PathBuf,
|
||||
pub efi_fallback_dir: PathBuf,
|
||||
pub efi_fallback: PathBuf,
|
||||
pub systemd: PathBuf,
|
||||
pub systemd_boot: PathBuf,
|
||||
pub loader: PathBuf,
|
||||
pub systemd_boot_loader_config: PathBuf,
|
||||
}
|
||||
|
||||
impl EspPaths {
|
||||
pub fn new(esp: impl AsRef<Path>) -> Self {
|
||||
let esp = esp.as_ref();
|
||||
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");
|
||||
let loader = esp.join("loader");
|
||||
let systemd_boot_loader_config = loader.join("loader.conf");
|
||||
|
||||
Self {
|
||||
esp: esp.to_path_buf(),
|
||||
efi,
|
||||
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"),
|
||||
loader,
|
||||
systemd_boot_loader_config,
|
||||
}
|
||||
}
|
||||
use crate::common::generation::Generation;
|
||||
|
||||
/// Generic ESP paths which can be specific to a bootloader
|
||||
// The const generics is necessary because:
|
||||
// (a) we cannot return Trait objects in trait definitions, see https://rust-lang.github.io/impl-trait-initiative/explainer/rpit_trait.html
|
||||
// (b) we cannot return std::slice::Iter<'_, PathBuf> because PathBuf is owned
|
||||
// (c) we cannot return std::slice::Iter<'_, &PathBuf> because then Item = &&PathBuf
|
||||
// (d) we cannot return std::slice::Iter<'_, Path> because Path is unsized
|
||||
// (e) we cannot return std::slice::Iter<'_, &Path> because then Item = &&Path
|
||||
// (f) we can bring an associated type `BorrowedIterator` and then because we want to return
|
||||
// borrows, Rust needs a lifetime and the struct cannot hold the borrow so you need to bring a
|
||||
// PhantomData<'a ()> inside the structure to keep the lifetime, this is needlessly complicated
|
||||
// when this solution ensures proper monomorphisation at a small complexity cost.
|
||||
pub trait EspPaths<const N: usize> {
|
||||
/// Build an ESP path structure out of the ESP root directory
|
||||
fn new(esp: impl AsRef<Path>) -> Self;
|
||||
/// Return the used file paths to store as garbage collection roots.
|
||||
pub fn to_iter(&self) -> IntoIter<&PathBuf, 10> {
|
||||
[
|
||||
&self.esp,
|
||||
&self.efi,
|
||||
&self.nixos,
|
||||
&self.linux,
|
||||
&self.efi_fallback_dir,
|
||||
&self.efi_fallback,
|
||||
&self.systemd,
|
||||
&self.systemd_boot,
|
||||
&self.loader,
|
||||
&self.systemd_boot_loader_config,
|
||||
]
|
||||
.into_iter()
|
||||
}
|
||||
fn iter(&self) -> std::array::IntoIter<&PathBuf, N>;
|
||||
/// Returns the path containing NixOS EFI binaries
|
||||
fn nixos_path(&self) -> &Path;
|
||||
/// Returns the path containing Linux EFI binaries
|
||||
fn linux_path(&self) -> &Path;
|
||||
}
|
||||
|
||||
/// Paths to the boot files of a specific generation.
|
||||
|
@ -70,21 +34,21 @@ pub struct EspGenerationPaths {
|
|||
}
|
||||
|
||||
impl EspGenerationPaths {
|
||||
pub fn new(esp_paths: &EspPaths, generation: &Generation) -> Result<Self> {
|
||||
pub fn new<const N: usize, P: EspPaths<N>>(esp_paths: &P, generation: &Generation) -> Result<Self> {
|
||||
let bootspec = &generation.spec.bootspec.bootspec;
|
||||
|
||||
Ok(Self {
|
||||
kernel: esp_paths
|
||||
.nixos
|
||||
.nixos_path()
|
||||
.join(nixos_path(&bootspec.kernel, "bzImage")?),
|
||||
initrd: esp_paths.nixos.join(nixos_path(
|
||||
initrd: esp_paths.nixos_path().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)),
|
||||
lanzaboote_image: esp_paths.linux_path().join(generation_path(generation)),
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
pub mod esp;
|
||||
pub mod gc;
|
||||
pub mod generation;
|
||||
pub mod os_release;
|
||||
pub mod pe;
|
||||
pub mod signature;
|
||||
pub mod utils;
|
|
@ -3,7 +3,7 @@ use std::fmt;
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use crate::generation::Generation;
|
||||
use crate::common::generation::Generation;
|
||||
|
||||
/// An os-release file represented by a BTreeMap.
|
||||
///
|
|
@ -8,8 +8,8 @@ use anyhow::{Context, Result};
|
|||
use goblin::pe::PE;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::esp::EspGenerationPaths;
|
||||
use crate::utils::{file_hash, tmpname, SecureTempDirExt};
|
||||
use crate::common::esp::EspGenerationPaths;
|
||||
use crate::common::utils::{file_hash, tmpname, SecureTempDirExt};
|
||||
|
||||
/// Assemble a lanzaboote image.
|
||||
#[allow(clippy::too_many_arguments)]
|
|
@ -1,18 +0,0 @@
|
|||
mod cli;
|
||||
mod esp;
|
||||
mod gc;
|
||||
mod generation;
|
||||
mod install;
|
||||
mod os_release;
|
||||
mod pe;
|
||||
mod signature;
|
||||
mod systemd;
|
||||
mod utils;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use cli::Cli;
|
||||
|
||||
fn main() {
|
||||
Cli::parse().call(module_path!())
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
mod systemd;
|
||||
pub mod common;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
fn main() {
|
||||
systemd::Cli::parse().call(module_path!())
|
||||
}
|
|
@ -3,8 +3,8 @@ use std::path::PathBuf;
|
|||
use anyhow::{Context, Result};
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
use crate::install;
|
||||
use crate::signature::KeyPair;
|
||||
use crate::systemd::install;
|
||||
use crate::common::signature::KeyPair;
|
||||
|
||||
/// The default log level.
|
||||
///
|
|
@ -0,0 +1,67 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::common::esp::EspPaths;
|
||||
|
||||
/// Paths to the boot files that are not specific to a generation.
|
||||
/// Systemd variant
|
||||
pub struct SystemdEspPaths {
|
||||
pub esp: PathBuf,
|
||||
pub efi: PathBuf,
|
||||
pub nixos: PathBuf,
|
||||
pub linux: PathBuf,
|
||||
pub efi_fallback_dir: PathBuf,
|
||||
pub efi_fallback: PathBuf,
|
||||
pub systemd: PathBuf,
|
||||
pub systemd_boot: PathBuf,
|
||||
pub loader: PathBuf,
|
||||
pub systemd_boot_loader_config: PathBuf,
|
||||
}
|
||||
|
||||
impl EspPaths<10> for SystemdEspPaths {
|
||||
fn new(esp: impl AsRef<Path>) -> Self {
|
||||
let esp = esp.as_ref();
|
||||
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");
|
||||
let loader = esp.join("loader");
|
||||
let systemd_boot_loader_config = loader.join("loader.conf");
|
||||
|
||||
Self {
|
||||
esp: esp.to_path_buf(),
|
||||
efi,
|
||||
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"),
|
||||
loader,
|
||||
systemd_boot_loader_config
|
||||
}
|
||||
}
|
||||
|
||||
fn nixos_path(&self) -> &Path {
|
||||
&self.nixos
|
||||
}
|
||||
|
||||
fn linux_path(&self) -> &Path {
|
||||
&self.linux
|
||||
}
|
||||
|
||||
fn iter(&self) -> std::array::IntoIter<&PathBuf, 10> {
|
||||
[
|
||||
&self.esp,
|
||||
&self.efi,
|
||||
&self.nixos,
|
||||
&self.linux,
|
||||
&self.efi_fallback_dir,
|
||||
&self.efi_fallback,
|
||||
&self.systemd,
|
||||
&self.systemd_boot,
|
||||
&self.loader,
|
||||
&self.systemd_boot_loader_config,
|
||||
].into_iter()
|
||||
}
|
||||
}
|
|
@ -10,14 +10,15 @@ use anyhow::{anyhow, Context, Result};
|
|||
use nix::unistd::syncfs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use crate::esp::{EspGenerationPaths, EspPaths};
|
||||
use crate::gc::Roots;
|
||||
use crate::generation::{Generation, GenerationLink};
|
||||
use crate::os_release::OsRelease;
|
||||
use crate::pe;
|
||||
use crate::signature::KeyPair;
|
||||
use crate::systemd::SystemdVersion;
|
||||
use crate::utils::{file_hash, SecureTempDirExt};
|
||||
use crate::common::gc::Roots;
|
||||
use crate::common::generation::{Generation, GenerationLink};
|
||||
use crate::common::os_release::OsRelease;
|
||||
use crate::common::pe;
|
||||
use crate::common::signature::KeyPair;
|
||||
use crate::common::esp::{EspGenerationPaths, EspPaths};
|
||||
use crate::systemd::esp::SystemdEspPaths;
|
||||
use crate::systemd::version::SystemdVersion;
|
||||
use crate::common::utils::{file_hash, SecureTempDirExt};
|
||||
|
||||
pub struct Installer {
|
||||
broken_gens: BTreeSet<u64>,
|
||||
|
@ -27,7 +28,7 @@ pub struct Installer {
|
|||
systemd_boot_loader_config: PathBuf,
|
||||
key_pair: KeyPair,
|
||||
configuration_limit: usize,
|
||||
esp_paths: EspPaths,
|
||||
esp_paths: SystemdEspPaths,
|
||||
generation_links: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
|
@ -42,8 +43,8 @@ impl Installer {
|
|||
generation_links: Vec<PathBuf>,
|
||||
) -> Self {
|
||||
let mut gc_roots = Roots::new();
|
||||
let esp_paths = EspPaths::new(esp);
|
||||
gc_roots.extend(esp_paths.to_iter());
|
||||
let esp_paths = SystemdEspPaths::new(esp);
|
||||
gc_roots.extend(esp_paths.iter());
|
||||
|
||||
Self {
|
||||
broken_gens: BTreeSet::new(),
|
|
@ -0,0 +1,6 @@
|
|||
pub mod version;
|
||||
mod cli;
|
||||
mod esp;
|
||||
mod install;
|
||||
|
||||
pub use cli::Cli;
|
|
@ -5,8 +5,8 @@ use std::str::FromStr;
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
use crate::os_release::OsRelease;
|
||||
use crate::pe;
|
||||
use crate::common::os_release::OsRelease;
|
||||
use crate::common::pe;
|
||||
|
||||
/// A systemd version.
|
||||
///
|
Loading…
Reference in New Issue