about summary refs log tree commit diff
path: root/nixos/modules/system
diff options
context:
space:
mode:
authorCole Helbling <cole.e.helbling@outlook.com>2022-12-02 13:19:35 -0800
committerCole Helbling <cole.e.helbling@outlook.com>2022-12-08 13:50:05 -0800
commitdce9add02b24d8ee02a2afb79ce972a9ebc0aaa3 (patch)
tree5048f9da0366c3a35accd7267cc497625f0f6b3f /nixos/modules/system
parent38e50898148a137bfbd97ed9acf52b87af37f19e (diff)
nixos/activation/bootspec: refactor the generator script
We separate the different steps (injecting the toplevel and injecting
the specialisations) so that it's easy to document what each snippet is
actually doing.
Diffstat (limited to 'nixos/modules/system')
-rw-r--r--nixos/modules/system/activation/bootspec.nix51
1 files changed, 32 insertions, 19 deletions
diff --git a/nixos/modules/system/activation/bootspec.nix b/nixos/modules/system/activation/bootspec.nix
index 59b9f47339653..99cc6f5374977 100644
--- a/nixos/modules/system/activation/bootspec.nix
+++ b/nixos/modules/system/activation/bootspec.nix
@@ -31,29 +31,42 @@ let
 
       generator =
         let
-          specialisationLoader = (lib.mapAttrsToList
-            (childName: childToplevel: lib.escapeShellArgs [ "--slurpfile" childName "${childToplevel}/bootspec/${filename}" ])
-            children);
+          # NOTE: Be careful to not introduce excess newlines at the end of the
+          # injectors, as that may affect the pipes and redirects.
+
+          # Inject toplevel and init into the bootspec.
+          # This can only be done here because we *cannot* depend on $out
+          # referring to the toplevel, except by living in the toplevel itself.
+          toplevelInjector = lib.escapeShellArgs [
+            "${pkgs.jq}/bin/jq"
+            ''
+              .v1.toplevel = $toplevel |
+              .v1.init = $init
+            ''
+            "--sort-keys"
+            "--arg" "toplevel" "$out"
+            "--arg" "init" "$out/init"
+          ] + " < ${json}";
+
+          # We slurp all specialisations and inject them as values, such that
+          # `.specialisations.${name}` embeds the specialisation's bootspec
+          # document.
+          specialisationInjector =
+            let
+              specialisationLoader = (lib.mapAttrsToList
+                (childName: childToplevel: lib.escapeShellArgs [ "--slurpfile" childName "${childToplevel}/bootspec/${filename}" ])
+                children);
+            in
+            lib.escapeShellArgs [
+              "${pkgs.jq}/bin/jq"
+              "--sort-keys"
+              ".v1.specialisation = ($ARGS.named | map_values(. | first | .v1))"
+            ] + " ${lib.concatStringsSep " " specialisationLoader}";
         in
         ''
           mkdir -p $out/bootspec
 
-          # Inject toplevel and init in the bootspec.
-          # This can be done only here because we *cannot* depend on $out, except
-          # by living in $out itself.
-          ${pkgs.jq}/bin/jq '
-            .v1.toplevel = $toplevel |
-            .v1.init = $init
-            ' \
-            --sort-keys \
-            --arg toplevel "$out" \
-            --arg init "$out/init" \
-            < ${json} \
-            | ${pkgs.jq}/bin/jq \
-              --sort-keys \
-              '.v1.specialisation = ($ARGS.named | map_values(. | first | .v1))' \
-              ${lib.concatStringsSep " " specialisationLoader} \
-            > $out/bootspec/${filename}
+          ${toplevelInjector} | ${specialisationInjector} > $out/bootspec/${filename}
         '';
 
       validator = pkgs.writeCueValidator ./bootspec.cue {