diff --git a/cluster/default.nix b/cluster/default.nix new file mode 100644 index 0000000..235c279 --- /dev/null +++ b/cluster/default.nix @@ -0,0 +1,19 @@ +{ lib, hostName }: + +lib.evalModules { + modules = [ + # Arbitrary variables to reference across multiple services + ./lib/vars + { vars = { inherit hostName; }; } + + # Cluster-level port-magic + ../modules/port-magic + + ../tools/inject.nix + ./lib/load-hosts.nix + ./lib/services.nix + ./lib/inject-nixos-config.nix + + ./import-services.nix + ]; +} \ No newline at end of file diff --git a/cluster/import-services.nix b/cluster/import-services.nix new file mode 100644 index 0000000..3786319 --- /dev/null +++ b/cluster/import-services.nix @@ -0,0 +1,9 @@ +{ lib, ... }: + +let + svcs' = builtins.readDir ./services; + svcs = lib.filterAttrs (_: type: type == "directory") svcs'; + loadService = ent: import ./services/${ent}; +in { + imports = map loadService (builtins.attrNames svcs); +} diff --git a/cluster/inject.nix b/cluster/inject.nix new file mode 100644 index 0000000..66ffb22 --- /dev/null +++ b/cluster/inject.nix @@ -0,0 +1,15 @@ +hostName: +{ lib, ... }: + +let + cluster = import ./. { inherit lib hostName; }; +in + +{ + _module.args.cluster = { + inherit (cluster.config) vars; + inherit (cluster.config.vars) hosts; + inherit (cluster) config; + }; + imports = cluster.config.out.injectedNixosConfig; +} diff --git a/cluster/lib/inject-nixos-config.nix b/cluster/lib/inject-nixos-config.nix new file mode 100644 index 0000000..c8b8bc3 --- /dev/null +++ b/cluster/lib/inject-nixos-config.nix @@ -0,0 +1,10 @@ +{ config, lib, ... }: +with lib; + +{ + options.out.injectedNixosConfig = mkOption { + description = "NixOS configuration modules to inject into the host."; + type = with types; listOf anything; + default = {}; + }; +} diff --git a/cluster/lib/load-hosts.nix b/cluster/lib/load-hosts.nix new file mode 100644 index 0000000..3b86f67 --- /dev/null +++ b/cluster/lib/load-hosts.nix @@ -0,0 +1,9 @@ +{ config, lib, ... }: +let + hosts = import ../../hosts; + self = hosts.${config.vars.hostName}; + others = lib.filterAttrs (_: host: host != self) hosts; +in +{ + config.vars.hosts = hosts // { inherit self others; }; +} diff --git a/cluster/lib/service-module.nix b/cluster/lib/service-module.nix new file mode 100644 index 0000000..4b30d77 --- /dev/null +++ b/cluster/lib/service-module.nix @@ -0,0 +1,26 @@ +{ name, config, lib, ... }: +with lib; + +{ + options = { + nodes = mkOption { + description = '' + Groups of worker machines to run this service on. + Allows for arbitrary multi-node constructs, such as: + * 1 master, N workers + * N masters, M workers + * N nodes + * 1 node + * X evaluators, Y smallBuilders, Z bigBuilders + etc. + ''; + type = with types; attrsOf (oneOf [ str (listOf str) ]); + default = []; + }; + nixos = mkOption { + description = "NixOS configurations per node group."; + type = with types; attrs; + default = {}; + }; + }; +} diff --git a/cluster/lib/services.nix b/cluster/lib/services.nix new file mode 100644 index 0000000..80c60c6 --- /dev/null +++ b/cluster/lib/services.nix @@ -0,0 +1,19 @@ +{ config, lib, ... }: +with lib; + +let + getHostConfigurations = svcConfig: hostName: + lib.mapAttrsToList (groupName: _: svcConfig.nixos.${groupName}) + (lib.filterAttrs (_: v: lib.elem hostName v) svcConfig.nodes); + + getServiceConfigurations = svcConfig: getHostConfigurations svcConfig config.vars.hostName; +in + +{ + options.services = mkOption { + description = "Cluster services."; + type = with types; attrsOf (submodule (import ./service-module.nix )); + default = {}; + }; + config.out.injectedNixosConfig = lib.flatten (lib.mapAttrsToList (_: getServiceConfigurations) config.services); +} diff --git a/cluster/lib/vars/default.nix b/cluster/lib/vars/default.nix new file mode 100644 index 0000000..cdcecdd --- /dev/null +++ b/cluster/lib/vars/default.nix @@ -0,0 +1,9 @@ +{ lib, ... }: +with lib; +{ + options.vars = mkOption { + description = "Miscellaneous variables."; + type = types.attrs; + default = {}; + }; +} diff --git a/cluster/services/.keep b/cluster/services/.keep new file mode 100644 index 0000000..e69de29 diff --git a/flake.nix b/flake.nix index 30a1f73..f6507c8 100644 --- a/flake.nix +++ b/flake.nix @@ -36,7 +36,7 @@ mkNixOS' = lib: name: let host = hosts.${name}; in lib.nixosSystem { inherit specialArgs; system = "${host.arch}-linux"; - modules = [ host.nixos ./tools/inject.nix ]; + modules = [ host.nixos ./tools/inject.nix (import ./cluster/inject.nix name) ]; }; mkNixOS = mkNixOS' lib;