Skip to content

Commit

Permalink
feat: enable synthesis support
Browse files Browse the repository at this point in the history
Bootspec has a mechanism called synthesis where you can synthesize
bootspecs if they are not present based on the generation link only.

This is useful for "vanilla bootspec" which does not contain any
extensions, as this is what we do right now.

If we need extensions, we can also implement our synthesis mechanism on
the top of it.

Enabling synthesis gives us the superpower to support non-bootspec
users. :-)
  • Loading branch information
RaitoBezarius committed Apr 24, 2023
1 parent 9e6ea4f commit cc592b2
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
11 changes: 11 additions & 0 deletions nix/tests/lanzaboote.nix
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,17 @@ in
'';
};

synthesis-works = mkSecureBootTest {
name = "synthesis-enable-a-bootspec-without-bootspec";
machine = { pkgs, ... }: {
boot.bootspec.enable = lib.mkForce false;
};
testScript = ''
machine.start()
print(machine.succeed("bootctl"))
'';
};

systemd-boot-loader-config = mkSecureBootTest {
name = "lanzaboote-systemd-boot-loader-config";
machine = {
Expand Down
26 changes: 22 additions & 4 deletions rust/tool/src/generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,28 @@ pub struct Generation {
impl Generation {
pub fn from_link(link: &GenerationLink) -> Result<Self> {
let bootspec_path = link.path.join("boot.json");
let generation: BootspecGeneration = serde_json::from_slice(
&fs::read(bootspec_path).context("Failed to read bootspec file")?,
)
.context("Failed to parse bootspec json")?;
let generation: BootspecGeneration;

if let Ok(bootspec_data) = fs::read(bootspec_path) {
generation = serde_json::from_slice(&bootspec_data)
.context("Failed to parse bootspec JSON")
// TODO: this should be much easier, add a From<GenerationVX> for BootspecGeneration
// this should enable us to do `into()` on the Result
// anyhow compatibility of bootspec would be nice too.
.or_else(|_err| Ok::<_, anyhow::Error>(
BootspecGeneration::V1(
BootJson::synthesize(&link.path)
.map_err(|err| anyhow!(err))
.context("Missing bootspec, failed to synthesize a valid replacement bootspec.")?
)
))?;
} else {
generation = BootspecGeneration::V1(BootJson::synthesize(&link.path)
.map_err(|err| anyhow!(err))
.context("Malformed bootspec, failed to synthesize a valid replacement bootspec.")?
);
}


let bootspec: BootJson = generation
.try_into()
Expand Down

0 comments on commit cc592b2

Please # to comment.