Skip to content

Commit 7550734

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

File tree

3 files changed

+125
-92
lines changed

3 files changed

+125
-92
lines changed

doc/release-notes/index.rst

Lines changed: 4 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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=${toString 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>" "${toString nixpkgs}"
71+
'';
72+
6873
# TODO: Re-add manual build
6974
};
7075

nix/eval-machine-info.nix

Lines changed: 116 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -11,104 +11,140 @@
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 = toString <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;
46+
inherit (builtins) removeAttrs;
5447

55-
inherit (pkgs) lib;
48+
in
49+
rec {
50+
inherit nixpkgs;
5651

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

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

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

65137
importedPluginNixExprs = map
66138
(expr: import expr)
67139
pluginNixExprs;
68-
pluginOptions = { imports = (lib.foldl (a: e: a ++ e.options) [] importedPluginNixExprs); };
140+
pluginOptions = lib.foldl (a: e: a ++ e.options) [ ] importedPluginNixExprs;
69141
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" ])));
142+
pluginDeploymentConfigExporters = (lib.foldl
143+
(a: e: a ++ (e.config_exporters {
144+
inherit pkgs;
145+
inherit (lib) optionalAttrs;
146+
})) [ ]
147+
importedPluginNixExprs);
112148

113149
# Compute the definitions of the non-machine resources.
114150
resourcesByType = lib.zipAttrs (network.resources or []);
@@ -158,18 +194,6 @@ in rec {
158194
publicIPv4 = "config.networking.publicIPv4";
159195
}.${key} or "config.deployment.${key}";
160196

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-
173197
# check if there are duplicate elements in a sorted list
174198
noDups = l:
175199
if lib.length l > 1

0 commit comments

Comments
 (0)