Merge pull request 'inventory: remove deprecated frontmatter' (#5168) from inv-1 into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5168
This commit is contained in:
@@ -34,7 +34,6 @@ lib.fix (
|
|||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
# ClanLib functions
|
# ClanLib functions
|
||||||
inventory = clanLib.callLib ./modules/inventory { };
|
inventory = clanLib.callLib ./modules/inventory { };
|
||||||
modules = clanLib.callLib ./modules/inventory/frontmatter { };
|
|
||||||
test = clanLib.callLib ./test { };
|
test = clanLib.callLib ./test { };
|
||||||
flake-inputs = clanLib.callLib ./flake-inputs.nix { };
|
flake-inputs = clanLib.callLib ./flake-inputs.nix { };
|
||||||
# Custom types
|
# Custom types
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
{
|
|
||||||
resolvedRoles,
|
|
||||||
instanceName,
|
|
||||||
moduleName,
|
|
||||||
allRoles,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (config) roles;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
(lib.modules.importApply ./interface.nix { inherit allRoles; })
|
|
||||||
# Role assertions
|
|
||||||
{
|
|
||||||
config.assertions = lib.foldlAttrs (
|
|
||||||
ass: roleName: roleConstraints:
|
|
||||||
let
|
|
||||||
members = resolvedRoles.${roleName}.machines;
|
|
||||||
memberCount = builtins.length members;
|
|
||||||
# Checks
|
|
||||||
minCheck = lib.optionalAttrs (roleConstraints.min > 0) {
|
|
||||||
"${moduleName}.${instanceName}.roles.${roleName}.min" = {
|
|
||||||
assertion = memberCount >= roleConstraints.min;
|
|
||||||
message = ''
|
|
||||||
The '${moduleName}' module requires at least ${builtins.toString roleConstraints.min} members of the '${roleName}' role
|
|
||||||
but found '${builtins.toString memberCount}' members within instance '${instanceName}':
|
|
||||||
|
|
||||||
${lib.concatLines members}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
maxCheck = lib.optionalAttrs (roleConstraints.max != null) {
|
|
||||||
"${moduleName}.${instanceName}.roles.${roleName}.max" = {
|
|
||||||
assertion = memberCount <= roleConstraints.max;
|
|
||||||
message = ''
|
|
||||||
The ${moduleName} module allows at most for ${builtins.toString roleConstraints.max} members of the '${roleName}' role
|
|
||||||
but found '${builtins.toString memberCount}' members within instance '${instanceName}':
|
|
||||||
|
|
||||||
${lib.concatLines members}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
ass // maxCheck // minCheck
|
|
||||||
) { } roles;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
{
|
|
||||||
allRoles,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
rolesAttrs = builtins.groupBy lib.id allRoles;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.roles = lib.mapAttrs (
|
|
||||||
_name: _:
|
|
||||||
mkOption {
|
|
||||||
description = ''
|
|
||||||
Sub-attributes of `${_name}` are constraints for the role.
|
|
||||||
'';
|
|
||||||
default = { };
|
|
||||||
type = types.submoduleWith {
|
|
||||||
modules = [
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
max = mkOption {
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Maximum number of instances of this role that can be assigned to a module of this type.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
min = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = 0;
|
|
||||||
description = ''
|
|
||||||
Minimum number of instances of this role that must at least be assigned to a module of this type.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) rolesAttrs;
|
|
||||||
|
|
||||||
# The resulting assertions
|
|
||||||
options.assertions = mkOption {
|
|
||||||
visible = false;
|
|
||||||
default = { };
|
|
||||||
type = types.attrsOf (
|
|
||||||
types.submoduleWith {
|
|
||||||
modules = [
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
assertion = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
};
|
|
||||||
message = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
{ lib, clanLib }:
|
|
||||||
let
|
|
||||||
# Trim the .nix extension from a filename
|
|
||||||
trimExtension = name: builtins.substring 0 (builtins.stringLength name - 4) name;
|
|
||||||
|
|
||||||
# For Documentation purposes only
|
|
||||||
frontmatterOptions =
|
|
||||||
(lib.evalModules {
|
|
||||||
modules = [
|
|
||||||
./interface.nix
|
|
||||||
{
|
|
||||||
constraints.imports = [
|
|
||||||
(lib.modules.importApply ../constraints {
|
|
||||||
resolvedRoles = { };
|
|
||||||
moduleName = "{moduleName}";
|
|
||||||
instanceName = "{instanceName}";
|
|
||||||
allRoles = [ "{roleName}" ];
|
|
||||||
})
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}).options;
|
|
||||||
|
|
||||||
migratedModules = [ ];
|
|
||||||
|
|
||||||
makeModuleNotFoundError =
|
|
||||||
serviceName:
|
|
||||||
if builtins.elem serviceName migratedModules then
|
|
||||||
''
|
|
||||||
(Legacy) ClanModule not found: '${serviceName}'.
|
|
||||||
|
|
||||||
Please update your configuration to use this module via 'inventory.instances'
|
|
||||||
See: https://docs.clan.lol/guides/clanServices/
|
|
||||||
''
|
|
||||||
else
|
|
||||||
''
|
|
||||||
(Legacy) ClanModule not found: '${serviceName}'.
|
|
||||||
|
|
||||||
Make sure the module is added to inventory.modules.${serviceName}
|
|
||||||
'';
|
|
||||||
# This is a legacy function
|
|
||||||
# Old modules needed to define their roles by directory
|
|
||||||
# This means if this function gets anything other than a string/path it will throw
|
|
||||||
getRoles =
|
|
||||||
_scope: allModules: serviceName:
|
|
||||||
let
|
|
||||||
module = allModules.${serviceName} or (throw (makeModuleNotFoundError serviceName));
|
|
||||||
moduleType = (lib.typeOf module);
|
|
||||||
checked =
|
|
||||||
if
|
|
||||||
builtins.elem moduleType [
|
|
||||||
"string"
|
|
||||||
"path"
|
|
||||||
]
|
|
||||||
then
|
|
||||||
true
|
|
||||||
else
|
|
||||||
throw "(Legacy) ClanModule must be a 'path' or 'string' pointing to a directory: Got 'typeOf inventory.modules.${serviceName}' => ${moduleType} ";
|
|
||||||
modulePath = lib.seq checked module + "/roles";
|
|
||||||
checkedPath =
|
|
||||||
if builtins.pathExists modulePath then
|
|
||||||
modulePath
|
|
||||||
else
|
|
||||||
throw ''
|
|
||||||
(Legacy) ClanModule must have a 'roles' directory'
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
- Provide a 'roles' subdirectory
|
|
||||||
- Use the newer 'clan.service' modules. (Recommended)
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
lib.seq checkedPath lib.mapAttrsToList (name: _value: trimExtension name) (
|
|
||||||
lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) (
|
|
||||||
builtins.readDir (checkedPath)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
getFrontmatter = _modulepath: _modulename: "clanModules are removed!";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit
|
|
||||||
frontmatterOptions
|
|
||||||
getFrontmatter
|
|
||||||
getRoles
|
|
||||||
;
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib) mkOption types;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
description = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
A Short description of the module.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
categories = mkOption {
|
|
||||||
default = [ "Uncategorized" ];
|
|
||||||
description = ''
|
|
||||||
Categories are used for Grouping and searching.
|
|
||||||
|
|
||||||
While initial oriented on [freedesktop](https://specifications.freedesktop.org/menu-spec/latest/category-registry.html) the following categories are allowed
|
|
||||||
'';
|
|
||||||
type = types.listOf (
|
|
||||||
types.enum [
|
|
||||||
"AudioVideo"
|
|
||||||
"Audio"
|
|
||||||
"Video"
|
|
||||||
"Development"
|
|
||||||
"Education"
|
|
||||||
"Game"
|
|
||||||
"Graphics"
|
|
||||||
"Social"
|
|
||||||
"Network"
|
|
||||||
"Office"
|
|
||||||
"Science"
|
|
||||||
"System"
|
|
||||||
"Settings"
|
|
||||||
"Utility"
|
|
||||||
"Uncategorized"
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
features = mkOption {
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
Clans Features that the module implements support for.
|
|
||||||
|
|
||||||
!!! warning "Important"
|
|
||||||
Every ClanModule, that specifies `features = [ "inventory" ]` MUST have at least one role.
|
|
||||||
Many modules use `roles/default.nix` which registers the role `default`.
|
|
||||||
|
|
||||||
If you are a clan module author and your module has only one role where you cannot determine the name, then we would like you to follow the convention.
|
|
||||||
'';
|
|
||||||
type = types.listOf (
|
|
||||||
types.enum [
|
|
||||||
"experimental"
|
|
||||||
"inventory"
|
|
||||||
]
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
constraints = mkOption {
|
|
||||||
default = { };
|
|
||||||
description = ''
|
|
||||||
Constraints for the module
|
|
||||||
|
|
||||||
The following example requires exactly one `server`
|
|
||||||
and supports up to `7` clients
|
|
||||||
|
|
||||||
```md
|
|
||||||
---
|
|
||||||
constraints.roles.server.eq = 1
|
|
||||||
constraints.roles.client.max = 7
|
|
||||||
---
|
|
||||||
```
|
|
||||||
'';
|
|
||||||
type = types.submoduleWith {
|
|
||||||
modules = [
|
|
||||||
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user