2019-10-06 21:39:10 +02:00
|
|
|
{ config, options, kubenix, pkgs, lib, ... }:
|
2019-02-10 21:03:47 +01:00
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
|
|
let
|
|
|
|
|
cfg = config.submodules;
|
2019-03-12 20:33:56 +01:00
|
|
|
parentConfig = config;
|
2019-02-10 21:03:47 +01:00
|
|
|
|
2019-03-12 20:33:56 +01:00
|
|
|
getDefaults = {name, tags, features}:
|
2019-02-26 21:23:14 +01:00
|
|
|
catAttrs "default" (filter (submodule:
|
|
|
|
|
(submodule.name == null || submodule.name == name) &&
|
|
|
|
|
(
|
|
|
|
|
(length submodule.tags == 0) ||
|
|
|
|
|
(length (intersectLists submodule.tags tags)) > 0
|
2019-03-12 20:33:56 +01:00
|
|
|
) &&
|
|
|
|
|
(
|
|
|
|
|
(length submodule.features == 0) ||
|
|
|
|
|
(length (intersectLists submodule.features features)) > 0
|
2019-02-26 21:23:14 +01:00
|
|
|
)
|
|
|
|
|
) config.submodules.defaults);
|
|
|
|
|
|
2019-02-10 21:03:47 +01:00
|
|
|
specialArgs = cfg.specialArgs // {
|
|
|
|
|
parentConfig = config;
|
|
|
|
|
};
|
|
|
|
|
|
2019-03-01 17:49:37 +01:00
|
|
|
findSubmodule = {name, version ? null, latest ? true}: let
|
2019-02-10 21:03:47 +01:00
|
|
|
matchingSubmodules = filter (el:
|
|
|
|
|
el.definition.name == name &&
|
2019-03-01 17:49:37 +01:00
|
|
|
(if version != null then
|
|
|
|
|
if hasPrefix "~" version
|
|
|
|
|
then (builtins.match (removePrefix "~" version) el.definition.version) != null
|
|
|
|
|
else el.definition.version == version
|
|
|
|
|
else true)
|
2019-02-10 21:03:47 +01:00
|
|
|
) cfg.imports;
|
|
|
|
|
|
|
|
|
|
versionSortedSubmodules = sort (s1: s2:
|
|
|
|
|
if builtins.compareVersions s1.definition.version s2.definition.version > 0
|
|
|
|
|
then true else false
|
|
|
|
|
) matchingSubmodules;
|
|
|
|
|
|
|
|
|
|
matchingModule =
|
|
|
|
|
if length versionSortedSubmodules == 0
|
|
|
|
|
then throw "No module found ${name}/${if version == null then "latest" else version}"
|
|
|
|
|
else head versionSortedSubmodules;
|
|
|
|
|
in matchingModule;
|
2019-10-06 21:36:13 +02:00
|
|
|
|
|
|
|
|
passthruConfig = mapAttrsToList (name: opt: {
|
|
|
|
|
${name} = mkMerge (mapAttrsToList (_: inst:
|
|
|
|
|
if inst.passthru.enable
|
|
|
|
|
then inst.config.submodule.passthru.${name} or {}
|
|
|
|
|
else {}
|
|
|
|
|
) config.submodules.instances);
|
|
|
|
|
|
|
|
|
|
_module.args = mkMerge (mapAttrsToList (_: inst:
|
|
|
|
|
if inst.passthru.enable
|
|
|
|
|
then inst.config.submodule.passthru._module.args or {}
|
|
|
|
|
else {}
|
|
|
|
|
) config.submodules.instances);
|
|
|
|
|
}) (removeAttrs options ["_definedNames" "_module" "submodules"]);
|
2019-02-10 21:03:47 +01:00
|
|
|
in {
|
2019-03-12 20:33:56 +01:00
|
|
|
imports = [ ./base.nix ];
|
|
|
|
|
|
2019-02-10 21:03:47 +01:00
|
|
|
options = {
|
|
|
|
|
submodules.specialArgs = mkOption {
|
|
|
|
|
description = "Special args to pass to submodules. These arguments can be used for imports";
|
|
|
|
|
type = types.attrs;
|
|
|
|
|
default = {};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
submodules.defaults = mkOption {
|
2019-02-26 21:23:14 +01:00
|
|
|
description = "List of defaults to apply to submodule instances";
|
|
|
|
|
type = types.listOf (types.submodule ({config, ...}: {
|
|
|
|
|
options = {
|
|
|
|
|
name = mkOption {
|
|
|
|
|
description = "Name of the submodule to apply defaults to";
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
default = null;
|
|
|
|
|
};
|
2019-02-10 21:03:47 +01:00
|
|
|
|
2019-02-26 21:23:14 +01:00
|
|
|
tags = mkOption {
|
|
|
|
|
description = "List of tags to apply defaults to";
|
|
|
|
|
type = types.listOf types.str;
|
|
|
|
|
default = [];
|
|
|
|
|
};
|
|
|
|
|
|
2019-03-12 20:33:56 +01:00
|
|
|
features = mkOption {
|
|
|
|
|
description = "List of features that submodule has to have to apply defaults";
|
|
|
|
|
type = types.listOf types.str;
|
|
|
|
|
default = [];
|
|
|
|
|
};
|
|
|
|
|
|
2019-02-26 21:23:14 +01:00
|
|
|
default = mkOption {
|
|
|
|
|
description = "Default to apply to submodule instance";
|
|
|
|
|
type = types.unspecified;
|
|
|
|
|
default = {};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}));
|
|
|
|
|
default = [];
|
2019-02-10 21:03:47 +01:00
|
|
|
};
|
|
|
|
|
|
2019-03-12 20:33:56 +01:00
|
|
|
submodules.propagate.enable = mkOption {
|
|
|
|
|
description = "Whether to propagate defaults and imports from parent to child";
|
2019-02-10 21:03:47 +01:00
|
|
|
type = types.bool;
|
2019-03-12 20:33:56 +01:00
|
|
|
default = true;
|
2019-02-10 21:03:47 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
submodules.imports = mkOption {
|
|
|
|
|
description = "List of submodule imports";
|
|
|
|
|
type = types.listOf (
|
|
|
|
|
types.coercedTo
|
|
|
|
|
types.path
|
|
|
|
|
(module: {inherit module;})
|
|
|
|
|
(types.submodule ({name, config, ...}: let
|
2019-03-20 20:52:59 +01:00
|
|
|
evaledSubmodule' = evalModules {
|
2019-02-10 21:03:47 +01:00
|
|
|
inherit specialArgs;
|
2019-03-12 20:33:56 +01:00
|
|
|
modules = config.modules ++ [ ./base.nix ];
|
2019-02-10 21:03:47 +01:00
|
|
|
check = false;
|
2019-03-20 20:52:59 +01:00
|
|
|
};
|
2019-03-12 20:33:56 +01:00
|
|
|
|
|
|
|
|
evaledSubmodule =
|
2019-03-20 20:52:59 +01:00
|
|
|
if (!(elem "submodule" evaledSubmodule'.config._module.features))
|
2019-03-12 20:33:56 +01:00
|
|
|
then throw "no submodule defined"
|
|
|
|
|
else evaledSubmodule';
|
2019-02-10 21:03:47 +01:00
|
|
|
in {
|
|
|
|
|
options = {
|
|
|
|
|
module = mkOption {
|
|
|
|
|
description = "Module defining submodule";
|
2019-02-26 21:23:14 +01:00
|
|
|
type = types.unspecified;
|
2019-02-10 21:03:47 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
modules = mkOption {
|
|
|
|
|
description = "List of modules defining submodule";
|
|
|
|
|
type = types.listOf types.unspecified;
|
|
|
|
|
default = [config.module];
|
|
|
|
|
};
|
|
|
|
|
|
2019-03-12 20:33:56 +01:00
|
|
|
features = mkOption {
|
|
|
|
|
description = "List of features exposed by submodule";
|
|
|
|
|
type = types.listOf types.str;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
definition = mkOption {
|
|
|
|
|
description = "Submodule definition";
|
|
|
|
|
type = types.attrs;
|
|
|
|
|
};
|
2019-03-01 09:54:34 +01:00
|
|
|
};
|
|
|
|
|
|
2019-03-12 20:33:56 +01:00
|
|
|
config = {
|
|
|
|
|
definition = {
|
2019-03-20 20:52:59 +01:00
|
|
|
inherit (evaledSubmodule.config.submodule) name description version tags;
|
2019-03-12 20:33:56 +01:00
|
|
|
};
|
|
|
|
|
|
2019-03-20 20:52:59 +01:00
|
|
|
features = evaledSubmodule.config._module.features;
|
2019-02-10 21:03:47 +01:00
|
|
|
};
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
default = [];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
submodules.instances = mkOption {
|
|
|
|
|
description = "Attribute set of submodule instances";
|
2019-03-05 21:26:49 +01:00
|
|
|
default = {};
|
2019-03-20 20:54:24 +01:00
|
|
|
type = types.attrsOf (types.submodule ({name, config, options, ...}: let
|
2019-02-26 21:23:14 +01:00
|
|
|
# submodule associated with
|
2019-03-01 17:49:37 +01:00
|
|
|
submodule = findSubmodule {
|
2019-02-10 21:03:47 +01:00
|
|
|
name = config.submodule;
|
|
|
|
|
version = config.version;
|
|
|
|
|
};
|
|
|
|
|
|
2019-02-26 21:23:14 +01:00
|
|
|
# definition of a submodule
|
2019-02-10 21:03:47 +01:00
|
|
|
submoduleDefinition = submodule.definition;
|
2019-02-26 21:23:14 +01:00
|
|
|
|
|
|
|
|
# submodule defaults
|
2019-03-12 20:33:56 +01:00
|
|
|
defaults = getDefaults {
|
|
|
|
|
name = submoduleDefinition.name;
|
|
|
|
|
tags = submoduleDefinition.tags;
|
|
|
|
|
features = submodule.features;
|
|
|
|
|
};
|
2019-02-10 21:03:47 +01:00
|
|
|
in {
|
|
|
|
|
options = {
|
|
|
|
|
name = mkOption {
|
|
|
|
|
description = "Submodule instance name";
|
|
|
|
|
type = types.str;
|
|
|
|
|
default = name;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
submodule = mkOption {
|
|
|
|
|
description = "Name of the submodule to use";
|
|
|
|
|
type = types.str;
|
|
|
|
|
default = name;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
version = mkOption {
|
2019-03-01 17:49:37 +01:00
|
|
|
description = ''
|
|
|
|
|
Version of submodule to use, if version starts with "~" it is
|
|
|
|
|
threated as regex pattern for example "~1.0.*"
|
|
|
|
|
'';
|
2019-02-10 21:03:47 +01:00
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
default = null;
|
|
|
|
|
};
|
|
|
|
|
|
2019-03-12 20:33:56 +01:00
|
|
|
passthru.enable = mkOption {
|
|
|
|
|
description = "Whether to passthru submodule resources";
|
|
|
|
|
type = types.bool;
|
|
|
|
|
default = true;
|
|
|
|
|
};
|
|
|
|
|
|
2019-02-10 21:03:47 +01:00
|
|
|
config = mkOption {
|
|
|
|
|
description = "Submodule instance ${config.name} for ${submoduleDefinition.name}:${submoduleDefinition.version} config";
|
2019-02-25 17:15:38 +01:00
|
|
|
type = submoduleWithSpecialArgs ({...}: {
|
2019-03-12 20:33:56 +01:00
|
|
|
imports = submodule.modules ++ defaults ++ [ ./base.nix ];
|
2019-03-11 20:49:00 +01:00
|
|
|
_module.args.pkgs = pkgs;
|
2019-02-17 19:43:04 +01:00
|
|
|
_module.args.name = config.name;
|
2019-03-01 17:50:18 +01:00
|
|
|
_module.args.submodule = config;
|
2019-03-20 20:54:24 +01:00
|
|
|
submodule.args = mkAliasDefinitions options.args;
|
2019-02-10 21:03:47 +01:00
|
|
|
}) specialArgs;
|
|
|
|
|
default = {};
|
|
|
|
|
};
|
2019-03-20 20:54:24 +01:00
|
|
|
|
|
|
|
|
args = mkOption {
|
|
|
|
|
description = "Submodule arguments (alias of config.submodule.args)";
|
|
|
|
|
};
|
2019-02-10 21:03:47 +01:00
|
|
|
};
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
default = {};
|
|
|
|
|
};
|
|
|
|
|
|
2019-10-06 21:30:20 +02:00
|
|
|
config = mkMerge ([
|
2019-03-12 20:33:56 +01:00
|
|
|
{
|
|
|
|
|
_module.features = ["submodules"];
|
|
|
|
|
|
|
|
|
|
submodules.specialArgs.kubenix = kubenix;
|
|
|
|
|
|
|
|
|
|
# passthru kubenix.project to submodules
|
2019-10-06 21:30:20 +02:00
|
|
|
submodules.defaults = mkMerge [
|
|
|
|
|
[{
|
|
|
|
|
default = {
|
|
|
|
|
kubenix.project = parentConfig.kubenix.project;
|
|
|
|
|
};
|
|
|
|
|
}]
|
|
|
|
|
|
|
|
|
|
(map (propagate: {
|
|
|
|
|
features = propagate.features;
|
|
|
|
|
default = propagate.module;
|
|
|
|
|
}) config._module.propagate)
|
|
|
|
|
];
|
2019-03-12 20:33:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(mkIf cfg.propagate.enable {
|
|
|
|
|
# if propagate is enabled and submodule has submodules included propagage defaults and imports
|
|
|
|
|
submodules.defaults = [{
|
|
|
|
|
features = ["submodules"];
|
|
|
|
|
default = {
|
|
|
|
|
submodules = {
|
|
|
|
|
defaults = cfg.defaults;
|
|
|
|
|
imports = cfg.imports;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}];
|
|
|
|
|
})
|
2019-10-06 21:36:13 +02:00
|
|
|
] ++ passthruConfig);
|
2019-02-10 21:03:47 +01:00
|
|
|
}
|