[Nix-dev] Fixing module arguments (PROPOSAL MAY BREAK EXISTING NIXOS CONFIGS, PLEASE READ)

Shea Levy shea at shealevy.com
Wed Feb 19 18:14:53 CET 2014


Hey ocharles,

At https://gist.github.com/shlevy/9096240 you can see my current
in-progress implementation of the "resources.machines" option for the
nixops top-level module. Note that the type of the option is
types.dependentAttrsOf submoduleFn, and submoduleFn is a function from
name to type. This is because arguments to submodules have to be part of
the type, and different machines will have different values for pkgs, so
we need potentially different types for each machine. Then note that
submoduleFn calls types.submoduleWithExtraArgs with *two* values: A list
of base modules and a set of arguments, both of which are used to pass
information to every module in the config. Further note that the
arguments passed are copied from <nixos/lib/eval-config.nix>. Finally
note that the pkgs argument is taken from (stage1Eval name), which
extracts the option definitions for the given machine from
options.resources.machines and manually calls evalModules with a fixed
dummy pkgs set to get the overridden pkgs set.

Suppose instead that pkgs was passed around in config.pkgs, where
nixpkgs.nix sets config.pkgs based on config.nixpkgs, and everywhere
that currently uses pkgs.lib instead uses the lib argument to the
module (and all other arguments handled similarly). Then I could just write

  { lib, ...}:

  with lib;

  {
    options = {
      resources.machines = mkOption {
        default = {};

        description = "The machines in the network.";

        # with mkMap, there's no real reason for submodule
        # to take an initial list of modules at all, but
        # that's a different discussion
        type = types.attrsOf (types.submodule []);
      };
    };

    config = {
      resources.machines = mkMap (name: { lib, ... }: rec {
        imports = [ ./options.nix ] ++ import <nixpkgs/nixos/modules/module-list.nix>;

        config = {
          networking.hostName = lib.mkOverride 900 name;

          deployment.targetHost = lib.mkOverride 900 name;
        };
      });
    };
  }

To get the same functionality as that gist. Note that I don't need the
two new type functions, and neither NixOS nor this needs to do any
double evaluation.

Cheers,
Shea

On Wed, Feb 19, 2014 at 04:37:50PM +0000, Oliver Charles wrote:
> Shea Levy <shea at shealevy.com> writes:
> Hi Shea,
> 
> > The Easy Solution
> > -----------------
> 
> In my opinion the whole project is young enough that we are not yet at a
> stage where we have to live with things being difficult to work with. I
> think most people who are using NixOS in real deployments are aware of
> the fact that they still have to interact with the Nix community, and be
> willing to change their deployments as configuration changes.
> 
> I may be putting words in other's mouths, but that is certainly how I
> feel.
> 
> > The Conservative Solution
> > -------------------------
> > [..]
> >
> > The Moderate Solution
> > ---------------------
> 
> Following on from my earlier feeling - if we're going to make massive
> changes, I'd prefer to keep that window as small as possible. If that
> means making a huge change in one pass, then that is what I would
> prefer. This means I only have to understand one type of change, and I
> only have to fiddle with my deployment configurations once. 
> 
> The more times I have to change things, the more likely I am to be
> confused as to what exactly is going on, and increases the chance that
> I'll screw something up. So...
> 
> > The Radical Solution
> > --------------------
> 
> *If* you're convinced that there is a problem in the module system and
> that this is the best solution, then I would not be against this type of
> change. The argument about having to do a partial evaluation with a
> dummy pkgs strongly suggests the model we have now is not the correct
> one, and I'd be willing to pay the cost (be that changing my
> configurations or helping out with changes in nixpkgs itself) to correct
> that.
> 
> That said, a few concrete examples would really help clarify the
> situtation for me, as I don't think I've entirely understood even the
> problem itself.
> 
> Is it possible for you to share some of the nixops work you've been
> doing, with how it looks now and what the pain points are? Ideally,
> seeing how these pain points are solved by some of these solutions would
> also be extremely useful - especially as the solutions tend towards the
> more radical changes.
> 
> - ocharles


More information about the nix-dev mailing list