Evaluate imports of imported module

I would like to know if it’s possible to resolve the imports of a module that I import, so that import ./myNixosModule.nix doesn’t just give me { imports = [ ... ]; } but instead the merged content of anything mentioned in those imports.

The reason is that my config describes multiple machines that are interconnected at runtime, and I would like to reference another machines config, for example to let my homeserver know the hostname or Wireguard IP of my backup server.

If resolving the imports isn’t possible, my best option is probably to extract “common things” into simple modules containing no imports, right? Or are other mechanisms for such things in place?

Simply stop using import (builtin function) in the module system.
Use imports(module system attribute) only.

  imports = [ ./myNixosModule.nix ];

Hmmm, I don’t see how that can solve my problem. I don’t want the imported config to become part of the current config, I just want to pick individual bits of information from it.

As far as my understanding goes, there is no way to use imports in a way that doesn’t make the imported module part of my NixOS configuration. Am I wrong?

As an example, assume my backup server config contains

{
  networking.hostName = "backup";
}

and on my home server I want to configure restic to target this server like

{
  services.restic.backup = {
    # this is nonsense but highlights the problem
    endpoint = (import ../backupserver/configuration.nix).config.networking.hostName;
  };
}

Let me rephrase then: I suggest refactoring the config so that you can add it to imports directly.

Without seeing the code in question I can’t make more specific suggestions.

That’s correct to a first approximation, though one could (I don’t advise this for your use case) call evalModules to create a distinct ‘instance’ of the module system.

But I would strongly recommend a more decoupled solution. Define a module that contains intermachine configuration (creates an option called mvb.backupServerName, for example), import (using imports = [ ... ];) that module in your backup server config and use the new option to set networking.hostName, and also import (still using imports = [ ... ];) that module in your home server config and use it to set services.restic.backup.endpoint.

1 Like

Okay seeing the post-edit I get what you mean now.
In that case the only method I could think of would be to shove in a new module arg or use lib.evalModules to create an “enclosing” instance of the module system (though that sounds highly prone to infrec if misused).

1 Like