summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaito Bezarius <masterancpp@gmail.com>2023-03-18 20:42:09 +0100
committerRaito Bezarius <masterancpp@gmail.com>2023-04-21 15:00:32 +0200
commit1aa9dcc14b344fe804fa1bc1606e425b22047d63 (patch)
treee32ad251d62106423a3b8c02ad90e8482cf00000
parentMerge pull request #225294 from gador/kodiPackages.certifi_add_cacert_support (diff)
downloadnixpkgs-origin/bootspecv1.tar.gz
nixos/bootspec: adopt the merged RFC-0125origin/bootspecv1
This removes the feature preview warning, enable by default bootspec, adds a validation flag to prevent Go to go into build-time closure. This will break all downstream users of bootspec as those changes are not backward-compatible.
-rw-r--r--nixos/doc/manual/release-notes/rl-2305.section.md2
-rw-r--r--nixos/modules/system/activation/bootspec.cue27
-rw-r--r--nixos/modules/system/activation/bootspec.nix42
-rw-r--r--nixos/modules/system/activation/top-level.nix3
-rw-r--r--nixos/tests/bootspec.nix12
5 files changed, 48 insertions, 38 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md
index 601109ccee5e..0d880b75563a 100644
--- a/nixos/doc/manual/release-notes/rl-2305.section.md
+++ b/nixos/doc/manual/release-notes/rl-2305.section.md
@@ -28,6 +28,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- `libxcrypt`, the library providing the `crypt(3)` password hashing function, is now built without support for algorithms not flagged [`strong`](https://github.com/besser82/libxcrypt/blob/v4.4.33/lib/hashes.conf#L48). This affects the availability of password hashing algorithms used for system login (`login(1)`, `passwd(1)`), but also Apache2 Basic-Auth, Samba, OpenLDAP, Dovecot, and [many other packages](https://github.com/search?q=repo%3ANixOS%2Fnixpkgs%20libxcrypt&type=code).
+- `boot.bootspec.enable` (internal option) is now enabled by default because [RFC-0125](https://github.com/NixOS/rfcs/pull/125) was merged. This means you will have a bootspec document called `boot.json` generated for each system and specialisation in the top-level. This is useful to enable advanced boot usecases in NixOS such as SecureBoot.
+
## New Services {#sec-release-23.05-new-services}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
diff --git a/nixos/modules/system/activation/bootspec.cue b/nixos/modules/system/activation/bootspec.cue
index 9f857a1b1cd8..1f7b4afa87ac 100644
--- a/nixos/modules/system/activation/bootspec.cue
+++ b/nixos/modules/system/activation/bootspec.cue
@@ -1,4 +1,6 @@
-#V1: {
+import "struct"
+
+#BootspecV1: {
system: string
init: string
initrd?: string
@@ -7,12 +9,23 @@
kernelParams: [...string]
label: string
toplevel: string
- specialisation?: {
- [=~"^"]: #V1
- }
- extensions?: {...}
}
-Document: {
- v1: #V1
+// A restricted document does not allow any official specialisation
+// information in it to avoid "recursive specialisations".
+#RestrictedDocument: struct.MinFields(1) & {
+ "org.nixos.bootspec.v1": #BootspecV1
+ [=~"^"]: #BootspecExtension
+}
+
+// Specialisations are a hashmap of strings
+#BootspecSpecialisationV1: [string]: #RestrictedDocument
+
+// Bootspec extensions are defined by the extension author.
+#BootspecExtension: {...}
+
+// A "full" document allows official specialisation information
+// in the top-level with a reserved namespaced key.
+Document: #RestrictedDocument & {
+ "org.nixos.specialisation.v1"?: #BootspecSpecialisationV1
}
diff --git a/nixos/modules/system/activation/bootspec.nix b/nixos/modules/system/activation/bootspec.nix
index 1055ed1dda90..b35a4a405ac5 100644
--- a/nixos/modules/system/activation/bootspec.nix
+++ b/nixos/modules/system/activation/bootspec.nix
@@ -16,20 +16,20 @@ let
filename = "boot.json";
json =
pkgs.writeText filename
- (builtins.toJSON
+ (builtins.toJSON
+ # Merge extensions first to not let them shadow NixOS bootspec data.
+ (cfg.extensions //
{
- v1 = {
+ "org.nixos.bootspec.v1" = {
system = config.boot.kernelPackages.stdenv.hostPlatform.system;
kernel = "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
kernelParams = config.boot.kernelParams;
label = "${config.system.nixos.distroName} ${config.system.nixos.codeName} ${config.system.nixos.label} (Linux ${config.boot.kernelPackages.kernel.modDirVersion})";
-
- inherit (cfg) extensions;
} // lib.optionalAttrs config.boot.initrd.enable {
initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
initrdSecrets = "${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets";
};
- });
+ }));
generator =
let
@@ -42,8 +42,8 @@ let
toplevelInjector = lib.escapeShellArgs [
"${pkgs.jq}/bin/jq"
''
- .v1.toplevel = $toplevel |
- .v1.init = $init
+ ."org.nixos.bootspec.v1".toplevel = $toplevel |
+ ."org.nixos.bootspec.v1".init = $init
''
"--sort-keys"
"--arg" "toplevel" "${placeholder "out"}"
@@ -62,14 +62,10 @@ let
lib.escapeShellArgs [
"${pkgs.jq}/bin/jq"
"--sort-keys"
- ".v1.specialisation = ($ARGS.named | map_values(. | first | .v1))"
+ ''."org.nixos.specialisation.v1" = ($ARGS.named | map_values(. | first))''
] + " ${lib.concatStringsSep " " specialisationLoader}";
in
- ''
- mkdir -p $out/bootspec
-
- ${toplevelInjector} | ${specialisationInjector} > $out/${filename}
- '';
+ "${toplevelInjector} | ${specialisationInjector} > $out/${filename}";
validator = pkgs.writeCueValidator ./bootspec.cue {
document = "Document"; # Universal validator for any version as long the schema is correctly set.
@@ -79,9 +75,16 @@ let
in
{
options.boot.bootspec = {
- enable = lib.mkEnableOption (lib.mdDoc "Enable generation of RFC-0125 bootspec in $system/bootspec, e.g. /run/current-system/bootspec");
+ enable = lib.mkEnableOption "the generation of RFC-0125 bootspec in $system/boot.json, e.g. /run/current-system/boot.json"
+ // { default = true; internal = true; };
+ enableValidation = lib.mkEnableOption (''the validation of bootspec documents for each build.
+ This will introduce Go in the build-time closure as we are relying on [Cuelang](https://cuelang.org/) for schema validation.
+ Enable this option if you want to ascertain that your documents are correct.
+ ''
+ );
extensions = lib.mkOption {
+ # FIXME(RaitoBezarius): this is not enough to validate: extensions."osRelease" = drv; those are picked up by cue validation.
type = lib.types.attrsOf lib.types.attrs; # <namespace>: { ...namespace-specific fields }
default = { };
description = lib.mdDoc ''
@@ -112,15 +115,4 @@ in
default = schemas.v1.filename;
};
};
-
- config = lib.mkIf (cfg.enable) {
- warnings = [
- ''RFC-0125 is not merged yet, this is a feature preview of bootspec.
- The schema is not definitive and features are not guaranteed to be stable until RFC-0125 is merged.
- See:
- - https://github.com/NixOS/nixpkgs/pull/172237 to track merge status in nixpkgs.
- - https://github.com/NixOS/rfcs/pull/125 to track RFC status.
- ''
- ];
- };
}
diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix
index 74ab7070fd0f..f2e741354782 100644
--- a/nixos/modules/system/activation/top-level.nix
+++ b/nixos/modules/system/activation/top-level.nix
@@ -82,7 +82,8 @@ let
${optionalString (!config.boot.isContainer && config.boot.bootspec.enable) ''
${config.boot.bootspec.writer}
- ${config.boot.bootspec.validator} "$out/${config.boot.bootspec.filename}"
+ ${optionalString config.boot.bootspec.enableValidation
+ ''${config.boot.bootspec.validator} "$out/${config.boot.bootspec.filename}"''}
''}
${config.system.extraSystemBuilderCmds}
diff --git a/nixos/tests/bootspec.nix b/nixos/tests/bootspec.nix
index f388a15ffa2d..45215321930d 100644
--- a/nixos/tests/bootspec.nix
+++ b/nixos/tests/bootspec.nix
@@ -110,7 +110,7 @@ in
machine.succeed("test -e /run/current-system/boot.json")
- bootspec = json.loads(machine.succeed("jq -r '.v1' /run/current-system/boot.json"))
+ bootspec = json.loads(machine.succeed("jq -r '.\"org.nixos.bootspec.v1\"' /run/current-system/boot.json"))
assert all(key in bootspec for key in ('initrd', 'initrdSecrets')), "Bootspec should contain initrd or initrdSecrets field when initrd is enabled"
'';
@@ -136,10 +136,10 @@ in
machine.succeed("test -e /run/current-system/boot.json")
machine.succeed("test -e /run/current-system/specialisation/something/boot.json")
- sp_in_parent = json.loads(machine.succeed("jq -r '.v1.specialisation.something' /run/current-system/boot.json"))
+ sp_in_parent = json.loads(machine.succeed("jq -r '.\"org.nixos.specialisation.v1\".something' /run/current-system/boot.json"))
sp_in_fs = json.loads(machine.succeed("cat /run/current-system/specialisation/something/boot.json"))
- assert sp_in_parent == sp_in_fs['v1'], "Bootspecs of the same specialisation are different!"
+ assert sp_in_parent == sp_in_fs['org.nixos.bootspec.v1'], "Bootspecs of the same specialisation are different!"
'';
};
@@ -152,7 +152,9 @@ in
imports = [ standard ];
environment.systemPackages = [ pkgs.jq ];
boot.bootspec.extensions = {
- osRelease = config.environment.etc."os-release".source;
+ "org.nix-tests.product" = {
+ osRelease = config.environment.etc."os-release".source;
+ };
};
};
@@ -161,7 +163,7 @@ in
machine.wait_for_unit("multi-user.target")
current_os_release = machine.succeed("cat /etc/os-release")
- bootspec_os_release = machine.succeed("cat $(jq -r '.v1.extensions.osRelease' /run/current-system/boot.json)")
+ bootspec_os_release = machine.succeed("cat $(jq -r '.\"org.nix-tests.product\".osRelease' /run/current-system/boot.json)")
assert current_os_release == bootspec_os_release, "Filename referenced by extension has unexpected contents"
'';