Merge pull request #19 from blitz/specialisation

Lanzatool: enable specialisation
This commit is contained in:
nikstur 2022-11-27 18:19:59 +01:00 committed by GitHub
commit e6aa11f76c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 69 additions and 10 deletions

View File

@ -103,11 +103,11 @@
},
"nixpkgs-test": {
"locked": {
"lastModified": 1669288333,
"narHash": "sha256-PMP3JiUBIYu40gmWAIw+DG2UVsx7m5exGaGxdSQE3ew=",
"lastModified": 1669495095,
"narHash": "sha256-wasu8T7ac+LVm4aXuAYkH76Rr98VW0Cp9oZvNPuKiiU=",
"owner": "RaitoBezarius",
"repo": "nixpkgs",
"rev": "308e09c57da1df2abeccc236431a2675a2b38555",
"rev": "8bbe1bb1f7352dd9c2e448e8d68846a66d0c2aca",
"type": "github"
},
"original": {

View File

@ -211,6 +211,30 @@
dst = "convert_to_esp(bootspec.get('kernel'))";
};
};
};
specialisation-works = mkSecureBootTest {
name = "specialisation-still-boot-under-secureboot";
machine = { pkgs, ... }: {
specialisation.variant.configuration = {
environment.systemPackages = [
pkgs.efibootmgr
];
};
};
testScript = ''
machine.start()
print(machine.succeed("ls -lah /boot/EFI/Linux"))
print(machine.succeed("cat /run/current-system/bootspec/boot.v1.json"))
# TODO: make it more reliable to find this filename, i.e. read it from somewhere?
machine.succeed("bootctl set-default nixos-generation-1-specialisation-variant.efi")
machine.succeed("sync")
machine.fail("efibootmgr")
machine.crash()
machine.start()
print(machine.succeed("bootctl"))
# We have efibootmgr in this specialisation.
machine.succeed("efibootmgr")
'';
};
};
};
}

View File

@ -14,6 +14,7 @@
],
"label": "LanzaOS",
"toplevel": "/run/current-system",
"specialisation": {},
"extension": {
"osRelease": "/etc/os-release"
}

View File

@ -1,8 +1,9 @@
use std::collections::HashMap;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Bootspec {
/// Label for the system closure
@ -19,10 +20,12 @@ pub struct Bootspec {
pub initrd_secrets: Option<PathBuf>,
/// config.system.build.toplevel path
pub toplevel: PathBuf,
/// Mapping of specialisation names to their boot.json
pub specialisation: HashMap<String, Bootspec>,
pub extension: Extension,
}
#[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Extension {
pub os_release: PathBuf,

View File

@ -67,5 +67,12 @@ fn nixos_path(path: impl AsRef<Path>, name: &str) -> Result<PathBuf> {
}
fn generation_path(generation: &Generation) -> PathBuf {
PathBuf::from(format!("nixos-generation-{}.efi", generation))
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))
}
}

View File

@ -9,6 +9,7 @@ use crate::bootspec::Bootspec;
#[derive(Debug)]
pub struct Generation {
version: u64,
specialisation_name: Option<String>,
pub bootspec: Bootspec,
}
@ -22,9 +23,22 @@ impl Generation {
Ok(Self {
version: parse_version(toplevel)?,
specialisation_name: None,
bootspec,
})
}
pub fn specialise(&self, name: &str, bootspec: &Bootspec) -> Self {
Self {
version: self.version,
specialisation_name: Some(String::from(name)),
bootspec: bootspec.clone(),
}
}
pub fn is_specialized(&self) -> Option<String> {
self.specialisation_name.clone()
}
}
impl fmt::Display for Generation {

View File

@ -51,18 +51,28 @@ impl Installer {
println!("Installing generation {generation}");
self.install_generation(generation)?
self.install_generation(&generation)
.context("Failed to install generation")?;
for (name, bootspec) in &generation.bootspec.specialisation {
let specialised_generation = generation.specialise(name, bootspec);
println!("Installing specialisation: {name} of generation: {generation}");
self.install_generation(&specialised_generation)
.context("Failed to install specialisation")?;
}
}
Ok(())
}
pub fn install_generation(&self, generation: Generation) -> Result<()> {
fn install_generation(&self, generation: &Generation) -> Result<()> {
println!("Reading bootspec...");
let bootspec = &generation.bootspec;
let esp_paths = EspPaths::new(&self.esp, &generation)?;
let esp_paths = EspPaths::new(&self.esp, generation)?;
println!("Assembling lanzaboote image...");