-
-
Notifications
You must be signed in to change notification settings - Fork 363
Description
I believe a custom require
feature was chosen in order to solve a bootstrapping problem.
This custom mechanism is not ideal because it adds to the growing list of "override", "overlay", "module", etc. It'd be better to reuse the module system. I suggest the following bootstrapping
- Load the raw network expressions as Nix functions
- Call them with bogus auto-arguments as in
module (mapAttrs (k: v: throw k) (functionArgs module)
- This should give us module attrsets containing a few attributes of interest that we'll evaluated and a bunch of things we don't need and can't evaluate at this stage. That's ok.
- Use these partial modules to determine what
lib
should be. - Call
lib.evalModules
on the network expressions. - Have the module system at our disposal
A more radical approach, suitable for flakes, is to let the user inject lib
manually. This would change the flake format to require a call like nixopsConfigurations.default = inputs.nixops.lib.mkNetwork { inherit lib; configuration = /* ... */; }
, which is more robust than step 3 and 4. For non-flake nixops.nix
we'll still want something like step 3 and 4 I think.
Pros:
- module system is more familiar
- module system is more powerful a custom composition method will be
- allows the user to define network-wide options to capture the variability of environments (dtap, etc)
- allows the user to define network-wide options to represent cross-machine concepts such as groups of machines
- network arguments can become option values
- familiar infrastructure for deprecations
- replace custom, buggy network expression merging code
Cons:
- breaks pre-release version (not that bad)
- step 3 and 4 are somewhat fragile. I am confident that this can be mitigated
Myths:
- "the module system is slow; look at NixOS": the module system scales with the number of options. It is very fast for small configuration systems. It is also quite lazy, so it is possible to avoid evaluating the machines for example. I see no reason for performance to degrade because of this change.
Note to self: requires
is not a recent addition; compatibility is needed and can be provided at next to no cost, because the module system still supports requires
as a hardly known legacy feature.