Skip to content

Commit 20ac995

Browse files
committed
eval-machine-info.nix: ported to modules
1 parent 06a182f commit 20ac995

File tree

3 files changed

+124
-92
lines changed

3 files changed

+124
-92
lines changed

doc/release-notes/index.rst

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ Release 2.0
1616

1717
- Major code cleanups.
1818

19+
- Now the network specification is using the module system from ``nixpkgs.lib``
20+
- Now network specification files can import other files via ``imports``.
21+
- We have a ``nodes.*`` option where we put every NixOS configuration for the configured nodes. We suggest to use it instead of defining nodes in the top level.
22+
1923
- Removed NixOS Options
2024

2125
- ``deployment.autoLuks.*`` - moved to `nixos-modules-contrib`_.

flake.nix

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
git_root=$(${pkgs.git}/bin/git rev-parse --show-toplevel)
4242
export PYTHONPATH=$git_root:$PYTHONPATH
4343
export PATH=$git_root/scripts:$PATH
44+
export NIX_PATH="nixpkgs=${nixpkgs}:$NIX_PATH"
4445
'';
4546
};
4647

@@ -65,6 +66,10 @@
6566
overrides
6667
];
6768

69+
postPatch = ''
70+
substituteInPlace nix/eval-machine-info.nix --replace "<nixpkgs>" "${nixpkgs}"
71+
'';
72+
6873
# TODO: Re-add manual build
6974
};
7075

nix/eval-machine-info.nix

+115-92
Original file line numberDiff line numberDiff line change
@@ -11,104 +11,139 @@
1111
let
1212
call = x: if builtins.isFunction x then x args else x;
1313

14-
# Copied from nixpkgs to avoid <nixpkgs> import
15-
optional = cond: elem: if cond then [elem] else [];
16-
1714
zipAttrs = set: builtins.listToAttrs (
1815
map (name: { inherit name; value = builtins.catAttrs name set; }) (builtins.concatMap builtins.attrNames set));
1916

20-
flakeExpr = (builtins.getFlake flakeUri).outputs.nixopsConfigurations.default;
21-
22-
networks =
23-
let
24-
getNetworkFromExpr = networkExpr:
25-
(call (import networkExpr)) // { _file = networkExpr; };
17+
flake = builtins.getFlake flakeUri;
18+
flakeExpr = (builtins.tryEval flake.outputs.nixopsConfigurations.default).value or { };
2619

27-
exprToKey = key: { key = toString key; };
20+
nixpkgsBoot = <nixpkgs> ; # this will be replaced on install by nixops' nixpkgs input
21+
libBoot = import "${nixpkgsBoot}/lib";
2822

29-
networkExprClosure = builtins.genericClosure {
30-
startSet = map exprToKey networkExprs;
31-
operator = { key }: map exprToKey ((getNetworkFromExpr key).require or []);
23+
baseMods = lib: [
24+
{
25+
options.nixpkgs = lib.mkOption {
26+
type = lib.types.path;
27+
description = "Path to the nixpkgs instance used to buld the machines.";
28+
defaultText = lib.literalDocBook "The 'nixpkgs' input to either the provided flake or nixops' own.";
29+
default = (builtins.tryEval flake.inputs.nixpkgs).value or nixpkgsBoot;
3230
};
33-
in
34-
map ({ key }: getNetworkFromExpr key) networkExprClosure
35-
++ optional (flakeUri != null)
36-
((call flakeExpr) // { _file = "<${flakeUri}>"; });
31+
config._module.freeformType = with lib.types;attrsOf anything;
32+
}
33+
flakeExpr
34+
] ++ networkExprs;
3735

38-
network = zipAttrs networks;
36+
evalBoot = libBoot.evalModules {
37+
specialArgs = args;
38+
modules = baseMods libBoot;
39+
};
3940

40-
evalConfig =
41-
if flakeUri != null
42-
then
43-
if network ? nixpkgs
44-
then (builtins.head (network.nixpkgs)).lib.nixosSystem
45-
else throw "NixOps network must have a 'nixpkgs' attribute"
46-
else import (pkgs.path + "/nixos/lib/eval-config.nix");
41+
inherit (evalBoot.config) nixpkgs;
4742

48-
pkgs = if flakeUri != null
49-
then
50-
if network ? nixpkgs
51-
then (builtins.head network.nixpkgs).legacyPackages.${system}
52-
else throw "NixOps network must have a 'nixpkgs' attribute"
53-
else (builtins.head (network.network)).nixpkgs or (import <nixpkgs> { inherit system; });
43+
pkgs = nixpkgs.legacyPackages.${system} or import nixpkgs { inherit system; };
44+
lib = nixpkgs.lib or pkgs.lib or libBoot;
45+
inherit (lib) mkOption types removeAttrs;
5446

55-
inherit (pkgs) lib;
47+
in
48+
rec {
49+
inherit nixpkgs;
5650

57-
# Expose path to imported nixpkgs (currently only used to find version suffix)
58-
nixpkgs = builtins.unsafeDiscardStringContext pkgs.path;
51+
netConfig = (lib.evalModules {
52+
specialArgs = args;
53+
modules = baseMods lib ++ [
54+
({ config, options, ... }: {
55+
options = {
56+
network = {
57+
enableRollback = lib.mkEnableOption "network wide rollback";
58+
description = mkOption {
59+
type = types.str;
60+
description = "A description of the entire network.";
61+
default = "";
62+
};
63+
nodesExtraArgs = mkOption {
64+
description = "Extra inputs to be passed to every node.";
65+
type = with types;attrsOf anything;
66+
default = {};
67+
};
68+
};
69+
resources = mkOption {
70+
type = types.submoduleWith {
71+
modules = [{
72+
# so what is this trying to do?
73+
sshKeyPairs = evalResources ./ssh-keypair.nix (lib.zipAttrs resourcesByType.sshKeyPairs or [ ]);
74+
commandOutput = evalResources ./command-output.nix (lib.zipAttrs resourcesByType.commandOutput or [ ]);
75+
machines = config.nodes;
76+
_module.check = false;
77+
}] ++ pluginResources;
78+
specialArgs = {
79+
inherit evalResources resourcesByType;
80+
inherit (lib) zipAttrs;
81+
};
82+
};
83+
};
84+
# Compute the definitions of the machines.
85+
nodes = mkOption {
86+
type = types.attrsOf (types.submoduleWith {
87+
specialArgs = {
88+
inherit uuid deploymentName;
89+
inherit (config) nodes resources;
90+
} // config.network.nodesExtraArgs;
91+
modules = (import "${nixpkgs}/nixos/modules/module-list.nix") ++
92+
config.defaults ++
93+
# Make NixOps's deployment.* options available.
94+
pluginOptions ++
95+
[
96+
./options.nix
97+
./resource.nix
98+
deploymentInfoModule
99+
({ name, ... }: rec{
100+
_file = ./eval-machine-info.nix;
101+
key = _file;
102+
# Provide a default hostname and deployment target equal
103+
# to the attribute name of the machine in the model.
104+
networking.hostName = lib.mkOverride 900 name;
105+
deployment.targetHost = lib.mkOverride 900 name;
106+
environment.checkConfigurationOptions = lib.mkOverride 900 checkConfigurationOptions;
107+
nixpkgs.system = lib.mkDefault system;
108+
})
109+
];
110+
});
111+
};
112+
defaults = mkOption {
113+
type = with types;listOf anything;
114+
default = [ ];
115+
description = ''
116+
Extra NixOS options to add to all nodes.
117+
'';
118+
};
119+
};
120+
config = let
121+
nodes = removeAttrs config (builtins.attrNames options);
122+
in mkIf ({} != nodes) { #TODO: actual warning/assert module impl.
123+
nodes = lib.warn "Please use the actual nodes.* option instead of assigning machines to the config's top level" nodes;
124+
};
125+
})
126+
];
127+
}).config;
59128

60-
in rec {
129+
inherit (netConfig) resources nodes;
130+
defaults = [ netConfig.defaults ];
61131

62-
inherit networks network;
63-
inherit nixpkgs;
132+
# for backward compatibility
133+
network = lib.mapAttrs (n: v: [v]) netConfig;
134+
networks = [ netConfig ];
64135

65136
importedPluginNixExprs = map
66137
(expr: import expr)
67138
pluginNixExprs;
68-
pluginOptions = { imports = (lib.foldl (a: e: a ++ e.options) [] importedPluginNixExprs); };
139+
pluginOptions = lib.foldl (a: e: a ++ e.options) [ ] importedPluginNixExprs;
69140
pluginResources = map (e: e.resources) importedPluginNixExprs;
70-
pluginDeploymentConfigExporters = (lib.foldl (a: e: a ++ (e.config_exporters {
71-
inherit pkgs;
72-
inherit (lib) optionalAttrs;
73-
})) [] importedPluginNixExprs);
74-
75-
defaults = network.defaults or [];
76-
77-
# Compute the definitions of the machines.
78-
nodes =
79-
lib.listToAttrs (map (machineName:
80-
let
81-
# Get the configuration of this machine from each network
82-
# expression, attaching _file attributes so the NixOS module
83-
# system can give sensible error messages.
84-
modules =
85-
lib.concatMap (n: lib.optional (lib.hasAttr machineName n)
86-
{ imports = [(lib.getAttr machineName n)]; inherit (n) _file; })
87-
networks;
88-
in
89-
{ name = machineName;
90-
value = evalConfig {
91-
modules =
92-
modules ++
93-
defaults ++
94-
[ deploymentInfoModule ] ++
95-
[ { key = "nixops-stuff";
96-
# Make NixOps's deployment.* options available.
97-
imports = [ ./options.nix ./resource.nix pluginOptions ];
98-
# Provide a default hostname and deployment target equal
99-
# to the attribute name of the machine in the model.
100-
networking.hostName = lib.mkOverride 900 machineName;
101-
deployment.targetHost = lib.mkOverride 900 machineName;
102-
environment.checkConfigurationOptions = lib.mkOverride 900 checkConfigurationOptions;
103-
104-
nixpkgs.system = lib.mkDefault system;
105-
106-
_module.args = { inherit nodes resources uuid deploymentName; name = machineName; };
107-
}
108-
];
109-
};
110-
}
111-
) (lib.attrNames (removeAttrs network [ "network" "defaults" "resources" "require" "nixpkgs" "_file" ])));
141+
pluginDeploymentConfigExporters = (lib.foldl
142+
(a: e: a ++ (e.config_exporters {
143+
inherit pkgs;
144+
inherit (lib) optionalAttrs;
145+
})) [ ]
146+
importedPluginNixExprs);
112147

113148
# Compute the definitions of the non-machine resources.
114149
resourcesByType = lib.zipAttrs (network.resources or []);
@@ -158,18 +193,6 @@ in rec {
158193
publicIPv4 = "config.networking.publicIPv4";
159194
}.${key} or "config.deployment.${key}";
160195

161-
resources = lib.foldl
162-
(a: b: a // (b {
163-
inherit evalResources resourcesByType;
164-
inherit (lib) zipAttrs;
165-
}))
166-
{
167-
sshKeyPairs = evalResources ./ssh-keypair.nix (lib.zipAttrs resourcesByType.sshKeyPairs or []);
168-
commandOutput = evalResources ./command-output.nix (lib.zipAttrs resourcesByType.commandOutput or []);
169-
machines = lib.mapAttrs (n: v: v.config) nodes;
170-
}
171-
pluginResources;
172-
173196
# check if there are duplicate elements in a sorted list
174197
noDups = l:
175198
if lib.length l > 1

0 commit comments

Comments
 (0)