Skip to content

Commit

Permalink
Merge pull request #2 from DeterminateSystems/rfc-embed-subs
Browse files Browse the repository at this point in the history
RFC updates: unify the specialisation documents into the root doc
  • Loading branch information
grahamc authored May 18, 2022
2 parents 95b5890 + e2f4992 commit d2ae15a
Show file tree
Hide file tree
Showing 21 changed files with 47 additions and 90 deletions.
11 changes: 0 additions & 11 deletions bootspec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@ pub struct SpecialisationName(pub String);
/// A wrapper type describing the root directory of a NixOS system configuration.
pub struct SystemConfigurationRoot(pub PathBuf);

#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
/// A wrapper type describing the path to the bootspec schema file.
pub struct BootSpecPath(pub PathBuf);

#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
/// Provides the information necessary to consume a specialisation with or without a bootspec.
pub struct SpecialisationDescription {
/// The optional path to the specialisation's bootspec.
pub bootspec: BootSpecPath,
}

// !!! IMPORTANT: KEEP `BootJson`, `SCHEMA_VERSION`, and `JSON_FILENAME` IN SYNC !!!
/// The current bootspec schema.
pub type BootJson = v1::BootJsonV1;
Expand Down
4 changes: 2 additions & 2 deletions bootspec/src/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::path::PathBuf;

use serde::{Deserialize, Serialize};

use crate::{SpecialisationDescription, SpecialisationName, SystemConfigurationRoot};
use crate::{SpecialisationName, SystemConfigurationRoot};

/// The V1 bootspec schema version.
pub const SCHEMA_VERSION: u32 = 1;
Expand All @@ -29,7 +29,7 @@ pub struct BootJsonV1 {
/// Path to "append-initrd-secrets" script -- $toplevel/append-initrd-secrets
pub initrd_secrets: Option<PathBuf>,
/// Mapping of specialisation names to their boot.json
pub specialisation: HashMap<SpecialisationName, SpecialisationDescription>,
pub specialisation: HashMap<SpecialisationName, BootJsonV1>,
/// config.system.build.toplevel path
pub toplevel: SystemConfigurationRoot,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"schemaVersion": 1,
"label": "NixOS 21.11pre-git (Linux 5.10.81)",
"kernel": "/nix/store/hprwry55jwyd71ng7v7c2rhk3a3z1im8-linux-5.10.81/bzImage",
"kernelParams": [
"loglevel=4",
"net.ifnames=0"
],
"init": "/nix/store/kgkjwhscv52r2y1ha1y19lb9h4j3lfrc-nixos-system-nixos-21.11pre-git/init",
"initrd": "/nix/store/69bhfdfv77y0vclnlxqrd8pxjzbkz47w-initrd-linux-5.10.81/initrd",
"initrdSecrets": "/nix/store/kgkjwhscv52r2y1ha1y19lb9h4j3lfrc-nixos-system-nixos-21.11pre-git/append-initrd-secrets",
"specialisation": {
"example": {
"schemaVersion": 1,
"label": "NixOS 21.11pre-git (Linux 5.10.81)",
"kernel": "/nix/store/hprwry55jwyd71ng7v7c2rhk3a3z1im8-linux-5.10.81/bzImage",
"kernelParams": [
"loglevel=4",
"net.ifnames=0"
],
"init": "/nix/store/3w5kr91xq46638fd310q2sa9mjm6r6hn-nixos-system-nixos-21.11pre-git/init",
"initrd": "/nix/store/69bhfdfv77y0vclnlxqrd8pxjzbkz47w-initrd-linux-5.10.81/initrd",
"initrdSecrets": "/nix/store/3w5kr91xq46638fd310q2sa9mjm6r6hn-nixos-system-nixos-21.11pre-git/append-initrd-secrets",
"specialisation": {},
"toplevel": "/nix/store/3w5kr91xq46638fd310q2sa9mjm6r6hn-nixos-system-nixos-21.11pre-git"
}
},
"toplevel": "/nix/store/kgkjwhscv52r2y1ha1y19lb9h4j3lfrc-nixos-system-nixos-21.11pre-git"
}

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion synthesize/integration-test-cases/verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ done) | xargs --max-procs=$(nproc) --max-lines=1 nix-build
rm -rf generated-synthesis
mkdir generated-synthesis
for out in ./builds/*; do
cargo run --bin synthesize -- "$out" "./generated-synthesis/$(basename "$out")"
cargo run --bin synthesize -- "$out" "./generated-synthesis/$(basename "$out").json"
done

diff -r ./expected-synthesis ./generated-synthesis
50 changes: 7 additions & 43 deletions synthesize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,16 @@ use std::error::Error;
use std::fs;
use std::path::Path;

use bootspec::{
BootJson, BootSpecPath, SpecialisationDescription, SpecialisationName, SystemConfigurationRoot,
JSON_FILENAME, SCHEMA_VERSION,
};
use bootspec::{BootJson, SpecialisationName, SystemConfigurationRoot, SCHEMA_VERSION};

#[doc(hidden)]
pub type Result<T, E = Box<dyn Error + Send + Sync + 'static>> = core::result::Result<T, E>;

/// Synthesize a [`BootJson`] struct from the path to a generation.
///
/// This is useful when used on generations that do not have a bootspec attached to it.
pub fn synthesize_schema_from_generation(generation: &Path, out_path: &Path) -> Result<()> {
fs::create_dir(&out_path)?;
let specialisationdir = out_path.join("specialisation");
let mut specialisationdir_created = false;

let mut toplevelspec = describe_system(&generation)?;
pub fn synthesize_schema_from_generation(generation: &Path) -> Result<BootJson> {
let mut toplevelspec = describe_system(generation)?;

if let Ok(specialisations) = fs::read_dir(generation.join("specialisation")) {
for spec in specialisations.map(|res| res.map(|e| e.path())) {
Expand All @@ -29,45 +22,16 @@ pub fn synthesize_schema_from_generation(generation: &Path, out_path: &Path) ->
.ok_or("Could not get name of specialisation dir")?
.to_str()
.ok_or("Specialisation dir name was invalid UTF8")?;
let toplevel = fs::canonicalize(generation.join(format!("specialisation/{}", name)))?;

let boot_json_path = toplevel.join(JSON_FILENAME);
let boot_json_path = match boot_json_path.exists() {
true => boot_json_path,
false => {
if !specialisationdir_created {
fs::create_dir(&specialisationdir)?;
specialisationdir_created = true;
}

let specname = specialisationdir.join(format!("{name}.json"));
let subspec = describe_system(&toplevel)?;
let pretty = serde_json::to_string_pretty(&subspec)
.map_err(|e| format!("Failed to make pretty JSON from bootspec:\n{e}"))?;

fs::write(&specname, pretty).map_err(|e| {
format!("Failed to write JSON to '{}':\n{e}", out_path.display())
})?;

specname
}
};
let toplevel = fs::canonicalize(generation.join("specialisation").join(name))?;

toplevelspec.specialisation.insert(
SpecialisationName(name.to_string()),
SpecialisationDescription {
bootspec: BootSpecPath(boot_json_path),
},
describe_system(&toplevel)?,
);
}
}

let pretty = serde_json::to_string_pretty(&toplevelspec)
.map_err(|e| format!("Failed to make pretty JSON from bootspec:\n{}", e))?;

fs::write(&out_path.join("boot.v1.json"), pretty)
.map_err(|e| format!("Failed to write JSON to '{}':\n{}", out_path.display(), e))?;

Ok(())
Ok(toplevelspec)
}

fn describe_system(generation: &Path) -> Result<BootJson> {
Expand Down
9 changes: 8 additions & 1 deletion synthesize/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;

Expand Down Expand Up @@ -34,13 +35,19 @@ fn cli() -> Result<()> {
.ok_or("Expected output path, got none.")?
.parse::<PathBuf>()?;

synthesize::synthesize_schema_from_generation(&generation_dir, &out_path).map_err(|e| {
let spec = synthesize::synthesize_schema_from_generation(&generation_dir).map_err(|e| {
format!(
"Failed to synthesize bootspec for {}:\n{}",
generation_dir.display(),
e
)
})?;

let pretty = serde_json::to_string_pretty(&spec)
.map_err(|e| format!("Failed to make pretty JSON from bootspec:\n{}", e))?;

fs::write(&out_path, pretty)
.map_err(|e| format!("Failed to write JSON to '{}':\n{}", out_path.display(), e))?;

Ok(())
}

0 comments on commit d2ae15a

Please sign in to comment.