From 5dd2e60371cc749dbccd44719df9a8c18a29d346 Mon Sep 17 00:00:00 2001
From: Raito Bezarius <masterancpp@gmail.com>
Date: Wed, 21 Dec 2022 23:28:21 +0100
Subject: [PATCH] nixos/activation/bootspec: make initrd optional, serialize
 system, precise extensions' type

---
 nixos/modules/system/activation/bootspec.cue |  1 +
 nixos/modules/system/activation/bootspec.nix |  8 +++---
 nixos/tests/bootspec.nix                     | 26 ++++++++++++++++++++
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/nixos/modules/system/activation/bootspec.cue b/nixos/modules/system/activation/bootspec.cue
index 3fc9ca381df7..9f857a1b1cd8 100644
--- a/nixos/modules/system/activation/bootspec.cue
+++ b/nixos/modules/system/activation/bootspec.cue
@@ -1,4 +1,5 @@
 #V1: {
+	system:         string
 	init:           string
 	initrd?:        string
 	initrdSecrets?: string
diff --git a/nixos/modules/system/activation/bootspec.nix b/nixos/modules/system/activation/bootspec.nix
index da76bf9084af..4255730250af 100644
--- a/nixos/modules/system/activation/bootspec.nix
+++ b/nixos/modules/system/activation/bootspec.nix
@@ -19,13 +19,15 @@ let
           (builtins.toJSON
           {
             v1 = {
+              system = config.boot.kernelPackages.stdenv.hostPlatform.system;
               kernel = "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
               kernelParams = config.boot.kernelParams;
-              initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
-              initrdSecrets = "${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets";
               label = "NixOS ${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";
             };
           });
 
@@ -80,7 +82,7 @@ in
     enable = lib.mkEnableOption (lib.mdDoc "Enable generation of RFC-0125 bootspec in $system/bootspec, e.g. /run/current-system/bootspec");
 
     extensions = lib.mkOption {
-      type = lib.types.attrs;
+      type = lib.types.attrsOf lib.types.attrs; # <namespace>: { ...namespace-specific fields }
       default = { };
       description = lib.mdDoc ''
         User-defined data that extends the bootspec document.
diff --git a/nixos/tests/bootspec.nix b/nixos/tests/bootspec.nix
index 13360bb1eaa2..8616cfdd937c 100644
--- a/nixos/tests/bootspec.nix
+++ b/nixos/tests/bootspec.nix
@@ -90,6 +90,32 @@ in
     '';
   };
 
+  # Check that initrd create corresponding entries in bootspec.
+  initrd = makeTest {
+    name = "bootspec-with-initrd";
+    meta.maintainers = with pkgs.lib.maintainers; [ raitobezarius ];
+
+    nodes.machine = {
+      imports = [ standard ];
+      environment.systemPackages = [ pkgs.jq ];
+      # It's probably the case, but we want to make it explicit here.
+      boot.initrd.enable = true;
+    };
+
+    testScript = ''
+      import json
+
+      machine.start()
+      machine.wait_for_unit("multi-user.target")
+
+      machine.succeed("test -e /run/current-system/bootspec/boot.json")
+
+      bootspec = json.loads(machine.succeed("jq -r '.v1' /run/current-system/bootspec/boot.json"))
+
+      assert all(key in bootspec for key in ('initrd', 'initrdSecrets')), "Bootspec should contain initrd or initrdSecrets field when initrd is enabled"
+    '';
+  };
+
   # Check that specialisations create corresponding entries in bootspec.
   specialisation = makeTest {
     name = "bootspec-with-specialisation";