difftreelog
fix baseModules arg
in: trunk
5 files changed
crates/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"
crates/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>(
modules/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;
}
modules/nixos/secrets.nixdiffbeforeafterboth--- a/modules/nixos/secrets.nix
+++ b/modules/nixos/secrets.nix
@@ -142,7 +142,7 @@
List of shared secrets, for which the current host was specified as `expectedOwners`
'';
type = listOf str;
- default = [];
+ default = [ ];
internal = true;
};
secrets = mkOption {
@@ -189,10 +189,7 @@
{
assertion =
(secret.definition.generator == "shared") == hasSharedDefinition
- && (
- hasSharedDefinition
- -> (elem host.name fleetConfiguration.secrets.${name}.expectedOwners)
- );
+ && (hasSharedDefinition -> (elem host.name fleetConfiguration.secrets.${name}.expectedOwners));
message =
if hasSharedDefinition then
"secret ${name} has host-specific secret generator, secrets with host-specific generators can not have shared generator in fleet configuration"
modules/secrets.nixdiffbeforeafterboth1{2 lib,3 config,4 ...5}:6let7 inherit (lib.options) mkOption;8 inherit (lib.types)9 nullOr10 listOf11 str12 bool13 attrsOf14 submodule15 functionTo16 package17 uniq18 ;19 inherit (lib.strings) concatStringsSep;20 inherit (lib.lists) elem filter;21 inherit (lib.attrsets) attrNames;2223 sharedSecret =24 { config, ... }:25 {26 options = {27 expectedOwners = mkOption {28 type = listOf str;29 description = ''30 Specifies the list of hosts authorized to decrypt and access this shared secret.31 '';32 };33 regenerateOnOwnerAdded = mkOption {34 type = bool;35 description = ''36 Whether the secret prefers to be rotated when new owners are added.3738 Note that this is only a security measure, if the secret needs to be regenerated due to e.g X.509 SANs39 changes - then you most likely want to use generationData for that instead.40 '';41 default = false;42 };43 regenerateOnOwnerRemoved = mkOption {44 type = bool;45 description = ''46 Whether the secret prefers to be rotated when the owners are removed, so the encrypted data47 stored in fleet state can't be decrypted by those. Note that the secrets are still present in encrypted48 form on those hosts until gc happens.49 '';50 default = false;51 };52 allowDifferent = mkOption {53 type = bool;54 description = ''55 When adding owner, do not update secret value for other owners, instead creating a new distribution.5657 Defaults to true, since all secrets might differ on hosts on some point of deployment process.5859 Secret generator might also have opinion on this, like it makes little sense for askPass/synchronizing60 generators to keep old data.61 '';62 default = true;63 };64 generator = mkOption {65 type = uniq (nullOr (functionTo package));66 description = ''67 Function evaluating to nix derivation responsible for (re)generating the secret's content.6869 An input to this function - `pkgs` of a generator host with implementation-defined representation of extra encryption data,70 use `mkSecretGenerator` helpers to implement own generators.71 '';72 default = null;73 };74 };75 };76in77{78 options = {79 secrets = mkOption {80 type = attrsOf (submodule sharedSecret);81 default = { };82 description = "Collection of secrets shared across multiple hosts with configurable ownership";83 };84 };85 config = {86 nixos = {host, ...}: {87 _providedSharedSecrets = filter (name: elem host.name config.secrets.${name}.expectedOwners) (attrNames config.secrets);88 };89 nixpkgs.overlays = [90 (final: prev: {91 mkSecretGenerators =92 { recipients }:93 rec {94 # TODO: Merge both generators to one with consistent options syntax?95 # Impure generator is built on local machine, then built closure is copied to remote machine,96 # and then it is ran in inpure context, so that this generator may access HSMs and other things.97 mkImpureSecretGenerator =98 {99 script,100 # If set - script will be run on remote machine, otherwise it will be run with fleet project in CWD101 # (Some secrets-encryption-in-git/managed PKI solution is expected)102 impureOn ? null,103 generationData ? null,104 allowDifferent ? true,105 parts,106 }:107 (prev.writeShellScript "impureGenerator.sh" ''108 #!/bin/sh109 set -eu110111 export GENERATOR_HELPER_IDENTITIES="${concatStringsSep"\n"recipients}";112 export PATH=${final.fleet-generator-helper}/bin:$PATH113114 # TODO: Provide tempdir from outside, to make it securely erasurable as needed?115 tmp=mktemp-d116 cd $tmp117 # cd /var/empty118119 created_at=date-u"%Y-%m-%dT%H:%M:%S.%NZ"120121 ${script}122123 if ! test -d $out; then124 echo "impure generator script did not produce expected \$out output"125 exit 1126 fi127128 echo -n $created_at > $out/created_at129 echo -n SUCCESS > $out/marker130 '').overrideAttrs131 (old: {132 passthru = {133 inherit134 impureOn135 parts136 generationData137 allowDifferent138 ;139 generatorKind = "impure";140 };141 });142 # Pure generators are disabled for now143 mkSecretGenerator = { script, parts }: mkImpureSecretGenerator { inherit script parts; };144145 # TODO: Implement consistent naming146 # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...147 # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.148 # mkSecretGenerator = {script}:149 # (prev.writeShellScript "generator.sh" ''150 # #!/bin/sh151 # set -eu152 # # TODO: make nix daemon build secret, not just the script.153 # cd /var/empty154 #155 # created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")156 #157 # ${script}158 # if ! test -d $out; then159 # echo "impure generator script did not produce expected \$out output"160 # exit 1161 # fi162 #163 # echo -n $created_at > $out/created_at164 # echo -n SUCCESS > $out/marker165 # '')166 # .overrideAttrs (old: {167 # passthru = {168 # generatorKind = "pure";169 # };170 # # TODO: make nix daemon build secret, not just the script.171 # # __impure = true;172 # });173 };174 })175 ];176 };177}1{2 lib,3 config,4 ...5}:6let7 inherit (lib.options) mkOption;8 inherit (lib.types)9 nullOr10 listOf11 str12 bool13 attrsOf14 submodule15 functionTo16 package17 uniq18 ;19 inherit (lib.strings) concatStringsSep;20 inherit (lib.lists) elem filter;21 inherit (lib.attrsets) attrNames;2223 sharedSecret =24 { config, ... }:25 {26 options = {27 expectedOwners = mkOption {28 type = listOf str;29 description = ''30 Specifies the list of hosts authorized to decrypt and access this shared secret.31 '';32 };33 regenerateOnOwnerAdded = mkOption {34 type = bool;35 description = ''36 Whether the secret prefers to be rotated when new owners are added.3738 Note that this is only a security measure, if the secret needs to be regenerated due to e.g X.509 SANs39 changes - then you most likely want to use generationData for that instead.40 '';41 default = false;42 };43 regenerateOnOwnerRemoved = mkOption {44 type = bool;45 description = ''46 Whether the secret prefers to be rotated when the owners are removed, so the encrypted data47 stored in fleet state can't be decrypted by those. Note that the secrets are still present in encrypted48 form on those hosts until gc happens.49 '';50 default = false;51 };52 allowDifferent = mkOption {53 type = bool;54 description = ''55 When adding owner, do not update secret value for other owners, instead creating a new distribution.5657 Defaults to true, since all secrets might differ on hosts on some point of deployment process.5859 Secret generator might also have opinion on this, like it makes little sense for askPass/synchronizing60 generators to keep old data.61 '';62 default = true;63 };64 generator = mkOption {65 type = uniq (nullOr (functionTo package));66 description = ''67 Function evaluating to nix derivation responsible for (re)generating the secret's content.6869 An input to this function - `pkgs` of a generator host with implementation-defined representation of extra encryption data,70 use `mkSecretGenerator` helpers to implement own generators.71 '';72 default = null;73 };74 };75 };76in77{78 options = {79 secrets = mkOption {80 type = attrsOf (submodule sharedSecret);81 default = { };82 description = "Collection of secrets shared across multiple hosts with configurable ownership";83 };84 };85 config = {86 nixos =87 { host, ... }:88 {89 _providedSharedSecrets = filter (name: elem host.name config.secrets.${name}.expectedOwners) (90 attrNames config.secrets91 );92 };93 nixpkgs.overlays = [94 (final: prev: {95 mkSecretGenerators =96 { recipients }:97 rec {98 # TODO: Merge both generators to one with consistent options syntax?99 # Impure generator is built on local machine, then built closure is copied to remote machine,100 # and then it is ran in inpure context, so that this generator may access HSMs and other things.101 mkImpureSecretGenerator =102 {103 script,104 # If set - script will be run on remote machine, otherwise it will be run with fleet project in CWD105 # (Some secrets-encryption-in-git/managed PKI solution is expected)106 impureOn ? null,107 generationData ? null,108 allowDifferent ? true,109 parts,110 }:111 (prev.writeShellScript "impureGenerator.sh" ''112 #!/bin/sh113 set -eu114115 export GENERATOR_HELPER_IDENTITIES="${concatStringsSep"\n"recipients}";116 export PATH=${final.fleet-generator-helper}/bin:$PATH117118 # TODO: Provide tempdir from outside, to make it securely erasurable as needed?119 tmp=mktemp-d120 cd $tmp121 # cd /var/empty122123 created_at=date-u"%Y-%m-%dT%H:%M:%S.%NZ"124125 ${script}126127 if ! test -d $out; then128 echo "impure generator script did not produce expected \$out output"129 exit 1130 fi131132 echo -n $created_at > $out/created_at133 echo -n SUCCESS > $out/marker134 '').overrideAttrs135 (old: {136 passthru = {137 inherit138 impureOn139 parts140 generationData141 allowDifferent142 ;143 generatorKind = "impure";144 };145 });146 # Pure generators are disabled for now147 mkSecretGenerator = { script, parts }: mkImpureSecretGenerator { inherit script parts; };148149 # TODO: Implement consistent naming150 # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...151 # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.152 # mkSecretGenerator = {script}:153 # (prev.writeShellScript "generator.sh" ''154 # #!/bin/sh155 # set -eu156 # # TODO: make nix daemon build secret, not just the script.157 # cd /var/empty158 #159 # created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")160 #161 # ${script}162 # if ! test -d $out; then163 # echo "impure generator script did not produce expected \$out output"164 # exit 1165 # fi166 #167 # echo -n $created_at > $out/created_at168 # echo -n SUCCESS > $out/marker169 # '')170 # .overrideAttrs (old: {171 # passthru = {172 # generatorKind = "pure";173 # };174 # # TODO: make nix daemon build secret, not just the script.175 # # __impure = true;176 # });177 };178 })179 ];180 };181}