Merge branch 'main' into flake-update-flake-parts-2024-11-04

This commit is contained in:
Mic92
2024-11-04 12:33:32 +00:00
5 changed files with 48 additions and 25 deletions

View File

@@ -62,6 +62,7 @@
"flakes" "flakes"
]; ];
}; };
system.extraDependencies = dependencies;
}; };
nodes.client = { nodes.client = {
environment.systemPackages = [ environment.systemPackages = [

View File

@@ -39,11 +39,9 @@ let
checkService = checkService =
serviceName: serviceName:
let builtins.elem "inventory" (clan-core.lib.modules.getFrontmatter serviceName).features or [ ];
frontmatter = clan-core.lib.modules.getFrontmatter serviceName;
in
if builtins.elem "inventory" frontmatter.features or [ ] then true else false;
trimExtension = name: builtins.substring 0 (builtins.stringLength name - 4) name;
/* /*
Returns a NixOS configuration for every machine in the inventory. Returns a NixOS configuration for every machine in the inventory.
@@ -65,18 +63,29 @@ let
acc2: instanceName: serviceConfig: acc2: instanceName: serviceConfig:
let let
resolvedRoles = builtins.mapAttrs ( roles = lib.mapAttrsToList (name: _value: trimExtension name) (
roleName: members: lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) (
builtins.readDir (
if clan-core.clanModules ? ${serviceName} then
clan-core.clanModules.${serviceName} + "/roles"
else
throw "ClanModule not found: '${serviceName}'. Make sure the module is added in the 'clanModules' attribute of clan-core."
)
)
);
resolvedRoles = lib.genAttrs roles (
roleName:
resolveTags { resolveTags {
members = serviceConfig.roles.${roleName} or { };
inherit inherit
serviceName serviceName
instanceName instanceName
roleName roleName
inventory inventory
members
; ;
} }
) serviceConfig.roles; );
isInService = builtins.any (members: builtins.elem machineName members.machines) ( isInService = builtins.any (members: builtins.elem machineName members.machines) (
builtins.attrValues resolvedRoles builtins.attrValues resolvedRoles
@@ -98,18 +107,12 @@ let
# TODO: maybe optimize this dont lookup the role in inverse roles. Imports are not lazy # TODO: maybe optimize this dont lookup the role in inverse roles. Imports are not lazy
roleModules = builtins.map ( roleModules = builtins.map (
role: role:
let if builtins.elem role roles && clan-core.clanModules ? ${serviceName} then
# Check the module exists clan-core.clanModules.${serviceName} + "/roles/${role}.nix"
module =
clan-core.clanModules.${serviceName}
or (throw "ClanModule not found: '${serviceName}'. Make sure the module is added in the 'clanModules' attribute of clan-core.");
path = module + "/roles/${role}.nix";
in
if builtins.pathExists path then
path
else else
throw "Module doesn't have role: '${role}'. Role: ${role}.nix not found." throw "Module ${serviceName} doesn't have role: '${role}'. Role: ${
clan-core.clanModules.${serviceName}
}/roles/${role}.nix not found."
) machineRoles; ) machineRoles;
roleServiceConfigs = builtins.filter (m: m != { }) ( roleServiceConfigs = builtins.filter (m: m != { }) (
@@ -119,8 +122,14 @@ let
extraModules = map (s: if builtins.typeOf s == "string" then "${directory}/${s}" else s) ( extraModules = map (s: if builtins.typeOf s == "string" then "${directory}/${s}" else s) (
globalExtraModules ++ machineExtraModules ++ roleServiceExtraModules globalExtraModules ++ machineExtraModules ++ roleServiceExtraModules
); );
nonExistingRoles = builtins.filter (role: !(builtins.elem role roles)) (
builtins.attrNames (serviceConfig.roles or { })
);
in in
if !(serviceConfig.enabled or true) then if (nonExistingRoles != [ ]) then
throw "Roles ${builtins.toString nonExistingRoles} are not defined in the service ${serviceName}."
else if !(serviceConfig.enabled or true) then
acc2 acc2
else if isInService then else if isInService then
acc2 acc2
@@ -139,14 +148,13 @@ let
); );
} }
) )
({
{ clan.inventory.services.${serviceName}.${instanceName} = {
config.clan.inventory.services.${serviceName}.${instanceName} = {
roles = resolvedRoles; roles = resolvedRoles;
# TODO: Add inverseRoles to the service config if needed # TODO: Add inverseRoles to the service config if needed
# inherit inverseRoles; # inherit inverseRoles;
}; };
} })
] ]
else else
acc2 acc2

View File

@@ -171,7 +171,7 @@ in
expr = configs; expr = configs;
expectedError = { expectedError = {
type = "ThrownError"; type = "ThrownError";
msg = "Module doesn't have role.*"; msg = "Roles roleXYZ are not defined in the service borgbackup.";
}; };
}; };
test_inventory_tag_doesnt_exist = test_inventory_tag_doesnt_exist =

View File

@@ -31,6 +31,7 @@ def install_nixos(
password: str | None = None, password: str | None = None,
no_reboot: bool = False, no_reboot: bool = False,
extra_args: list[str] | None = None, extra_args: list[str] | None = None,
build_on_remote: bool = False,
) -> None: ) -> None:
if extra_args is None: if extra_args is None:
extra_args = [] extra_args = []
@@ -70,6 +71,9 @@ def install_nixos(
if no_reboot: if no_reboot:
cmd.append("--no-reboot") cmd.append("--no-reboot")
if build_on_remote:
cmd.append("--build-on-remote")
if password: if password:
cmd += [ cmd += [
"--env-password", "--env-password",
@@ -104,6 +108,7 @@ class InstallOptions:
debug: bool = False debug: bool = False
no_reboot: bool = False no_reboot: bool = False
json_ssh_deploy: dict[str, str] | None = None json_ssh_deploy: dict[str, str] | None = None
build_on_remote: bool = False
nix_options: list[str] = field(default_factory=list) nix_options: list[str] = field(default_factory=list)
@@ -119,6 +124,7 @@ def install_machine(opts: InstallOptions, password: str | None) -> None:
password=password, password=password,
no_reboot=opts.no_reboot, no_reboot=opts.no_reboot,
extra_args=opts.nix_options, extra_args=opts.nix_options,
build_on_remote=opts.build_on_remote,
) )
@@ -159,6 +165,7 @@ def install_command(args: argparse.Namespace) -> None:
no_reboot=args.no_reboot, no_reboot=args.no_reboot,
json_ssh_deploy=json_ssh_deploy, json_ssh_deploy=json_ssh_deploy,
nix_options=args.option, nix_options=args.option,
build_on_remote=args.build_on_remote,
), ),
password, password,
) )
@@ -192,6 +199,12 @@ def register_install_parser(parser: argparse.ArgumentParser) -> None:
help="do not reboot after installation", help="do not reboot after installation",
default=False, default=False,
) )
parser.add_argument(
"--build-on-remote",
action="store_true",
help="build the NixOS configuration on the remote machine",
default=False,
)
parser.add_argument( parser.add_argument(
"--yes", "--yes",
action="store_true", action="store_true",

View File

@@ -49,6 +49,7 @@ class Command:
for p in reversed(self.processes): for p in reversed(self.processes):
with contextlib.suppress(OSError): with contextlib.suppress(OSError):
os.killpg(os.getpgid(p.pid), signal.SIGKILL) os.killpg(os.getpgid(p.pid), signal.SIGKILL)
p.wait()
@pytest.fixture @pytest.fixture