···2829- `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).
300031## New Services {#sec-release-23.05-new-services}
3233<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
···2829- `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).
3031+- `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.
32+33## New Services {#sec-release-23.05-new-services}
3435<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
···1+import "struct"
2+3+#BootspecV1: {
4 system: string
5 init: string
6 initrd?: string
···9 kernelParams: [...string]
10 label: string
11 toplevel: string
12+}
13+14+// A restricted document does not allow any official specialisation
15+// information in it to avoid "recursive specialisations".
16+#RestrictedDocument: struct.MinFields(1) & {
17+ "org.nixos.bootspec.v1": #BootspecV1
18+ [=~"^"]: #BootspecExtension
19}
2021+// Specialisations are a hashmap of strings
22+#BootspecSpecialisationV1: [string]: #RestrictedDocument
23+24+// Bootspec extensions are defined by the extension author.
25+#BootspecExtension: {...}
26+27+// A "full" document allows official specialisation information
28+// in the top-level with a reserved namespaced key.
29+Document: #RestrictedDocument & {
30+ "org.nixos.specialisation.v1"?: #BootspecSpecialisationV1
31}
+18-26
nixos/modules/system/activation/bootspec.nix
···16 filename = "boot.json";
17 json =
18 pkgs.writeText filename
19- (builtins.toJSON
0020 {
21- v1 = {
22 system = config.boot.kernelPackages.stdenv.hostPlatform.system;
23 kernel = "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
24 kernelParams = config.boot.kernelParams;
25 label = "${config.system.nixos.distroName} ${config.system.nixos.codeName} ${config.system.nixos.label} (Linux ${config.boot.kernelPackages.kernel.modDirVersion})";
26-27- inherit (cfg) extensions;
28 } // lib.optionalAttrs config.boot.initrd.enable {
29 initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
30 initrdSecrets = "${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets";
31 };
32- });
3334 generator =
35 let
···42 toplevelInjector = lib.escapeShellArgs [
43 "${pkgs.jq}/bin/jq"
44 ''
45- .v1.toplevel = $toplevel |
46- .v1.init = $init
47 ''
48 "--sort-keys"
49 "--arg" "toplevel" "${placeholder "out"}"
···62 lib.escapeShellArgs [
63 "${pkgs.jq}/bin/jq"
64 "--sort-keys"
65- ".v1.specialisation = ($ARGS.named | map_values(. | first | .v1))"
66 ] + " ${lib.concatStringsSep " " specialisationLoader}";
67 in
68- ''
69- mkdir -p $out/bootspec
70-71- ${toplevelInjector} | ${specialisationInjector} > $out/${filename}
72- '';
7374 validator = pkgs.writeCueValidator ./bootspec.cue {
75 document = "Document"; # Universal validator for any version as long the schema is correctly set.
···79in
80{
81 options.boot.bootspec = {
82- enable = lib.mkEnableOption (lib.mdDoc "Enable generation of RFC-0125 bootspec in $system/bootspec, e.g. /run/current-system/bootspec");
0000008384 extensions = lib.mkOption {
85- type = lib.types.attrsOf lib.types.attrs; # <namespace>: { ...namespace-specific fields }
086 default = { };
87 description = lib.mdDoc ''
88 User-defined data that extends the bootspec document.
···111 internal = true;
112 default = schemas.v1.filename;
113 };
114- };
115-116- config = lib.mkIf (cfg.enable) {
117- warnings = [
118- ''RFC-0125 is not merged yet, this is a feature preview of bootspec.
119- The schema is not definitive and features are not guaranteed to be stable until RFC-0125 is merged.
120- See:
121- - https://github.com/NixOS/nixpkgs/pull/172237 to track merge status in nixpkgs.
122- - https://github.com/NixOS/rfcs/pull/125 to track RFC status.
123- ''
124- ];
125 };
126}
···16 filename = "boot.json";
17 json =
18 pkgs.writeText filename
19+ (builtins.toJSON
20+ # Merge extensions first to not let them shadow NixOS bootspec data.
21+ (cfg.extensions //
22 {
23+ "org.nixos.bootspec.v1" = {
24 system = config.boot.kernelPackages.stdenv.hostPlatform.system;
25 kernel = "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
26 kernelParams = config.boot.kernelParams;
27 label = "${config.system.nixos.distroName} ${config.system.nixos.codeName} ${config.system.nixos.label} (Linux ${config.boot.kernelPackages.kernel.modDirVersion})";
0028 } // lib.optionalAttrs config.boot.initrd.enable {
29 initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
30 initrdSecrets = "${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets";
31 };
32+ }));
3334 generator =
35 let
···42 toplevelInjector = lib.escapeShellArgs [
43 "${pkgs.jq}/bin/jq"
44 ''
45+ ."org.nixos.bootspec.v1".toplevel = $toplevel |
46+ ."org.nixos.bootspec.v1".init = $init
47 ''
48 "--sort-keys"
49 "--arg" "toplevel" "${placeholder "out"}"
···62 lib.escapeShellArgs [
63 "${pkgs.jq}/bin/jq"
64 "--sort-keys"
65+ ''."org.nixos.specialisation.v1" = ($ARGS.named | map_values(. | first))''
66 ] + " ${lib.concatStringsSep " " specialisationLoader}";
67 in
68+ "${toplevelInjector} | ${specialisationInjector} > $out/${filename}";
00006970 validator = pkgs.writeCueValidator ./bootspec.cue {
71 document = "Document"; # Universal validator for any version as long the schema is correctly set.
···75in
76{
77 options.boot.bootspec = {
78+ enable = lib.mkEnableOption (lib.mdDoc "the generation of RFC-0125 bootspec in $system/boot.json, e.g. /run/current-system/boot.json")
79+ // { default = true; internal = true; };
80+ enableValidation = lib.mkEnableOption (lib.mdDoc ''the validation of bootspec documents for each build.
81+ This will introduce Go in the build-time closure as we are relying on [Cuelang](https://cuelang.org/) for schema validation.
82+ Enable this option if you want to ascertain that your documents are correct.
83+ ''
84+ );
8586 extensions = lib.mkOption {
87+ # NOTE(RaitoBezarius): this is not enough to validate: extensions."osRelease" = drv; those are picked up by cue validation.
88+ type = lib.types.attrsOf lib.types.anything; # <namespace>: { ...namespace-specific fields }
89 default = { };
90 description = lib.mdDoc ''
91 User-defined data that extends the bootspec document.
···114 internal = true;
115 default = schemas.v1.filename;
116 };
00000000000117 };
118}