From cdbb69617f9f4c8e878552f0b0d18d4f32c80aab Mon Sep 17 00:00:00 2001
From: Zhaofeng Li <hello@zhaofeng.li>
Date: Sat, 1 Jan 2022 16:41:35 -0800
Subject: [PATCH] eval.nix: Support specifying a list of configs

---
 src/nix/hive/eval.nix     | 14 ++++++++++----
 src/nix/hive/tests/mod.rs | 22 ++++++++++++++++++++++
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/nix/hive/eval.nix b/src/nix/hive/eval.nix
index 8e17b48..28e4471 100644
--- a/src/nix/hive/eval.nix
+++ b/src/nix/hive/eval.nix
@@ -302,6 +302,13 @@ let
     };
   in mergedHive // meta;
 
+  configsFor = node: let
+    nodeConfig = hive.${node};
+  in
+    assert lib.assertMsg (!elem node reservedNames) "\"${node}\" is a reserved name and cannot be used as the name of a node";
+    if typeOf nodeConfig == "list" then nodeConfig
+    else [ nodeConfig ];
+
   mkNixpkgs = configName: pkgConf: let
     uninitializedError = typ: ''
       Passing ${typ} as ${configName} is no longer accepted with Flakes.
@@ -348,7 +355,7 @@ let
   lib = pkgs.lib;
   reservedNames = [ "defaults" "network" "meta" ];
 
-  evalNode = name: config: let
+  evalNode = name: configs: let
     npkgs =
       if hasAttr name hive.meta.nodeNixpkgs
       then mkNixpkgs "meta.nodeNixpkgs.${name}" hive.meta.nodeNixpkgs.${name}
@@ -436,8 +443,7 @@ let
       keyChownModule
       deploymentOptions
       hive.defaults
-      config
-    ] ++ (import (npkgs.path + "/nixos/modules/module-list.nix"));
+    ] ++ configs ++ (import (npkgs.path + "/nixos/modules/module-list.nix"));
     specialArgs = hive.meta.specialArgs // {
       inherit name nodes;
       modulesPath = npkgs.path + "/nixos/modules";
@@ -452,7 +458,7 @@ let
 
   nodes = listToAttrs (map (name: {
     inherit name;
-    value = evalNode name hive.${name};
+    value = evalNode name (configsFor name);
   }) nodeNames);
 
   toplevel = lib.mapAttrs (name: eval: eval.config.system.build.toplevel) nodes;
diff --git a/src/nix/hive/tests/mod.rs b/src/nix/hive/tests/mod.rs
index 417bac1..67700e6 100644
--- a/src/nix/hive/tests/mod.rs
+++ b/src/nix/hive/tests/mod.rs
@@ -200,6 +200,28 @@ fn test_parse_unknown_option() {
     "#);
 }
 
+#[test]
+fn test_config_list() {
+    TempHive::valid(r#"
+      with builtins;
+      {
+        host-a = [
+          {
+            time.timeZone = "America/Los_Angeles";
+          }
+          {
+            deployment.tags = [ "some-tag" ];
+          }
+        ];
+        host-b = { name, nodes, ... }:
+          assert length (attrNames nodes) == 2;
+          assert nodes.host-a.config.time.timeZone == "America/Los_Angeles";
+          assert elem "some-tag" nodes.host-a.config.deployment.tags;
+        {};
+      }
+    "#);
+}
+
 #[test]
 fn test_parse_key_text() {
     TempHive::valid(r#"