2021-04-19 05:29:28 +02:00
|
|
|
{ lib }:
|
|
|
|
|
2021-04-26 01:52:02 +02:00
|
|
|
{ args }:
|
2021-03-26 19:57:24 +01:00
|
|
|
let
|
2021-04-02 04:10:24 +02:00
|
|
|
argOpts = with lib; { config, ... }:
|
2021-03-26 19:57:24 +01:00
|
|
|
let
|
2021-04-18 03:35:05 +02:00
|
|
|
inherit (lib) os;
|
2021-03-26 19:57:24 +01:00
|
|
|
|
2021-04-26 01:52:02 +02:00
|
|
|
cfg = config;
|
2021-03-26 19:57:24 +01:00
|
|
|
inherit (config) self;
|
|
|
|
|
2021-04-12 05:01:13 +02:00
|
|
|
maybeImport = obj:
|
|
|
|
if (builtins.typeOf obj == "path") || (builtins.typeOf obj == "string") then
|
|
|
|
import obj
|
|
|
|
else
|
|
|
|
obj;
|
|
|
|
|
|
|
|
/* Custom types needed for arguments */
|
|
|
|
|
2021-04-12 17:42:22 +02:00
|
|
|
moduleType = with types; pathTo (anything // {
|
2021-04-10 03:22:08 +02:00
|
|
|
inherit (submodule { }) check;
|
2021-03-26 19:57:24 +01:00
|
|
|
description = "valid module";
|
2021-04-12 17:42:22 +02:00
|
|
|
});
|
2021-04-27 18:35:44 +02:00
|
|
|
|
|
|
|
# to export modules we need paths to get the name
|
|
|
|
exportModuleType = with types;
|
|
|
|
(addCheck path (x: moduleType.check (import x))) // {
|
|
|
|
description = "path to a module";
|
|
|
|
};
|
2021-04-12 17:42:22 +02:00
|
|
|
overlayType = pathTo (types.anything // {
|
2021-04-12 05:01:13 +02:00
|
|
|
check = builtins.isFunction;
|
|
|
|
description = "valid Nixpkgs overlay";
|
2021-04-12 17:42:22 +02:00
|
|
|
});
|
2021-04-12 07:25:37 +02:00
|
|
|
systemType = types.enum config.supportedSystems;
|
2021-04-02 04:10:24 +02:00
|
|
|
flakeType = with types; (addCheck attrs lib.isStorePath) // {
|
2021-04-12 05:01:13 +02:00
|
|
|
description = "nix flake";
|
|
|
|
};
|
|
|
|
|
2021-04-12 17:42:22 +02:00
|
|
|
# Apply maybeImport during merge and before check
|
2021-04-12 05:01:13 +02:00
|
|
|
# To simplify apply keys and improve type checking
|
2021-04-24 02:59:01 +02:00
|
|
|
pathTo = elemType: with types; coercedTo path maybeImport elemType;
|
2021-04-12 05:01:13 +02:00
|
|
|
|
2021-04-26 01:52:02 +02:00
|
|
|
pathToListOf = elemType: with types; pathTo (listOf elemType);
|
2021-04-12 17:42:22 +02:00
|
|
|
|
2021-04-26 01:52:02 +02:00
|
|
|
coercedListOf = elemType: with types;
|
2021-04-27 18:35:44 +02:00
|
|
|
coercedTo anything (x: flatten (singleton x)) (listOf elemType);
|
2021-04-12 05:01:13 +02:00
|
|
|
|
|
|
|
/* Submodules needed for API containers */
|
|
|
|
|
2021-04-26 01:52:02 +02:00
|
|
|
channelsModule = { name, ... }: {
|
2021-04-12 05:01:13 +02:00
|
|
|
options = with types; {
|
|
|
|
input = mkOption {
|
|
|
|
type = flakeType;
|
2021-04-26 01:52:02 +02:00
|
|
|
default = cfg.inputs.${name};
|
|
|
|
defaultText = escape [ "<" ">" ] "inputs.<name>";
|
2021-04-12 05:01:13 +02:00
|
|
|
description = ''
|
|
|
|
nixpkgs flake input to use for this channel
|
2021-04-24 03:13:03 +02:00
|
|
|
'';
|
2021-04-12 05:01:13 +02:00
|
|
|
};
|
|
|
|
overlays = mkOption {
|
2021-04-27 18:35:44 +02:00
|
|
|
type = coercedListOf overlayType;
|
2021-04-12 05:01:13 +02:00
|
|
|
default = [ ];
|
2021-04-26 01:52:02 +02:00
|
|
|
description = escape [ "<" ">" ] ''
|
2021-04-12 05:01:13 +02:00
|
|
|
overlays to apply to this channel
|
2021-04-27 06:38:27 +02:00
|
|
|
these will get exported under the 'overlays' flake output
|
|
|
|
as <channel>/<name> and any overlay pulled from ''\${inputs}
|
|
|
|
will be filtered out
|
2021-04-12 05:01:13 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
config = mkOption {
|
|
|
|
type = pathTo attrs;
|
|
|
|
default = { };
|
2021-04-26 01:52:02 +02:00
|
|
|
apply = lib.recursiveUpdate cfg.channelsConfig;
|
2021-04-12 05:01:13 +02:00
|
|
|
description = ''
|
|
|
|
nixpkgs config for this channel
|
|
|
|
'';
|
2021-03-26 19:57:24 +01:00
|
|
|
};
|
|
|
|
};
|
2021-04-12 05:01:13 +02:00
|
|
|
};
|
|
|
|
|
2021-04-22 04:44:08 +02:00
|
|
|
hostModule = {
|
2021-04-12 05:01:13 +02:00
|
|
|
options = with types; {
|
2021-04-26 01:52:02 +02:00
|
|
|
# anything null in hosts gets filtered out by mkFlake
|
2021-04-12 05:01:13 +02:00
|
|
|
system = mkOption {
|
2021-04-27 06:38:27 +02:00
|
|
|
type = (nullOr systemType) // {
|
|
|
|
description = "system defined in `supportedSystems`";
|
|
|
|
};
|
2021-04-26 01:52:02 +02:00
|
|
|
default = null;
|
2021-04-12 05:01:13 +02:00
|
|
|
description = ''
|
2021-04-22 04:44:08 +02:00
|
|
|
system for this host
|
2021-04-12 05:01:13 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
channelName = mkOption {
|
2021-04-27 06:38:27 +02:00
|
|
|
type = (nullOr (types.enum (builtins.attrNames config.channels))) // {
|
|
|
|
description = "a channel defined in `channels`";
|
|
|
|
};
|
2021-04-26 01:52:02 +02:00
|
|
|
default = null;
|
2021-04-12 05:01:13 +02:00
|
|
|
description = ''
|
2021-04-22 04:44:08 +02:00
|
|
|
Channel this host should follow
|
2021-04-12 05:01:13 +02:00
|
|
|
'';
|
|
|
|
};
|
2021-04-24 02:59:01 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
# This is only needed for hostDefaults
|
|
|
|
# modules in each host don't get exported
|
|
|
|
externalModulesModule = {
|
|
|
|
options = {
|
|
|
|
externalModules = mkOption {
|
2021-04-26 01:52:02 +02:00
|
|
|
type = with types; listOf moduleType;
|
2021-04-12 05:01:13 +02:00
|
|
|
default = [ ];
|
|
|
|
description = ''
|
2021-04-27 06:38:27 +02:00
|
|
|
modules to include that won't be exported
|
|
|
|
meant importing modules from external flakes
|
2021-04-12 05:01:13 +02:00
|
|
|
'';
|
|
|
|
};
|
2021-04-12 17:42:22 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-04-24 02:59:01 +02:00
|
|
|
modulesModule = {
|
2021-04-12 17:42:22 +02:00
|
|
|
options = {
|
2021-04-24 02:59:01 +02:00
|
|
|
modules = mkOption {
|
2021-04-26 01:52:02 +02:00
|
|
|
type = with types; coercedListOf moduleType;
|
2021-04-12 05:01:13 +02:00
|
|
|
default = [ ];
|
|
|
|
description = ''
|
2021-04-24 02:59:01 +02:00
|
|
|
modules to include
|
2021-04-12 05:01:13 +02:00
|
|
|
'';
|
|
|
|
};
|
2021-03-26 19:57:24 +01:00
|
|
|
};
|
2021-04-12 05:01:13 +02:00
|
|
|
};
|
|
|
|
|
2021-04-26 01:52:02 +02:00
|
|
|
exportModulesModule = name: {
|
|
|
|
options = {
|
|
|
|
modules = mkOption {
|
2021-04-27 18:35:44 +02:00
|
|
|
type = with types; pathTo (coercedListOf exportModuleType);
|
2021-04-26 01:52:02 +02:00
|
|
|
default = [ ];
|
|
|
|
description = ''
|
|
|
|
modules to include in all hosts and export to ${name}Modules output
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-04-12 05:01:13 +02:00
|
|
|
# Home-manager's configs get exported automatically from nixos.hosts
|
2021-04-22 04:44:08 +02:00
|
|
|
# So there is no need for a host options in the home namespace
|
2021-04-12 05:01:13 +02:00
|
|
|
# This is only needed for nixos
|
2021-04-26 01:52:02 +02:00
|
|
|
includeHostsModule = name: {
|
2021-04-12 05:01:13 +02:00
|
|
|
options = with types; {
|
2021-04-22 04:44:08 +02:00
|
|
|
hostDefaults = mkOption {
|
2021-04-26 01:52:02 +02:00
|
|
|
type = submodule [
|
|
|
|
hostModule
|
|
|
|
externalModulesModule
|
|
|
|
(exportModulesModule name)
|
|
|
|
];
|
2021-04-12 05:01:13 +02:00
|
|
|
default = { };
|
|
|
|
description = ''
|
2021-04-22 04:44:08 +02:00
|
|
|
Defaults for all hosts.
|
|
|
|
the modules passed under hostDefaults will be exported
|
2021-04-12 17:42:22 +02:00
|
|
|
to the '${name}Modules' flake output.
|
2021-04-22 04:44:08 +02:00
|
|
|
They will also be added to all hosts.
|
2021-04-12 05:01:13 +02:00
|
|
|
'';
|
|
|
|
};
|
2021-04-22 04:44:08 +02:00
|
|
|
hosts = mkOption {
|
2021-04-24 02:59:01 +02:00
|
|
|
type = attrsOf (submodule [ hostModule modulesModule ]);
|
2021-04-12 05:01:13 +02:00
|
|
|
default = { };
|
|
|
|
description = ''
|
|
|
|
configurations to include in the ${name}Configurations output
|
|
|
|
'';
|
|
|
|
};
|
2021-03-26 19:57:24 +01:00
|
|
|
};
|
2021-04-12 05:01:13 +02:00
|
|
|
};
|
|
|
|
|
2021-04-12 17:42:22 +02:00
|
|
|
# profiles and suites - which are profile collections
|
2021-04-26 01:52:02 +02:00
|
|
|
profilesModule = { config, ... }: {
|
2021-04-12 05:01:13 +02:00
|
|
|
options = with types; {
|
|
|
|
profiles = mkOption {
|
2021-04-26 01:52:02 +02:00
|
|
|
type = listOf path;
|
2021-04-12 17:42:22 +02:00
|
|
|
default = [ ];
|
2021-04-27 06:38:27 +02:00
|
|
|
description = ''
|
|
|
|
profile folders that can be collected into suites
|
|
|
|
the name of the argument passed to suites is based
|
|
|
|
on the folder name.
|
|
|
|
[ ./profiles ] => { profiles }:
|
|
|
|
'';
|
2021-04-12 05:01:13 +02:00
|
|
|
};
|
|
|
|
suites = mkOption {
|
|
|
|
type = pathTo (functionTo attrs);
|
|
|
|
default = _: { };
|
|
|
|
apply = suites: os.mkSuites {
|
2021-03-26 19:57:24 +01:00
|
|
|
inherit suites;
|
2021-04-12 05:01:13 +02:00
|
|
|
inherit (config) profiles;
|
2021-03-26 19:57:24 +01:00
|
|
|
};
|
|
|
|
description = ''
|
2021-04-27 06:38:27 +02:00
|
|
|
Function that takes profiles and returns suites for this config system
|
2021-04-12 05:01:13 +02:00
|
|
|
These can be accessed through the 'suites' special argument.
|
2021-03-26 19:57:24 +01:00
|
|
|
'';
|
|
|
|
};
|
2021-04-12 05:01:13 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
in
|
|
|
|
{
|
2021-04-27 06:32:26 +02:00
|
|
|
# this does not get propagated to submodules
|
|
|
|
# to allow passing flake outputs directly to mkFlake
|
|
|
|
config._module.check = false;
|
|
|
|
|
2021-04-12 05:01:13 +02:00
|
|
|
options = with types; {
|
|
|
|
self = mkOption {
|
|
|
|
type = flakeType;
|
|
|
|
description = "The flake to create the devos outputs for";
|
|
|
|
};
|
2021-04-26 01:52:02 +02:00
|
|
|
inputs = mkOption {
|
|
|
|
type = attrsOf flakeType;
|
|
|
|
description = ''
|
|
|
|
inputs for this flake
|
|
|
|
used to set channel defaults and create registry
|
|
|
|
'';
|
|
|
|
};
|
2021-04-12 05:01:13 +02:00
|
|
|
supportedSystems = mkOption {
|
|
|
|
type = listOf str;
|
2021-04-18 03:56:24 +02:00
|
|
|
default = lib.defaultSystems;
|
2021-03-26 19:57:24 +01:00
|
|
|
description = ''
|
2021-04-12 05:01:13 +02:00
|
|
|
The systems supported by this flake
|
2021-03-26 19:57:24 +01:00
|
|
|
'';
|
|
|
|
};
|
2021-04-26 01:52:02 +02:00
|
|
|
channelsConfig = mkOption {
|
|
|
|
type = pathTo attrs;
|
|
|
|
default = { };
|
|
|
|
description = ''
|
|
|
|
nixpkgs config for all channels
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
channels = mkOption {
|
|
|
|
type = attrsOf (submodule channelsModule);
|
|
|
|
default = { };
|
|
|
|
description = ''
|
|
|
|
nixpkgs channels to create
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
nixos = mkOption {
|
|
|
|
type = submodule [ (includeHostsModule "nixos") profilesModule ];
|
2021-04-12 05:01:13 +02:00
|
|
|
default = { };
|
2021-03-26 19:57:24 +01:00
|
|
|
description = ''
|
2021-04-12 05:01:13 +02:00
|
|
|
hosts, modules, suites, and profiles for nixos
|
2021-03-26 19:57:24 +01:00
|
|
|
'';
|
|
|
|
};
|
2021-04-12 05:01:13 +02:00
|
|
|
home = mkOption {
|
2021-04-26 01:52:02 +02:00
|
|
|
type = submodule [
|
|
|
|
profilesModule
|
|
|
|
(exportModulesModule "home")
|
|
|
|
externalModulesModule
|
|
|
|
];
|
2021-04-12 05:01:13 +02:00
|
|
|
default = { };
|
|
|
|
description = ''
|
|
|
|
hosts, modules, suites, and profiles for home-manager
|
|
|
|
'';
|
2021-03-26 19:57:24 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
in
|
2021-04-02 04:10:24 +02:00
|
|
|
lib.evalModules {
|
2021-04-10 03:22:08 +02:00
|
|
|
modules = [ argOpts args ];
|
|
|
|
}
|