diff --git a/flake.nix b/flake.nix index ece4207..ff9a365 100644 --- a/flake.nix +++ b/flake.nix @@ -133,10 +133,7 @@ }; }; - outputs = inputs: let - inherit (inputs) self; - inherit (self) outputs; - in + outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } ({ withSystem, flake-parts-lib, ... }: { systems = [ "aarch64-linux" @@ -147,12 +144,12 @@ ]; imports = [ - ./nix/pkgs.nix - ./nix/modules.nix - ./nix/configurations.nix - ./nix/agenix.nix - ./nix/deploy.nix - ./nix/topology + ./modules/flake/pkgs.nix + ./modules/flake/modules.nix + ./modules/flake/configurations.nix + ./modules/flake/agenix.nix + ./modules/flake/deploy.nix + ./modules/flake/topology ]; perSystem = { lib, pkgs, system, ... }: { @@ -170,10 +167,14 @@ }; flake = { - inherit self; + inherit (inputs) self; + # Automatic modules, see `./modules/flake/modules.nix` autoModules.enableAll = true; + # Automatic configurations, see `./modules/flake/configurations.nix` + autoConfigurations.enableAll = true; + # Templates templates = import ./templates { inherit inputs; diff --git a/nix/agenix.nix b/modules/flake/agenix.nix similarity index 100% rename from nix/agenix.nix rename to modules/flake/agenix.nix diff --git a/modules/flake/configurations.nix b/modules/flake/configurations.nix new file mode 100644 index 0000000..485bb3b --- /dev/null +++ b/modules/flake/configurations.nix @@ -0,0 +1,299 @@ +{ lib, config, self, inputs, withSystem, ... }: + +let + outputs = self; + inherit (import ../../nix/utils.nix { inherit lib self; }) + and + hasFiles + hasDirectories + recurseDir + configuration-type-to-outputs-machines; +in +let + homeManagerModule = { root, system, hostname, users ? null }: { + home-manager = { + # Use same `pkgs` instance as system (i.e. carry over overlays) + useGlobalPkgs = true; + # Do not keep packages in ${HOME} + useUserPackages = true; + # Default import all of our exported homeManagerModules + sharedModules = builtins.attrValues config.flake.homeManagerModules; + # Pass in `inputs`, `outputs` and maybe `meta` + extraSpecialArgs = { + inherit inputs outputs; + # TODO: meta? + inherit hostname; + }; + } // (if users == null then { + # nixOnDroid + config = "${root}/home.nix"; + } else { + # Not nixOnDroid + users = lib.attrsets.genAttrs + users + (user: import "${root}/home/${user}.nix"); + }); + }; + + # Configuration helpers + configurationTypes = ["nixos" "nix-on-droid" "nix-darwin" "home-manager"]; + + mkNixosHost = args @ { root, system, hostname, users }: lib.nixosSystem { + inherit system; + pkgs = withSystem system ({ pkgs, ... }: pkgs); + + modules = [ + # Main configuration + "${root}/configuration.nix" + # Home Manager + inputs.home-manager.nixosModules.home-manager + (homeManagerModule args) + # (r)agenix && agenix-rekey + inputs.ragenix.nixosModules.default + inputs.agenix-rekey.nixosModules.default + # nix-topology + inputs.nix-topology.nixosModules.default + # Sane default `networking.hostName` + { + networking.hostName = lib.mkDefault hostname; + } + ] ++ (builtins.attrValues config.flake.nixosModules); + + specialArgs = { + inherit inputs outputs; + }; + }; + + mkNixOnDroidHost = args @ { root, system, hostname }: inputs.nix-on-droid.lib.nixOnDroidConfiguration { + # NOTE: inferred by `pkgs.system` + # inherit system; + pkgs = withSystem system ({ pkgs, ... }: pkgs); + + modules = [ + # Main configuration + "${root}/configuration.nix" + # Home Manager + (homeManagerModule args) + ] ++ (builtins.attrValues config.flake.nixOnDroidModules); + + extraSpecialArgs = { + inherit inputs outputs; + }; + + home-manager-path = inputs.home-manager.outPath; + }; + + mkNixDarwinHost = args @ { root, system, hostname, users }: inputs.nix-darwin.lib.darwinSystem { + inherit system; + pkgs = withSystem system ({ pkgs, ... }: pkgs); + + modules = [ + # Main configuration + "${root}/configuration.nix" + # Home Manager + inputs.home-manager.darwinModules.home-manager + (homeManagerModule args) + # # Set `nixpkgs.hostPlatform` + # { + # nixpkgs.hostPlatform = system; + # } + ] ++ (builtins.attrValues config.flake.nixDarwinModules); + + specialArgs = { + inherit inputs outputs; + }; + }; + + mkHomeManagerHost = args @ { root, system, hostname }: inputs.home-manager.lib.homeManagerConfiguration { + inherit system; + pkgs = withSystem system ({ pkgs, ... }: pkgs); + + modules = [ + "${root}/home.nix" + ] ++ (builtins.attrValues config.flake.homeManagerModules); + + extraSpecialArgs = { + inherit inputs outputs; + inherit hostname; + }; + }; + + createConfigurations = + pred: mkHost: machines: + lib.foldAttrs + lib.const + [ ] + (builtins.attrValues + (builtins.mapAttrs + (system: hosts: + lib.concatMapAttrs + (host: configurationFiles: + lib.optionalAttrs + (and [ + (host != "__template__") + (pred { inherit system host configurationFiles; }) + ]) + { + ${host} = mkHost { inherit system host configurationFiles; }; + }) + hosts) + machines)); +in +{ + options = let + inherit (lib) types; + in { + flake.autoConfigurations = lib.mkOption { + description = '' + Automagically generate configurations from walking directories with Nix files + ''; + type = types.submodule (submodule: { + options = { + enableAll = lib.mkEnableOption "Automatic ${builtins.toString configurationTypes} configurations extraction"; + baseDir = lib.mkOption { + description = '' + Base directory of the contained configurations, used as a base for the rest of the options + ''; + type = types.path; + default = "${self}/machines"; + defaultText = ''''${self}/machines''; + }; + } // ( + lib.pipe + configurationTypes + [ + (builtins.map + # NOTE: create small submodule for every `configurationType` + (configurationType: + lib.nameValuePair + "${configurationType}" + (lib.mkOption { + type = types.submodule { + options = { + # NOTE: each can be enabled (default global `enableAll`) + enable = lib.mkEnableOption "Automatic ${configurationType} configurations extraction" // { + default = submodule.config.enableAll; + }; + # NOTE: each can be read from a different directory + # (default global `baseDir` + `camelToKebab`-ed `configurationType`) + dir = lib.mkOption { + type = types.path; + default = "${submodule.config.baseDir}/${configurationType}"; + }; + }; + }; + default = {}; + }))) + builtins.listToAttrs + ]); + }); + default = {}; + }; + }; + + config = { + flake = let + autoMachines = + lib.pipe + configurationTypes + [ + (builtins.map + (configurationType: + lib.nameValuePair + "${configuration-type-to-outputs-machines configurationType}" + (if config.flake.autoConfigurations.${configurationType}.enable + then recurseDir config.flake.autoConfigurations.${configurationType}.dir + else { }))) + builtins.listToAttrs + ]; + in { + # Machines + inherit (autoMachines) + nixosMachines + nixDarwinMachines + nixOnDroidMachines + homeManagerMachines; + + # Configurations + nixosConfigurations = + createConfigurations + ({ system, host, configurationFiles, ... }: + and + [ + (hasFiles + [ "configuration.nix" ] + configurationFiles) + # (hasDirectories + # [ "home" ] + # config) + ]) + ({ system, host, configurationFiles, ... }: + mkNixosHost { + root = "${config.flake.autoConfigurations.nixos.dir}/${system}/${host}"; + inherit system; + hostname = host; + users = (builtins.map + (lib.strings.removeSuffix ".nix") + (builtins.attrNames (configurationFiles."home" or { }))); + }) + config.flake.nixosMachines; + + nixOnDroidConfigurations = + createConfigurations + ({ system, host, configurationFiles, ... }: + and + [ + (hasFiles + [ "configuration.nix" "home.nix" ] + configurationFiles) + ]) + ({ system, host, configurationFiles, ... }: + mkNixOnDroidHost { + root = "${config.flake.autoConfigurations.nix-on-droid.dir}/${system}/${host}"; + inherit system; + hostname = host; + }) + config.flake.nixOnDroidMachines; + + darwinConfigurations = + createConfigurations + ({ system, host, configurationFiles, ... }: + and + [ + (hasFiles + [ "configuration.nix" ] + configurationFiles) + (hasDirectories + [ "home" ] + configurationFiles) + ]) + ({ system, host, configurationFiles, ... }: + mkNixDarwinHost { + root = "${config.flake.autoConfigurations.nix-darwin.dir}/${system}/${host}"; + inherit system; + hostname = host; + users = (builtins.map + (lib.strings.removeSuffix ".nix") + (builtins.attrNames (configurationFiles."home" or { }))); + }) + config.flake.nixDarwinMachines; + + homeConfigurations = + createConfigurations + ({ system, host, configurationFiles, ... }: + and + [ + (hasFiles + [ "home.nix" ] + configurationFiles) + ]) + ({ system, host, configurationFiles, ... }: + mkHomeManagerHost { + root = "${config.flake.homeManager.home-manager.dir}/${system}/${host}"; + inherit system; + hostname = host; + }) + config.flake.homeManagerMachines; + }; + }; +} diff --git a/nix/deploy.nix b/modules/flake/deploy.nix similarity index 87% rename from nix/deploy.nix rename to modules/flake/deploy.nix index fdac8b0..46dc4e7 100644 --- a/nix/deploy.nix +++ b/modules/flake/deploy.nix @@ -1,7 +1,7 @@ { lib, config, self, inputs, ... }: let - inherit (import ./utils.nix { inherit lib self; }) + inherit (import ../../nix/utils.nix { inherit lib self; }) accumulateMachines configuration-type-to-deploy-type; in @@ -14,7 +14,7 @@ in ({ host, system, configuration-type, configuration }: let deploy-config-path = - ../machines/${configuration-type}/${system}/${host}/deploy.nix; + "${config.flake.autoConfigurations.${configuration-type}.dir}/${system}/${host}/deploy.nix"; deploy-config = import deploy-config-path; in diff --git a/nix/modules.nix b/modules/flake/modules.nix similarity index 92% rename from nix/modules.nix rename to modules/flake/modules.nix index 993a097..10017e0 100644 --- a/nix/modules.nix +++ b/modules/flake/modules.nix @@ -2,15 +2,16 @@ let outputs = self; - inherit (import ./utils.nix { inherit lib self; }) + inherit (import ../../nix/utils.nix { inherit lib self; }) eq and hasFiles - camelToKebab; + configuration-type-to-outputs-modules; in let # Modules helpers - moduleTypes = ["nixos" "nixOnDroid" "nixDarwin" "homeManager" "flake"]; + moduleTypes = ["nixos" "nix-on-droid" "nix-darwin" "home-manager" "flake"]; + createModules = baseDir: { passthru ? { inherit inputs outputs; }, ... }: lib.pipe baseDir [ # Read given directory @@ -68,7 +69,7 @@ in in { flake.autoModules = lib.mkOption { description = '' - Automagivally generate modules from walking directories with Nix files + Automagically generate modules from walking directories with Nix files ''; type = types.submodule (submodule: { options = { @@ -101,7 +102,7 @@ in # (default global `baseDir` + `camelToKebab`-ed `moduleType`) dir = lib.mkOption { type = types.path; - default = "${submodule.config.baseDir}/${camelToKebab moduleType}"; + default = "${submodule.config.baseDir}/${moduleType}"; }; }; }; @@ -123,7 +124,7 @@ in (builtins.map (moduleType: lib.nameValuePair - "${moduleType}Modules" + "${configuration-type-to-outputs-modules moduleType}" (if config.flake.autoModules.${moduleType}.enable then createModules config.flake.autoModules.${moduleType}.dir { } else { }))) diff --git a/nix/pkgs.nix b/modules/flake/pkgs.nix similarity index 100% rename from nix/pkgs.nix rename to modules/flake/pkgs.nix diff --git a/nix/topology/default.nix b/modules/flake/topology/default.nix similarity index 79% rename from nix/topology/default.nix rename to modules/flake/topology/default.nix index e1dcc85..005f1a2 100644 --- a/nix/topology/default.nix +++ b/modules/flake/topology/default.nix @@ -23,32 +23,38 @@ -shave 1x1 \ $out ''; - images.TL-WR740N = removebg { - image = pkgs.fetchurl { - name = "TL-WR740N.jpg"; - url = "https://static.tp-link.com/res/images/products/TL-WR740N_un_V6_1068_large_2_20150807163606.jpg"; - hash = "sha256-/NpnnDh2V015lc3TGzez9eS8rINFtzVbCdN7d85NOt4="; + images = { + TL-WR740N = removebg { + image = pkgs.fetchurl { + name = "TL-WR740N.jpg"; + url = "https://static.tp-link.com/res/images/products/TL-WR740N_un_V6_1068_large_2_20150807163606.jpg"; + hash = "sha256-/NpnnDh2V015lc3TGzez9eS8rINFtzVbCdN7d85NOt4="; + }; + fuzz = 15; }; - fuzz = 15; - }; - images.ZBT-WR8305RT = removebg { - image = pkgs.fetchurl { - name = "ZBT-WR8305RT.jpg"; - url = "https://vseplus.com/images/p/full/213140a.jpg"; - hash = "sha256-ftTuXaBm99n+y+6fpRf0i63ykDx6xoJgwsQFpu2fNy4="; + ZBT-WR8305RT = removebg { + image = pkgs.fetchurl { + name = "ZBT-WR8305RT.jpg"; + url = "https://vseplus.com/images/p/full/213140a.jpg"; + hash = "sha256-ftTuXaBm99n+y+6fpRf0i63ykDx6xoJgwsQFpu2fNy4="; + }; + fuzz = 2; }; - fuzz = 2; - }; - images.cheetah = removebg { - image = pkgs.fetchurl { - name = "cheetah.jpg"; - url = "https://m.media-amazon.com/images/I/51OFxuD1GgL._AC_SL1000_.jpg"; - hash = "sha256-Lvylh1geh81FZpqK1shj108M217zobWRgR4mEfbvKrc="; + cheetah = removebg { + image = pkgs.fetchurl { + name = "cheetah.jpg"; + url = "https://m.media-amazon.com/images/I/51OFxuD1GgL._AC_SL1000_.jpg"; + hash = "sha256-Lvylh1geh81FZpqK1shj108M217zobWRgR4mEfbvKrc="; + }; + fuzz = 20; }; - fuzz = 20; }; in { topology = { + # nixosConfigurations = { + # inherit (self.nixosConfigurations) + # jeeves; + # }; nixosConfigurations = self.nixosConfigurations; modules = [ ({ config, ... }: let diff --git a/nix/configurations.nix b/nix/configurations.nix deleted file mode 100644 index 0ebd331..0000000 --- a/nix/configurations.nix +++ /dev/null @@ -1,225 +0,0 @@ -{ lib, config, self, inputs, withSystem, ... }: - -let - outputs = self; - inherit (import ./utils.nix { inherit lib self; }) - and - hasFiles - hasDirectories; -in -let - homeManagerModule = { root, system, hostname, users ? null }: { - home-manager = { - # Use same `pkgs` instance as system (i.e. carry over overlays) - useGlobalPkgs = true; - # Do not keep packages in ${HOME} - useUserPackages = true; - # Default import all of our exported homeManagerModules - sharedModules = builtins.attrValues config.flake.homeManagerModules; - # Pass in `inputs`, `outputs` and maybe `meta` - extraSpecialArgs = { - inherit inputs outputs; - # TODO: meta? - inherit hostname; - }; - } // (if users == null then { - # nixOnDroid - config = (lib.path.append root "home.nix"); - } else { - # Not nixOnDroid - users = lib.attrsets.genAttrs - users - (user: import (lib.path.append root "home/${user}.nix")); - }); - }; - - # Configuration helpers - mkNixosHost = args @ { root, system, hostname, users }: lib.nixosSystem { - inherit system; - pkgs = withSystem system ({ pkgs, ... }: pkgs); - - modules = [ - # Main configuration - (lib.path.append root "configuration.nix") - # Home Manager - inputs.home-manager.nixosModules.home-manager - (homeManagerModule args) - # (r)agenix && agenix-rekey - inputs.ragenix.nixosModules.default - inputs.agenix-rekey.nixosModules.default - # nix-topology - inputs.nix-topology.nixosModules.default - # Sane default `networking.hostName` - { - networking.hostName = lib.mkDefault hostname; - } - ] ++ (builtins.attrValues config.flake.nixosModules); - - specialArgs = { - inherit inputs outputs; - }; - }; - - mkNixOnDroidHost = args @ { root, system, hostname }: inputs.nix-on-droid.lib.nixOnDroidConfiguration { - # NOTE: inferred by `pkgs.system` - # inherit system; - pkgs = withSystem system ({ pkgs, ... }: pkgs); - - modules = [ - # Main configuration - (lib.path.append root "configuration.nix") - # Home Manager - (homeManagerModule args) - ] ++ (builtins.attrValues config.flake.nixOnDroidModules); - - extraSpecialArgs = { - inherit inputs outputs; - }; - - home-manager-path = inputs.home-manager.outPath; - }; - - mkNixDarwinHost = args @ { root, system, hostname, users }: inputs.nix-darwin.lib.darwinSystem { - inherit system; - pkgs = withSystem system ({ pkgs, ... }: pkgs); - - modules = [ - # Main configuration - (lib.path.append root "configuration.nix") - # Home Manager - inputs.home-manager.darwinModules.home-manager - (homeManagerModule args) - # # Set `nixpkgs.hostPlatform` - # { - # nixpkgs.hostPlatform = system; - # } - ] ++ (builtins.attrValues config.flake.nixDarwinModules); - - specialArgs = { - inherit inputs outputs; - }; - }; - - mkHomeManagerHost = args @ { root, system, hostname }: inputs.home-manager.lib.homeManagerConfiguration { - inherit system; - pkgs = withSystem system ({ pkgs, ... }: pkgs); - - modules = [ - (lib.path.append root "home.nix") - ] ++ (builtins.attrValues config.flake.homeManagerModules); - - extraSpecialArgs = { - inherit inputs outputs; - inherit hostname; - }; - }; - - createConfigurations = - pred: mkHost: machines: - lib.foldAttrs - lib.const - [ ] - (builtins.attrValues - (builtins.mapAttrs - (system: hosts: - lib.concatMapAttrs - (host: configurationFiles: - lib.optionalAttrs - (and [ - (host != "__template__") - (pred { inherit system host configurationFiles; }) - ]) - { - ${host} = mkHost { inherit system host configurationFiles; }; - }) - hosts) - machines)); -in -{ - imports = [ - ./machines.nix - ]; - - flake = { - # Configurations - nixosConfigurations = - createConfigurations - ({ system, host, configurationFiles, ... }: - and - [ - (hasFiles - [ "configuration.nix" ] - configurationFiles) - # (hasDirectories - # [ "home" ] - # config) - ]) - ({ system, host, configurationFiles, ... }: - mkNixosHost { - root = ../machines/nixos/${system}/${host}; - inherit system; - hostname = host; - users = (builtins.map - (lib.strings.removeSuffix ".nix") - (builtins.attrNames (configurationFiles."home" or { }))); - }) - config.flake.nixosMachines; - - nixOnDroidConfigurations = - createConfigurations - ({ system, host, configurationFiles, ... }: - and - [ - (hasFiles - [ "configuration.nix" "home.nix" ] - configurationFiles) - ]) - ({ system, host, configurationFiles, ... }: - mkNixOnDroidHost { - root = ../machines/nix-on-droid/${system}/${host}; - inherit system; - hostname = host; - }) - config.flake.nixOnDroidMachines; - - darwinConfigurations = - createConfigurations - ({ system, host, configurationFiles, ... }: - and - [ - (hasFiles - [ "configuration.nix" ] - configurationFiles) - (hasDirectories - [ "home" ] - configurationFiles) - ]) - ({ system, host, configurationFiles, ... }: - mkNixDarwinHost { - root = ../machines/nix-darwin/${system}/${host}; - inherit system; - hostname = host; - users = (builtins.map - (lib.strings.removeSuffix ".nix") - (builtins.attrNames (configurationFiles."home" or { }))); - }) - config.flake.nixDarwinMachines; - - homeConfigurations = - createConfigurations - ({ system, host, configurationFiles, ... }: - and - [ - (hasFiles - [ "home.nix" ] - configurationFiles) - ]) - ({ system, host, configurationFiles, ... }: - mkHomeManagerHost { - root = ../machines/home-manager/${system}/${host}; - inherit system; - hostname = host; - }) - config.flake.homeManagerMachines; - }; -} diff --git a/nix/machines.nix b/nix/machines.nix deleted file mode 100644 index 6dd4b23..0000000 --- a/nix/machines.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ lib, config, self, inputs, ... }: - -let - inherit (import ./utils.nix { inherit lib self; }) - recurseDir; -in -let - machines = recurseDir ../machines; -in -{ - flake = { - # Machines - nixosMachines = machines.nixos or { }; - nixDarwinMachines = machines.nix-darwin or { }; - nixOnDroidMachines = machines.nix-on-droid or { }; - homeManagerMachines = machines.home-manager or { }; - }; -} diff --git a/nix/utils.nix b/nix/utils.nix index 10b32c5..f3a05dd 100644 --- a/nix/utils.nix +++ b/nix/utils.nix @@ -34,7 +34,7 @@ rec { lib.stringAsChars (c: if c == lib.toUpper c then "-${lib.toLower c}" else c); - # NOTE: from Tweag's Nix Hour 76 - + # NOTE: from Tweag's Nix Hour 76 - mutFirstChar = f: s: let @@ -55,18 +55,33 @@ rec { (builtins.throw (mkError configuration-type)); + # TODO: abstract away `_Machines` and `_Modules` + configuration-type-to-outputs-machines = gen-configuration-type-to { nixos = "nixosMachines"; nix-on-droid = "nixOnDroidMachines"; nix-darwin = "nixDarwinMachines"; - home-manager = "homeMachines"; + home-manager = "homeManagerMachines"; } (configuration-type: builtins.throw "Invaild configuration-type \"${configuration-type}\" for flake outputs' machines"); + configuration-type-to-outputs-modules = + gen-configuration-type-to + { + nixos = "nixosModules"; + nix-on-droid = "nixOnDroidModules"; + nix-darwin = "nixDarwinModules"; + home-manager = "homeManagerModules"; + flake = "flakeModules"; + } + (configuration-type: + builtins.throw + "Invaild configuration-type \"${configuration-type}\" for flake outputs' modules"); + configuration-type-to-outputs-configurations = gen-configuration-type-to {