[Nix-dev] NixOS module system obscurities

Nicolas Pierron nicolas.b.pierron at gmail.com
Wed Apr 27 19:50:47 CEST 2011


Hi Sander,

On Wed, Apr 27, 2011 at 16:02, Sander van der Burg - EWI
<S.vanderBurg at tudelft.nl> wrote:
> I'm trying to implement some new features to nixos-deploy-network, but I
> stumbled upon some obscurities in the NixOS module system. that I don't
> completely understand. Apparently, if I run the eval-config function with
> some modules which aren't files, they won't get evaluated, unless a key
> attribute is given:
>
> For example, if I try this:
>
> import /etc/nixos/nixos/lib/eval-config.nix {
>   ...
>   modules = [ /etc/nixos/configuration.nix
>    { foo = "bar"; } # Does not get evaluated
> }
>
> The latter attribute set (which should trigger an error), isn't evaluated.
> If I add a key to it:
>
> import /etc/nixos/nixos/lib/eval-config.nix {
>   ...
>   modules = [ /etc/nixos/configuration.nix
>    { foo = "bar"; # Now it gets evaluated!
>      key = "some-key"; # Because a key is given
>    }
> }
>
> It will get evaluated!

First, what is the key attribute:

The key attribute has 2 purpose: it is by the genericClosure to define
if a module has already been imported or not.  When a module does not
have a key attribute, one default is attributed to it which is
"<unknown location>".  The second purpose of the key attribute is to
provide information about the location of the module.  The key
attributes are used to compute where options are declared and where
they are defined.  Thus "nixos-option -l" can provide debug
information as well as error messages printed when an error occur
during the evaluation.

Second, from where the problem is coming from:

When you give arguments to eval-config, then this arguments are parts
of the startSet of the genericClosure.  The generic closure associate
a key to one attribute set.  The problem you have is that attribute
set provided at the top-level have been given the same name, which
cause only one attribute set to be handled.

> What I want is to avoid specifying the usage of these key attributes.

I'll fix this bug, but I don't recommend that because it removes debug
information where is could be very useful.  If you can give a unique
name for each, it would be great.

> The
> reason why I want this is because I want to adapt nixos-deploy-network to
> accept multiple network expressions that are zipped together.

Then, as I suggested before, you should use modules for network
expressions.  Thus, instead of making the root of configuration roots
as a NixOS system, make the configuration root a NixOS-Network.  You
can define a module such as:

// NixOS-Network main module
{
    nodes = mkOption {
      default = {};
      description = ''
        Nodes of servers which are part of the network
      '';
      type = types.attrsOf types.optionSet;
      options = import ./nixos/module-list.nix;
    };
}

// network configuration part 1
{
   nodes.firewall = {
      // NixOS configuration for firewall
      services. ... ;
   };
   nodes.webserver = {
      // NixOS configuration for webserver
      services.httpd.enable = true;
   };
}

// network configuration part 2
{
   nodes.firewall = {
      // NixOS configuration for firewall
      networking. ...;
   };
   nodes.webserver = {
      // NixOS configuration for webserver
      networking. ...;
   };
}

> Because of the
> key requirement, the second NixOS network expression won't get evaluated
> (unless I manually specify key attributes, which isn't very nice).

I'll fix that.

> Anyone an idea/suggestion how to deal with this issue?

1/ Use modules instead of multiple instances of NixOS.
2/ Generate good "key" names in your generated attributes set.
3/ Wait a bit and don't do anything until the bug is fixed.

-- 
Nicolas Pierron
http://www.linkedin.com/in/nicolasbpierron - http://nbp.name/



More information about the nix-dev mailing list