How to import / load options from a subset of a nix file?

Hello there,

I’m currently having the following problem: I have a bunch of nix files (which contain attrsets) that I’d like to store some settings in, some of these settings are read out and used by a module I’ve written, but I’d like to add an extraConfig section, that will contain some nixos configuration code, e.g.:

{
  a = {
    foo = "...";
    bar = ''
      ...
    '';
  };
  b = {    
    foo = [];
    baz = [];
  };
  extraConfig = {
    networking.extraHosts = '' 
      1.2.3.4         some-host-name
      192.168.1.1     some-host-name
    '';
  };
}

What currently works is that I can access sections a and b in my module code and assign their content to the respective NixOS configuration keys inside of my module. I’m using import to do this on the separate sections with a let statement like this:

...
someNixConfigKey = let
  a = builtins.concatLists (map .. (map (x: (import x).a) [ "/path/to/file0.nix" "/path/to/file1.nix"]));
in a;
...

Now what I’d like to do with the extraConfig section is basically to go over all of my nix files and simply load the extraConfig section into my configuration. I can access it using import, however from what I’ve gathered so far, import simply returns the content of the files (or sections of files), so simply writing an import statement into my module won’t work. The next thing I wanted to try out was to use the imports variable, but it seems to only store file paths, not configuration snippets…

My question is: is there a way for me to grab part of an attrset from a file and simply use it as part of my configuration?

(I know that I could basically just define all the options in extraConfig as key/value pairs in my module and load them this way - maybe this would even be the cleaner approach - but I still kind of wonder if this is possible in nix)

Many thanks in advance!

imports is a list of any type of module. So that includes a path, a function ala ({config, ...}: {}) or an attrset

Thanks for your reply!

I guess I have to elaborate on my problem: I think I’m not really sure how to use imports inside my module. What I want to do is to load the content of extraConfig in the config section of my module (where I can access the values of the options I defined):


{ config, lib, pkgs, ... }:

with lib;

let

  cfg = config.services.myModule;

in

  options = {
    ...
  };

  config = {

    imports = [ (map (x: (import x).extraConfig ) [ "/path/to/file.nix" ]) ];

    ...

  };
}

But when I try doing this, I get the following error:

error: The option `imports' defined in `/etc/nixos/modules/myModule.nix' does not exist.

Also using just something like import does not work in config:

  config = {
    import /path/to/file.nix;
    ...
  };

Then I get:

error: syntax error, unexpected PATH, expecting '.' or '=', at /etc/nixos/modules/myModule.nix:73:12

Is it possible to import extraConfig or is this not possible using nix?

imports doesn’t go under config = {} in the module. imports is a special prefix that goes in the root of the module.

Also keep in mind any file or nix object you import using the imports statement HAS to be a module. So you can’t use it to import arbitrary data. You can instead use let ... in statements above the actual module.

let
  customSettings = import ./settings.nix;
in
{
  config = {
    environment.etc."someting.conf".text = builtins.toJSON customSettings;
  };
}
1 Like