infinisil / nixus

Experimental deployment tool supporting multi-host abstractions
GNU General Public License v3.0
195 stars 15 forks source link

`specialArgs.sources`, infinite recursion #55

Open eyJhb opened 8 months ago

eyJhb commented 8 months ago

Hello @infinisil !

I think I almost figured it out. I've based my solution on yours, where I've added specialArgs.sources = sources, and config._module.args.sources = sources; to my deploy file. This actually works well, until I try to use sources inside a module.

Ie, the below causes a infinite recursion, and AFAIK, it's only inside modules this happens.

{ config, lib, sources, ... }:

with lib;

{
  options.mine.state.enable = mkOption {
    type = types.bool;
    default = false;
  };

  imports = [
    (sources.impermanence + "/nixos.nix")
  ];

  config = mkIf config.mine.state.enable {
    environment.persistence = {
      root = {
        persistentStoragePath = "/state/root";

        directories = [
          "/var/lib/nixos"
          "/var/lib/nixus-secrets"
          "/var/log"
        ];
      };
    };
  };
}

Is this just a NixOS limitation?

eyJhb commented 8 months ago

Basic poc can be seen here https://gist.github.com/eyJhb/a1bee280d82ecf018a9dd888d29888c1

infinisil commented 8 months ago

Ahh the problem is that specialArgs.sources is set on the Nixus-module level, not on the NixOS-module level. So the sources argument doesn't actually exist for the NixOS module you're trying to use it in. In this case it tries to fallback to evaluating _module.args.sources, though that fails because it needs to know sources to even evaluate imports.

In my own config I used _module.args.sources, but didn't run into problems because I'm never using its value in imports: https://github.com/infinisil/system/blob/07534666e0592d9ceb1fc157dc48baa7b1494d99/default.nix#L68

You can do this instead, though ideally this would be exposed in a more convenient way by Nixus directly:

diff --git a/default.nix b/default.nix
index 0afbc67..28b45c3 100644
--- a/default.nix
+++ b/default.nix
@@ -1,15 +1,24 @@
 let
   sources = import ./sources.nix;
 in import sources.nixus {
-  specialArgs.sources = sources;
-} ({ config, ... }: {
+} ({ config, lib, ... }: {
+
   defaults = { lib, name, ... }: {
-    configuration = {
-      config._module.args.sources = sources;
-      config.networking.hostName = lib.mkDefault name;
+
+    options.configuration = lib.mkOption {
+      type = lib.types.submoduleWith {
+        modules = [];
+        specialArgs.sources = sources;
+      };
     };

-    nixpkgs = lib.mkDefault sources.nixpkgs-stable;
+    config = {
+      configuration = {
+        config.networking.hostName = lib.mkDefault name;
+      };
+
+      nixpkgs = lib.mkDefault sources.nixpkgs-stable;
+    };
   };
eyJhb commented 8 months ago

Works! Thanks! Should we keep this issue open, until it maybe might at some point, be implemented into nixus?

infinisil commented 8 months ago

Yeah sounds good :)