Merge branch 'main' into flake-update-treefmt-nix-2024-11-04
This commit is contained in:
@@ -62,6 +62,7 @@
|
|||||||
"flakes"
|
"flakes"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
system.extraDependencies = dependencies;
|
||||||
};
|
};
|
||||||
nodes.client = {
|
nodes.client = {
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 =
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user