2024-07-25 00:25:21 +02:00
|
|
|
{ lib, config, self, inputs, withSystem, ... }:
|
|
|
|
|
|
|
|
let
|
2024-07-29 01:11:32 +02:00
|
|
|
inherit (config.lib)
|
2024-07-25 00:25:21 +02:00
|
|
|
and
|
|
|
|
hasFiles
|
|
|
|
hasDirectories
|
|
|
|
recurseDir
|
2024-08-13 14:53:14 +02:00
|
|
|
kebabToCamel
|
2024-09-01 03:29:32 +02:00
|
|
|
configuration-type-to-outputs-modules;
|
2024-07-25 00:25:21 +02:00
|
|
|
in
|
|
|
|
{
|
2024-09-05 22:37:49 +02:00
|
|
|
imports = [
|
|
|
|
./default-generators.nix
|
|
|
|
];
|
|
|
|
|
2024-07-25 00:25:21 +02:00
|
|
|
options = let
|
|
|
|
inherit (lib) types;
|
|
|
|
in {
|
2024-09-01 03:29:32 +02:00
|
|
|
auto.configurations = lib.mkOption {
|
2024-07-25 00:25:21 +02:00
|
|
|
description = ''
|
|
|
|
Automagically generate configurations from walking directories with Nix files
|
|
|
|
'';
|
2024-08-13 14:53:14 +02:00
|
|
|
internal = true;
|
|
|
|
type = types.submodule (autoConfigurationsSubmodule: let
|
|
|
|
inherit (autoConfigurationsSubmodule.config)
|
|
|
|
configurationTypes
|
|
|
|
enableAll
|
|
|
|
baseDir
|
|
|
|
;
|
|
|
|
in {
|
2024-07-25 00:25:21 +02:00
|
|
|
options = {
|
2024-08-13 14:53:14 +02:00
|
|
|
enableAll = lib.mkEnableOption ''
|
|
|
|
Automatic ${builtins.toString (lib.attrValues configurationTypes)} configurations extraction
|
|
|
|
'';
|
2024-07-25 00:25:21 +02:00
|
|
|
baseDir = lib.mkOption {
|
|
|
|
description = ''
|
|
|
|
Base directory of the contained configurations, used as a base for the rest of the options
|
|
|
|
'';
|
|
|
|
type = types.path;
|
2024-07-27 12:04:48 +02:00
|
|
|
default = "${self}/hosts";
|
|
|
|
defaultText = ''''${self}/hosts'';
|
2024-07-25 00:25:21 +02:00
|
|
|
};
|
2024-08-13 14:53:14 +02:00
|
|
|
configurationTypes = lib.mkOption {
|
|
|
|
type = types.attrsOf (types.submodule (configurationTypeSubmodule@{ name, ... }: let
|
|
|
|
inherit (configurationTypeSubmodule.config)
|
|
|
|
# enable
|
|
|
|
dir
|
|
|
|
predicate
|
|
|
|
mkHost
|
|
|
|
mkDeployNode
|
|
|
|
;
|
|
|
|
in {
|
|
|
|
options = {
|
|
|
|
enable = lib.mkEnableOption "Automatic ${name} configurations extraction" // {
|
|
|
|
default = enableAll;
|
|
|
|
};
|
|
|
|
# NOTE: each can be read from a different directory
|
|
|
|
dir = lib.mkOption {
|
|
|
|
type = types.path;
|
|
|
|
default = "${baseDir}/${name}";
|
|
|
|
};
|
|
|
|
hostsName = lib.mkOption {
|
|
|
|
description = ''
|
|
|
|
Name of the `hosts` output
|
|
|
|
'';
|
|
|
|
type = types.str;
|
|
|
|
default = "${kebabToCamel name}Hosts";
|
|
|
|
};
|
|
|
|
configurationsName = lib.mkOption {
|
|
|
|
description = ''
|
|
|
|
Name of the `configurations` output
|
|
|
|
'';
|
|
|
|
type = types.str;
|
|
|
|
default = "${kebabToCamel name}Configurations";
|
|
|
|
};
|
|
|
|
predicate = lib.mkOption {
|
|
|
|
description = ''
|
|
|
|
Function for filtering configurations
|
|
|
|
'';
|
|
|
|
# FIXME: `merge` of `functionTo` type causes a stray `passthru` to attempt getting evaluated
|
|
|
|
# type = types.functionTo types.anything;
|
|
|
|
type = types.unspecified;
|
|
|
|
example = /* nix */ ''
|
|
|
|
{ root, host, configurationFiles, ... }:
|
|
|
|
# Utils from `./modules/flake/lib/default.nix`
|
|
|
|
and [
|
|
|
|
(! (host == "__template__"))
|
|
|
|
(hasFiles
|
|
|
|
[ "configuration.nix" ]
|
|
|
|
configurationFiles)
|
|
|
|
(hasDirectories
|
|
|
|
[ "home" ]
|
|
|
|
configurationFiles)
|
|
|
|
]
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
mkHost = lib.mkOption {
|
|
|
|
description = ''
|
|
|
|
Function for generating a configuration
|
|
|
|
'';
|
|
|
|
# type = types.functionTo types.anything;
|
|
|
|
type = types.unspecified;
|
|
|
|
example = /* nix */ ''
|
|
|
|
args @ { root, meta, users }: inputs.nixpkgs.lib.nixosSystem {
|
|
|
|
inherit (meta) system;
|
|
|
|
|
|
|
|
modules = [
|
|
|
|
# Main configuration
|
|
|
|
"''${root}/configuration.nix"
|
|
|
|
# Home Manager
|
|
|
|
inputs.home-manager.nixosModules.home-manager
|
|
|
|
(homeManagerModule args)
|
|
|
|
] ++ (builtins.attrValues config.flake.''${configuration-type-to-outputs-modules "nixos"});
|
|
|
|
|
|
|
|
specialArgs = {
|
|
|
|
inherit inputs;
|
|
|
|
inherit meta;
|
2024-07-29 00:35:14 +02:00
|
|
|
};
|
2024-07-25 00:25:21 +02:00
|
|
|
};
|
2024-08-13 14:53:14 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
mkDeployNode = lib.mkOption {
|
|
|
|
description = ''
|
|
|
|
Function for generating a `deploy-rs` node (null to skip)
|
|
|
|
'';
|
|
|
|
type = types.nullOr (types.functionTo types.anything);
|
|
|
|
default = null;
|
|
|
|
# TODO: update
|
|
|
|
example = /* nix */ ''
|
2024-09-05 22:37:49 +02:00
|
|
|
{ root, host, meta, configuration }: {
|
|
|
|
inherit (meta.deploy) hostname;
|
|
|
|
profiles.system = meta.deploy // {
|
|
|
|
path = inputs.deploy-rs.lib.''${meta.system}.activate."nixos" configuration;
|
|
|
|
};
|
|
|
|
}
|
2024-08-13 14:53:14 +02:00
|
|
|
'';
|
|
|
|
};
|
2024-09-05 22:37:49 +02:00
|
|
|
result = lib.mkOption {
|
2024-08-13 14:53:14 +02:00
|
|
|
description = ''
|
2024-09-05 22:37:49 +02:00
|
|
|
The resulting automatic host && deploy-rs configurations
|
2024-08-13 14:53:14 +02:00
|
|
|
'';
|
|
|
|
# TODO: specify
|
|
|
|
type = types.unspecified;
|
|
|
|
readOnly = true;
|
|
|
|
default =
|
|
|
|
lib.pipe dir [
|
|
|
|
recurseDir
|
|
|
|
(lib.concatMapAttrs
|
|
|
|
(host: configurationFiles:
|
|
|
|
let
|
|
|
|
root = "${dir}/${host}";
|
|
|
|
meta-path = "${root}/meta.nix";
|
2024-09-05 22:37:49 +02:00
|
|
|
meta = (lib.evalModules {
|
|
|
|
class = "meta";
|
|
|
|
modules = [
|
|
|
|
(if builtins.pathExists meta-path
|
|
|
|
then import meta-path
|
|
|
|
else {})
|
|
|
|
./meta-module.nix
|
|
|
|
{
|
|
|
|
config = {
|
|
|
|
enable = lib.mkDefault (host != "__template__");
|
|
|
|
hostname = lib.mkDefault host;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
];
|
|
|
|
}).config;
|
|
|
|
deploy-config = meta.deploy;
|
2024-08-13 14:53:14 +02:00
|
|
|
has-mkDeployNode = mkDeployNode != null;
|
2024-09-05 22:37:49 +02:00
|
|
|
has-deploy-config = deploy-config != null;
|
|
|
|
configuration-args = { inherit root meta configurationFiles; };
|
2024-08-13 14:53:14 +02:00
|
|
|
valid = predicate configuration-args;
|
|
|
|
configuration = mkHost configuration-args;
|
2024-09-05 22:37:49 +02:00
|
|
|
deploy-args = { inherit root meta configuration; };
|
2024-08-13 14:53:14 +02:00
|
|
|
deploy = mkDeployNode deploy-args;
|
|
|
|
in
|
|
|
|
lib.optionalAttrs valid {
|
|
|
|
${host} = {
|
|
|
|
inherit configuration;
|
|
|
|
} // lib.optionalAttrs (has-mkDeployNode && has-deploy-config) {
|
|
|
|
inherit deploy;
|
|
|
|
};
|
|
|
|
}))
|
|
|
|
];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}));
|
2024-09-05 22:37:49 +02:00
|
|
|
default = {};
|
2024-08-13 14:53:14 +02:00
|
|
|
};
|
2024-09-05 22:37:49 +02:00
|
|
|
result = lib.mkOption {
|
2024-08-13 14:53:14 +02:00
|
|
|
readOnly = true;
|
2024-09-05 22:37:49 +02:00
|
|
|
default = {
|
|
|
|
configurations =
|
|
|
|
lib.pipe configurationTypes [
|
|
|
|
(lib.mapAttrs'
|
|
|
|
(configurationType: configurationTypeConfig:
|
|
|
|
lib.nameValuePair
|
|
|
|
configurationTypeConfig.configurationsName
|
|
|
|
(lib.mapAttrs
|
|
|
|
(host: { configuration, ... }:
|
|
|
|
configuration)
|
|
|
|
configurationTypeConfig.result)))
|
|
|
|
];
|
|
|
|
deployNodes =
|
|
|
|
lib.pipe configurationTypes [
|
2024-08-13 14:53:14 +02:00
|
|
|
(lib.concatMapAttrs
|
2024-09-05 22:37:49 +02:00
|
|
|
(configurationType: configurationTypeConfig:
|
|
|
|
(lib.concatMapAttrs
|
|
|
|
(host: { deploy ? null, ... }:
|
|
|
|
lib.optionalAttrs
|
|
|
|
(deploy != null)
|
|
|
|
{
|
|
|
|
${host} = deploy;
|
|
|
|
})
|
|
|
|
configurationTypeConfig.result)))
|
|
|
|
];
|
|
|
|
};
|
2024-08-13 14:53:14 +02:00
|
|
|
};
|
|
|
|
};
|
2024-07-25 00:25:21 +02:00
|
|
|
});
|
|
|
|
default = {};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = {
|
2024-08-13 14:53:14 +02:00
|
|
|
flake = let
|
2024-09-05 22:37:49 +02:00
|
|
|
configurations = config.auto.configurations.result.configurations;
|
2024-08-13 14:53:14 +02:00
|
|
|
deployNodes = {
|
2024-09-05 22:37:49 +02:00
|
|
|
deploy.nodes = config.auto.configurations.result.deployNodes;
|
2024-08-13 14:53:14 +02:00
|
|
|
};
|
|
|
|
deployChecks = {
|
|
|
|
checks =
|
|
|
|
lib.mapAttrs
|
|
|
|
(system: deployLib:
|
|
|
|
deployLib.deployChecks
|
|
|
|
self.deploy)
|
|
|
|
inputs.deploy-rs.lib;
|
|
|
|
};
|
|
|
|
# TODO: lib.something for merging (asserting for no overwrites)
|
|
|
|
in configurations // deployNodes // deployChecks;
|
2024-07-25 00:25:21 +02:00
|
|
|
};
|
|
|
|
}
|