forked from clan/clan-core
refactor: rename clanCore -> clan.core
This commit is contained in:
parent
93a6d7a476
commit
313db5643f
@ -68,7 +68,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
clanCore.facts.secretStore = "vm";
|
clan.core.facts.secretStore = "vm";
|
||||||
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
self.packages.${pkgs.system}.clan-cli
|
self.packages.${pkgs.system}.clan-cli
|
||||||
@ -87,9 +87,9 @@
|
|||||||
flake-registry = pkgs.writeText "flake-registry" ''{"flakes":[],"version":2}'';
|
flake-registry = pkgs.writeText "flake-registry" ''{"flakes":[],"version":2}'';
|
||||||
};
|
};
|
||||||
system.extraDependencies = dependencies;
|
system.extraDependencies = dependencies;
|
||||||
clanCore.state.test-backups.folders = [ "/var/test-backups" ];
|
clan.core.state.test-backups.folders = [ "/var/test-backups" ];
|
||||||
|
|
||||||
clanCore.state.test-service = {
|
clan.core.state.test-service = {
|
||||||
preBackupCommand = ''
|
preBackupCommand = ''
|
||||||
touch /var/test-service/pre-backup-command
|
touch /var/test-service/pre-backup-command
|
||||||
'';
|
'';
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
clanCore.machineName = "machine";
|
clan.core.machineName = "machine";
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
clanCore.state.testState.folders = [ "/etc/state" ];
|
clan.core.state.testState.folders = [ "/etc/state" ];
|
||||||
environment.etc.state.text = "hello world";
|
environment.etc.state.text = "hello world";
|
||||||
systemd.tmpfiles.settings."vmsecrets" = {
|
systemd.tmpfiles.settings."vmsecrets" = {
|
||||||
"/etc/secrets/borgbackup.ssh" = {
|
"/etc/secrets/borgbackup.ssh" = {
|
||||||
@ -36,7 +36,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
clanCore.facts.secretStore = "vm";
|
clan.core.facts.secretStore = "vm";
|
||||||
|
|
||||||
clan.borgbackup.destinations.test.repo = "borg@localhost:.";
|
clan.borgbackup.destinations.test.repo = "borg@localhost:.";
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
self.clanModules.deltachat
|
self.clanModules.deltachat
|
||||||
self.nixosModules.clanCore
|
self.nixosModules.clanCore
|
||||||
{
|
{
|
||||||
clanCore.machineName = "machine";
|
clan.core.machineName = "machine";
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
options =
|
options =
|
||||||
(pkgs.nixos {
|
(pkgs.nixos {
|
||||||
imports = [ self.nixosModules.clanCore ];
|
imports = [ self.nixosModules.clanCore ];
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
}).options;
|
}).options;
|
||||||
warningsAreErrors = false;
|
warningsAreErrors = false;
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
self.clanModules.matrix-synapse
|
self.clanModules.matrix-synapse
|
||||||
self.nixosModules.clanCore
|
self.nixosModules.clanCore
|
||||||
{
|
{
|
||||||
clanCore.machineName = "machine";
|
clan.core.machineName = "machine";
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
|
|
||||||
services.nginx.virtualHosts."matrix.clan.test" = {
|
services.nginx.virtualHosts."matrix.clan.test" = {
|
||||||
enableACME = lib.mkForce false;
|
enableACME = lib.mkForce false;
|
||||||
@ -26,7 +26,7 @@
|
|||||||
clan.matrix-synapse.users.admin.admin = true;
|
clan.matrix-synapse.users.admin.admin = true;
|
||||||
clan.matrix-synapse.users.someuser = { };
|
clan.matrix-synapse.users.someuser = { };
|
||||||
|
|
||||||
clanCore.facts.secretStore = "vm";
|
clan.core.facts.secretStore = "vm";
|
||||||
|
|
||||||
# because we use systemd-tmpfiles to copy the secrets, we need to a seperate systemd-tmpfiles call to provison them.
|
# because we use systemd-tmpfiles to copy the secrets, we need to a seperate systemd-tmpfiles call to provison them.
|
||||||
boot.postBootCommands = "${config.systemd.package}/bin/systemd-tmpfiles --create /etc/tmpfiles.d/00-vmsecrets.conf";
|
boot.postBootCommands = "${config.systemd.package}/bin/systemd-tmpfiles --create /etc/tmpfiles.d/00-vmsecrets.conf";
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
machine.succeed("""
|
machine.succeed("""
|
||||||
set -x
|
set -x
|
||||||
${nodes.machine.clanCore.state.postgresql-test.postRestoreCommand}
|
${nodes.machine.clan.core.state.postgresql-test.postRestoreCommand}
|
||||||
""")
|
""")
|
||||||
machine.succeed("runuser -u postgres -- /run/current-system/sw/bin/psql -l >&2")
|
machine.succeed("runuser -u postgres -- /run/current-system/sw/bin/psql -l >&2")
|
||||||
machine.succeed("runuser -u postgres -- /run/current-system/sw/bin/psql -d test -c '\dt' >&2")
|
machine.succeed("runuser -u postgres -- /run/current-system/sw/bin/psql -d test -c '\dt' >&2")
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
environment.etc."group-secret".source = config.sops.secrets.group-secret.path;
|
environment.etc."group-secret".source = config.sops.secrets.group-secret.path;
|
||||||
sops.age.keyFile = "/etc/privkey.age";
|
sops.age.keyFile = "/etc/privkey.age";
|
||||||
|
|
||||||
clanCore.clanDir = "${./.}";
|
clan.core.clanDir = "${./.}";
|
||||||
clanCore.machineName = "machine";
|
clan.core.machineName = "machine";
|
||||||
|
|
||||||
networking.hostName = "machine";
|
networking.hostName = "machine";
|
||||||
};
|
};
|
||||||
|
@ -12,14 +12,14 @@
|
|||||||
self.clanModules.syncthing
|
self.clanModules.syncthing
|
||||||
self.nixosModules.clanCore
|
self.nixosModules.clanCore
|
||||||
{
|
{
|
||||||
clanCore.machineName = "introducer";
|
clan.core.machineName = "introducer";
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"syncthing.pam".source = ./introducer/introducer_test_cert;
|
"syncthing.pam".source = ./introducer/introducer_test_cert;
|
||||||
"syncthing.key".source = ./introducer/introducer_test_key;
|
"syncthing.key".source = ./introducer/introducer_test_key;
|
||||||
"syncthing.api".source = ./introducer/introducer_test_api;
|
"syncthing.api".source = ./introducer/introducer_test_api;
|
||||||
};
|
};
|
||||||
clanCore.facts.services.syncthing.secret."syncthing.api".path = "/etc/syncthing.api";
|
clan.core.facts.services.syncthing.secret."syncthing.api".path = "/etc/syncthing.api";
|
||||||
services.syncthing.cert = "/etc/syncthing.pam";
|
services.syncthing.cert = "/etc/syncthing.pam";
|
||||||
services.syncthing.key = "/etc/syncthing.key";
|
services.syncthing.key = "/etc/syncthing.key";
|
||||||
# Doesn't test zerotier!
|
# Doesn't test zerotier!
|
||||||
@ -53,8 +53,8 @@
|
|||||||
self.clanModules.syncthing
|
self.clanModules.syncthing
|
||||||
self.nixosModules.clanCore
|
self.nixosModules.clanCore
|
||||||
{
|
{
|
||||||
clanCore.machineName = "peer1";
|
clan.core.machineName = "peer1";
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
clan.syncthing.introducer = lib.strings.removeSuffix "\n" (
|
clan.syncthing.introducer = lib.strings.removeSuffix "\n" (
|
||||||
builtins.readFile ./introducer/introducer_device_id
|
builtins.readFile ./introducer/introducer_device_id
|
||||||
);
|
);
|
||||||
@ -75,8 +75,8 @@
|
|||||||
self.clanModules.syncthing
|
self.clanModules.syncthing
|
||||||
self.nixosModules.clanCore
|
self.nixosModules.clanCore
|
||||||
{
|
{
|
||||||
clanCore.machineName = "peer2";
|
clan.core.machineName = "peer2";
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
clan.syncthing.introducer = lib.strings.removeSuffix "\n" (
|
clan.syncthing.introducer = lib.strings.removeSuffix "\n" (
|
||||||
builtins.readFile ./introducer/introducer_device_id
|
builtins.readFile ./introducer/introducer_device_id
|
||||||
);
|
);
|
||||||
|
@ -14,8 +14,8 @@ import ../lib/test-base.nix (
|
|||||||
imports = [
|
imports = [
|
||||||
self.nixosModules.clanCore
|
self.nixosModules.clanCore
|
||||||
{
|
{
|
||||||
clanCore.machineName = "machine";
|
clan.core.machineName = "machine";
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
services.wayland-proxy-virtwl.enable = true;
|
services.wayland-proxy-virtwl.enable = true;
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
self.nixosModules.clanCore
|
self.nixosModules.clanCore
|
||||||
self.clanModules.zt-tcp-relay
|
self.clanModules.zt-tcp-relay
|
||||||
{
|
{
|
||||||
clanCore.machineName = "machine";
|
clan.core.machineName = "machine";
|
||||||
clanCore.clanDir = ./.;
|
clan.core.clanDir = ./.;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ lib, config, ... }:
|
{ lib, config, ... }:
|
||||||
let
|
let
|
||||||
clanDir = config.clanCore.clanDir;
|
clanDir = config.clan.core.clanDir;
|
||||||
machineDir = clanDir + "/machines/";
|
machineDir = clanDir + "/machines/";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@ -9,7 +9,7 @@ in
|
|||||||
options.clan.borgbackup-static = {
|
options.clan.borgbackup-static = {
|
||||||
excludeMachines = lib.mkOption {
|
excludeMachines = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
example = [ config.clanCore.machineName ];
|
example = [ config.clan.core.machineName ];
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
Machines that should not be backuped.
|
Machines that should not be backuped.
|
||||||
@ -20,7 +20,7 @@ in
|
|||||||
};
|
};
|
||||||
includeMachines = lib.mkOption {
|
includeMachines = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
example = [ config.clanCore.machineName ];
|
example = [ config.clan.core.machineName ];
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
Machines that should be backuped.
|
Machines that should be backuped.
|
||||||
@ -62,7 +62,9 @@ in
|
|||||||
}) machinesWithKey;
|
}) machinesWithKey;
|
||||||
in
|
in
|
||||||
lib.mkIf
|
lib.mkIf
|
||||||
(builtins.any (target: target == config.clanCore.machineName) config.clan.borgbackup-static.targets)
|
(builtins.any (
|
||||||
|
target: target == config.clan.core.machineName
|
||||||
|
) config.clan.borgbackup-static.targets)
|
||||||
(if (builtins.listToAttrs hosts) != null then builtins.listToAttrs hosts else { });
|
(if (builtins.listToAttrs hosts) != null then builtins.listToAttrs hosts else { });
|
||||||
|
|
||||||
config.clan.borgbackup.destinations =
|
config.clan.borgbackup.destinations =
|
||||||
@ -70,12 +72,12 @@ in
|
|||||||
destinations = builtins.map (d: {
|
destinations = builtins.map (d: {
|
||||||
name = d;
|
name = d;
|
||||||
value = {
|
value = {
|
||||||
repo = "borg@${d}:/var/lib/borgbackup/${config.clanCore.machineName}";
|
repo = "borg@${d}:/var/lib/borgbackup/${config.clan.core.machineName}";
|
||||||
};
|
};
|
||||||
}) config.clan.borgbackup-static.targets;
|
}) config.clan.borgbackup-static.targets;
|
||||||
in
|
in
|
||||||
lib.mkIf (builtins.any (
|
lib.mkIf (builtins.any (
|
||||||
target: target == config.clanCore.machineName
|
target: target == config.clan.core.machineName
|
||||||
) config.clan.borgbackup-static.includeMachines) (builtins.listToAttrs destinations);
|
) config.clan.borgbackup-static.includeMachines) (builtins.listToAttrs destinations);
|
||||||
|
|
||||||
config.assertions = [
|
config.assertions = [
|
||||||
|
@ -17,7 +17,7 @@ let
|
|||||||
preCommandErrors["${state.name}"]=1
|
preCommandErrors["${state.name}"]=1
|
||||||
fi
|
fi
|
||||||
''
|
''
|
||||||
) (lib.attrValues config.clanCore.state)}
|
) (lib.attrValues config.clan.core.state)}
|
||||||
|
|
||||||
if [[ ''${#preCommandErrors[@]} -gt 0 ]]; then
|
if [[ ''${#preCommandErrors[@]} -gt 0 ]]; then
|
||||||
echo "PreBackupCommand failed for the following services:"
|
echo "PreBackupCommand failed for the following services:"
|
||||||
@ -47,9 +47,9 @@ in
|
|||||||
rsh = lib.mkOption {
|
rsh = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "ssh -i ${
|
default = "ssh -i ${
|
||||||
config.clanCore.facts.services.borgbackup.secret."borgbackup.ssh".path
|
config.clan.core.facts.services.borgbackup.secret."borgbackup.ssh".path
|
||||||
} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=Yes";
|
} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=Yes";
|
||||||
defaultText = "ssh -i \${config.clanCore.facts.services.borgbackup.secret.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null";
|
defaultText = "ssh -i \${config.clan.core.facts.services.borgbackup.secret.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null";
|
||||||
description = "the rsh to use for the backup";
|
description = "the rsh to use for the backup";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -83,7 +83,7 @@ in
|
|||||||
|
|
||||||
services.borgbackup.jobs = lib.mapAttrs (_: dest: {
|
services.borgbackup.jobs = lib.mapAttrs (_: dest: {
|
||||||
paths = lib.unique (
|
paths = lib.unique (
|
||||||
lib.flatten (map (state: state.folders) (lib.attrValues config.clanCore.state))
|
lib.flatten (map (state: state.folders) (lib.attrValues config.clan.core.state))
|
||||||
);
|
);
|
||||||
exclude = [ "*.pyc" ];
|
exclude = [ "*.pyc" ];
|
||||||
repo = dest.repo;
|
repo = dest.repo;
|
||||||
@ -94,7 +94,7 @@ in
|
|||||||
|
|
||||||
encryption = {
|
encryption = {
|
||||||
mode = "repokey";
|
mode = "repokey";
|
||||||
passCommand = "cat ${config.clanCore.facts.services.borgbackup.secret."borgbackup.repokey".path}";
|
passCommand = "cat ${config.clan.core.facts.services.borgbackup.secret."borgbackup.repokey".path}";
|
||||||
};
|
};
|
||||||
|
|
||||||
prune.keep = {
|
prune.keep = {
|
||||||
@ -105,7 +105,7 @@ in
|
|||||||
};
|
};
|
||||||
}) cfg.destinations;
|
}) cfg.destinations;
|
||||||
|
|
||||||
clanCore.facts.services.borgbackup = {
|
clan.core.facts.services.borgbackup = {
|
||||||
public."borgbackup.ssh.pub" = { };
|
public."borgbackup.ssh.pub" = { };
|
||||||
secret."borgbackup.ssh" = { };
|
secret."borgbackup.ssh" = { };
|
||||||
secret."borgbackup.repokey" = { };
|
secret."borgbackup.repokey" = { };
|
||||||
@ -152,7 +152,7 @@ in
|
|||||||
'')
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
clanCore.backups.providers.borgbackup = {
|
clan.core.backups.providers.borgbackup = {
|
||||||
list = "borgbackup-list";
|
list = "borgbackup-list";
|
||||||
create = "borgbackup-create";
|
create = "borgbackup-create";
|
||||||
restore = "borgbackup-restore";
|
restore = "borgbackup-restore";
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
services.maddy =
|
services.maddy =
|
||||||
let
|
let
|
||||||
domain = "${config.clanCore.machineName}.local";
|
domain = "${config.clan.core.machineName}.local";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -10,5 +10,5 @@ _: {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
clanCore.state.ergochat.folders = [ "/var/lib/ergo" ];
|
clan.core.state.ergochat.folders = [ "/var/lib/ergo" ];
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
let
|
let
|
||||||
cfg = config.clan.localbackup;
|
cfg = config.clan.localbackup;
|
||||||
uniqueFolders = lib.unique (
|
uniqueFolders = lib.unique (
|
||||||
lib.flatten (lib.mapAttrsToList (_name: state: state.folders) config.clanCore.state)
|
lib.flatten (lib.mapAttrsToList (_name: state: state.folders) config.clan.core.state)
|
||||||
);
|
);
|
||||||
rsnapshotConfig = target: ''
|
rsnapshotConfig = target: ''
|
||||||
config_version 1.2
|
config_version 1.2
|
||||||
@ -143,7 +143,7 @@ in
|
|||||||
preCommandErrors["${state.name}"]=1
|
preCommandErrors["${state.name}"]=1
|
||||||
fi
|
fi
|
||||||
''
|
''
|
||||||
) (builtins.attrValues config.clanCore.state)}
|
) (builtins.attrValues config.clan.core.state)}
|
||||||
|
|
||||||
rsnapshot -c "${pkgs.writeText "rsnapshot.conf" (rsnapshotConfig target)}" sync
|
rsnapshot -c "${pkgs.writeText "rsnapshot.conf" (rsnapshotConfig target)}" sync
|
||||||
rsnapshot -c "${pkgs.writeText "rsnapshot.conf" (rsnapshotConfig target)}" snapshot
|
rsnapshot -c "${pkgs.writeText "rsnapshot.conf" (rsnapshotConfig target)}" snapshot
|
||||||
@ -233,7 +233,7 @@ in
|
|||||||
''
|
''
|
||||||
) cfg.targets;
|
) cfg.targets;
|
||||||
|
|
||||||
clanCore.backups.providers.localbackup = {
|
clan.core.backups.providers.localbackup = {
|
||||||
# TODO list needs to run locally or on the remote machine
|
# TODO list needs to run locally or on the remote machine
|
||||||
list = "localbackup-list";
|
list = "localbackup-list";
|
||||||
create = "localbackup-create";
|
create = "localbackup-create";
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf config.clan.localsend.enable {
|
config = lib.mkIf config.clan.localsend.enable {
|
||||||
clanCore.state.localsend.folders = [
|
clan.core.state.localsend.folders = [
|
||||||
"/var/localsend"
|
"/var/localsend"
|
||||||
config.clan.localsend.defaultLocation
|
config.clan.localsend.defaultLocation
|
||||||
];
|
];
|
||||||
|
@ -131,7 +131,7 @@ in
|
|||||||
systemd.tmpfiles.settings."01-matrix" = {
|
systemd.tmpfiles.settings."01-matrix" = {
|
||||||
"/run/synapse-registration-shared-secret" = {
|
"/run/synapse-registration-shared-secret" = {
|
||||||
C.argument =
|
C.argument =
|
||||||
config.clanCore.facts.services.matrix-synapse.secret.synapse-registration_shared_secret.path;
|
config.clan.core.facts.services.matrix-synapse.secret.synapse-registration_shared_secret.path;
|
||||||
z = {
|
z = {
|
||||||
mode = "0400";
|
mode = "0400";
|
||||||
user = "matrix-synapse";
|
user = "matrix-synapse";
|
||||||
@ -149,7 +149,7 @@ in
|
|||||||
};
|
};
|
||||||
clan.postgresql.databases.matrix-synapse.restore.stopOnRestore = [ "matrix-synapse" ];
|
clan.postgresql.databases.matrix-synapse.restore.stopOnRestore = [ "matrix-synapse" ];
|
||||||
|
|
||||||
clanCore.facts.services =
|
clan.core.facts.services =
|
||||||
{
|
{
|
||||||
"matrix-synapse" = {
|
"matrix-synapse" = {
|
||||||
secret."synapse-registration_shared_secret" = { };
|
secret."synapse-registration_shared_secret" = { };
|
||||||
|
@ -13,10 +13,10 @@ in
|
|||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d '/var/lib/moonlight' 0770 'user' 'users' - -"
|
"d '/var/lib/moonlight' 0770 'user' 'users' - -"
|
||||||
"C '/var/lib/moonlight/moonlight.cert' 0644 'user' 'users' - ${
|
"C '/var/lib/moonlight/moonlight.cert' 0644 'user' 'users' - ${
|
||||||
config.clanCore.facts.services.moonlight.secret."moonlight.cert".path or ""
|
config.clan.core.facts.services.moonlight.secret."moonlight.cert".path or ""
|
||||||
}"
|
}"
|
||||||
"C '/var/lib/moonlight/moonlight.key' 0644 'user' 'users' - ${
|
"C '/var/lib/moonlight/moonlight.key' 0644 'user' 'users' - ${
|
||||||
config.clanCore.facts.services.moonlight.secret."moonlight.key".path or ""
|
config.clan.core.facts.services.moonlight.secret."moonlight.key".path or ""
|
||||||
}"
|
}"
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ in
|
|||||||
systemd.user.services.moonlight-join = {
|
systemd.user.services.moonlight-join = {
|
||||||
description = "Join sunshine hosts";
|
description = "Join sunshine hosts";
|
||||||
script = ''${ms-accept}/bin/moonlight-sunshine-accept moonlight join --port ${builtins.toString defaultPort} --cert '${
|
script = ''${ms-accept}/bin/moonlight-sunshine-accept moonlight join --port ${builtins.toString defaultPort} --cert '${
|
||||||
config.clanCore.facts.services.moonlight.public."moonlight.cert".value or ""
|
config.clan.core.facts.services.moonlight.public."moonlight.cert".value or ""
|
||||||
}' --host fd2e:25da:6035:c98f:cd99:93e0:b9b8:9ca1'';
|
}' --host fd2e:25da:6035:c98f:cd99:93e0:b9b8:9ca1'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
@ -68,7 +68,7 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
clanCore.facts.services.moonlight = {
|
clan.core.facts.services.moonlight = {
|
||||||
secret."moonlight.key" = { };
|
secret."moonlight.key" = { };
|
||||||
secret."moonlight.cert" = { };
|
secret."moonlight.cert" = { };
|
||||||
public."moonlight.cert" = { };
|
public."moonlight.cert" = { };
|
||||||
|
@ -128,7 +128,7 @@ in
|
|||||||
${lib.concatStringsSep "\n" databaseClauses}
|
${lib.concatStringsSep "\n" databaseClauses}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
clanCore.state = lib.mapAttrs' (
|
clan.core.state = lib.mapAttrs' (
|
||||||
_: db: lib.nameValuePair "postgresql-${db.name}" (createDatatbaseState db)
|
_: db: lib.nameValuePair "postgresql-${db.name}" (createDatatbaseState db)
|
||||||
) config.clan.postgresql.databases;
|
) config.clan.postgresql.databases;
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
{
|
{
|
||||||
users.mutableUsers = false;
|
users.mutableUsers = false;
|
||||||
users.users.root.hashedPasswordFile =
|
users.users.root.hashedPasswordFile =
|
||||||
config.clanCore.facts.services.root-password.secret.password-hash.path;
|
config.clan.core.facts.services.root-password.secret.password-hash.path;
|
||||||
sops.secrets."${config.clanCore.machineName}-password-hash".neededForUsers = true;
|
sops.secrets."${config.clan.core.machineName}-password-hash".neededForUsers = true;
|
||||||
clanCore.facts.services.root-password = {
|
clan.core.facts.services.root-password = {
|
||||||
secret.password = { };
|
secret.password = { };
|
||||||
secret.password-hash = { };
|
secret.password-hash = { };
|
||||||
generator.path = with pkgs; [
|
generator.path = with pkgs; [
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
services.openssh.hostKeys = [
|
services.openssh.hostKeys = [
|
||||||
{
|
{
|
||||||
path = config.clanCore.facts.services.openssh.secret."ssh.id_ed25519".path;
|
path = config.clan.core.facts.services.openssh.secret."ssh.id_ed25519".path;
|
||||||
type = "ed25519";
|
type = "ed25519";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
clanCore.facts.services.openssh = {
|
clan.core.facts.services.openssh = {
|
||||||
secret."ssh.id_ed25519" = { };
|
secret."ssh.id_ed25519" = { };
|
||||||
public."ssh.id_ed25519.pub" = { };
|
public."ssh.id_ed25519.pub" = { };
|
||||||
generator.path = [
|
generator.path = [
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
excludeHosts = lib.mkOption {
|
excludeHosts = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default =
|
default =
|
||||||
if config.clan.static-hosts.topLevelDomain != "" then [ ] else [ config.clanCore.machineName ];
|
if config.clan.static-hosts.topLevelDomain != "" then [ ] else [ config.clan.core.machineName ];
|
||||||
description = "Hosts that should be excluded";
|
description = "Hosts that should be excluded";
|
||||||
};
|
};
|
||||||
topLevelDomain = lib.mkOption {
|
topLevelDomain = lib.mkOption {
|
||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
config.networking.hosts =
|
config.networking.hosts =
|
||||||
let
|
let
|
||||||
clanDir = config.clanCore.clanDir;
|
clanDir = config.clan.core.clanDir;
|
||||||
machineDir = clanDir + "/machines/";
|
machineDir = clanDir + "/machines/";
|
||||||
zerotierIpMachinePath = machines: machineDir + machines + "/facts/zerotier-ip";
|
zerotierIpMachinePath = machines: machineDir + machines + "/facts/zerotier-ip";
|
||||||
machinesFileSet = builtins.readDir machineDir;
|
machinesFileSet = builtins.readDir machineDir;
|
||||||
|
@ -97,10 +97,10 @@ in
|
|||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d '/var/lib/sunshine' 0770 'user' 'users' - -"
|
"d '/var/lib/sunshine' 0770 'user' 'users' - -"
|
||||||
"C '/var/lib/sunshine/sunshine.cert' 0644 'user' 'users' - ${
|
"C '/var/lib/sunshine/sunshine.cert' 0644 'user' 'users' - ${
|
||||||
config.clanCore.facts.services.sunshine.secret."sunshine.cert".path or ""
|
config.clan.core.facts.services.sunshine.secret."sunshine.cert".path or ""
|
||||||
}"
|
}"
|
||||||
"C '/var/lib/sunshine/sunshine.key' 0644 'user' 'users' - ${
|
"C '/var/lib/sunshine/sunshine.key' 0644 'user' 'users' - ${
|
||||||
config.clanCore.facts.services.sunshine.secret."sunshine.key".path or ""
|
config.clan.core.facts.services.sunshine.secret."sunshine.key".path or ""
|
||||||
}"
|
}"
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -117,8 +117,8 @@ in
|
|||||||
RestartSec = "5s";
|
RestartSec = "5s";
|
||||||
ReadWritePaths = [ "/var/lib/sunshine" ];
|
ReadWritePaths = [ "/var/lib/sunshine" ];
|
||||||
ReadOnlyPaths = [
|
ReadOnlyPaths = [
|
||||||
(config.clanCore.facts.services.sunshine.secret."sunshine.key".path or "")
|
(config.clan.core.facts.services.sunshine.secret."sunshine.key".path or "")
|
||||||
(config.clanCore.facts.services.sunshine.secret."sunshine.cert".path or "")
|
(config.clan.core.facts.services.sunshine.secret."sunshine.cert".path or "")
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
wantedBy = [ "graphical-session.target" ];
|
wantedBy = [ "graphical-session.target" ];
|
||||||
@ -137,7 +137,7 @@ in
|
|||||||
startLimitIntervalSec = 500;
|
startLimitIntervalSec = 500;
|
||||||
script = ''
|
script = ''
|
||||||
${ms-accept}/bin/moonlight-sunshine-accept sunshine init-state --uuid ${
|
${ms-accept}/bin/moonlight-sunshine-accept sunshine init-state --uuid ${
|
||||||
config.clanCore.facts.services.sunshine.public.sunshine-uuid.value or null
|
config.clan.core.facts.services.sunshine.public.sunshine-uuid.value or null
|
||||||
} --state-file /var/lib/sunshine/state.json
|
} --state-file /var/lib/sunshine/state.json
|
||||||
'';
|
'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
@ -173,9 +173,9 @@ in
|
|||||||
startLimitIntervalSec = 500;
|
startLimitIntervalSec = 500;
|
||||||
script = ''
|
script = ''
|
||||||
${ms-accept}/bin/moonlight-sunshine-accept sunshine listen --port ${builtins.toString listenPort} --uuid ${
|
${ms-accept}/bin/moonlight-sunshine-accept sunshine listen --port ${builtins.toString listenPort} --uuid ${
|
||||||
config.clanCore.facts.services.sunshine.public.sunshine-uuid.value or null
|
config.clan.core.facts.services.sunshine.public.sunshine-uuid.value or null
|
||||||
} --state /var/lib/sunshine/state.json --cert '${
|
} --state /var/lib/sunshine/state.json --cert '${
|
||||||
config.clanCore.facts.services.sunshine.public."sunshine.cert".value or null
|
config.clan.core.facts.services.sunshine.public."sunshine.cert".value or null
|
||||||
}'
|
}'
|
||||||
'';
|
'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
@ -187,7 +187,7 @@ in
|
|||||||
wantedBy = [ "graphical-session.target" ];
|
wantedBy = [ "graphical-session.target" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
clanCore.facts.services.ergochat = {
|
clan.core.facts.services.ergochat = {
|
||||||
secret."sunshine.key" = { };
|
secret."sunshine.key" = { };
|
||||||
secret."sunshine.cert" = { };
|
secret."sunshine.cert" = { };
|
||||||
public."sunshine-uuid" = { };
|
public."sunshine-uuid" = { };
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
clanDir = config.clanCore.clanDir;
|
clanDir = config.clan.core.clanDir;
|
||||||
machineDir = clanDir + "/machines/";
|
machineDir = clanDir + "/machines/";
|
||||||
syncthingPublicKeyPath = machines: machineDir + machines + "/facts/syncthing.pub";
|
syncthingPublicKeyPath = machines: machineDir + machines + "/facts/syncthing.pub";
|
||||||
machinesFileSet = builtins.readDir machineDir;
|
machinesFileSet = builtins.readDir machineDir;
|
||||||
@ -47,7 +47,7 @@ in
|
|||||||
options.clan.syncthing-static-peers = {
|
options.clan.syncthing-static-peers = {
|
||||||
excludeMachines = lib.mkOption {
|
excludeMachines = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
example = [ config.clanCore.machineName ];
|
example = [ config.clan.core.machineName ];
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = ''
|
description = ''
|
||||||
Machines that should not be added.
|
Machines that should not be added.
|
||||||
@ -83,11 +83,11 @@ in
|
|||||||
configDir = "/var/lib/syncthing";
|
configDir = "/var/lib/syncthing";
|
||||||
group = "syncthing";
|
group = "syncthing";
|
||||||
|
|
||||||
key = lib.mkDefault config.clanCore.facts.services.syncthing.secret."syncthing.key".path or null;
|
key = lib.mkDefault config.clan.core.facts.services.syncthing.secret."syncthing.key".path or null;
|
||||||
cert = lib.mkDefault config.clanCore.facts.services.syncthing.secret."syncthing.cert".path or null;
|
cert = lib.mkDefault config.clan.core.facts.services.syncthing.secret."syncthing.cert".path or null;
|
||||||
};
|
};
|
||||||
|
|
||||||
clanCore.facts.services.syncthing = {
|
clan.core.facts.services.syncthing = {
|
||||||
secret."syncthing.key" = { };
|
secret."syncthing.key" = { };
|
||||||
secret."syncthing.cert" = { };
|
secret."syncthing.cert" = { };
|
||||||
public."syncthing.pub" = { };
|
public."syncthing.pub" = { };
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
id = lib.mkOption {
|
id = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
example = "BABNJY4-G2ICDLF-QQEG7DD-N3OBNGF-BCCOFK6-MV3K7QJ-2WUZHXS-7DTW4AS";
|
example = "BABNJY4-G2ICDLF-QQEG7DD-N3OBNGF-BCCOFK6-MV3K7QJ-2WUZHXS-7DTW4AS";
|
||||||
default = config.clanCore.facts.services.syncthing.public."syncthing.pub".value or null;
|
default = config.clan.core.facts.services.syncthing.public."syncthing.pub".value or null;
|
||||||
defaultText = "config.clanCore.facts.services.syncthing.public.\"syncthing.pub\".value";
|
defaultText = "config.clan.core.facts.services.syncthing.public.\"syncthing.pub\".value";
|
||||||
};
|
};
|
||||||
introducer = lib.mkOption {
|
introducer = lib.mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
@ -119,7 +119,7 @@
|
|||||||
getPendingDevices = "/rest/cluster/pending/devices";
|
getPendingDevices = "/rest/cluster/pending/devices";
|
||||||
postNewDevice = "/rest/config/devices";
|
postNewDevice = "/rest/config/devices";
|
||||||
SharedFolderById = "/rest/config/folders/";
|
SharedFolderById = "/rest/config/folders/";
|
||||||
apiKey = config.clanCore.facts.services.syncthing.secret."syncthing.api".path or null;
|
apiKey = config.clan.core.facts.services.syncthing.secret."syncthing.api".path or null;
|
||||||
in
|
in
|
||||||
lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
||||||
description = "Syncthing auto accept devices";
|
description = "Syncthing auto accept devices";
|
||||||
@ -161,7 +161,7 @@
|
|||||||
|
|
||||||
systemd.services.syncthing-init-api-key =
|
systemd.services.syncthing-init-api-key =
|
||||||
let
|
let
|
||||||
apiKey = config.clanCore.facts.services.syncthing.secret."syncthing.api".path or null;
|
apiKey = config.clan.core.facts.services.syncthing.secret."syncthing.api".path or null;
|
||||||
in
|
in
|
||||||
lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
||||||
description = "Set the api key";
|
description = "Set the api key";
|
||||||
@ -183,7 +183,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
clanCore.facts.services.syncthing = {
|
clan.core.facts.services.syncthing = {
|
||||||
secret."syncthing.key" = { };
|
secret."syncthing.key" = { };
|
||||||
secret."syncthing.cert" = { };
|
secret."syncthing.cert" = { };
|
||||||
secret."syncthing.api" = { };
|
secret."syncthing.api" = { };
|
||||||
|
@ -11,5 +11,5 @@ _: {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
clanCore.state.thelounde.folders = [ "/var/lib/thelounge" ];
|
clan.core.state.thelounde.folders = [ "/var/lib/thelounge" ];
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@
|
|||||||
config = {
|
config = {
|
||||||
users.mutableUsers = false;
|
users.mutableUsers = false;
|
||||||
users.users.${config.clan.user-password.user}.hashedPasswordFile =
|
users.users.${config.clan.user-password.user}.hashedPasswordFile =
|
||||||
config.clanCore.facts.services.user-password.secret.user-password-hash.path;
|
config.clan.core.facts.services.user-password.secret.user-password-hash.path;
|
||||||
sops.secrets."${config.clanCore.machineName}-user-password-hash".neededForUsers = true;
|
sops.secrets."${config.clan.core.machineName}-user-password-hash".neededForUsers = true;
|
||||||
clanCore.facts.services.user-password = {
|
clan.core.facts.services.user-password = {
|
||||||
secret.user-password = { };
|
secret.user-password = { };
|
||||||
secret.user-password-hash = { };
|
secret.user-password-hash = { };
|
||||||
generator.prompt = (
|
generator.prompt = (
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
clanDir = config.clanCore.clanDir;
|
clanDir = config.clan.core.clanDir;
|
||||||
machineDir = clanDir + "/machines/";
|
machineDir = clanDir + "/machines/";
|
||||||
machinesFileSet = builtins.readDir machineDir;
|
machinesFileSet = builtins.readDir machineDir;
|
||||||
machines = lib.mapAttrsToList (name: _: name) machinesFileSet;
|
machines = lib.mapAttrsToList (name: _: name) machinesFileSet;
|
||||||
@ -28,7 +28,7 @@ in
|
|||||||
options.clan.zerotier-static-peers = {
|
options.clan.zerotier-static-peers = {
|
||||||
excludeHosts = lib.mkOption {
|
excludeHosts = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ config.clanCore.machineName ];
|
default = [ config.clan.core.machineName ];
|
||||||
description = "Hosts that should be excluded";
|
description = "Hosts that should be excluded";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -13,7 +13,7 @@ let
|
|||||||
|
|
||||||
clanCoreNixosModules = [
|
clanCoreNixosModules = [
|
||||||
clanCore
|
clanCore
|
||||||
{ clanCore.clanDir = ./.; }
|
{ clan.core.clanDir = ./.; }
|
||||||
] ++ allNixosModules;
|
] ++ allNixosModules;
|
||||||
|
|
||||||
# TODO: optimally we would not have to evaluate all nixos modules for every page
|
# TODO: optimally we would not have to evaluate all nixos modules for every page
|
||||||
@ -25,6 +25,8 @@ let
|
|||||||
# improves eval performance slightly (10%)
|
# improves eval performance slightly (10%)
|
||||||
getOptions = modules: (clanCoreNixos.extendModules { inherit modules; }).options;
|
getOptions = modules: (clanCoreNixos.extendModules { inherit modules; }).options;
|
||||||
|
|
||||||
|
getOptionsWithoutCore = modules: builtins.removeAttrs (getOptions modules) [ "core" ];
|
||||||
|
|
||||||
evalDocs =
|
evalDocs =
|
||||||
options:
|
options:
|
||||||
pkgs.nixosOptionsDoc {
|
pkgs.nixosOptionsDoc {
|
||||||
@ -34,7 +36,7 @@ let
|
|||||||
|
|
||||||
# clanModules docs
|
# clanModules docs
|
||||||
clanModulesDocs = builtins.mapAttrs (
|
clanModulesDocs = builtins.mapAttrs (
|
||||||
name: module: (evalDocs ((getOptions [ module ]).clan.${name} or { })).optionsJSON
|
name: module: (evalDocs ((getOptionsWithoutCore [ module ]).clan.${name} or { })).optionsJSON
|
||||||
) clanModules;
|
) clanModules;
|
||||||
|
|
||||||
clanModulesReadmes = builtins.mapAttrs (
|
clanModulesReadmes = builtins.mapAttrs (
|
||||||
@ -42,7 +44,7 @@ let
|
|||||||
) clanModules;
|
) clanModules;
|
||||||
|
|
||||||
# clanCore docs
|
# clanCore docs
|
||||||
clanCoreDocs = (evalDocs (getOptions [ ]).clanCore).optionsJSON;
|
clanCoreDocs = (evalDocs (getOptions [ ]).clan.core).optionsJSON;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit clanModulesReadmes;
|
inherit clanModulesReadmes;
|
||||||
|
@ -163,7 +163,7 @@ def produce_clan_core_docs() -> None:
|
|||||||
outfile = f"{module_name}/index.md"
|
outfile = f"{module_name}/index.md"
|
||||||
|
|
||||||
# Create separate files for nested options
|
# Create separate files for nested options
|
||||||
if len(option_name.split(".")) <= 2:
|
if len(option_name.split(".")) <= 3:
|
||||||
# i.e. clan-core.clanDir
|
# i.e. clan-core.clanDir
|
||||||
output = core_outputs.get(
|
output = core_outputs.get(
|
||||||
outfile,
|
outfile,
|
||||||
@ -174,7 +174,7 @@ def produce_clan_core_docs() -> None:
|
|||||||
core_outputs[outfile] = output
|
core_outputs[outfile] = output
|
||||||
else:
|
else:
|
||||||
# Clan sub-options
|
# Clan sub-options
|
||||||
[_, sub] = option_name.split(".")[0:2]
|
[_, sub] = option_name.split(".")[1:3]
|
||||||
outfile = f"{module_name}/{sub}.md"
|
outfile = f"{module_name}/{sub}.md"
|
||||||
# Get the content or write the header
|
# Get the content or write the header
|
||||||
output = core_outputs.get(outfile, render_option_header(sub))
|
output = core_outputs.get(outfile, render_option_header(sub))
|
||||||
|
@ -98,7 +98,7 @@ Start by indicating where your backup data should be sent. Replace `hostname` wi
|
|||||||
Decide which folders you want to back up. For example, to backup your home and root directories:
|
Decide which folders you want to back up. For example, to backup your home and root directories:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ clanCore.state.userdata.folders = [ "/home" "/root" ]; }
|
{ clan.core.state.userdata.folders = [ "/home" "/root" ]; }
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Generate Backup Credentials:**
|
3. **Generate Backup Credentials:**
|
||||||
@ -116,7 +116,7 @@ On the server where backups will be stored, enable the SSH daemon and set up a r
|
|||||||
services.borgbackup.repos.myhostname = {
|
services.borgbackup.repos.myhostname = {
|
||||||
path = "/var/lib/borgbackup/myhostname";
|
path = "/var/lib/borgbackup/myhostname";
|
||||||
authorizedKeys = [
|
authorizedKeys = [
|
||||||
(builtins.readFile (config.clanCore.clanDir + "/machines/myhostname/facts/borgbackup.ssh.pub"))
|
(builtins.readFile (config.clan.core.clanDir + "/machines/myhostname/facts/borgbackup.ssh.pub"))
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ To introduce a new machine to the VPN, adhere to the following steps:
|
|||||||
configuration, substituting `<CONTROLLER>` with the controller machine name:
|
configuration, substituting `<CONTROLLER>` with the controller machine name:
|
||||||
```nix
|
```nix
|
||||||
{ config, ... }: {
|
{ config, ... }: {
|
||||||
clan.networking.zerotier.networkId = builtins.readFile (config.clanCore.clanDir + "/machines/<CONTROLLER>/facts/zerotier-network-id");
|
clan.networking.zerotier.networkId = builtins.readFile (config.clan.core.clanDir + "/machines/<CONTROLLER>/facts/zerotier-network-id");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
1. **Update the New Machine**: Execute:
|
1. **Update the New Machine**: Execute:
|
||||||
|
@ -101,13 +101,13 @@ let
|
|||||||
(
|
(
|
||||||
{
|
{
|
||||||
# Settings
|
# Settings
|
||||||
clanCore.clanDir = directory;
|
clan.core.clanDir = directory;
|
||||||
# Inherited from clan wide settings
|
# Inherited from clan wide settings
|
||||||
clanCore.clanName = meta.name or clanName;
|
clan.core.clanName = meta.name or clanName;
|
||||||
clanCore.clanIcon = meta.icon or clanIcon;
|
clan.core.clanIcon = meta.icon or clanIcon;
|
||||||
|
|
||||||
# Machine specific settings
|
# Machine specific settings
|
||||||
clanCore.machineName = name;
|
clan.core.machineName = name;
|
||||||
networking.hostName = lib.mkDefault name;
|
networking.hostName = lib.mkDefault name;
|
||||||
nixpkgs.hostPlatform = lib.mkDefault system;
|
nixpkgs.hostPlatform = lib.mkDefault system;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
{
|
{
|
||||||
imports = [ ./state.nix ];
|
imports = [ ./state.nix ];
|
||||||
options.clanCore.backups = {
|
options.clan.core.backups = {
|
||||||
providers = lib.mkOption {
|
providers = lib.mkOption {
|
||||||
type = lib.types.attrsOf (
|
type = lib.types.attrsOf (
|
||||||
lib.types.submodule (
|
lib.types.submodule (
|
||||||
|
@ -2,37 +2,43 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(lib.mkRemovedOptionModule [
|
(lib.mkRemovedOptionModule [
|
||||||
"clanCore"
|
"clan"
|
||||||
|
"core"
|
||||||
"secretsPrefix"
|
"secretsPrefix"
|
||||||
] "secretsPrefix was only used by the sops module and the code is now integrated in there")
|
] "secretsPrefix was only used by the sops module and the code is now integrated in there")
|
||||||
(lib.mkRenamedOptionModule
|
(lib.mkRenamedOptionModule
|
||||||
[
|
[
|
||||||
"clanCore"
|
"clan"
|
||||||
|
"core"
|
||||||
"secretStore"
|
"secretStore"
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
"clanCore"
|
"clan"
|
||||||
|
"core"
|
||||||
"facts"
|
"facts"
|
||||||
"secretStore"
|
"secretStore"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
(lib.mkRemovedOptionModule [
|
(lib.mkRemovedOptionModule [
|
||||||
"clanCore"
|
"clan"
|
||||||
|
"core"
|
||||||
"secretsDirectory"
|
"secretsDirectory"
|
||||||
] "clancore.secretsDirectory was removed. Use clanCore.facts.secretPathFunction instead")
|
] "clan.core.secretsDirectory was removed. Use clan.core.facts.secretPathFunction instead")
|
||||||
(lib.mkRenamedOptionModule
|
(lib.mkRenamedOptionModule
|
||||||
[
|
[
|
||||||
"clanCore"
|
"clan"
|
||||||
|
"core"
|
||||||
"secretsUploadDirectory"
|
"secretsUploadDirectory"
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
"clanCore"
|
"clan"
|
||||||
|
"core"
|
||||||
"facts"
|
"facts"
|
||||||
"secretUploadDirectory"
|
"secretUploadDirectory"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
options.clanCore.secrets = lib.mkOption {
|
options.clan.core.secrets = lib.mkOption {
|
||||||
visible = false;
|
visible = false;
|
||||||
default = { };
|
default = { };
|
||||||
type = lib.types.attrsOf (
|
type = lib.types.attrsOf (
|
||||||
@ -97,14 +103,14 @@
|
|||||||
description = ''
|
description = ''
|
||||||
path to a secret which is generated by the generator
|
path to a secret which is generated by the generator
|
||||||
'';
|
'';
|
||||||
default = config.clanCore.facts.secretPathFunction secret;
|
default = config.clan.core.facts.secretPathFunction secret;
|
||||||
defaultText = lib.literalExpression "config.clanCore.facts.secretPathFunction secret";
|
defaultText = lib.literalExpression "config.clan.core.facts.secretPathFunction secret";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs (config.clanCore.facts.secretStore == "sops") {
|
// lib.optionalAttrs (config.clan.core.facts.secretStore == "sops") {
|
||||||
groups = lib.mkOption {
|
groups = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = config.clanCore.sops.defaultGroups;
|
default = config.clan.core.sops.defaultGroups;
|
||||||
description = ''
|
description = ''
|
||||||
Groups to decrypt the secret for. By default we always use the user's key.
|
Groups to decrypt the secret for. By default we always use the user's key.
|
||||||
'';
|
'';
|
||||||
@ -134,12 +140,12 @@
|
|||||||
path to a fact which is generated by the generator
|
path to a fact which is generated by the generator
|
||||||
'';
|
'';
|
||||||
default =
|
default =
|
||||||
config.clanCore.clanDir
|
config.clan.core.clanDir
|
||||||
+ "/machines/${config.clanCore.machineName}/facts/${fact.config._module.args.name}";
|
+ "/machines/${config.clan.core.machineName}/facts/${fact.config._module.args.name}";
|
||||||
defaultText = lib.literalExpression "\${config.clanCore.clanDir}/machines/\${config.clanCore.machineName}/facts/\${fact.config._module.args.name}";
|
defaultText = lib.literalExpression "\${config.clan.core.clanDir}/machines/\${config.clan.core.machineName}/facts/\${fact.config._module.args.name}";
|
||||||
};
|
};
|
||||||
value = lib.mkOption {
|
value = lib.mkOption {
|
||||||
defaultText = lib.literalExpression "\${config.clanCore.clanDir}/\${fact.config.path}";
|
defaultText = lib.literalExpression "\${config.clan.core.clanDir}/\${fact.config.path}";
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default =
|
default =
|
||||||
if builtins.pathExists fact.config.path then lib.strings.fileContents fact.config.path else null;
|
if builtins.pathExists fact.config.path then lib.strings.fileContents fact.config.path else null;
|
||||||
@ -152,16 +158,16 @@
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
config = lib.mkIf (config.clanCore.secrets != { }) {
|
config = lib.mkIf (config.clan.core.secrets != { }) {
|
||||||
clanCore.facts.services = lib.mapAttrs' (
|
clan.core.facts.services = lib.mapAttrs' (
|
||||||
name: service:
|
name: service:
|
||||||
lib.warn "clanCore.secrets.${name} is deprecated, use clanCore.facts.services.${name} instead" (
|
lib.warn "clan.core.secrets.${name} is deprecated, use clan.core.facts.services.${name} instead" (
|
||||||
lib.nameValuePair name ({
|
lib.nameValuePair name ({
|
||||||
secret = service.secrets;
|
secret = service.secrets;
|
||||||
public = service.facts;
|
public = service.facts;
|
||||||
generator = service.generator;
|
generator = service.generator;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
) config.clanCore.secrets;
|
) config.clan.core.secrets;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
options.clanCore.facts = {
|
options.clan.core.facts = {
|
||||||
secretStore = lib.mkOption {
|
secretStore = lib.mkOption {
|
||||||
type = lib.types.enum [
|
type = lib.types.enum [
|
||||||
"sops"
|
"sops"
|
||||||
@ -115,6 +115,7 @@
|
|||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
internal = true;
|
internal = true;
|
||||||
|
defaultText = "read only script";
|
||||||
default = ''
|
default = ''
|
||||||
set -eu -o pipefail
|
set -eu -o pipefail
|
||||||
|
|
||||||
@ -155,13 +156,13 @@
|
|||||||
description = ''
|
description = ''
|
||||||
path to a secret which is generated by the generator
|
path to a secret which is generated by the generator
|
||||||
'';
|
'';
|
||||||
default = config.clanCore.facts.secretPathFunction secret;
|
default = config.clan.core.facts.secretPathFunction secret;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs (config.clanCore.facts.secretModule == "clan_cli.facts.secret_modules.sops") {
|
// lib.optionalAttrs (config.clan.core.facts.secretModule == "clan_cli.facts.secret_modules.sops") {
|
||||||
groups = lib.mkOption {
|
groups = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = config.clanCore.sops.defaultGroups;
|
default = config.clan.core.sops.defaultGroups;
|
||||||
description = ''
|
description = ''
|
||||||
Groups to decrypt the secret for. By default we always use the user's key.
|
Groups to decrypt the secret for. By default we always use the user's key.
|
||||||
'';
|
'';
|
||||||
@ -190,12 +191,12 @@
|
|||||||
description = ''
|
description = ''
|
||||||
path to a fact which is generated by the generator
|
path to a fact which is generated by the generator
|
||||||
'';
|
'';
|
||||||
defaultText = lib.literalExpression "\${config.clanCore.clanDir}/machines/\${config.clanCore.machineName}/facts/\${fact.config.name}";
|
defaultText = lib.literalExpression "\${config.clan.core.clanDir}/machines/\${config.clan.core.machineName}/facts/\${fact.config.name}";
|
||||||
default =
|
default =
|
||||||
config.clanCore.clanDir + "/machines/${config.clanCore.machineName}/facts/${fact.config.name}";
|
config.clan.core.clanDir + "/machines/${config.clan.core.machineName}/facts/${fact.config.name}";
|
||||||
};
|
};
|
||||||
value = lib.mkOption {
|
value = lib.mkOption {
|
||||||
defaultText = lib.literalExpression "\${config.clanCore.clanDir}/\${fact.config.path}";
|
defaultText = lib.literalExpression "\${config.clan.core.clanDir}/\${fact.config.path}";
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default =
|
default =
|
||||||
if builtins.pathExists fact.config.path then lib.strings.fileContents fact.config.path else null;
|
if builtins.pathExists fact.config.path then lib.strings.fileContents fact.config.path else null;
|
||||||
@ -218,5 +219,15 @@
|
|||||||
|
|
||||||
./public/in_repo.nix
|
./public/in_repo.nix
|
||||||
./public/vm.nix
|
./public/vm.nix
|
||||||
|
|
||||||
|
# (lib.mkRenamedOptionModule
|
||||||
|
# [
|
||||||
|
# "clanCore"
|
||||||
|
# ]
|
||||||
|
# [
|
||||||
|
# "clan"
|
||||||
|
# "core"
|
||||||
|
# ]
|
||||||
|
# )
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
{
|
{
|
||||||
config = lib.mkIf (config.clanCore.facts.publicStore == "in_repo") {
|
config = lib.mkIf (config.clan.core.facts.publicStore == "in_repo") {
|
||||||
clanCore.facts.publicModule = "clan_cli.facts.public_modules.in_repo";
|
clan.core.facts.publicModule = "clan_cli.facts.public_modules.in_repo";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
{
|
{
|
||||||
config = lib.mkIf (config.clanCore.facts.publicStore == "vm") {
|
config = lib.mkIf (config.clan.core.facts.publicStore == "vm") {
|
||||||
clanCore.facts.publicModule = "clan_cli.facts.public_modules.vm";
|
clan.core.facts.publicModule = "clan_cli.facts.public_modules.vm";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf (config.clanCore.facts.secretStore == "password-store") {
|
config = lib.mkIf (config.clan.core.facts.secretStore == "password-store") {
|
||||||
clanCore.facts.secretPathFunction =
|
clan.core.facts.secretPathFunction =
|
||||||
secret: "${config.clan.password-store.targetDirectory}/${secret.config.name}";
|
secret: "${config.clan.password-store.targetDirectory}/${secret.config.name}";
|
||||||
clanCore.facts.secretUploadDirectory = config.clan.password-store.targetDirectory;
|
clan.core.facts.secretUploadDirectory = config.clan.password-store.targetDirectory;
|
||||||
clanCore.facts.secretModule = "clan_cli.facts.secret_modules.password_store";
|
clan.core.facts.secretModule = "clan_cli.facts.secret_modules.password_store";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
secretsDir = config.clanCore.clanDir + "/sops/secrets";
|
secretsDir = config.clan.core.clanDir + "/sops/secrets";
|
||||||
groupsDir = config.clanCore.clanDir + "/sops/groups";
|
groupsDir = config.clan.core.clanDir + "/sops/groups";
|
||||||
|
|
||||||
# My symlink is in the nixos module detected as a directory also it works in the repl. Is this because of pure evaluation?
|
# My symlink is in the nixos module detected as a directory also it works in the repl. Is this because of pure evaluation?
|
||||||
containsSymlink =
|
containsSymlink =
|
||||||
@ -16,7 +16,7 @@ let
|
|||||||
|
|
||||||
containsMachine =
|
containsMachine =
|
||||||
parent: name: type:
|
parent: name: type:
|
||||||
type == "directory" && containsSymlink "${parent}/${name}/machines/${config.clanCore.machineName}";
|
type == "directory" && containsSymlink "${parent}/${name}/machines/${config.clan.core.machineName}";
|
||||||
|
|
||||||
containsMachineOrGroups =
|
containsMachineOrGroups =
|
||||||
name: type:
|
name: type:
|
||||||
@ -34,7 +34,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
clanCore.sops.defaultGroups = lib.mkOption {
|
clan.core.sops.defaultGroups = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
example = [ "admins" ];
|
example = [ "admins" ];
|
||||||
@ -42,16 +42,16 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf (config.clanCore.facts.secretStore == "sops") {
|
config = lib.mkIf (config.clan.core.facts.secretStore == "sops") {
|
||||||
# Before we generate a secret we cannot know the path yet, so we need to set it to an empty string
|
# Before we generate a secret we cannot know the path yet, so we need to set it to an empty string
|
||||||
clanCore.facts.secretPathFunction =
|
clan.core.facts.secretPathFunction =
|
||||||
secret:
|
secret:
|
||||||
config.sops.secrets.${"${config.clanCore.machineName}-${secret.config.name}"}.path
|
config.sops.secrets.${"${config.clan.core.machineName}-${secret.config.name}"}.path
|
||||||
or "/no-such-path";
|
or "/no-such-path";
|
||||||
clanCore.facts.secretModule = "clan_cli.facts.secret_modules.sops";
|
clan.core.facts.secretModule = "clan_cli.facts.secret_modules.sops";
|
||||||
clanCore.facts.secretUploadDirectory = lib.mkDefault "/var/lib/sops-nix";
|
clan.core.facts.secretUploadDirectory = lib.mkDefault "/var/lib/sops-nix";
|
||||||
sops.secrets = builtins.mapAttrs (name: _: {
|
sops.secrets = builtins.mapAttrs (name: _: {
|
||||||
sopsFile = config.clanCore.clanDir + "/sops/secrets/${name}/secret";
|
sopsFile = config.clan.core.clanDir + "/sops/secrets/${name}/secret";
|
||||||
format = "binary";
|
format = "binary";
|
||||||
}) secrets;
|
}) secrets;
|
||||||
# To get proper error messages about missing secrets we need a dummy secret file that is always present
|
# To get proper error messages about missing secrets we need a dummy secret file that is always present
|
||||||
@ -60,7 +60,7 @@ in
|
|||||||
);
|
);
|
||||||
|
|
||||||
sops.age.keyFile = lib.mkIf (builtins.pathExists (
|
sops.age.keyFile = lib.mkIf (builtins.pathExists (
|
||||||
config.clanCore.clanDir + "/sops/secrets/${config.clanCore.machineName}-age.key/secret"
|
config.clan.core.clanDir + "/sops/secrets/${config.clan.core.machineName}-age.key/secret"
|
||||||
)) (lib.mkDefault "/var/lib/sops-nix/key.txt");
|
)) (lib.mkDefault "/var/lib/sops-nix/key.txt");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
{
|
{
|
||||||
config = lib.mkIf (config.clanCore.facts.secretStore == "vm") {
|
config = lib.mkIf (config.clan.core.facts.secretStore == "vm") {
|
||||||
clanCore.facts.secretPathFunction = secret: "/etc/secrets/${secret.config.name}";
|
clan.core.facts.secretPathFunction = secret: "/etc/secrets/${secret.config.name}";
|
||||||
clanCore.facts.secretUploadDirectory = "/etc/secrets";
|
clan.core.facts.secretUploadDirectory = "/etc/secrets";
|
||||||
clanCore.facts.secretModule = "clan_cli.facts.secret_modules.vm";
|
clan.core.facts.secretModule = "clan_cli.facts.secret_modules.vm";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ lib, pkgs, ... }:
|
{ lib, pkgs, ... }:
|
||||||
{
|
{
|
||||||
options.clanCore = {
|
options.clan.core = {
|
||||||
clanName = lib.mkOption {
|
clanName = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -5,7 +5,13 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
options.clanCore.optionsNix = lib.mkOption {
|
imports = [
|
||||||
|
(lib.mkRenamedOptionModule [ "clanCore" ] [
|
||||||
|
"clan"
|
||||||
|
"core"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
options.clan.core.optionsNix = lib.mkOption {
|
||||||
type = lib.types.raw;
|
type = lib.types.raw;
|
||||||
internal = true;
|
internal = true;
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
|
@ -66,7 +66,7 @@
|
|||||||
config = {
|
config = {
|
||||||
system.clan.deployment.data = {
|
system.clan.deployment.data = {
|
||||||
facts = {
|
facts = {
|
||||||
inherit (config.clanCore.facts)
|
inherit (config.clan.core.facts)
|
||||||
secretUploadDirectory
|
secretUploadDirectory
|
||||||
secretModule
|
secretModule
|
||||||
publicModule
|
publicModule
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{ lib, ... }:
|
{ lib, ... }:
|
||||||
{
|
{
|
||||||
# defaults
|
# defaults
|
||||||
config.clanCore.state.HOME.folders = [ "/home" ];
|
config.clan.core.state.HOME.folders = [ "/home" ];
|
||||||
|
|
||||||
# interface
|
# interface
|
||||||
options.clanCore.state = lib.mkOption {
|
options.clan.core.state = lib.mkOption {
|
||||||
default = { };
|
default = { };
|
||||||
type = lib.types.attrsOf (
|
type = lib.types.attrsOf (
|
||||||
lib.types.submodule (
|
lib.types.submodule (
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
# Flatten the list of state folders into a single list
|
# Flatten the list of state folders into a single list
|
||||||
stateFolders = lib.flatten (lib.mapAttrsToList (_item: attrs: attrs.folders) config.clanCore.state);
|
stateFolders = lib.flatten (
|
||||||
|
lib.mapAttrsToList (_item: attrs: attrs.folders) config.clan.core.state
|
||||||
|
);
|
||||||
|
|
||||||
vmModule = {
|
vmModule = {
|
||||||
imports = [
|
imports = [
|
||||||
@ -86,7 +88,7 @@ let
|
|||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
${config.clanCore.secretsUploadDirectory} = {
|
${config.clan.core.secretsUploadDirectory} = {
|
||||||
device = "secrets";
|
device = "secrets";
|
||||||
fsType = "9p";
|
fsType = "9p";
|
||||||
neededForBoot = true;
|
neededForBoot = true;
|
||||||
@ -158,7 +160,7 @@ in
|
|||||||
# All important VM config variables needed by the vm runner
|
# All important VM config variables needed by the vm runner
|
||||||
# this is really just a remapping of values defined elsewhere
|
# this is really just a remapping of values defined elsewhere
|
||||||
# and therefore not intended to be set by the user
|
# and therefore not intended to be set by the user
|
||||||
clanCore.vm.inspect = {
|
clan.core.vm.inspect = {
|
||||||
clan_name = lib.mkOption {
|
clan_name = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
internal = true;
|
internal = true;
|
||||||
@ -228,11 +230,11 @@ in
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
# for clan vm inspect
|
# for clan vm inspect
|
||||||
clanCore.vm.inspect = {
|
clan.core.vm.inspect = {
|
||||||
clan_name = config.clanCore.clanName;
|
clan_name = config.clan.core.clanName;
|
||||||
machine_icon = config.clanCore.machineIcon or config.clanCore.clanIcon;
|
machine_icon = config.clan.core.machineIcon or config.clan.core.clanIcon;
|
||||||
machine_name = config.clanCore.machineName;
|
machine_name = config.clan.core.machineName;
|
||||||
machine_description = config.clanCore.machineDescription;
|
machine_description = config.clan.core.machineDescription;
|
||||||
memory_size = config.clan.virtualisation.memorySize;
|
memory_size = config.clan.virtualisation.memorySize;
|
||||||
inherit (config.clan.virtualisation) cores graphics waypipe;
|
inherit (config.clan.virtualisation) cores graphics waypipe;
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
cfg = config.clan.networking.zerotier;
|
cfg = config.clan.networking.zerotier;
|
||||||
facts = config.clanCore.facts.services.zerotier.public or { };
|
facts = config.clan.core.facts.services.zerotier.public or { };
|
||||||
genMoonScript = pkgs.runCommand "genmoon" { nativeBuildInputs = [ pkgs.python3 ]; } ''
|
genMoonScript = pkgs.runCommand "genmoon" { nativeBuildInputs = [ pkgs.python3 ]; } ''
|
||||||
install -Dm755 ${./genmoon.py} $out/bin/genmoon
|
install -Dm755 ${./genmoon.py} $out/bin/genmoon
|
||||||
patchShebangs $out/bin/genmoon
|
patchShebangs $out/bin/genmoon
|
||||||
@ -23,8 +23,8 @@ in
|
|||||||
};
|
};
|
||||||
name = lib.mkOption {
|
name = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = config.clanCore.clanName;
|
default = config.clan.core.clanName;
|
||||||
defaultText = "config.clanCore.clanName";
|
defaultText = "config.clan.core.clanName";
|
||||||
description = ''
|
description = ''
|
||||||
zerotier network name
|
zerotier network name
|
||||||
'';
|
'';
|
||||||
@ -111,7 +111,7 @@ in
|
|||||||
|
|
||||||
systemd.services.zerotierone.serviceConfig.ExecStartPre = [
|
systemd.services.zerotierone.serviceConfig.ExecStartPre = [
|
||||||
"+${pkgs.writeShellScript "init-zerotier" ''
|
"+${pkgs.writeShellScript "init-zerotier" ''
|
||||||
cp ${config.clanCore.facts.services.zerotier.secret.zerotier-identity-secret.path} /var/lib/zerotier-one/identity.secret
|
cp ${config.clan.core.facts.services.zerotier.secret.zerotier-identity-secret.path} /var/lib/zerotier-one/identity.secret
|
||||||
zerotier-idtool getpublic /var/lib/zerotier-one/identity.secret > /var/lib/zerotier-one/identity.public
|
zerotier-idtool getpublic /var/lib/zerotier-one/identity.secret > /var/lib/zerotier-one/identity.public
|
||||||
|
|
||||||
${lib.optionalString (cfg.controller.enable) ''
|
${lib.optionalString (cfg.controller.enable) ''
|
||||||
@ -176,7 +176,7 @@ in
|
|||||||
(lib.mkIf cfg.controller.enable {
|
(lib.mkIf cfg.controller.enable {
|
||||||
# only the controller needs to have the key in the repo, the other clients can be dynamic
|
# only the controller needs to have the key in the repo, the other clients can be dynamic
|
||||||
# we generate the zerotier code manually for the controller, since it's part of the bootstrap command
|
# we generate the zerotier code manually for the controller, since it's part of the bootstrap command
|
||||||
clanCore.facts.services.zerotier = {
|
clan.core.facts.services.zerotier = {
|
||||||
public.zerotier-ip = { };
|
public.zerotier-ip = { };
|
||||||
public.zerotier-network-id = { };
|
public.zerotier-network-id = { };
|
||||||
secret.zerotier-identity-secret = { };
|
secret.zerotier-identity-secret = { };
|
||||||
@ -192,12 +192,12 @@ in
|
|||||||
--network-id "$facts/zerotier-network-id"
|
--network-id "$facts/zerotier-network-id"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
clanCore.state.zerotier.folders = [ "/var/lib/zerotier-one" ];
|
clan.core.state.zerotier.folders = [ "/var/lib/zerotier-one" ];
|
||||||
|
|
||||||
environment.systemPackages = [ config.clanCore.clanPkgs.zerotier-members ];
|
environment.systemPackages = [ config.clan.core.clanPkgs.zerotier-members ];
|
||||||
})
|
})
|
||||||
(lib.mkIf (!cfg.controller.enable && cfg.networkId != null) {
|
(lib.mkIf (!cfg.controller.enable && cfg.networkId != null) {
|
||||||
clanCore.facts.services.zerotier = {
|
clan.core.facts.services.zerotier = {
|
||||||
public.zerotier-ip = { };
|
public.zerotier-ip = { };
|
||||||
secret.zerotier-identity-secret = { };
|
secret.zerotier-identity-secret = { };
|
||||||
generator.path = [
|
generator.path = [
|
||||||
@ -255,7 +255,7 @@ in
|
|||||||
environment.etc."zerotier/network-id".text = facts.zerotier-network-id.value;
|
environment.etc."zerotier/network-id".text = facts.zerotier-network-id.value;
|
||||||
systemd.services.zerotierone.serviceConfig.ExecStartPost = [
|
systemd.services.zerotierone.serviceConfig.ExecStartPost = [
|
||||||
"+${pkgs.writeShellScript "whitelist-controller" ''
|
"+${pkgs.writeShellScript "whitelist-controller" ''
|
||||||
${config.clanCore.clanPkgs.zerotier-members}/bin/zerotier-members allow ${
|
${config.clan.core.clanPkgs.zerotier-members}/bin/zerotier-members allow ${
|
||||||
builtins.substring 0 10 cfg.networkId
|
builtins.substring 0 10 cfg.networkId
|
||||||
}
|
}
|
||||||
''}"
|
''}"
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
(
|
(
|
||||||
{ pkgs, lib, ... }:
|
{ pkgs, lib, ... }:
|
||||||
{
|
{
|
||||||
clanCore.clanPkgs = lib.mkDefault self.packages.${pkgs.hostPlatform.system};
|
clan.core.clanPkgs = lib.mkDefault self.packages.${pkgs.hostPlatform.system};
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
@ -19,7 +19,9 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Flatten the list of state folders into a single list
|
# Flatten the list of state folders into a single list
|
||||||
stateFolders = lib.flatten (lib.mapAttrsToList (_item: attrs: attrs.folders) config.clanCore.state);
|
stateFolders = lib.flatten (
|
||||||
|
lib.mapAttrsToList (_item: attrs: attrs.folders) config.clan.core.state
|
||||||
|
);
|
||||||
|
|
||||||
# A module setting up bind mounts for all state folders
|
# A module setting up bind mounts for all state folders
|
||||||
stateMounts = {
|
stateMounts = {
|
||||||
|
@ -15,7 +15,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
def create_backup(machine: Machine, provider: str | None = None) -> None:
|
def create_backup(machine: Machine, provider: str | None = None) -> None:
|
||||||
log.info(f"creating backup for {machine.name}")
|
log.info(f"creating backup for {machine.name}")
|
||||||
backup_scripts = json.loads(machine.eval_nix("config.clanCore.backups"))
|
backup_scripts = json.loads(machine.eval_nix("config.clan.core.backups"))
|
||||||
if provider is None:
|
if provider is None:
|
||||||
for provider in backup_scripts["providers"]:
|
for provider in backup_scripts["providers"]:
|
||||||
proc = machine.target_host.run(
|
proc = machine.target_host.run(
|
||||||
|
@ -20,7 +20,7 @@ class Backup:
|
|||||||
|
|
||||||
def list_provider(machine: Machine, provider: str) -> list[Backup]:
|
def list_provider(machine: Machine, provider: str) -> list[Backup]:
|
||||||
results = []
|
results = []
|
||||||
backup_metadata = json.loads(machine.eval_nix("config.clanCore.backups"))
|
backup_metadata = json.loads(machine.eval_nix("config.clan.core.backups"))
|
||||||
proc = machine.target_host.run(
|
proc = machine.target_host.run(
|
||||||
[backup_metadata["providers"][provider]["list"]],
|
[backup_metadata["providers"][provider]["list"]],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
@ -40,7 +40,7 @@ def list_provider(machine: Machine, provider: str) -> list[Backup]:
|
|||||||
|
|
||||||
|
|
||||||
def list_backups(machine: Machine, provider: str | None = None) -> list[Backup]:
|
def list_backups(machine: Machine, provider: str | None = None) -> list[Backup]:
|
||||||
backup_metadata = json.loads(machine.eval_nix("config.clanCore.backups"))
|
backup_metadata = json.loads(machine.eval_nix("config.clan.core.backups"))
|
||||||
results = []
|
results = []
|
||||||
if provider is None:
|
if provider is None:
|
||||||
for _provider in backup_metadata["providers"]:
|
for _provider in backup_metadata["providers"]:
|
||||||
|
@ -12,8 +12,8 @@ from ..machines.machines import Machine
|
|||||||
|
|
||||||
|
|
||||||
def restore_service(machine: Machine, name: str, provider: str, service: str) -> None:
|
def restore_service(machine: Machine, name: str, provider: str, service: str) -> None:
|
||||||
backup_metadata = json.loads(machine.eval_nix("config.clanCore.backups"))
|
backup_metadata = json.loads(machine.eval_nix("config.clan.core.backups"))
|
||||||
backup_folders = json.loads(machine.eval_nix("config.clanCore.state"))
|
backup_folders = json.loads(machine.eval_nix("config.clan.core.state"))
|
||||||
|
|
||||||
if service not in backup_folders:
|
if service not in backup_folders:
|
||||||
msg = f"Service {service} not found in configuration. Available services are: {', '.join(backup_folders.keys())}"
|
msg = f"Service {service} not found in configuration. Available services are: {', '.join(backup_folders.keys())}"
|
||||||
@ -66,7 +66,7 @@ def restore_backup(
|
|||||||
) -> None:
|
) -> None:
|
||||||
errors = []
|
errors = []
|
||||||
if service is None:
|
if service is None:
|
||||||
backup_folders = json.loads(machine.eval_nix("config.clanCore.state"))
|
backup_folders = json.loads(machine.eval_nix("config.clan.core.state"))
|
||||||
for _service in backup_folders:
|
for _service in backup_folders:
|
||||||
try:
|
try:
|
||||||
restore_service(machine, name, provider, _service)
|
restore_service(machine, name, provider, _service)
|
||||||
|
@ -56,7 +56,7 @@ def inspect_flake(flake_url: str | Path, machine_name: str) -> FlakeConfig:
|
|||||||
# Get the Clan name
|
# Get the Clan name
|
||||||
cmd = nix_eval(
|
cmd = nix_eval(
|
||||||
[
|
[
|
||||||
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clanCore.clanName'
|
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clan.core.clanName'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
res = run_cmd(cmd)
|
res = run_cmd(cmd)
|
||||||
@ -65,7 +65,7 @@ def inspect_flake(flake_url: str | Path, machine_name: str) -> FlakeConfig:
|
|||||||
# Get the clan icon path
|
# Get the clan icon path
|
||||||
cmd = nix_eval(
|
cmd = nix_eval(
|
||||||
[
|
[
|
||||||
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clanCore.clanIcon'
|
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clan.core.clanIcon'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
res = run_cmd(cmd)
|
res = run_cmd(cmd)
|
||||||
@ -78,7 +78,7 @@ def inspect_flake(flake_url: str | Path, machine_name: str) -> FlakeConfig:
|
|||||||
|
|
||||||
cmd = nix_build(
|
cmd = nix_build(
|
||||||
[
|
[
|
||||||
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clanCore.clanIcon'
|
f'{flake_url}#clanInternals.machines."{system}"."{machine_name}".config.clan.core.clanIcon'
|
||||||
],
|
],
|
||||||
machine_gcroot(flake_url=str(flake_url)) / "clanIcon",
|
machine_gcroot(flake_url=str(flake_url)) / "clanIcon",
|
||||||
)
|
)
|
||||||
|
@ -95,7 +95,7 @@ def complete_services_for_machine(
|
|||||||
run(
|
run(
|
||||||
nix_eval(
|
nix_eval(
|
||||||
flags=[
|
flags=[
|
||||||
f"{flake}#nixosConfigurations.{machines[0]}.config.clanCore.facts.services",
|
f"{flake}#nixosConfigurations.{machines[0]}.config.clan.core.facts.services",
|
||||||
"--apply",
|
"--apply",
|
||||||
"builtins.attrNames",
|
"builtins.attrNames",
|
||||||
],
|
],
|
||||||
@ -137,7 +137,7 @@ def complete_backup_providers_for_machine(
|
|||||||
run(
|
run(
|
||||||
nix_eval(
|
nix_eval(
|
||||||
flags=[
|
flags=[
|
||||||
f"{flake}#nixosConfigurations.{machine}.config.clanCore.backups.providers",
|
f"{flake}#nixosConfigurations.{machine}.config.clan.core.backups.providers",
|
||||||
"--apply",
|
"--apply",
|
||||||
"builtins.attrNames",
|
"builtins.attrNames",
|
||||||
],
|
],
|
||||||
|
@ -114,7 +114,7 @@ def options_for_machine(
|
|||||||
if show_trace:
|
if show_trace:
|
||||||
flags.append("--show-trace")
|
flags.append("--show-trace")
|
||||||
flags.append(
|
flags.append(
|
||||||
f"{clan_dir}#nixosConfigurations.{machine_name}.config.clanCore.optionsNix"
|
f"{clan_dir}#nixosConfigurations.{machine_name}.config.clan.core.optionsNix"
|
||||||
)
|
)
|
||||||
cmd = nix_eval(flags=flags)
|
cmd = nix_eval(flags=flags)
|
||||||
proc = run(
|
proc = run(
|
||||||
|
@ -50,7 +50,7 @@ def verify_machine_config(
|
|||||||
# potentially the config might affect submodule options,
|
# potentially the config might affect submodule options,
|
||||||
# therefore we need to import it
|
# therefore we need to import it
|
||||||
config
|
config
|
||||||
{{clanCore.clanDir = {flake};}}
|
{{clan.core.clanDir = {flake};}}
|
||||||
]
|
]
|
||||||
# add all clan modules specified via clanImports
|
# add all clan modules specified via clanImports
|
||||||
++ (map (name: clan-core.clanModules.${{name}}) config.clanImports or []);
|
++ (map (name: clan-core.clanModules.${{name}}) config.clanImports or []);
|
||||||
|
@ -84,7 +84,7 @@ def machine_schema(
|
|||||||
# potentially the config might affect submodule options,
|
# potentially the config might affect submodule options,
|
||||||
# therefore we need to import it
|
# therefore we need to import it
|
||||||
config
|
config
|
||||||
{{ clanCore.clanName = "fakeClan"; }}
|
{{ clan.core.clanName = "fakeClan"; }}
|
||||||
]
|
]
|
||||||
# add all clan modules specified via clanImports
|
# add all clan modules specified via clanImports
|
||||||
++ (map (name: clan-core.clanModules.${{name}}) config.clanImports or []);
|
++ (map (name: clan-core.clanModules.${{name}}) config.clanImports or []);
|
||||||
|
@ -29,7 +29,7 @@ def show_machine(flake_url: str | Path, machine_name: str) -> MachineInfo:
|
|||||||
[
|
[
|
||||||
f"{flake_url}#clanInternals.machines.{system}.{machine_name}",
|
f"{flake_url}#clanInternals.machines.{system}.{machine_name}",
|
||||||
"--apply",
|
"--apply",
|
||||||
"machine: { inherit (machine.config.clanCore) machineDescription machineIcon machineName; }",
|
"machine: { inherit (machine.config.clan.core) machineDescription machineIcon machineName; }",
|
||||||
"--json",
|
"--json",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,7 @@ class VmConfig:
|
|||||||
|
|
||||||
|
|
||||||
def inspect_vm(machine: Machine) -> VmConfig:
|
def inspect_vm(machine: Machine) -> VmConfig:
|
||||||
data = json.loads(machine.eval_nix("config.clanCore.vm.inspect"))
|
data = json.loads(machine.eval_nix("config.clan.core.vm.inspect"))
|
||||||
return VmConfig(flake_url=str(machine.flake), **data)
|
return VmConfig(flake_url=str(machine.flake), **data)
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,6 +47,8 @@ def generate_flake(
|
|||||||
substitutions: dict[str, str] = {
|
substitutions: dict[str, str] = {
|
||||||
"__CHANGE_ME__": "_test_vm_persistence",
|
"__CHANGE_ME__": "_test_vm_persistence",
|
||||||
"git+https://git.clan.lol/clan/clan-core": "path://" + str(CLAN_CORE),
|
"git+https://git.clan.lol/clan/clan-core": "path://" + str(CLAN_CORE),
|
||||||
|
"https://git.clan.lol/clan/clan-core/archive/main.tar.gz": "path://"
|
||||||
|
+ str(CLAN_CORE),
|
||||||
},
|
},
|
||||||
# define the machines directly including their config
|
# define the machines directly including their config
|
||||||
machine_configs: dict[str, dict] = {},
|
machine_configs: dict[str, dict] = {},
|
||||||
@ -58,13 +60,15 @@ def generate_flake(
|
|||||||
Example:
|
Example:
|
||||||
machine_configs = dict(
|
machine_configs = dict(
|
||||||
my_machine=dict(
|
my_machine=dict(
|
||||||
clanCore=dict(
|
clan=dict(
|
||||||
|
core=dict(
|
||||||
backups=dict(
|
backups=dict(
|
||||||
...
|
...
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# copy the template to a new temporary location
|
# copy the template to a new temporary location
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
||||||
system.stateVersion = lib.version;
|
system.stateVersion = lib.version;
|
||||||
sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__";
|
sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__";
|
||||||
clanCore.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__";
|
clan.core.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__";
|
||||||
clan.virtualisation.graphics = false;
|
clan.virtualisation.graphics = false;
|
||||||
|
|
||||||
clan.networking.zerotier.controller.enable = true;
|
clan.networking.zerotier.controller.enable = true;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
||||||
system.stateVersion = lib.version;
|
system.stateVersion = lib.version;
|
||||||
sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__";
|
sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__";
|
||||||
clanCore.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__";
|
clan.core.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__";
|
||||||
clan.virtualisation.graphics = false;
|
clan.virtualisation.graphics = false;
|
||||||
|
|
||||||
clan.networking.zerotier.controller.enable = true;
|
clan.networking.zerotier.controller.enable = true;
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
nixpkgs.pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
|
nixpkgs.pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
|
||||||
documentation.enable = false;
|
documentation.enable = false;
|
||||||
};
|
};
|
||||||
options.clanCore.optionsNix = lib.mkOption {
|
options.clan.core.optionsNix = lib.mkOption {
|
||||||
type = lib.types.raw;
|
type = lib.types.raw;
|
||||||
internal = true;
|
internal = true;
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
||||||
system.stateVersion = lib.version;
|
system.stateVersion = lib.version;
|
||||||
sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__";
|
sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__";
|
||||||
clanCore.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__";
|
clan.core.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__";
|
||||||
clanCore.sops.defaultGroups = [ "admins" ];
|
clan.core.sops.defaultGroups = [ "admins" ];
|
||||||
clan.virtualisation.graphics = false;
|
clan.virtualisation.graphics = false;
|
||||||
|
|
||||||
clan.networking.zerotier.controller.enable = true;
|
clan.networking.zerotier.controller.enable = true;
|
||||||
@ -41,7 +41,7 @@
|
|||||||
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
||||||
system.stateVersion = lib.version;
|
system.stateVersion = lib.version;
|
||||||
sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__";
|
sops.age.keyFile = "__CLAN_SOPS_KEY_PATH__";
|
||||||
clanCore.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__";
|
clan.core.secretsUploadDirectory = "__CLAN_SOPS_KEY_DIR__";
|
||||||
clan.networking.zerotier.networkId = "82b44b162ec6c013";
|
clan.networking.zerotier.networkId = "82b44b162ec6c013";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
{
|
{
|
||||||
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
clan.networking.targetHost = "__CLAN_TARGET_ADDRESS__";
|
||||||
system.stateVersion = lib.version;
|
system.stateVersion = lib.version;
|
||||||
clanCore.secretStore = "password-store";
|
clan.core.secretStore = "password-store";
|
||||||
clanCore.secretsUploadDirectory = lib.mkForce "__CLAN_SOPS_KEY_DIR__/secrets";
|
clan.core.secretsUploadDirectory = lib.mkForce "__CLAN_SOPS_KEY_DIR__/secrets";
|
||||||
|
|
||||||
clan.networking.zerotier.controller.enable = true;
|
clan.networking.zerotier.controller.enable = true;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ def run_vm_in_thread(machine_name: str) -> None:
|
|||||||
# wait for qmp socket to exist
|
# wait for qmp socket to exist
|
||||||
def wait_vm_up(state_dir: Path) -> None:
|
def wait_vm_up(state_dir: Path) -> None:
|
||||||
socket_file = state_dir / "qga.sock"
|
socket_file = state_dir / "qga.sock"
|
||||||
timeout: float = 300
|
timeout: float = 20
|
||||||
while True:
|
while True:
|
||||||
if timeout <= 0:
|
if timeout <= 0:
|
||||||
raise TimeoutError(
|
raise TimeoutError(
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
imports = (import (pkgs.path + "/nixos/modules/module-list.nix")) ++ [
|
imports = (import (pkgs.path + "/nixos/modules/module-list.nix")) ++ [
|
||||||
{
|
{
|
||||||
nixpkgs.hostPlatform = "x86_64-linux";
|
nixpkgs.hostPlatform = "x86_64-linux";
|
||||||
clanCore.clanName = "dummy";
|
clan.core.clanName = "dummy";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user