git.delta.rocks / jrsonnet / refs/commits / 6fa49bc8c59c

difftreelog

fix baseModules arg

ntqvslxqYaroslav Bolyukin2026-02-03parent: #d0ea8ea.patch.diff
in: trunk

5 files changed

modifiedcrates/nix-eval/Cargo.tomldiffbeforeafterboth
--- a/crates/nix-eval/Cargo.toml
+++ b/crates/nix-eval/Cargo.toml
@@ -16,9 +16,9 @@
 cxx = "1.0.168"
 itertools = "0.14.0"
 test-log = { version = "0.2.18", features = ["trace"] }
+tokio.workspace = true
 tracing-indicatif = { version = "0.3.13", optional = true }
 vte = { version = "0.15.0", features = ["ansi"] }
-tokio.workspace = true
 
 [build-dependencies]
 bindgen = "0.72.0"
modifiedcrates/nix-eval/src/lib.rsdiffbeforeafterboth
--- a/crates/nix-eval/src/lib.rs
+++ b/crates/nix-eval/src/lib.rs
@@ -307,9 +307,8 @@
 	}
 }
 
-static GLOBAL_STATE: LazyLock<GlobalState> = LazyLock::new(|| {
-	GlobalState::new().expect("global state init shouldn't fail")
-});
+static GLOBAL_STATE: LazyLock<GlobalState> =
+	LazyLock::new(|| GlobalState::new().expect("global state init shouldn't fail"));
 
 thread_local! {
 	static THREAD_STATE: RefCell<ThreadState> = RefCell::new(ThreadState::new().expect("thread state init shouldn't fail"));
@@ -965,7 +964,9 @@
 	let runtime = TOKIO_FOR_NIX
 		.get()
 		.expect("init_tokio_for_nix was not called");
-	std::thread::spawn(move || runtime.block_on(f)).join().expect("await_in_nix inner thread panicked")
+	std::thread::spawn(move || runtime.block_on(f))
+		.join()
+		.expect("await_in_nix inner thread panicked")
 }
 
 unsafe extern "C" fn nix_primop_closure_adapter<const N: usize>(
modifiedmodules/nixos.nixdiffbeforeafterboth
--- a/modules/nixos.nix
+++ b/modules/nixos.nix
@@ -10,7 +10,12 @@
 let
   inherit (lib.attrsets) mapAttrs;
   inherit (lib.options) mkOption;
-  inherit (lib.types) deferredModule unspecified uniq str;
+  inherit (lib.types)
+    deferredModule
+    unspecified
+    uniq
+    str
+    ;
   inherit (lib.strings) escapeNixIdentifier;
   inherit (fleetLib.options) mkHostsOption;
 
@@ -24,92 +29,102 @@
       '';
       type = deferredModule;
     };
-    hosts = mkHostsOption (hostArgs: let
-      hostName = hostArgs.config._module.args.name;
-    in {
-      inherit _file;
-      options = {
-        name = mkOption {
-          description = ''
-            Host name (alias)
-          '';
-          type = uniq str;
-          default = hostName;
+    hosts = mkHostsOption (
+      hostArgs:
+      let
+        hostName = hostArgs.config._module.args.name;
+      in
+      {
+        inherit _file;
+        options = {
+          name = mkOption {
+            description = ''
+              Host name (alias)
+            '';
+            type = uniq str;
+            default = hostName;
+          };
+          nixos = mkOption {
+            description = ''
+              Nixos configuration for the current host.
+            '';
+            type = deferredModule;
+            apply =
+              module:
+              let
+                modulesPath = "${config.nixpkgs.buildUsing}/nixos/modules";
+                baseModules = (import "${modulesPath}/module-list.nix");
+                modules = baseModules ++ [
+                  (module // { key = "attr<host.nixos>"; })
+                  (config.nixos // { key = "attr<fleet.nixos>"; })
+                ];
+              in
+              config.nixpkgs.buildUsing.lib.evalModules {
+                class = "nixos";
+                prefix = [
+                  "fleetConfiguration"
+                  "hosts"
+                  hostName
+                  "nixos"
+                ];
+                inherit modules;
+                specialArgs = {
+                  inherit
+                    fleetLib
+                    inputs
+                    self
+                    modulesPath
+                    baseModules
+                    modules
+                    ;
+                  noUserModules = baseModules;
+                  extraModules = [ ];
+                };
+              };
+          };
+          nixos_unchecked = mkOption {
+            type = unspecified;
+          };
         };
-        nixos = mkOption {
-          description = ''
-            Nixos configuration for the current host.
-          '';
-          type = deferredModule;
-          apply =
-            module:
+        config = {
+          nixos =
             let
-              modulesPath = "${config.nixpkgs.buildUsing}/nixos/modules";
+              inherit (hostArgs.config) system;
             in
-            config.nixpkgs.buildUsing.lib.evalModules {
-              class = "nixos";
-              prefix = [
-                "fleetConfiguration"
-                "hosts"
-                hostName
-                "nixos"
-              ];
-              modules = (import "${modulesPath}/module-list.nix") ++ [
-                (module // { key = "attr<host.nixos>"; })
-                (config.nixos // { key = "attr<fleet.nixos>"; })
-              ];
-              specialArgs = {
-                inherit
-                  fleetLib
-                  inputs
-                  self
-                  modulesPath
-                  ;
-              };
-            };
-        };
-        nixos_unchecked = mkOption {
-          type = unspecified;
-        };
-      };
-      config = {
-        nixos =
-          let
-            inherit (hostArgs.config) system;
-          in
-          {
-            _module.args = {
-              nixosHosts = mapAttrs (_: value: value.nixos_unchecked.config) config.hosts;
-              hosts = config.hosts;
-              host = hostArgs.config;
-              fleetConfiguration = config;
+            {
+              _module.args = {
+                nixosHosts = mapAttrs (_: value: value.nixos_unchecked.config) config.hosts;
+                hosts = config.hosts;
+                host = hostArgs.config;
+                fleetConfiguration = config;
 
-              inputs' = mapAttrs (
-                inputName: input:
-                builtins.addErrorContext
-                  "while retrieving system-dependent attributes for input ${escapeNixIdentifier inputName}"
-                  (
-                    if input._type or null == "flake" then
-                      _fleetFlakeRootConfig.perInput system input
-                    else
-                      "input is not a flake, perhaps flake = false was added to te input declaration?"
-                  )
-              ) inputs;
-              self' = builtins.addErrorContext "while retrieving system-dependent attributes for a flake's own outputs" (
-                _fleetFlakeRootConfig.perInput system self
-              );
+                inputs' = mapAttrs (
+                  inputName: input:
+                  builtins.addErrorContext
+                    "while retrieving system-dependent attributes for input ${escapeNixIdentifier inputName}"
+                    (
+                      if input._type or null == "flake" then
+                        _fleetFlakeRootConfig.perInput system input
+                      else
+                        "input is not a flake, perhaps flake = false was added to te input declaration?"
+                    )
+                ) inputs;
+                self' = builtins.addErrorContext "while retrieving system-dependent attributes for a flake's own outputs" (
+                  _fleetFlakeRootConfig.perInput system self
+                );
+              };
+              nixpkgs.hostPlatform = system;
             };
-            nixpkgs.hostPlatform = system;
+          nixos_unchecked = hostArgs.config.nixos.extendModules {
+            modules = [
+              {
+                _module.check = false;
+              }
+            ];
           };
-        nixos_unchecked = hostArgs.config.nixos.extendModules {
-          modules = [
-            {
-              _module.check = false;
-            }
-          ];
         };
-      };
-    });
+      }
+    );
   };
   config.nixos.imports = import ./nixos/module-list.nix;
 }
modifiedmodules/nixos/secrets.nixdiffbeforeafterboth
before · modules/nixos/secrets.nix
1{2  lib,3  fleetLib,4  config,5  pkgs,6  host,7  fleetConfiguration,8  ...9}:10let11  inherit (builtins)12    hashString13    toJSON14    ;15  inherit (lib.stringsWithDeps) stringAfter;16  inherit (lib.options) mkOption literalExpression;17  inherit (lib.lists) optional elem;18  inherit (lib.attrsets)19    mapAttrs20    mapAttrsToList21    filterAttrs22    attrNames23    ;24  inherit (lib.modules) mkIf;25  inherit (lib.types)26    submodule27    str28    attrsOf29    unspecified30    uniq31    functionTo32    package33    enum34    either35    listOf36    ;37  inherit (fleetLib.strings) decodeRawSecret;3839  sysConfig = config;40  secretPartType =41    secretName:42    submodule (43      { config, ... }:44      let45        partName = config._module.args.name;46      in47      {48        options = {49          hash = mkOption {50            type = str;51            description = "Hash of secret in encoded format";52          };53          path = mkOption {54            type = str;55            description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";56          };57          stablePath = mkOption {58            type = str;59            description = "Path to secret part, stable path (users are expected to watch for file changes/re-read secret on demand)";60          };61          data = mkOption {62            type = str;63            description = "Secret public data (only available for plaintext)";64          };65          raw = mkOption {66            type = str;67            description = "Raw (encoded/encrypted secret part data)";68          };69        };70        config = {71          hash = hashString "sha1" config.raw;72          data = decodeRawSecret config.raw;73          path = "/run/secrets/${secretName}/${config.hash}-${partName}";74          stablePath = "/run/secrets/${secretName}/${partName}";75        };76      }77    );78  secretType = submodule (79    {80      config,81      ...82    }:83    let84      secretName = config._module.args.name;85      literal = l: enum [ l ];86    in87    {88      options = {89        parts = mkOption {90          type = uniq (attrsOf (secretPartType secretName));91          description = "Definition of secret parts";92        };93        generator = mkOption {94          type = either (functionTo package) (literal "shared");95          description = "Derivation to evaluate for secret generation";96        };97        mode = mkOption {98          type = str;99          description = "Secret mode";100          default = "0440";101        };102        owner = mkOption {103          type = str;104          description = "Owner of the secret";105          default = "root";106        };107        group = mkOption {108          type = str;109          description = "Group of the secret";110          default = sysConfig.users.users.${config.owner}.group;111          defaultText = literalExpression "config.users.users.$${owner}.group";112        };113      };114      config = {115        # C api is broken in regard to thunks116        # https://github.com/NixOS/nix/issues/12800117        parts =118          let119            hostName = host._module.args.name;120            generator = config.generator;121          in122          builtins.deepSeq [123            hostName124            secretName125            generator126          ] (builtins.fleetEnsureHostSecret hostName secretName generator);127      };128    }129  );130  secretsFile = pkgs.writeTextFile {131    name = "secrets.json";132    text = toJSON config.system.secretsData;133  };134  useSysusers =135    (config.systemd ? sysusers && config.systemd.sysusers.enable)136    || (config ? userborn && config.userborn.enable);137in138{139  options = {140    _providedSharedSecrets = mkOption {141      description = ''142        List of shared secrets, for which the current host was specified as `expectedOwners`143      '';144      type = listOf str;145      default = [];146      internal = true;147    };148    secrets = mkOption {149      type = attrsOf secretType;150      default = { };151      apply =152        secrets:153        mapAttrs (_: secret: secret.parts // { definition = secret; })154155          (156            let157              hostName = host.name;158              expectedNonshared = attrNames (filterAttrs (_: def: def.generator != "shared") secrets);159              expectedShared = config._providedSharedSecrets;160            in161            builtins.deepSeq [162              hostName163              expectedNonshared164              expectedShared165            ] (builtins.fleetEnsureHostSecrets hostName expectedNonshared expectedShared secrets)166          );167      description = "Host-local secrets";168    };169    system.secretsData = mkOption {170      type = unspecified;171      default = mapAttrs (172        _: s:173        (removeAttrs s.definition [ "generator" ])174        // {175          parts = mapAttrs (_: part: removeAttrs part [ "data" ]) s.definition.parts;176        }177      ) config.secrets;178      description = "secrets.json contents";179    };180  };181  config = {182    environment.systemPackages = [ pkgs.fleet-install-secrets ];183184    assertions = mapAttrsToList (185      name: secret:186      let187        hasSharedDefinition = fleetConfiguration.secrets ? ${name};188      in189      {190        assertion =191          (secret.definition.generator == "shared") == hasSharedDefinition192          && (193            hasSharedDefinition194            -> (elem host.name fleetConfiguration.secrets.${name}.expectedOwners)195          );196        message =197          if hasSharedDefinition then198            "secret ${name} has host-specific secret generator, secrets with host-specific generators can not have shared generator in fleet configuration"199          else200            "secret ${name} is declared as shared, for shared secret fleet configuration should include shared secret generator, and expectedOwners should contain this host";201      }202    ) config.secrets;203204    systemd.services.fleet-install-secrets = mkIf useSysusers {205      wantedBy = [ "sysinit.target" ];206      after = [ "systemd-sysusers.service" ];207      restartTriggers = [208        secretsFile209      ];210      aliases = [211        "sops-install-secrets"212        "agenix-install-secrets"213      ];214215      unitConfig.DefaultDependencies = false;216217      serviceConfig = {218        Type = "oneshot";219        RemainAfterExit = true;220        ExecStart = "${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}";221      };222    };223    system.activationScripts.decryptSecrets = mkIf (!useSysusers) (224      stringAfter225        (226          [227            # secrets are owned by user/group, thus we need to refer to those228            "users"229            "groups"230            "specialfs"231          ]232          # nixos-impermanence compatibility: secrets are encrypted by host-key,233          # but with impermanence we expect that the host-key is installed by234          # persist-file activation script.235          ++ (optional (config.system.activationScripts ? "persist-files") "persist-files")236        )237        ''238          1>&2 echo "setting up secrets"239          ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}240        ''241    );242  };243}
after · modules/nixos/secrets.nix
1{2  lib,3  fleetLib,4  config,5  pkgs,6  host,7  fleetConfiguration,8  ...9}:10let11  inherit (builtins)12    hashString13    toJSON14    ;15  inherit (lib.stringsWithDeps) stringAfter;16  inherit (lib.options) mkOption literalExpression;17  inherit (lib.lists) optional elem;18  inherit (lib.attrsets)19    mapAttrs20    mapAttrsToList21    filterAttrs22    attrNames23    ;24  inherit (lib.modules) mkIf;25  inherit (lib.types)26    submodule27    str28    attrsOf29    unspecified30    uniq31    functionTo32    package33    enum34    either35    listOf36    ;37  inherit (fleetLib.strings) decodeRawSecret;3839  sysConfig = config;40  secretPartType =41    secretName:42    submodule (43      { config, ... }:44      let45        partName = config._module.args.name;46      in47      {48        options = {49          hash = mkOption {50            type = str;51            description = "Hash of secret in encoded format";52          };53          path = mkOption {54            type = str;55            description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";56          };57          stablePath = mkOption {58            type = str;59            description = "Path to secret part, stable path (users are expected to watch for file changes/re-read secret on demand)";60          };61          data = mkOption {62            type = str;63            description = "Secret public data (only available for plaintext)";64          };65          raw = mkOption {66            type = str;67            description = "Raw (encoded/encrypted secret part data)";68          };69        };70        config = {71          hash = hashString "sha1" config.raw;72          data = decodeRawSecret config.raw;73          path = "/run/secrets/${secretName}/${config.hash}-${partName}";74          stablePath = "/run/secrets/${secretName}/${partName}";75        };76      }77    );78  secretType = submodule (79    {80      config,81      ...82    }:83    let84      secretName = config._module.args.name;85      literal = l: enum [ l ];86    in87    {88      options = {89        parts = mkOption {90          type = uniq (attrsOf (secretPartType secretName));91          description = "Definition of secret parts";92        };93        generator = mkOption {94          type = either (functionTo package) (literal "shared");95          description = "Derivation to evaluate for secret generation";96        };97        mode = mkOption {98          type = str;99          description = "Secret mode";100          default = "0440";101        };102        owner = mkOption {103          type = str;104          description = "Owner of the secret";105          default = "root";106        };107        group = mkOption {108          type = str;109          description = "Group of the secret";110          default = sysConfig.users.users.${config.owner}.group;111          defaultText = literalExpression "config.users.users.$${owner}.group";112        };113      };114      config = {115        # C api is broken in regard to thunks116        # https://github.com/NixOS/nix/issues/12800117        parts =118          let119            hostName = host._module.args.name;120            generator = config.generator;121          in122          builtins.deepSeq [123            hostName124            secretName125            generator126          ] (builtins.fleetEnsureHostSecret hostName secretName generator);127      };128    }129  );130  secretsFile = pkgs.writeTextFile {131    name = "secrets.json";132    text = toJSON config.system.secretsData;133  };134  useSysusers =135    (config.systemd ? sysusers && config.systemd.sysusers.enable)136    || (config ? userborn && config.userborn.enable);137in138{139  options = {140    _providedSharedSecrets = mkOption {141      description = ''142        List of shared secrets, for which the current host was specified as `expectedOwners`143      '';144      type = listOf str;145      default = [ ];146      internal = true;147    };148    secrets = mkOption {149      type = attrsOf secretType;150      default = { };151      apply =152        secrets:153        mapAttrs (_: secret: secret.parts // { definition = secret; })154155          (156            let157              hostName = host.name;158              expectedNonshared = attrNames (filterAttrs (_: def: def.generator != "shared") secrets);159              expectedShared = config._providedSharedSecrets;160            in161            builtins.deepSeq [162              hostName163              expectedNonshared164              expectedShared165            ] (builtins.fleetEnsureHostSecrets hostName expectedNonshared expectedShared secrets)166          );167      description = "Host-local secrets";168    };169    system.secretsData = mkOption {170      type = unspecified;171      default = mapAttrs (172        _: s:173        (removeAttrs s.definition [ "generator" ])174        // {175          parts = mapAttrs (_: part: removeAttrs part [ "data" ]) s.definition.parts;176        }177      ) config.secrets;178      description = "secrets.json contents";179    };180  };181  config = {182    environment.systemPackages = [ pkgs.fleet-install-secrets ];183184    assertions = mapAttrsToList (185      name: secret:186      let187        hasSharedDefinition = fleetConfiguration.secrets ? ${name};188      in189      {190        assertion =191          (secret.definition.generator == "shared") == hasSharedDefinition192          && (hasSharedDefinition -> (elem host.name fleetConfiguration.secrets.${name}.expectedOwners));193        message =194          if hasSharedDefinition then195            "secret ${name} has host-specific secret generator, secrets with host-specific generators can not have shared generator in fleet configuration"196          else197            "secret ${name} is declared as shared, for shared secret fleet configuration should include shared secret generator, and expectedOwners should contain this host";198      }199    ) config.secrets;200201    systemd.services.fleet-install-secrets = mkIf useSysusers {202      wantedBy = [ "sysinit.target" ];203      after = [ "systemd-sysusers.service" ];204      restartTriggers = [205        secretsFile206      ];207      aliases = [208        "sops-install-secrets"209        "agenix-install-secrets"210      ];211212      unitConfig.DefaultDependencies = false;213214      serviceConfig = {215        Type = "oneshot";216        RemainAfterExit = true;217        ExecStart = "${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}";218      };219    };220    system.activationScripts.decryptSecrets = mkIf (!useSysusers) (221      stringAfter222        (223          [224            # secrets are owned by user/group, thus we need to refer to those225            "users"226            "groups"227            "specialfs"228          ]229          # nixos-impermanence compatibility: secrets are encrypted by host-key,230          # but with impermanence we expect that the host-key is installed by231          # persist-file activation script.232          ++ (optional (config.system.activationScripts ? "persist-files") "persist-files")233        )234        ''235          1>&2 echo "setting up secrets"236          ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}237        ''238    );239  };240}
modifiedmodules/secrets.nixdiffbeforeafterboth
--- a/modules/secrets.nix
+++ b/modules/secrets.nix
@@ -83,9 +83,13 @@
     };
   };
   config = {
-    nixos = {host, ...}: {
-      _providedSharedSecrets = filter (name: elem host.name config.secrets.${name}.expectedOwners) (attrNames config.secrets);
-    };
+    nixos =
+      { host, ... }:
+      {
+        _providedSharedSecrets = filter (name: elem host.name config.secrets.${name}.expectedOwners) (
+          attrNames config.secrets
+        );
+      };
     nixpkgs.overlays = [
       (final: prev: {
         mkSecretGenerators =