nixos/activation/bootspec: module-ify
This does the following: * turns bootspec into a NixOS module * validates bootspecs with Cue * exposes internal knobs
This commit is contained in:
parent
9a431a57b1
commit
348ba1b33c
|
@ -1241,6 +1241,7 @@
|
||||||
./services/x11/xserver.nix
|
./services/x11/xserver.nix
|
||||||
./system/activation/activation-script.nix
|
./system/activation/activation-script.nix
|
||||||
./system/activation/specialisation.nix
|
./system/activation/specialisation.nix
|
||||||
|
./system/activation/bootspec.nix
|
||||||
./system/activation/top-level.nix
|
./system/activation/top-level.nix
|
||||||
./system/boot/binfmt.nix
|
./system/boot/binfmt.nix
|
||||||
./system/boot/emergency-mode.nix
|
./system/boot/emergency-mode.nix
|
||||||
|
|
23
nixos/modules/system/activation/bootspec.cue
Normal file
23
nixos/modules/system/activation/bootspec.cue
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#V1: {
|
||||||
|
init: string
|
||||||
|
initrd?: string
|
||||||
|
initrdSecrets?: string
|
||||||
|
kernel: string
|
||||||
|
kernelParams: [...string]
|
||||||
|
label: string
|
||||||
|
toplevel: string
|
||||||
|
specialisation?: {
|
||||||
|
[=~"^"]: #V1
|
||||||
|
}
|
||||||
|
extensions?: {...}
|
||||||
|
}
|
||||||
|
|
||||||
|
#SecureBootExtensions: #V1 & {
|
||||||
|
extensions: {
|
||||||
|
osRelease: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Document: {
|
||||||
|
v1: #V1
|
||||||
|
}
|
|
@ -3,23 +3,31 @@
|
||||||
# Changes to the structure of the document, or the semantics of the values should go through an RFC.
|
# Changes to the structure of the document, or the semantics of the values should go through an RFC.
|
||||||
#
|
#
|
||||||
# See: https://github.com/NixOS/rfcs/pull/125
|
# See: https://github.com/NixOS/rfcs/pull/125
|
||||||
{ config, pkgs, lib, children }:
|
{ config
|
||||||
|
, pkgs
|
||||||
|
, lib
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
|
cfg = config.boot.bootspec;
|
||||||
|
children = lib.mapAttrs (childName: childConfig: childConfig.configuration.system.build.toplevel) config.specialisation;
|
||||||
schemas = {
|
schemas = {
|
||||||
v1 = rec {
|
v1 = rec {
|
||||||
filename = "boot.v1.json";
|
filename = "boot.json";
|
||||||
json =
|
json =
|
||||||
pkgs.writeText filename
|
pkgs.writeText filename
|
||||||
(builtins.toJSON
|
(builtins.toJSON
|
||||||
{
|
{
|
||||||
schemaVersion = 1;
|
v1 = {
|
||||||
|
|
||||||
kernel = "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
|
kernel = "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
|
||||||
kernelParams = config.boot.kernelParams;
|
kernelParams = config.boot.kernelParams;
|
||||||
initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
|
initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
|
||||||
initrdSecrets = "${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets";
|
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})";
|
label = "NixOS ${config.system.nixos.codeName} ${config.system.nixos.label} (Linux ${config.boot.kernelPackages.kernel.modDirVersion})";
|
||||||
});
|
|
||||||
|
inherit (cfg) extensions;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
generator =
|
generator =
|
||||||
let
|
let
|
||||||
|
@ -31,8 +39,8 @@ let
|
||||||
mkdir -p $out/bootspec
|
mkdir -p $out/bootspec
|
||||||
|
|
||||||
${pkgs.jq}/bin/jq '
|
${pkgs.jq}/bin/jq '
|
||||||
.toplevel = $toplevel |
|
.v1.toplevel = $toplevel |
|
||||||
.init = $init
|
.v1.init = $init
|
||||||
' \
|
' \
|
||||||
--sort-keys \
|
--sort-keys \
|
||||||
--arg toplevel "$out" \
|
--arg toplevel "$out" \
|
||||||
|
@ -40,17 +48,50 @@ let
|
||||||
< ${json} \
|
< ${json} \
|
||||||
| ${pkgs.jq}/bin/jq \
|
| ${pkgs.jq}/bin/jq \
|
||||||
--sort-keys \
|
--sort-keys \
|
||||||
'.specialisation = ($ARGS.named | map_values(. | first))' \
|
'.v1.specialisation = ($ARGS.named | map_values(. | first | .v1))' \
|
||||||
${lib.concatStringsSep " " specialisationLoader} \
|
${lib.concatStringsSep " " specialisationLoader} \
|
||||||
> $out/bootspec/${filename}
|
> $out/bootspec/${filename}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
validator = pkgs.writeCueValidator ./bootspec.cue {
|
||||||
|
document = "Document"; # Universal validator for any version as long the schema is correctly set.
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# This will be run as a part of the `systemBuilder` in ./top-level.nix. This
|
options.boot.bootspec = {
|
||||||
# means `$out` points to the output of `config.system.build.toplevel` and can
|
enable = lib.mkEnableOption "Enable generation of RFC-0125 bootspec in $system/bootspec, e.g. /run/current-system/bootspec";
|
||||||
# be used for a variety of things (though, for now, it's only used to report
|
extensions = lib.mkOption {
|
||||||
# the path of the `toplevel` itself and the `init` executable).
|
type = lib.types.attrs;
|
||||||
writer = schemas.v1.generator;
|
default = {};
|
||||||
|
};
|
||||||
|
# This will be run as a part of the `systemBuilder` in ./top-level.nix. This
|
||||||
|
# means `$out` points to the output of `config.system.build.toplevel` and can
|
||||||
|
# be used for a variety of things (though, for now, it's only used to report
|
||||||
|
# the path of the `toplevel` itself and the `init` executable).
|
||||||
|
writer = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
default = schemas.v1.generator;
|
||||||
|
};
|
||||||
|
validator = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
default = schemas.v1.validator;
|
||||||
|
};
|
||||||
|
filename = lib.mkOption {
|
||||||
|
internal = true;
|
||||||
|
default = schemas.v1.filename;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf (cfg.enable) {
|
||||||
|
warnings = [
|
||||||
|
''RFC-0125 is not merged yet, this is a feature preview of bootspec.
|
||||||
|
Schema is not definitive and features are not stabilized 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.
|
||||||
|
''
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,14 +9,6 @@ let
|
||||||
"${config.system.boot.loader.kernelFile}";
|
"${config.system.boot.loader.kernelFile}";
|
||||||
initrdPath = "${config.system.build.initialRamdisk}/" +
|
initrdPath = "${config.system.build.initialRamdisk}/" +
|
||||||
"${config.system.boot.loader.initrdFile}";
|
"${config.system.boot.loader.initrdFile}";
|
||||||
|
|
||||||
bootSpec = import ./bootspec.nix {
|
|
||||||
inherit
|
|
||||||
config
|
|
||||||
pkgs
|
|
||||||
lib
|
|
||||||
children;
|
|
||||||
};
|
|
||||||
in ''
|
in ''
|
||||||
mkdir $out
|
mkdir $out
|
||||||
|
|
||||||
|
@ -88,7 +80,8 @@ let
|
||||||
echo -n "${toString config.system.extraDependencies}" > $out/extra-dependencies
|
echo -n "${toString config.system.extraDependencies}" > $out/extra-dependencies
|
||||||
|
|
||||||
${optionalString (!config.boot.isContainer) ''
|
${optionalString (!config.boot.isContainer) ''
|
||||||
${bootSpec.writer}
|
${config.boot.bootspec.writer}
|
||||||
|
${config.boot.bootspec.validator} "$out/bootspec/${config.boot.bootspec.filename}"
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${config.system.extraSystemBuilderCmds}
|
${config.system.extraSystemBuilderCmds}
|
||||||
|
|
Loading…
Reference in a new issue