# TODO Add per host: # - apps to run as VMs # - checks # - deploy scripts (`nixos-rebuild`) { self, lib, config, inputs, ... }: let cfg = config.fleet; in { options.fleet = { hosts = lib.mkOption { description = "Host configuration"; type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { options = { name = lib.mkOption { description = "Host name"; type = lib.types.strMatching "^$|^[[:alnum:]]([[:alnum:]_-]{0,61}[[:alnum:]])?$"; default = name; }; system = lib.mkOption { description = "NixOS architecture (a.k.a. system)"; type = lib.types.str; default = "x86_64-linux"; }; nixpkgs = lib.mkOption { description = "Used nixpkgs"; type = lib.types.anything; default = inputs.nixpkgsUnstable; }; vpn = { ip = lib.mkOption { description = "Wireguard VPN ip"; type = lib.types.str; }; publicKey = lib.mkOption { description = "Wireguard public key"; type = lib.types.str; }; }; secrets = lib.mkOption { description = "List of secrets names in the `secrets` folder"; type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { options = { owner = lib.mkOption { type = lib.types.str; default = "root"; }; group = lib.mkOption { type = lib.types.str; default = "root"; }; file = lib.mkOption { type = lib.types.path; default = "${self.outPath}/secrets/${name}.age"; }; mode = lib.mkOption { # TODO improve type type = lib.types.str; default = "0440"; }; }; })); default = {}; }; enableHomeManager = lib.mkOption { description = "Enable home-manager module"; type = lib.types.bool; default = true; }; overlays = lib.mkOption { description = "Enabled Nixpkgs overlays"; type = lib.types.listOf (lib.mkOptionType { name = "nixpkgs-overlay"; description = "nixpkgs overlay"; check = lib.isFunction; merge = lib.mergeOneOption; }); default = []; }; extraModules = lib.mkOption { description = "Extra NixOS modules"; type = lib.types.listOf lib.types.deferredModule; default = []; }; extraHmModules = lib.mkOption { description = "Extra home-manager modules"; type = lib.types.listOf lib.types.deferredModule; default = []; }; extraHmModulesUser = lib.mkOption { description = "User for which to import extraHmModulesUser"; type = lib.types.str; default = "ccr"; }; }; config.overlays = with inputs; [ nur.overlay ] ++ cfg.overlays; })); default = {}; }; vpnExtra = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule { options = { ip = lib.mkOption { description = "Wireguard VPN ip"; type = lib.types.str; }; publicKey = lib.mkOption { description = "Wireguard public key"; type = lib.types.str; }; }; }); default = {}; }; _mkNixosConfiguration = lib.mkOption { description = "Function returning a proper NixOS configuration"; type = lib.types.functionTo (lib.types.functionTo lib.types.attrs); # TODO improve this type internal = true; default = hostname: config: config.nixpkgs.lib.nixosSystem { inherit (config) system; modules = [ ({lib, ...}: { networking.hostName = lib.mkForce hostname; nixpkgs.overlays = config.overlays; }) "${self.outPath}/hosts/${hostname}" ] ++ (lib.optionals (config.secrets != []) [ inputs.agenix.nixosModules.default ({lib, ...}: let allSecrets = lib.mapAttrs' (name: value: { name = lib.removeSuffix ".age" name; inherit value; }) (import "${self.outPath}/secrets/secrets.nix"); filteredSecrets = lib.filterAttrs (name: _: builtins.hasAttr name config.secrets) allSecrets; in { age.secrets = lib.mapAttrs' (name: _: { name = builtins.baseNameOf name; value = { inherit (config.secrets.${name}) owner group file mode; }; }) filteredSecrets; }) ]) ++ (lib.optionals config.enableHomeManager (let user = config.extraHmModulesUser; extraHmModules = config.extraHmModules; in [ inputs.homeManager.nixosModule ({ config, pkgs, ... }: { home-manager.users."${user}" = { imports = extraHmModules; _module.args = { age = config.age or {}; fleetFlake = self; pkgsStable = inputs.nixpkgsStable.legacyPackages.${pkgs.system}; }; }; }) ])) ++ config.extraModules; specialArgs = { fleetModules = builtins.map (moduleName: "${self.outPath}/modules/${moduleName}"); fleetHmModules = builtins.map (moduleName: "${self.outPath}/hmModules/${moduleName}"); fleetFlake = self; vpn = cfg.vpnExtra // (lib.mapAttrs (_: host: host.vpn) cfg.hosts); }; }; }; }; }