rix101/modules/flake/configurations.nix
reo101 2941536b80
refactor(flake)!: export packages using a flake module
Also stop passing `outputs` around, prefer `inputs.self`
Also put all `auto_` in `readOnly` `internal` options
- `autoModules`, `autoConfigurations` and `autoPackages`
Do not export packages as overlay (causes an infinite recursion)
- this is documented on the two places it has effect on
-- in `./overlays/default.nix` and `./modules/flake/configurations.nix`
-- in `autoConfigurations` we manually extend `pkgs` with the flake packages
Allow packages to say what `systems` they are compatible with
- See `./pkgs/swww/systems.nix` - disabled for all systems
- See `./pkgs/pngpaste/systems.nix` - enabled only for `darwin` targets
2024-07-29 01:54:22 +03:00

298 lines
9.6 KiB
Nix

{ lib, config, self, inputs, withSystem, ... }:
let
inherit (import ../../nix/utils.nix { inherit lib config self; })
and
hasFiles
hasDirectories
recurseDir
configuration-type-to-outputs-modules;
in
let
# Configuration helpers
configurationTypes = ["nixos" "nix-on-droid" "nix-darwin" "home-manager"];
# `pkgs` with flake's overlays
# NOTE: done here to avoid infinite recursion
pkgs' = system:
(withSystem system ({ pkgs, ... }: pkgs)).extend
(final: prev: inputs.self.packages.${system});
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 `home-manager` modules
sharedModules = builtins.attrValues config.flake.${configuration-type-to-outputs-modules "home-manager"};
# Pass in `inputs`, `outputs` and maybe `meta`
extraSpecialArgs = {
inherit inputs;
# 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");
});
};
mkNixosHost = args @ { root, system, hostname, users }: inputs.nixpkgs.lib.nixosSystem {
inherit system;
pkgs = pkgs' system;
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.${configuration-type-to-outputs-modules "nixos"});
specialArgs = {
inherit inputs;
};
};
mkNixOnDroidHost = args @ { root, system, hostname }: inputs.nix-on-droid.lib.nixOnDroidConfiguration {
# NOTE: inferred by `pkgs.system`
# inherit system;
pkgs = pkgs' system;
modules = [
# Main configuration
"${root}/configuration.nix"
# Home Manager
(homeManagerModule args)
] ++ (builtins.attrValues config.flake.${configuration-type-to-outputs-modules "nix-on-droid"});
extraSpecialArgs = {
inherit inputs;
};
home-manager-path = inputs.home-manager.outPath;
};
mkNixDarwinHost = args @ { root, system, hostname, users }: inputs.nix-darwin.lib.darwinSystem {
inherit system;
pkgs = pkgs' system;
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.${configuration-type-to-outputs-modules "nix-darwin"});
specialArgs = {
inherit inputs;
};
};
mkHomeManagerHost = args @ { root, system, hostname }: inputs.home-manager.lib.homeManagerConfiguration {
inherit system;
pkgs = pkgs' system;
modules = [
"${root}/home.nix"
] ++ (builtins.attrValues config.flake.${configuration-type-to-outputs-modules "home-manager"});
extraSpecialArgs = {
inherit inputs;
inherit hostname;
};
};
createConfigurations =
pred: mkHost: hosts:
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)
hosts));
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}/hosts";
defaultText = ''''${self}/hosts'';
};
} // (
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}";
};
# TODO: split hosts and configurations?
resultHosts = lib.mkOption {
description = ''
The resulting automatic packages
'';
# TODO: specify
type = types.unspecified;
readOnly = true;
internal = true;
default =
lib.optionalAttrs
config.flake.autoConfigurations.${configurationType}.enable
(recurseDir config.flake.autoConfigurations.${configurationType}.dir);
};
};
};
default = {};
})))
builtins.listToAttrs
]);
});
default = {};
};
};
config = {
flake = {
# 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.autoConfigurations.nixos.resultHosts;
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.autoConfigurations.nix-on-droid.resultHosts;
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.autoConfigurations.nix-darwin.resultHosts;
homeConfigurations =
createConfigurations
({ system, host, configurationFiles, ... }:
and
[
(hasFiles
[ "home.nix" ]
configurationFiles)
])
({ system, host, configurationFiles, ... }:
mkHomeManagerHost {
root = "${config.flake.autoConfigurations.home-manager.dir}/${system}/${host}";
inherit system;
hostname = host;
})
config.flake.autoConfigurations.home-manager.resultHosts;
};
};
}