Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

require -> imports #1486

Open
roberth opened this issue Nov 18, 2021 · 0 comments · May be fixed by #1508
Open

require -> imports #1486

roberth opened this issue Nov 18, 2021 · 0 comments · May be fixed by #1508
Labels
Projects

Comments

@roberth
Copy link
Member

roberth commented Nov 18, 2021

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

  1. Load the raw network expressions as Nix functions
  2. Call them with bogus auto-arguments as in module (mapAttrs (k: v: throw k) (functionArgs module)
  3. 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.
  4. Use these partial modules to determine what lib should be.
  5. Call lib.evalModules on the network expressions.
  6. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

Successfully merging a pull request may close this issue.

1 participant