Skip to content

Commit a914e16

Browse files
committed
eval-machine-info.nix: ported to modules
1 parent ce1c57e commit a914e16

3 files changed

Lines changed: 122 additions & 95 deletions

File tree

doc/release-notes/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Release 2.0
1515
- Separate state backends for storing state.
1616

1717
- Major code cleanups.
18+
- Now network specification files can import other files via ``imports`` and ``requires`` is no longer supported.
19+
- 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.
1820

1921
- Removed NixOS Options
2022

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=${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

Lines changed: 115 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -11,104 +11,136 @@
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; };
28-
29-
networkExprClosure = builtins.genericClosure {
30-
startSet = map exprToKey networkExprs;
31-
operator = { key }: map exprToKey ((getNetworkFromExpr key).require or []);
32-
};
33-
in
34-
map ({ key }: getNetworkFromExpr key) networkExprClosure
35-
++ optional (flakeUri != null)
36-
((call flakeExpr) // { _file = "<${flakeUri}>"; });
20+
nixpkgs1 = <nixpkgs>; # this will be replaced on install by nixops' nixpkgs input
21+
lib = import "${nixpkgs1}/lib";
3722

38-
network = zipAttrs networks;
39-
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");
47-
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; });
23+
inherit (lib) mkOption types;
5424

55-
inherit (pkgs) lib;
25+
stage1Eval = lib.evalModules {
26+
specialArgs = args;
27+
modules = [
28+
(lib.mkRemovedOptionModule [ "require" ] "Use the imports option instead.")
29+
{
30+
options.nixpkgs = mkOption {
31+
type = types.path;
32+
description = "Path to the nixpkgs instance used to buld the machines.";
33+
defaultText = lib.literalDocBook "The 'nixpkgs' input to either the provided flake or nixops' own.";
34+
default = (builtins.tryEval flake.inputs.nixpkgs).value or nixpkgs1;
35+
};
36+
config._module.freeformType = with types;attrsOf anything;
37+
}
38+
flakeExpr
39+
] ++ networkExprs;
40+
};
5641

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

60-
in rec {
129+
inherit (network) defaults resources nodes;
61130

62-
inherit networks network;
63131
inherit nixpkgs;
64132

65133
importedPluginNixExprs = map
66134
(expr: import expr)
67135
pluginNixExprs;
68-
pluginOptions = { imports = (lib.foldl (a: e: a ++ e.options) [] importedPluginNixExprs); };
136+
pluginOptions = lib.foldl (a: e: a ++ e.options) [ ] importedPluginNixExprs;
69137
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" ])));
138+
pluginDeploymentConfigExporters = (lib.foldl
139+
(a: e: a ++ (e.config_exporters {
140+
inherit pkgs;
141+
inherit (lib) optionalAttrs;
142+
})) [ ]
143+
importedPluginNixExprs);
112144

113145
# Compute the definitions of the non-machine resources.
114146
resourcesByType = lib.zipAttrs (network.resources or []);
@@ -144,18 +176,6 @@ in rec {
144176
publicIPv4 = "config.networking.publicIPv4";
145177
}.${key} or "config.deployment.${key}";
146178

147-
resources = lib.foldl
148-
(a: b: a // (b {
149-
inherit evalResources resourcesByType;
150-
inherit (lib) zipAttrs;
151-
}))
152-
{
153-
sshKeyPairs = evalResources ./ssh-keypair.nix (lib.zipAttrs resourcesByType.sshKeyPairs or []);
154-
commandOutput = evalResources ./command-output.nix (lib.zipAttrs resourcesByType.commandOutput or []);
155-
machines = lib.mapAttrs (n: v: v.config) nodes;
156-
}
157-
pluginResources;
158-
159179
# check if there are duplicate elements in a sorted list
160180
noDups = l:
161181
if lib.length l > 1

0 commit comments

Comments
 (0)