Compare commits
202 Commits
deps-poc
...
hgl-ui-tex
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18edf5f992 | ||
|
|
f6bc4ca6df | ||
|
|
8567c2c09d | ||
|
|
59aec481b2 | ||
|
|
fe04eb827f | ||
|
|
7be9e3f333 | ||
|
|
6b059ca71d | ||
|
|
9ea5156f32 | ||
|
|
519ff4c0f3 | ||
|
|
bc045ee972 | ||
|
|
5de0d37f0e | ||
|
|
3574b37a29 | ||
|
|
2921ae7b84 | ||
|
|
8f5cae5671 | ||
|
|
bc241cdd5f | ||
|
|
d1b65d5a06 | ||
|
|
8402463296 | ||
|
|
461e7ee968 | ||
|
|
b273cc9c6a | ||
|
|
51f3ffec42 | ||
|
|
48ddf22879 | ||
|
|
7a9f3dfc03 | ||
|
|
2588813578 | ||
|
|
c95ab34807 | ||
|
|
54fc2aec03 | ||
|
|
9a03644a80 | ||
|
|
381c190ba2 | ||
|
|
bd50e1ee40 | ||
|
|
00d38180d3 | ||
|
|
7e1b7b056d | ||
|
|
4ec3043a4e | ||
|
|
78634d0165 | ||
|
|
4d4a689519 | ||
|
|
bd4285a638 | ||
|
|
c418d688dc | ||
|
|
69ea1a211f | ||
|
|
02117d8698 | ||
|
|
91643bafbe | ||
|
|
8223120521 | ||
|
|
8e279a1e71 | ||
|
|
d6c891750d | ||
|
|
c73d954b55 | ||
|
|
4ec6ec0090 | ||
|
|
ec98cdf097 | ||
|
|
4ad348d881 | ||
|
|
728d651ad1 | ||
|
|
fb4c151969 | ||
|
|
3cf979f0ed | ||
|
|
3bc31b3e3f | ||
|
|
99f167a89f | ||
|
|
ed432cc4cf | ||
|
|
4ec5be9476 | ||
|
|
00a864663b | ||
|
|
9f1d8d22e8 | ||
|
|
6f791ac086 | ||
|
|
133f4aee53 | ||
|
|
91985504d0 | ||
|
|
ba5968ce93 | ||
|
|
3370212cea | ||
|
|
3043a92815 | ||
|
|
77921f2857 | ||
|
|
f22c8f166e | ||
|
|
d6ae9cde3f | ||
|
|
51b6717202 | ||
|
|
d27576c130 | ||
|
|
0a972b387c | ||
|
|
e8bbe91685 | ||
|
|
455268f6ce | ||
|
|
ce2e80bcf1 | ||
|
|
8e9105735c | ||
|
|
db75af2445 | ||
|
|
24014564e8 | ||
|
|
4939723477 | ||
|
|
8be04e790b | ||
|
|
eaf94f90fe | ||
|
|
ac07265ea4 | ||
|
|
92ca540a42 | ||
|
|
8b18418e7c | ||
|
|
9b1573db63 | ||
|
|
47be7d6865 | ||
|
|
1e18d7b897 | ||
|
|
f099e92394 | ||
|
|
668fc39dba | ||
|
|
589d353285 | ||
|
|
62eedacd33 | ||
|
|
4ce8f03ea6 | ||
|
|
75367f4d6f | ||
|
|
1a344f759a | ||
|
|
3cc1ea6d83 | ||
|
|
09af3f38ee | ||
|
|
0f71ffd3c7 | ||
|
|
0fef161391 | ||
|
|
854481fd49 | ||
|
|
74f853bd7c | ||
|
|
5613cbe7cb | ||
|
|
4b549365f7 | ||
|
|
e03fcc25e7 | ||
|
|
a798fcb359 | ||
|
|
d163f0da14 | ||
|
|
92e2c841e3 | ||
|
|
01856cf4cb | ||
|
|
0d04b24473 | ||
|
|
bc521a1b9b | ||
|
|
eb321df10d | ||
|
|
cdceb2a211 | ||
|
|
6546f8a952 | ||
|
|
b7798f5466 | ||
|
|
132728d757 | ||
|
|
2a52548120 | ||
|
|
71533f118f | ||
|
|
c9ab0a42ac | ||
|
|
e7fe50fd6e | ||
|
|
757f2412a6 | ||
|
|
f8d153b318 | ||
|
|
782a9375bf | ||
|
|
e332ae9059 | ||
|
|
9a9d6bf22d | ||
|
|
593c2d3d5b | ||
|
|
59c463f326 | ||
|
|
f1416bdcba | ||
|
|
7a38e976a4 | ||
|
|
ae28196039 | ||
|
|
a1b7c4f8f7 | ||
|
|
66b6290d32 | ||
|
|
4aff2a9d40 | ||
|
|
9b39ca42e0 | ||
|
|
104058b79c | ||
|
|
5dd30a8edd | ||
|
|
5127a74515 | ||
|
|
fd1c0dfabc | ||
|
|
3d8fab062d | ||
|
|
559c13f41b | ||
|
|
3afe48f9cf | ||
|
|
555c2e1bc9 | ||
|
|
80bc3daf96 | ||
|
|
fc1a68b99c | ||
|
|
cbdf8745eb | ||
|
|
b08f9743f0 | ||
|
|
50239028b6 | ||
|
|
0f0cfbc7e0 | ||
|
|
d4e601586d | ||
|
|
ada80be417 | ||
|
|
e4b316c14a | ||
|
|
a0fda9b819 | ||
|
|
125a882938 | ||
|
|
fc223939ec | ||
|
|
2152646df6 | ||
|
|
1f9b44a4ad | ||
|
|
8a1f924f72 | ||
|
|
e43779f8d6 | ||
|
|
69b0c36381 | ||
|
|
479d7d536e | ||
|
|
19a209c75a | ||
|
|
c249994e18 | ||
|
|
6910620629 | ||
|
|
3f17a6c121 | ||
|
|
864b131010 | ||
|
|
50c8df7e40 | ||
|
|
a80df32c59 | ||
|
|
b1e3e3616e | ||
|
|
3d680bcc5f | ||
|
|
3f5bf8e171 | ||
|
|
31ff7b903c | ||
|
|
62eb42ae5b | ||
|
|
d25818580d | ||
|
|
13eba4d7c5 | ||
|
|
86c4555bc0 | ||
|
|
39eb13eebb | ||
|
|
daea2da358 | ||
|
|
d995c0b118 | ||
|
|
5e22830048 | ||
|
|
15d117d06b | ||
|
|
c936830bc6 | ||
|
|
8e50ddc84b | ||
|
|
f2134754c5 | ||
|
|
f49df8d574 | ||
|
|
d873e667ba | ||
|
|
6c2fa3e4ed | ||
|
|
0bce953c2f | ||
|
|
dd1f045022 | ||
|
|
f7cd8c8863 | ||
|
|
ee0f111fc9 | ||
|
|
ea32fdbd93 | ||
|
|
1f3aa0075e | ||
|
|
5d38824d8e | ||
|
|
5ee6156b29 | ||
|
|
a90197cfd4 | ||
|
|
cd1351cd6f | ||
|
|
1b193123b2 | ||
|
|
81126da053 | ||
|
|
67795730a2 | ||
|
|
e6797c6f20 | ||
|
|
8c42cc377c | ||
|
|
5750ab8d3a | ||
|
|
d3397af442 | ||
|
|
ea3818bb50 | ||
|
|
93280a9f98 | ||
|
|
d89ddfabec | ||
|
|
e2946615f0 | ||
|
|
bce9f9a747 | ||
|
|
b494bdee21 | ||
|
|
13632ff659 |
@@ -8,6 +8,6 @@ jobs:
|
||||
runs-on: nix
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: nix run .#deploy-docs
|
||||
- run: nix run --print-build-logs .#deploy-docs
|
||||
env:
|
||||
SSH_HOMEPAGE_KEY: ${{ secrets.SSH_HOMEPAGE_KEY }}
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -52,3 +52,5 @@ pkgs/clan-app/ui/.fonts
|
||||
*.gif
|
||||
*.mp4
|
||||
*.mkv
|
||||
|
||||
.jj
|
||||
|
||||
@@ -12,7 +12,6 @@ let
|
||||
elem
|
||||
filter
|
||||
filterAttrs
|
||||
flip
|
||||
genAttrs
|
||||
hasPrefix
|
||||
pathExists
|
||||
@@ -45,7 +44,7 @@ in
|
||||
flake.check = genAttrs [ "x86_64-linux" "aarch64-darwin" ] (
|
||||
system:
|
||||
let
|
||||
checks = flip filterAttrs self.checks.${system} (
|
||||
checks = filterAttrs (
|
||||
name: _check:
|
||||
!(hasPrefix "nixos-test-" name)
|
||||
&& !(hasPrefix "nixos-" name)
|
||||
@@ -57,7 +56,7 @@ in
|
||||
"clan-core-for-checks"
|
||||
"clan-deps"
|
||||
])
|
||||
);
|
||||
) self.checks.${system};
|
||||
in
|
||||
inputs.nixpkgs.legacyPackages.${system}.runCommand "fast-flake-checks-${system}"
|
||||
{ passthru.checks = checks; }
|
||||
|
||||
@@ -29,9 +29,20 @@
|
||||
imports = [ self.nixosModules.test-install-machine-without-system ];
|
||||
|
||||
clan.core.vars.generators.test = lib.mkForce { };
|
||||
|
||||
disko.devices.disk.main.preCreateHook = lib.mkForce "";
|
||||
|
||||
# Every option here should match the options set through `clan flash write`
|
||||
# if you get a mass rebuild on the disko derivation, this means you need to
|
||||
# adjust something here. Also make sure that the injected json in clan flash write
|
||||
# is up to date.
|
||||
i18n.defaultLocale = "de_DE.UTF-8";
|
||||
console.keyMap = "de";
|
||||
services.xserver.xkb.layout = "de";
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRWUusawhlIorx7VFeQJHmMkhl9X3QpnvOdhnV/bQNG root@target\n"
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
perSystem =
|
||||
@@ -44,6 +55,8 @@
|
||||
dependencies = [
|
||||
pkgs.disko
|
||||
pkgs.buildPackages.xorg.lndir
|
||||
pkgs.glibcLocales
|
||||
pkgs.kbd.out
|
||||
self.nixosConfigurations."test-flash-machine-${pkgs.hostPlatform.system}".pkgs.perlPackages.ConfigIniFiles
|
||||
self.nixosConfigurations."test-flash-machine-${pkgs.hostPlatform.system}".pkgs.perlPackages.FileSlurp
|
||||
|
||||
@@ -83,10 +96,10 @@
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
machine.succeed("echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRWUusawhlIorx7VFeQJHmMkhl9X3QpnvOdhnV/bQNG root@target' > ./test_id_ed25519.pub")
|
||||
# Some distros like to automount disks with spaces
|
||||
machine.succeed('mkdir -p "/mnt/with spaces" && mkfs.ext4 /dev/vdc && mount /dev/vdc "/mnt/with spaces"')
|
||||
machine.succeed("clan flash write --debug --flake ${self.checks.x86_64-linux.clan-core-for-checks} --yes --disk main /dev/vdc test-flash-machine-${pkgs.hostPlatform.system}")
|
||||
machine.succeed("clan flash write --ssh-pubkey ./test_id_ed25519.pub --keymap de --language de_DE.UTF-8 --debug --flake ${self.checks.x86_64-linux.clan-core-for-checks} --yes --disk main /dev/vdc test-flash-machine-${pkgs.hostPlatform.system}")
|
||||
'';
|
||||
} { inherit pkgs self; };
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{ ... }:
|
||||
{
|
||||
_class = "clan.service";
|
||||
manifest.name = "clan-core/admin";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
{
|
||||
self,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix {
|
||||
inherit (self) packages;
|
||||
};
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.certificates = module;
|
||||
|
||||
@@ -8,7 +8,7 @@ The service consists of two roles:
|
||||
- A `server` role: This is the DNS-server that will be queried when trying to
|
||||
resolve clan-internal services. It defines the top-level domain.
|
||||
- A `default` role: This does two things. First, it sets up the nameservers so
|
||||
thatclan-internal queries are resolved via the `server` machine, while
|
||||
that clan-internal queries are resolved via the `server` machine, while
|
||||
external queries are resolved as normal via DHCP. Second, it allows exposing
|
||||
services (see example below).
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
{
|
||||
clan.modules = {
|
||||
emergency-access = lib.modules.importApply ./default.nix { };
|
||||
emergency-access = ./default.nix;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
# The test for this module in ./tests/vm/default.nix shows an example of how
|
||||
# the service is used.
|
||||
|
||||
{ packages }:
|
||||
{ ... }:
|
||||
{
|
||||
_class = "clan.service";
|
||||
@@ -34,20 +33,17 @@
|
||||
settings,
|
||||
|
||||
# The name of this instance of the service
|
||||
instanceName,
|
||||
|
||||
# The current machine
|
||||
machine,
|
||||
|
||||
# All roles of this service, with their assigned machines
|
||||
roles,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# Analog to 'perSystem' of flake-parts.
|
||||
# For every instance of this service we will add a nixosModule to a morning-machine
|
||||
nixosModule =
|
||||
{ config, ... }:
|
||||
{ ... }:
|
||||
{
|
||||
# Interaction examples what you could do here:
|
||||
# - Get some settings of this machine
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix {
|
||||
inherit (self) packages;
|
||||
};
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
{
|
||||
clan.modules = {
|
||||
importer = lib.modules.importApply ./default.nix { };
|
||||
importer = ./default.nix;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
{
|
||||
roles,
|
||||
lib,
|
||||
settings,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.localbackup = module;
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
};
|
||||
}
|
||||
// lib.mapAttrs' (
|
||||
name: user:
|
||||
_name: user:
|
||||
lib.nameValuePair "matrix-password-${user.name}" {
|
||||
files."matrix-password-${user.name}" = { };
|
||||
migrateFact = "matrix-password-${user.name}";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.matrix-synapse = module;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{ packages }:
|
||||
{ ... }:
|
||||
{
|
||||
_class = "clan.service";
|
||||
@@ -11,15 +10,15 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
options.allowAllInterfaces = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "If true, Telegraf will listen on all interfaces. Otherwise, it will only listen on the interfaces specified in `interfaces`";
|
||||
type = lib.types.nullOr lib.types.bool;
|
||||
default = null;
|
||||
description = "Deprecated. Has no effect.";
|
||||
};
|
||||
|
||||
options.interfaces = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ "zt+" ];
|
||||
description = "List of interfaces to expose the metrics to";
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = null;
|
||||
description = "Deprecated. Has no effect.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
{
|
||||
self,
|
||||
lib,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix {
|
||||
inherit (self) packages;
|
||||
};
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.monitoring = module;
|
||||
|
||||
perSystem =
|
||||
{ ... }:
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
clan.nixosTests.monitoring = {
|
||||
imports = [ ./tests/vm/default.nix ];
|
||||
|
||||
imports = [
|
||||
(lib.modules.importApply ./tests/vm/default.nix {
|
||||
inherit (self) packages;
|
||||
inherit pkgs;
|
||||
})
|
||||
];
|
||||
clan.modules.monitoring = module;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,34 +11,54 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
jsonpath = "/tmp/telegraf.json";
|
||||
auth_user = "prometheus";
|
||||
in
|
||||
{
|
||||
warnings =
|
||||
lib.optionals (settings.allowAllInterfaces != null) [
|
||||
"monitoring.settings.allowAllInterfaces is deprecated and and has no effect. Please remove it from your inventory."
|
||||
"The monitoring service will now always listen on all interfaces over https."
|
||||
]
|
||||
++ (lib.optionals (settings.interfaces != null) [
|
||||
"monitoring.settings.interfaces is deprecated and and has no effect. Please remove it from your inventory."
|
||||
"The monitoring service will now always listen on all interfaces over https."
|
||||
]);
|
||||
|
||||
networking.firewall.interfaces = lib.mkIf (settings.allowAllInterfaces == false) (
|
||||
builtins.listToAttrs (
|
||||
map (name: {
|
||||
inherit name;
|
||||
value.allowedTCPPorts = [
|
||||
9273
|
||||
9990
|
||||
];
|
||||
}) settings.interfaces
|
||||
)
|
||||
);
|
||||
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf (settings.allowAllInterfaces == true) [
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
9273
|
||||
9990
|
||||
];
|
||||
|
||||
clan.core.vars.generators."telegraf" = {
|
||||
clan.core.vars.generators."telegraf-certs" = {
|
||||
files.crt = {
|
||||
restartUnits = [ "telegraf.service" ];
|
||||
deploy = true;
|
||||
secret = false;
|
||||
};
|
||||
files.key = {
|
||||
mode = "0600";
|
||||
restartUnits = [ "telegraf.service" ];
|
||||
};
|
||||
|
||||
runtimeInputs = [
|
||||
pkgs.openssl
|
||||
];
|
||||
|
||||
script = ''
|
||||
openssl req -x509 -nodes -newkey rsa:4096 \
|
||||
-keyout "$out"/key \
|
||||
-out "$out"/crt \
|
||||
-subj "/C=US/ST=CA/L=San Francisco/O=Example Corp/OU=IT/CN=example.com"
|
||||
'';
|
||||
};
|
||||
|
||||
clan.core.vars.generators."telegraf" = {
|
||||
files.password.restartUnits = [ "telegraf.service" ];
|
||||
files.password-env.restartUnits = [ "telegraf.service" ];
|
||||
files.miniserve-auth.restartUnits = [ "telegraf.service" ];
|
||||
|
||||
dependencies = [ "telegraf-certs" ];
|
||||
|
||||
runtimeInputs = [
|
||||
pkgs.coreutils
|
||||
pkgs.xkcdpass
|
||||
@@ -57,11 +77,37 @@
|
||||
enable = true;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "telegraf.service" ];
|
||||
wants = [ "telegraf.service" ];
|
||||
requires = [ "telegraf.service" ];
|
||||
serviceConfig = {
|
||||
LoadCredential = [
|
||||
"auth_file_path:${config.clan.core.vars.generators.telegraf.files.miniserve-auth.path}"
|
||||
"telegraf_crt_path:${config.clan.core.vars.generators.telegraf-certs.files.crt.path}"
|
||||
"telegraf_key_path:${config.clan.core.vars.generators.telegraf-certs.files.key.path}"
|
||||
];
|
||||
Environment = [
|
||||
"AUTH_FILE_PATH=%d/auth_file_path"
|
||||
"CRT_PATH=%d/telegraf_crt_path"
|
||||
"KEY_PATH=%d/telegraf_key_path"
|
||||
];
|
||||
Restart = "on-failure";
|
||||
User = "telegraf";
|
||||
Group = "telegraf";
|
||||
RuntimeDirectory = "telegraf-www";
|
||||
};
|
||||
script = "${pkgs.miniserve}/bin/miniserve -p 9990 /run/telegraf-www --auth-file \"$AUTH_FILE_PATH\" --tls-cert \"$CRT_PATH\" --tls-key \"$KEY_PATH\"";
|
||||
};
|
||||
|
||||
systemd.services.telegraf = {
|
||||
serviceConfig = {
|
||||
LoadCredential = [
|
||||
"telegraf_crt_path:${config.clan.core.vars.generators.telegraf-certs.files.crt.path}"
|
||||
"telegraf_key_path:${config.clan.core.vars.generators.telegraf-certs.files.key.path}"
|
||||
];
|
||||
Environment = [
|
||||
"CRT_PATH=%d/telegraf_crt_path"
|
||||
"KEY_PATH=%d/telegraf_key_path"
|
||||
];
|
||||
};
|
||||
script = "${pkgs.miniserve}/bin/miniserve -p 9990 ${jsonpath} --auth-file ${config.clan.core.vars.generators.telegraf.files.miniserve-auth.path}";
|
||||
};
|
||||
|
||||
services.telegraf = {
|
||||
@@ -69,6 +115,7 @@
|
||||
environmentFiles = [
|
||||
(builtins.toString config.clan.core.vars.generators.telegraf.files.password-env.path)
|
||||
];
|
||||
|
||||
extraConfig = {
|
||||
agent.interval = "60s";
|
||||
inputs = {
|
||||
@@ -104,10 +151,12 @@
|
||||
metric_version = 2;
|
||||
basic_username = "${auth_user}";
|
||||
basic_password = "$${BASIC_AUTH_PWD}";
|
||||
tls_cert = "$${CRT_PATH}";
|
||||
tls_key = "$${KEY_PATH}";
|
||||
};
|
||||
|
||||
outputs.file = {
|
||||
files = [ jsonpath ];
|
||||
files = [ "/run/telegraf-www/telegraf.json" ];
|
||||
data_format = "json";
|
||||
json_timestamp_units = "1s";
|
||||
};
|
||||
|
||||
@@ -1,24 +1,95 @@
|
||||
{ ... }:
|
||||
{
|
||||
name = "monitoring";
|
||||
|
||||
clan = {
|
||||
directory = ./.;
|
||||
inventory = {
|
||||
machines.peer1 = { };
|
||||
machines.peer1 = {
|
||||
deploy.targetHost = "[2001:db8:1::1]";
|
||||
};
|
||||
|
||||
instances."test" = {
|
||||
module.name = "monitoring";
|
||||
module.input = "self";
|
||||
|
||||
roles.telegraf.machines.peer1 = { };
|
||||
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nodes = {
|
||||
peer1 =
|
||||
{ lib, ... }:
|
||||
{
|
||||
services.telegraf.extraConfig = {
|
||||
agent.interval = lib.mkForce "1s";
|
||||
outputs.prometheus_client = {
|
||||
# BUG: We have to disable basic auth here because the prometheus_client
|
||||
# output plugin will otherwise deadlock Telegraf on startup.
|
||||
basic_password = lib.mkForce "";
|
||||
basic_username = lib.mkForce "";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# !!! ANY CHANGES HERE MUST BE REFLECTED IN:
|
||||
# clan_lib/metrics/telegraf.py::get_metrics
|
||||
testScript =
|
||||
{ ... }:
|
||||
{ nodes, ... }:
|
||||
''
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import ssl
|
||||
import json
|
||||
import shlex
|
||||
import urllib.request
|
||||
from base64 import b64encode
|
||||
start_all()
|
||||
|
||||
peer1.wait_for_unit("network-online.target")
|
||||
peer1.wait_for_unit("telegraf.service")
|
||||
peer1.wait_for_unit("telegraf-json.service")
|
||||
|
||||
# Fetch the basic auth password from the secret file
|
||||
password = peer1.succeed("cat ${nodes.peer1.clan.core.vars.generators.telegraf.files.password.path}").strip()
|
||||
credentials = f"prometheus:{password}"
|
||||
|
||||
print("Using credentials:", credentials)
|
||||
peer1.succeed(f"curl -k -u {credentials} https://localhost:9990/telegraf.json")
|
||||
peer1.succeed(f"curl -k -u {credentials} https://localhost:9273/metrics")
|
||||
|
||||
cert_path = "${nodes.peer1.clan.core.vars.generators.telegraf-certs.files.crt.path}"
|
||||
url = "https://192.168.1.1:9990/telegraf.json" # HTTPS required
|
||||
|
||||
print("Waiting for /var/run/telegraf-www/telegraf.json to be bigger then 200 bytes")
|
||||
peer1.wait_until_succeeds(f"test \"$(stat -c%s /var/run/telegraf-www/telegraf.json)\" -ge 200", timeout=30)
|
||||
|
||||
encoded_credentials = b64encode(credentials.encode("utf-8")).decode("utf-8")
|
||||
headers = {"Authorization": f"Basic {encoded_credentials}"}
|
||||
req = urllib.request.Request(url, headers=headers) # noqa: S310
|
||||
|
||||
# Trust the provided CA/server certificate
|
||||
context = ssl.create_default_context(cafile=cert_path)
|
||||
context.check_hostname = False
|
||||
context.verify_mode = ssl.CERT_REQUIRED
|
||||
|
||||
found_system = False
|
||||
with urllib.request.urlopen(req, context=context, timeout=5) as response:
|
||||
for raw_line in response:
|
||||
line_str = raw_line.decode("utf-8").strip()
|
||||
if not line_str:
|
||||
continue
|
||||
obj = json.loads(line_str)
|
||||
if obj.get("name") == "nixos_systems":
|
||||
found_system = True
|
||||
print("Found nixos_systems metric in json output")
|
||||
break
|
||||
|
||||
assert found_system, "nixos_systems metric not found in json output"
|
||||
|
||||
'';
|
||||
}
|
||||
|
||||
6
clanServices/monitoring/tests/vm/sops/machines/peer1/key.json
Executable file
6
clanServices/monitoring/tests/vm/sops/machines/peer1/key.json
Executable file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"publickey": "age1ntpf7lqqw4zrk8swjvwtyfak7f2wg04uf7ggu6vk2yyt9qt74qkswn25ck",
|
||||
"type": "age"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:ACFpRJRDIgVPurZwHYW0J1MnvyuiRGnXMeQj1nb9rDAIqHbZzZk8+E0Nu1+EdXwk78ziP6tHR1GQP2ILTtpLME4lXXRVjouW5Eo=,iv:ctR1HENO3XGIq1/gzYi47nateYzsSK317EKn92ptqDI=,tag:q1yuk/ZMx3nuORkiT/XXqg==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvMUtabnp3V0dzNFFYRzk0\nd0ZJbUtDMXRPRGxpRjhYR1MyQzdJYWdJTUFrCjBNV0pPTTlIOHBBbzlEQkFzVy92\ndENxcDdIZlNDSm1oZTNveUtIeVc3MXcKLS0tIGtocENjMFNYT0s1LzhYNy92QU5G\nREVEdjErb0xPSE1yb0g5bGlackh6bEUKwxBoDteD7+JfnlFF71CHx4oEdV/TFYcF\n3JPYUbTWAIyMtUu/CLbX+Pn9Mv+McrEIqhwT7TWL/YbELKVadX/k5Q==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-18T14:33:37Z",
|
||||
"mac": "ENC[AES256_GCM,data:4631iJmioJ2vZ2PTFbdEJu7UqtyQbp43XBlgEbFAviGZdugb3weVI24rJ8m1Rdnxq8uciEeiX6YHBhURdWQY4JNm2wTGnjz7e2PwQ8FCwOmxCcIQPpdKKsziq/M4HArgD66eUxIWfTt1yJfHgBcUuuANbrbH8MirllT+hJTBhqE=,iv:rM8a/MpKbK7DlqjuR4BG77XDHLK11Q+E2rzZLDJalhk=,tag:bbGMn4anXrLHg4eLA0/CXA==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../users/admin
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"type": "age"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
25.11
|
||||
@@ -0,0 +1,33 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
k1PNWTkgLsXO8DNkCudxcvPElXfmaw6zwaLrZys=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/peer1
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data: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,iv:q3j8EAokyyxiszf+wyRqxEr2igaD1bX7YnFx/NbsGg8=,tag:HKKYWRJEUwW2/TxL+5dSng==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1ntpf7lqqw4zrk8swjvwtyfak7f2wg04uf7ggu6vk2yyt9qt74qkswn25ck",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaeXRjU214aWk5ajl1aW9E\naGJlb1ViaVRmMTBHdkFDQUNDZS94WFZiNUNvCllmWTJBck9hR3U3V09VWDZwQ2xI\nd3ZEQnBIUG5ZSTVIdS8rQ2FMYVhyNk0KLS0tIEE1UG8rSzFyU01sVXhGVHpoaE9i\nSis4Qi9tMGFqbTNMTDZUVk1ZdXkrM28Km4VkfaOsZ69ckjvrg+os43H/O1IoWHzC\nt4LqZRz1Tk7/d1aLWavSPPjVYrCOMZeNBqGbQpGfjjuXrafClRNQdQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3R1RHTGViTnRLVVkyM3J0\nbm96cGVPTlo4NXBNL0g1eEVSNG9DUkgwVFRBCmRKVTlMRmV3Tmg2RTZIclBlWlcr\ndzI5MUxhcllzbE1IMDNxa08zVkpITmsKLS0tIG01Y2dyQkY3UmRudFk2d0p6bThn\nemlaWnZoS3p4VHhMTFFwTm9VN0ttYzQKVbLFgtK6NIRIiryWHeeOPD45iwUds4QD\n7b8xYYoxlo+DETggxK6Vz3IdT/BSK5bFtgAxl864b5gW+Aw4c6AO5w==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-18T14:33:37Z",
|
||||
"mac": "ENC[AES256_GCM,data:XKCnd0QrAlOCECSeSvbLYHMLbmUh4fMRnLaTb5ARoP4Zc9joWGsCaRZxokc2/sG4BXA/6pkbQXHyIOudKbcBpVjjvs9E+6Mnzt53nfRoH/iOkYPbN2EO49okVZJXW0M1rlBxrxvGuiDlz2p2p6L7neKLy4EB482pYea5+dUr2Yw=,iv:oj/MkZCfkvCmAb79uzEvKwEAm1bKtWhS4rPRAWSgRgw=,tag:h5TPPILXkhJplnDT2Gqtfw==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/peer1
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:Q0Vn7J0nERccBYT8HZxHF0Zi5qxmMu40n0H1c+L2SCRF6vRLdURxXKDwvh8xtTU=,iv:ucExjoYDFYy19GsBbNNldJRPBSpT+L+x4PrwTG+m2K8=,tag:/Quupyy/nnUNZsDudEMmNA==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1ntpf7lqqw4zrk8swjvwtyfak7f2wg04uf7ggu6vk2yyt9qt74qkswn25ck",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQWWo5OEJ5N1RTR0xMaDhL\nQnlUV2RrRXIzM01OemhQWjVkd3FNZjRhR2dzCi9IeE56b3VZTkNkdW9DMzVia3Zx\nbklxWmFpenRjdEIrc0ZDTGdmSTAxRTQKLS0tIHZJdjdYUzhhY0YzQjRqS0psZmpI\nVHJpUjNZNHRpc2ZWSml1TVNNejhiT28K8TTP/J+XspXZ7TVYj9YaBhEodPIXjojB\nRLqAIgJXRaK4NCLukC6l0IMii6w5J/512RnO2ZBTGhKfbdLfyLOFqg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrZVc5b0FhbzNXcG1zUDlD\neEVWcWpSRkRCMkxBTHdBM3dCbjVpR3FBa0VjCitlTmx4eUJOMHlaU0dFZEhpK3ZD\nZzlMQXVuZWpnaUNmQW9kOGtOaGVDMU0KLS0tIFNlUi9LSzF0UEJCSVBiRlRSNFQz\nNHhMbmNlRXd4ZEJQWVcvTWdCRWEzMUkKls7RbmNOdPDx8z15F+7qay9qIWx6jNsN\nTahT+GgbG29t1aGQCb0yEzKuUyAp39maxxSWToPsfCgJSYJ8RYiUng==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-18T14:33:39Z",
|
||||
"mac": "ENC[AES256_GCM,data:g+9/fRiqom2+W28ZpiF+oBj9V6ieq5Xz3sRz3GyzvHoLr6yw51JvpG2QuYNYANW0WCiUjFDkU0qPj/9gLHcuX52nc+gNaTzznb1QGPg7WCGSQI7xaMzyYsPxHpg/BOdj5CL8GyLiOWstD1ch0kc3bJmyu68sJUs04uGtHAADzsE=,iv:oASrYaZarEPDu0R3hd/jMazLgwG5r//hIdMyU/tN15o=,tag:o1fgf5oy+rlWXg88FN5Nfw==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/peer1
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:4NIUEK05kEQAKjR8F9mU3M/XvtZXw+X6CejVI0usMcb4WzagNz7XTVDhLWXZ9St5Ev0Y,iv:bD2+rDLMoWSqUAIZRJof0wRrJVya1xwZUTIJBdCs98I=,tag:g2s4byFHTzwU3ikcBGMElA==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1ntpf7lqqw4zrk8swjvwtyfak7f2wg04uf7ggu6vk2yyt9qt74qkswn25ck",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQeVh2M2tqSGlOVkpzNlhU\nd0pMd1R0c0tQWnZzdXViWmtxcjl1Wk1Ka0FNCnBUUWJVbjlyR1hSNGpXNWlPRHJB\nNnMzN3BMQ2NDamFBMlhHbVdJUEZ6cjQKLS0tIEJjWmI0ZDl1NXgrSW9uc0R0LzAr\neEwwOC9DdDg2RTJHQ0M3QTFlcVBaSE0K2Du4NguefdEyY1gS6OuVdO3gHga4omcR\n8B+K1wUfIQbArxZLawPxrj7WNDoW5d4mF9fA3MeV1DFyc4KwtYZmUw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvWkdBakVrMVR4RU8xdDlF\nRDkvL0Mrb3ltazhIMjRLZDVlSTVlaFY2ODBBCnlQM2s0SGEvZjFDN3dGWDhIN0dK\nenhQbjZ1ZS9QZzg5SE5XazZXS3dFSkkKLS0tIHJhKzhadGpjTXd4L3hOQkhpR0Fy\nYzhTN2dxVSt3OE5uZFpuWmVlYW4vd1kKwHOxP0C5mLcm4oIT/sGQtUsdsmu3LSN0\nSola5+N+IrAZ+HKnuZlDLZ5JmJSc5j/YhGNn7KR1xhkhfGSS1e3UZw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-18T14:33:39Z",
|
||||
"mac": "ENC[AES256_GCM,data:ehbrYqTJcsBKGHUB25JHFnKXrJ6z3LkcElZ89xVr4XxLet+odbhsjIoP2FCcxex7PlXcegMduhHBpXwNGUbX+IUNAXTxlWA9CLDmYhWuS2WLiEVXrS11NE03/zUyHdVx/C38dbIPrWD9iaYSrAiuOyfqDTh9k/Bn7vehLTtadoE=,iv:Nk2WVuJydi5tfsb1Mib4A6NocBCDp9QoIbSadq3bIDI=,tag:IaoyfCv3SkmtemXMR9XnkA==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/peer1
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:0BmP+NwG/NGe6R5yU55/MdPEQ8E5u+VXWtvstHc4GpDtmBY=,iv:vo8XBcN7KcYjiyKvvp+XDOdP9yR9B7wJi0XlaiCdVbk=,tag:brK9ntAPSuOvw/C+oDo51g==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1ntpf7lqqw4zrk8swjvwtyfak7f2wg04uf7ggu6vk2yyt9qt74qkswn25ck",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4Tk1INGtybUVlejlNNlZE\nVms3TkdRVVF1T0E4TmV3NmxvYWVEL2U3WVhNCjJIaHhBcWVlMEYxRjg5bzJpTWdJ\neUhaRTNRTmtlTW0zUXQxTVZEMkQ2MFEKLS0tIFNGWDI4b2FXTE8xQ2xqb0cyK3FI\ncktHWnE5c1ZSVFpmQU1HZmU2VVB1QmcK/s1fVmwpMMg4BYkkAJzSY7hVQWae1F7g\nmfH8EGlr74mifWUNEbd49/K13nl8atQx6bcau83JIEQR+yyihuY4Jw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsL2FXVytUUVZnVU90bG5L\nYURiYjgwN3RuTldWMGl4clpUWmxkeUsrVzM0CkhKZFgwWHl4dWhNSWRQRXVPNDR6\na3hHNmp2RG9YNDhNM2MyV2FuOGY2UlUKLS0tIFpNU2tNOHdhRDRTdHhYWVh2NGZa\nU3J3S0hpclZzWGIwTlFyczdNZkZSZTAKXCZrLaIOVq90ejoKMaRiK0xNw8WOPcnm\nz2uxProEYvQhY8k29mhCFX5HCN0tGn1XTtHeDL7uHuKuFsnSG/fgYQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-18T14:33:39Z",
|
||||
"mac": "ENC[AES256_GCM,data:QkGJKj/H+MI9Mr9Up5NDUToSddY5eTz47egc2+IatfxR8RebKJ2/mYaeLV26vPdmY60bIac4N/nZkoa6IVBhkHHMvsEHsx3nD6Lro9Wf/pWP8Zddzr90LF5p2+wusq25JutKQiPKOb2gmrcagmSsH/7V/UqI/my3PMeKmw6irhw=,iv:hOtHF/cDFdNfvqCKRhJsOwAHEiQmCPjENzsg23sKG+Q=,tag:K7qG9b4fQD0VbAV8OYp3vw==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix {
|
||||
inherit (self) packages;
|
||||
};
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
pkgs.syncthing
|
||||
];
|
||||
script = ''
|
||||
syncthing generate --config "$out"
|
||||
export TMPDIR=/tmp
|
||||
TEMPORARY=$(mktemp -d)
|
||||
syncthing generate --config "$out" --data "$TEMPORARY"
|
||||
mv "$out"/key.pem "$out"/key
|
||||
mv "$out"/cert.pem "$out"/cert
|
||||
cat "$out"/config.xml | grep -oP '(?<=<device id=")[^"]+' | uniq > "$out"/id
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
priority = lib.mkDefault 10;
|
||||
# TODO add user space network support to clan-cli
|
||||
module = "clan_lib.network.tor";
|
||||
peers = lib.mapAttrs (name: machine: {
|
||||
peers = lib.mapAttrs (name: _machine: {
|
||||
host.var = {
|
||||
machine = name;
|
||||
generator = "tor_${instanceName}";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.trusted-nix-caches = module;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.users = module;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{ packages }:
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib)
|
||||
@@ -29,6 +28,15 @@ in
|
||||
default = true;
|
||||
description = "Automatically try to join this wifi network";
|
||||
};
|
||||
keyMgmt = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "wpa-psk";
|
||||
description = ''
|
||||
Key management used for the connection.
|
||||
One of "none" (WEP or no password protection), "ieee8021x" (Dynamic WEP), "owe" (Opportunistic Wireless Encryption), "wpa-psk" (WPA2 + WPA3 personal),
|
||||
"sae" (WPA3 personal only), "wpa-eap" (WPA2 + WPA3 enterprise) or "wpa-eap-suite-b-192" (WPA3 enterprise only).
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
@@ -50,7 +58,7 @@ in
|
||||
ssid_path =
|
||||
network_name: config.clan.core.vars.generators."wifi.${network_name}".files.network-name.path;
|
||||
|
||||
secret_generator = name: value: {
|
||||
secret_generator = name: _value: {
|
||||
name = "wifi.${name}";
|
||||
value = {
|
||||
prompts.network-name.type = "line";
|
||||
@@ -80,7 +88,7 @@ in
|
||||
wifi.mode = "infrastructure";
|
||||
wifi.ssid = "$ssid_${name}";
|
||||
wifi-security.psk = "$pw_${name}";
|
||||
wifi-security.key-mgmt = "wpa-psk";
|
||||
wifi-security.key-mgmt = networkCfg.keyMgmt;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
{
|
||||
self,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix {
|
||||
inherit (self) packages;
|
||||
};
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.wifi = module;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.wireguard = module;
|
||||
|
||||
33
clanServices/yggdrasil/README.md
Normal file
33
clanServices/yggdrasil/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
This module sets up [yggdrasil](https://yggdrasil-network.github.io/) across
|
||||
your clan.
|
||||
|
||||
Yggdrasil is designed to be a future-proof and decentralised alternative to
|
||||
the structured routing protocols commonly used today on the internet. Inside
|
||||
your clan, it will allow you to reach all of your machines.
|
||||
|
||||
## Example Usage
|
||||
|
||||
While you can specify statically configured peers for each host, yggdrasil does
|
||||
auto-discovery of local peers.
|
||||
|
||||
```nix
|
||||
inventory = {
|
||||
|
||||
machines = {
|
||||
peer1 = { };
|
||||
peer2 = { };
|
||||
};
|
||||
|
||||
instances = {
|
||||
yggdrasil = {
|
||||
|
||||
# Deploy on all machines
|
||||
roles.default.tags.all = { };
|
||||
|
||||
# Or individual hosts
|
||||
roles.default.machines.peer1 = { };
|
||||
roles.default.machines.peer2 = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
125
clanServices/yggdrasil/default.nix
Normal file
125
clanServices/yggdrasil/default.nix
Normal file
@@ -0,0 +1,125 @@
|
||||
{ ... }:
|
||||
{
|
||||
_class = "clan.service";
|
||||
manifest.name = "clan-core/yggdrasil";
|
||||
manifest.description = "Yggdrasil encrypted IPv6 routing overlay network";
|
||||
|
||||
roles.default = {
|
||||
interface =
|
||||
{ lib, ... }:
|
||||
{
|
||||
options.extraMulticastInterfaces = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Additional interfaces to use for Multicast. See
|
||||
https://yggdrasil-network.github.io/configurationref.html#multicastinterfaces
|
||||
for reference.
|
||||
'';
|
||||
example = [
|
||||
{
|
||||
Regex = "(wg).*";
|
||||
Beacon = true;
|
||||
Listen = true;
|
||||
Port = 5400;
|
||||
Priority = 1020;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
options.peers = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Static peers to configure for this host.
|
||||
If not set, local peers will be auto-discovered
|
||||
'';
|
||||
example = [
|
||||
"tcp://192.168.1.1:6443"
|
||||
"quic://192.168.1.1:6443"
|
||||
"tls://192.168.1.1:6443"
|
||||
"ws://192.168.1.1:6443"
|
||||
];
|
||||
};
|
||||
};
|
||||
perInstance =
|
||||
{ settings, ... }:
|
||||
{
|
||||
nixosModule =
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
clan.core.vars.generators.yggdrasil = {
|
||||
|
||||
files.privateKey = { };
|
||||
files.publicKey.secret = false;
|
||||
files.address.secret = false;
|
||||
|
||||
runtimeInputs = with pkgs; [
|
||||
yggdrasil
|
||||
jq
|
||||
openssl
|
||||
];
|
||||
|
||||
script = ''
|
||||
# Generate private key
|
||||
openssl genpkey -algorithm Ed25519 -out $out/privateKey
|
||||
|
||||
# Generate corresponding public key
|
||||
openssl pkey -in $out/privateKey -pubout -out $out/publicKey
|
||||
|
||||
# Derive IPv6 address from key
|
||||
echo "{\"PrivateKeyPath\": \"$out/privateKey\"}" | yggdrasil -useconf -address | tr -d '\n' > $out/address
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.yggdrasil.serviceConfig.BindReadOnlyPaths = [
|
||||
"%d/key:/key"
|
||||
];
|
||||
|
||||
systemd.services.yggdrasil.serviceConfig.LoadCredential =
|
||||
"key:${config.clan.core.vars.generators.yggdrasil.files.privateKey.path}";
|
||||
|
||||
services.yggdrasil = {
|
||||
enable = true;
|
||||
openMulticastPort = true;
|
||||
# We don't need this option, because we persist our keys with
|
||||
# vars by ourselfs. This option creates an unnessesary additional
|
||||
# systemd service to save/load the keys and should be removed
|
||||
# from the NixOS module entirely, as it can be replaced by the
|
||||
# (at the time of writing undocumented) PrivateKeyPath= setting.
|
||||
# See https://github.com/NixOS/nixpkgs/pull/440910#issuecomment-3301835895 for details.
|
||||
persistentKeys = false;
|
||||
settings = {
|
||||
PrivateKeyPath = "/key";
|
||||
IfName = "ygg";
|
||||
Peers = settings.peers;
|
||||
MulticastInterfaces = [
|
||||
# Ethernet is preferred over WIFI
|
||||
{
|
||||
Regex = "(eth|en).*";
|
||||
Beacon = true;
|
||||
Listen = true;
|
||||
Port = 5400;
|
||||
Priority = 1024;
|
||||
}
|
||||
{
|
||||
Regex = "(wl).*";
|
||||
Beacon = true;
|
||||
Listen = true;
|
||||
Port = 5400;
|
||||
Priority = 1025;
|
||||
}
|
||||
]
|
||||
++ settings.extraMulticastInterfaces;
|
||||
};
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 5400 ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
24
clanServices/yggdrasil/flake-module.nix
Normal file
24
clanServices/yggdrasil/flake-module.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
self,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix {
|
||||
inherit (self) packages;
|
||||
};
|
||||
in
|
||||
{
|
||||
clan.modules = {
|
||||
yggdrasil = module;
|
||||
};
|
||||
perSystem =
|
||||
{ ... }:
|
||||
{
|
||||
clan.nixosTests.yggdrasil = {
|
||||
imports = [ ./tests/vm/default.nix ];
|
||||
|
||||
clan.modules.yggdrasil = module;
|
||||
};
|
||||
};
|
||||
}
|
||||
67
clanServices/yggdrasil/tests/vm/default.nix
Normal file
67
clanServices/yggdrasil/tests/vm/default.nix
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
name = "yggdrasil";
|
||||
|
||||
clan = {
|
||||
test.useContainers = false;
|
||||
directory = ./.;
|
||||
inventory = {
|
||||
|
||||
machines.peer1 = { };
|
||||
machines.peer2 = { };
|
||||
|
||||
instances."yggdrasil" = {
|
||||
module.name = "yggdrasil";
|
||||
module.input = "self";
|
||||
|
||||
# Assign the roles to the two machines
|
||||
roles.default.machines.peer1 = { };
|
||||
roles.default.machines.peer2 = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
# Wait for both machines to be ready
|
||||
peer1.wait_for_unit("multi-user.target")
|
||||
peer2.wait_for_unit("multi-user.target")
|
||||
|
||||
# Check that yggdrasil service is running on both machines
|
||||
peer1.wait_for_unit("yggdrasil")
|
||||
peer2.wait_for_unit("yggdrasil")
|
||||
peer1.succeed("systemctl is-active yggdrasil")
|
||||
peer2.succeed("systemctl is-active yggdrasil")
|
||||
|
||||
# Check that both machines have yggdrasil network interfaces
|
||||
peer1.wait_until_succeeds("ip link show | grep -E 'ygg'", 30)
|
||||
peer2.wait_until_succeeds("ip link show | grep -E 'ygg'", 30)
|
||||
|
||||
# Get yggdrasil IPv6 addresses from both machines
|
||||
peer1_ygg_ip = peer1.succeed("yggdrasilctl -json getself | jq -r '.address'").strip()
|
||||
peer2_ygg_ip = peer2.succeed("yggdrasilctl -json getself | jq -r '.address'").strip()
|
||||
|
||||
# Compare runtime addresses with saved addresses from vars
|
||||
expected_peer1_ip = "${builtins.readFile ./vars/per-machine/peer1/yggdrasil/address/value}"
|
||||
expected_peer2_ip = "${builtins.readFile ./vars/per-machine/peer2/yggdrasil/address/value}"
|
||||
|
||||
print(f"peer1 yggdrasil IP: {peer1_ygg_ip}")
|
||||
print(f"peer2 yggdrasil IP: {peer2_ygg_ip}")
|
||||
print(f"peer1 expected IP: {expected_peer1_ip}")
|
||||
print(f"peer2 expected IP: {expected_peer2_ip}")
|
||||
|
||||
# Verify that runtime addresses match expected addresses
|
||||
assert peer1_ygg_ip == expected_peer1_ip, f"peer1 runtime IP {peer1_ygg_ip} != expected IP {expected_peer1_ip}"
|
||||
assert peer2_ygg_ip == expected_peer2_ip, f"peer2 runtime IP {peer2_ygg_ip} != expected IP {expected_peer2_ip}"
|
||||
|
||||
# Wait a bit for the yggdrasil network to establish connectivity
|
||||
import time
|
||||
time.sleep(10)
|
||||
|
||||
# Test connectivity: peer1 should be able to ping peer2 via yggdrasil
|
||||
peer1.succeed(f"ping -6 -c 3 {peer2_ygg_ip}")
|
||||
|
||||
# Test connectivity: peer2 should be able to ping peer1 via yggdrasil
|
||||
peer2.succeed(f"ping -6 -c 3 {peer1_ygg_ip}")
|
||||
'';
|
||||
}
|
||||
6
clanServices/yggdrasil/tests/vm/sops/machines/peer1/key.json
Executable file
6
clanServices/yggdrasil/tests/vm/sops/machines/peer1/key.json
Executable file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"publickey": "age1p8trv2dmpanl3gnzj294c4t5uysu7d6rfjncp5lmn6redyda8fns6p7kca",
|
||||
"type": "age"
|
||||
}
|
||||
]
|
||||
6
clanServices/yggdrasil/tests/vm/sops/machines/peer2/key.json
Executable file
6
clanServices/yggdrasil/tests/vm/sops/machines/peer2/key.json
Executable file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"publickey": "age107mprppm3r9u7f26e6t5mhtdny0h5ugfmfjy8kac2tw9nrh9a3ksex0xca",
|
||||
"type": "age"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:jDEog7FFXl28Le3rh5VTiY0DFmLhIy2ZccFjuYWx+OQrKNEqTLI1fzaeMWIcgu6ln6wfGUk640d3IhmrF45MVZiJGkpkOU8UFx0=,iv:4oGaoxhFQwr9OQfdLL7y1N/gJo/uGkTPG/xicVprIAQ=,tag:Smu0/P2bQB66w+0J2Bjlxw==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpQ2hib2Mrb0plWUVwNWU5\nWmpxNlduaUVJckhuQlhQbUJpanloWGFLelJ3CjJJMlBGbGRTWEhGUHh2VVkzUzNa\nL3FGVkF3R3JJT051UTg4UlkwOHRNanMKLS0tIDVWcHU4NmFMUWp3STFTYmg5YmNp\nVzd1Uzg2Wkp5QnJ3V1Qyb2lwSXdBRDgK/V5lgw2TePhUC9ngW53ZapIMkcwPvJus\ns0jUYkStHXjsvEiN7BG8cG7/vRbLD8CnKXnmieM20mT6o7GHGfhHMg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-17T07:12:51Z",
|
||||
"mac": "ENC[AES256_GCM,data:gy/1NFmpFz/tdhgU/Vr+xg46DUjy9ZbrAtCBnIxclwZLJ/fneBpblv8TFgdysY4Ay6jp1S/TOc8eyr+KLHMqcBlje09wd1ac/Y3ee6GccXitB+/c5ayuXX/ShVCdicsr/9COw7vfndAQPU8XIz6tdy0dbL7jgVTyViZW/P5CXEU=,iv:BQ/INwTTCshl5BVnJbVzHW8rwafERS6bKh2JAJsMv9s=,tag:QhsbjeEBivbl8fQLHjiKtQ==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../users/admin
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:1rVgSwg2qPHuXUOQCgOunaNYiBbsh99dZ2y0BV4TxzACwdb3lb6/XnLeDenLELOpKruZQoNJax/NziRr+VHzmh/TlQhNgTkS71A=,iv:Wi5/cFOETb1rhAYeyzkpppzSSm+S+8cCQYc7zkp74FY=,tag:JQHFZJwYMQH4jUqSw6Ld8Q==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGV3ZLZmNrejlvTFF6NDZW\nYmljS0VXQUtCR3IzMG9tMksvSllVVkIxVTEwCi9Fd1dBbmFlYmF2cE1raVJoS3RR\nWmxQY3RwanRZUE5aN1Q2SzhJOFU1elEKLS0tIG9RMElDMEo3TFJjU0RvU3FMQk12\nT1pNc1VjeUliejk3YmJ6d29zUU15aDQKuZ62Q/ywLrpyu1jB34OCPKQEDd150qH6\nHzyw+MasUlzKNs0ZrALwfhnCKiNb/Pq0Lu660Dx5/sFxI/TAqC7NGg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-17T07:13:24Z",
|
||||
"mac": "ENC[AES256_GCM,data:N7mmiEZxinOgWdd7QcZBAumnWaApjlQVww4EzAQ1/JH5i8r8CIfPh/7lGMQntlJj5ob+UgrS96nl6XKdvs3Bt7z34zPq7KV3c0mSmclEctRfcZiG4F+rZ0QIMIRJjq7xJL/M9WupSn8Lgms7qHJMdJyHdDkw47bmXz3MIw9c9zo=,iv:ZYPoo5jTIGnZ1HcAWlr26gloVhSjfhwbO/xH5YCbgF0=,tag:UKMVMGEfqyfo04cIkuKD0A==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../users/admin
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"type": "age"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
25.11
|
||||
@@ -0,0 +1 @@
|
||||
200:fa3b:ad0e:6821:9a51:3ad5:62a4:9ab1
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/peer1
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:oLWxmCqCLyKCdN90eScYC4eMsY5mcpXexk03P+KfQX9hCUg7iOSv+BTujvAFuJA0z2Pgg7B/L0noYSImE3208gDC2exdZme+szpNwxD6oh1bBx5XuYGc/TDzEl7IdPrf1piuqCkWgD6wNb9aFVA9NB/CrNaszY8=,iv:pU8OGFwtqkxy0+iyhWaOnWdSVvaxYBUgnQwv89CTfKc=,tag:V/GVEvjEpeaf3Tl3XCVL7w==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1p8trv2dmpanl3gnzj294c4t5uysu7d6rfjncp5lmn6redyda8fns6p7kca",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBidXZxMVg2bkFCekFza3FV\naGVJTjRSSnQrVkgyTVU4Vk9YZFR2Nk1Xcnl3ClNTZnJsR2xZc3hGRFA0NGp2L2Uy\nU2w0N1ZON0xQRXRKL0NId1J3dWNSeXcKLS0tIFlKNk5walJrM2FGM0ozYTBUNVN1\nNHd0N3g2VWFjTUZtbHExdmsvSjJQUGMKDHgRMyTf4CuoIRdsfl6TmPLgcjxHdR4N\nzNmnSmT6QXJr4gBQ7e/3zpMdq4sKzyAOjJPkQra8nJ/KvhpFwXkdtg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1L3hBYnNTdEhTK1M0TEUx\nM1BFb3IwWDZPc2tkN0JUNXRPWkhEWHpXaFFNCkFlZ3Ixb1hhVWMvUmpKdCtjbW5h\nTVpLSkdxUXI4SVE3MW5LZkFVSmM3dDgKLS0tICtKWGYzbFQ1VGQydktHSDVadVQy\nM3JTSGc0NWVHWGl4akV2VUNNVjVvT00KKmbkGJ2KclTBb7NI0MamWZnlWMaXscws\nYO261RHc/j4s3KdbWATklh2KTicKpgta0mh294Y+hKYLGgBpnXjtOw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-17T07:12:51Z",
|
||||
"mac": "ENC[AES256_GCM,data:YG4k+PvsF0NVfjqKY/MBhCOwn9Kcn5orq8aD41X3NEPBT+wU5RlN0XqXhH2nkZ52ZHdCN84Ulbd4guwBcJcUtGvxqOpfE4SJ9RFE+SjYw+2+S9wlArQx5R5Zd+Sr+Rgtaip3moENbxETxHZazbEK3u5o0aXKrZvoXH2xgPRYUOg=,iv:lDnNELLpqykrsmoORMW7p6gF43C2QvPwf0PZep2pEo8=,tag:CZNOBx3Aeoq5WeDbANqFVw==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -0,0 +1,3 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MCowBQYDK2VwAyEAguIpeMvvMtdilU6tsqdBClci2YUgBKEUPQ5ID55zOVY=
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
25.11
|
||||
@@ -0,0 +1 @@
|
||||
200:3975:b69f:fd15:f39a:bf24:f644:432b
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/peer2
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:Ik+mzD41SwfGZrqGi5oy0u8ZS8qCKgV34aohIt7J/11S3ayhKKN8451cYPltGg+2i/+2DWRSkqYZsctgIahvthnvb30r91XHRUCtE3oT8iPOKwEuW2xnZBL2dK0qHrKFGn8B/o3Bl/+4cWuR5Jt9QHlN4oF3o50=,iv:a9mSIr7TT9im19P5XKiDGL71hMLfQE8IB6NV8WABZ+s=,tag:dVQ0HZdpbkcmFA37Il+VIw==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age107mprppm3r9u7f26e6t5mhtdny0h5ugfmfjy8kac2tw9nrh9a3ksex0xca",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3WEtncHIrd2YrbHduUm4y\nYkh1U0NERDR0MzRNQXZ0elNMZzl0ZmJPMlVVCnJ1UC9uNnk0dC9JVzdReUxLZmdR\nMGIwSjBKUW8yQmQ1R3dqU29ZM2czMEUKLS0tIFpMM3l6YnVFRUtLOFRvSTBXRXU0\nQUJWNk5obzBINS90dWwybXlXdEZFZjgKrZtViJwgPpKT+Bhx6ymEhf6QmnMmZ6Jf\n3kIxzDWxGbxrDTrrdXm33gYs9bRvtXsTACRT3TRAKIwSjIV/ycCUBA==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArY1A4blFZNjdTU3lGUFA3\nb1hscVhLVmtuQnJMS3VHZVVEOXBDRktXNVhjCkdLZEFFZXhubFJrZTU3RjRDN1lh\nVzgyd3E3a0NGTGh1N2lPQWZBVG9BaW8KLS0tIFN1eEhpMk5mUkNaL29MS2NlWDdP\nVXFtb3c0Y25MT3NLK0N2RStkY1R0MGsKLv8yOSl2iQx39JRJA/e0dOtIz7ZND0+o\nzmqxapD6pxbj8RGswj0szLrxaveWT6Vkmmy/a4fz35uw3xuF7uiJJA==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-09-17T07:13:24Z",
|
||||
"mac": "ENC[AES256_GCM,data:KCBHfavyg1U/Z1e3rr0jdHivUa5/rl42N/K6c0BR47srdYqcpAS+SWW6tH7kPI3EO+P7TgXVoGlmcXaKgrlRpe37eNzdAT6PJYm7rhe6rm2UgZ1yw/NFqA11p/i3dDbTzYHaHMNGGGg9t/BdT1tD0zCICfptGQnSSBx/BEmT3ak=,iv:GOk8/z1mLIVKxFX4ayt9HvA90gv0Af1KqcDbdJRUYu4=,tag:hJpOBFRESQXmE7iMqDqO6g==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -0,0 +1,3 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MCowBQYDK2VwAyEA40UksAF1BjKgbYTd3motmeXa/belhNOoRfaaPQTXy8E=
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -8,8 +8,25 @@
|
||||
|
||||
roles.peer = {
|
||||
perInstance =
|
||||
{ instanceName, roles, ... }:
|
||||
{
|
||||
instanceName,
|
||||
roles,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
exports.networking = {
|
||||
priority = lib.mkDefault 900;
|
||||
# TODO add user space network support to clan-cli
|
||||
module = "clan_lib.network.zerotier";
|
||||
peers = lib.mapAttrs (name: _machine: {
|
||||
host.var = {
|
||||
machine = name;
|
||||
generator = "zerotier";
|
||||
file = "zerotier-ip";
|
||||
};
|
||||
}) roles.peer.machines;
|
||||
};
|
||||
nixosModule =
|
||||
{
|
||||
config,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
module = lib.modules.importApply ./default.nix { };
|
||||
module = ./default.nix;
|
||||
in
|
||||
{
|
||||
clan.modules.zerotier = module;
|
||||
|
||||
18
devFlake/flake.lock
generated
18
devFlake/flake.lock
generated
@@ -84,11 +84,11 @@
|
||||
},
|
||||
"nixpkgs-dev": {
|
||||
"locked": {
|
||||
"lastModified": 1757752761,
|
||||
"narHash": "sha256-HBM2YTKSegLZjdamfqH9KADj2zQBQBNQHmwdrYkatpg=",
|
||||
"lastModified": 1758573205,
|
||||
"narHash": "sha256-0ybDco+HjG5h46wx7ww4JIyg3y/mBDgkMCVX/Ua0e/Q=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4b46c744cbd5f9336027dff287e74ead84d80041",
|
||||
"rev": "803b1683f562edc00665874bf98c1aad0b111482",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -107,11 +107,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1757624466,
|
||||
"narHash": "sha256-25ExS2AkQD05Jf0Y2Wnn5KHpucN2d3ObEQOVaDh7ubg=",
|
||||
"lastModified": 1758272005,
|
||||
"narHash": "sha256-1u3xTH+3kaHhztPmWtLAD8LF5pTYLR2CpsPFWTFnVtQ=",
|
||||
"owner": "NuschtOS",
|
||||
"repo": "search",
|
||||
"rev": "da8bcb74407e41d334fc79081fdd8948b795bd6f",
|
||||
"rev": "aa975a3757f28ce862812466c5848787b868e116",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -165,11 +165,11 @@
|
||||
"nixpkgs": []
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1756662192,
|
||||
"narHash": "sha256-F1oFfV51AE259I85av+MAia221XwMHCOtZCMcZLK2Jk=",
|
||||
"lastModified": 1758206697,
|
||||
"narHash": "sha256-/DbPkh6PZOgfueCbs3uzlk4ASU2nPPsiVWhpMCNkAd0=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "1aabc6c05ccbcbf4a635fb7a90400e44282f61c4",
|
||||
"rev": "128222dc911b8e2e18939537bed1762b7f3a04aa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
177
docs/mkdocs.yml
177
docs/mkdocs.yml
@@ -1,4 +1,4 @@
|
||||
site_name: Clan Documentation
|
||||
site_name: Documentation
|
||||
site_url: https://docs.clan.lol
|
||||
repo_url: https://git.clan.lol/clan/clan-core/
|
||||
repo_name: "_>"
|
||||
@@ -45,82 +45,80 @@ exclude_docs: |
|
||||
/drafts/
|
||||
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Getting Started:
|
||||
- Overview: index.md
|
||||
- Creating Your First Clan: guides/getting-started/index.md
|
||||
- Add Machines: guides/getting-started/add-machines.md
|
||||
- Add User: guides/getting-started/add-user.md
|
||||
- Add Services: guides/getting-started/add-services.md
|
||||
- Deploy to Physical Machine:
|
||||
- Create USB Installer: guides/getting-started/create-installer.md
|
||||
- Deploy Physical Machine: guides/getting-started/hardware-report-physical.md
|
||||
- Deploy to Virtual Machine: guides/getting-started/hardware-report-virtual.md
|
||||
- Configure Disk Config: guides/getting-started/choose-disk.md
|
||||
- Update Machine: guides/getting-started/update.md
|
||||
- Continuous Integration: guides/getting-started/flake-check.md
|
||||
- Convert Existing NixOS Config: guides/getting-started/convert-flake.md
|
||||
- Guides:
|
||||
- Getting Started:
|
||||
- Creating Your First Clan: guides/getting-started/index.md
|
||||
- Add Machines: guides/getting-started/add-machines.md
|
||||
- Add User: guides/getting-started/add-user.md
|
||||
- Add Services: guides/getting-started/add-services.md
|
||||
- Deploy to Physical Machine:
|
||||
- Create USB Installer: guides/getting-started/create-installer.md
|
||||
- Deploy Physical Machine: guides/getting-started/hardware-report-physical.md
|
||||
- Deploy to Virtual Machine: guides/getting-started/hardware-report-virtual.md
|
||||
- Configure Disk Config: guides/getting-started/choose-disk.md
|
||||
- Update Machine: guides/getting-started/update.md
|
||||
- Continuous Integration: guides/getting-started/flake-check.md
|
||||
- Convert Existing NixOS Config: guides/getting-started/convert-flake.md
|
||||
- ClanServices: guides/clanServices.md
|
||||
- Inventory:
|
||||
- Introduction to Inventory: guides/inventory/inventory.md
|
||||
- File Autoincludes: guides/inventory/autoincludes.md
|
||||
|
||||
- Clan Services:
|
||||
- Inventory Guide: guides/inventory/clanServices.md
|
||||
- Author Your Own Service: guides/services/community.md
|
||||
- Vars:
|
||||
- Overview: guides/vars/vars-overview.md
|
||||
- Getting Started: guides/vars/vars-backend.md
|
||||
- Concepts: guides/vars/vars-concepts.md
|
||||
- Sops Backend:
|
||||
- Yubikeys & Age Plugins: guides/vars/sops/age-plugins.md
|
||||
- Introduction to Vars: guides/vars/vars-overview.md
|
||||
- Minimal Example: guides/vars/vars-backend.md
|
||||
- Diving deeper: guides/vars/vars-concepts.md
|
||||
- Advanced Examples: guides/vars/vars-advanced-examples.md
|
||||
- Troubleshooting: guides/vars/vars-troubleshooting.md
|
||||
- Backup & Restore: guides/backups.md
|
||||
- Disk Encryption: guides/disk-encryption.md
|
||||
- Secrets management: guides/secrets.md
|
||||
- Networking: guides/networking.md
|
||||
- Zerotier VPN: guides/mesh-vpn.md
|
||||
- How to disable Secure Boot: guides/secure-boot.md
|
||||
- Sops Backend:
|
||||
- Yubikeys & Age Plugins: guides/vars/sops/age-plugins.md
|
||||
- Managing Users (OLD): guides/secrets.md
|
||||
- Networking:
|
||||
- Introduction to Networking: guides/networking/networking.md
|
||||
- Zerotier VPN: guides/networking/mesh-vpn.md
|
||||
- Disko Templates:
|
||||
- Community Disko Templates: guides/disko-templates/community.md
|
||||
- Backups:
|
||||
- Introduction to Backups: guides/backups.md
|
||||
- Flake-parts: guides/flake-parts.md
|
||||
- macOS: guides/macos.md
|
||||
- NixOS Rebuild: guides/nixos-rebuild.md
|
||||
- macOS:
|
||||
- Managing macOS Machines: guides/macos.md
|
||||
# Should be part of the respective sections above
|
||||
# machines, disko, clan
|
||||
- Templates: concepts/templates.md
|
||||
- Migrations:
|
||||
- clan modules --> clan services: guides/migrations/migrate-inventory-services.md
|
||||
- Facts --> Vars: guides/migrations/migration-facts-vars.md
|
||||
- Disk id: guides/migrations/disk-id.md
|
||||
- Disk Encryption: guides/disk-encryption.md
|
||||
- Disable Secure Boot: guides/secure-boot.md
|
||||
- Contributing:
|
||||
- Contributing: guides/contributing/CONTRIBUTING.md
|
||||
- Debugging: guides/contributing/debugging.md
|
||||
- Hacking: guides/contributing/CONTRIBUTING.md
|
||||
- Advanced Debugging: guides/contributing/debugging.md
|
||||
- Testing: guides/contributing/testing.md
|
||||
|
||||
- Writing a Service Module: guides/services/community.md
|
||||
- Writing a Disko Template: guides/disko-templates/community.md
|
||||
- Migrations:
|
||||
- Migrate from clan modules to services: guides/migrations/migrate-inventory-services.md
|
||||
- Facts Vars Migration: guides/migrations/migration-facts-vars.md
|
||||
- Disk id: guides/migrations/disk-id.md
|
||||
- Concepts:
|
||||
- Inventory: concepts/inventory.md
|
||||
- Autoincludes: concepts/autoincludes.md
|
||||
- Templates: concepts/templates.md
|
||||
- Reference:
|
||||
- Overview: reference/index.md
|
||||
- Browse Options: "/options"
|
||||
- Services:
|
||||
- Overview:
|
||||
- reference/clanServices/index.md
|
||||
- reference/clanServices/admin.md
|
||||
- reference/clanServices/borgbackup.md
|
||||
- reference/clanServices/certificates.md
|
||||
- reference/clanServices/coredns.md
|
||||
- reference/clanServices/data-mesher.md
|
||||
- reference/clanServices/dyndns.md
|
||||
- reference/clanServices/emergency-access.md
|
||||
- reference/clanServices/garage.md
|
||||
- reference/clanServices/hello-world.md
|
||||
- reference/clanServices/importer.md
|
||||
- reference/clanServices/localbackup.md
|
||||
- reference/clanServices/matrix-synapse.md
|
||||
- reference/clanServices/mycelium.md
|
||||
- reference/clanServices/monitoring.md
|
||||
- reference/clanServices/packages.md
|
||||
- reference/clanServices/sshd.md
|
||||
- reference/clanServices/syncthing.md
|
||||
- reference/clanServices/trusted-nix-caches.md
|
||||
- reference/clanServices/users.md
|
||||
- reference/clanServices/wifi.md
|
||||
- reference/clanServices/wireguard.md
|
||||
- reference/clanServices/zerotier.md
|
||||
- API: reference/clanServices/clan-service-author-interface.md
|
||||
- Clan Options: reference/options/clan.md
|
||||
- Clan Inventory Options: reference/options/clan_inventory.md
|
||||
|
||||
- Clan Service API: reference/clanServices/clan-service-author-interface.md
|
||||
|
||||
- clan.core (Machine Options):
|
||||
- Overview: reference/clan.core/index.md
|
||||
- reference/clan.core/backups.md
|
||||
- reference/clan.core/deployment.md
|
||||
- reference/clan.core/facts.md
|
||||
- reference/clan.core/networking.md
|
||||
- reference/clan.core/postgresql.md
|
||||
- reference/clan.core/settings.md
|
||||
- reference/clan.core/sops.md
|
||||
- reference/clan.core/state.md
|
||||
- reference/clan.core/vars.md
|
||||
|
||||
- CLI:
|
||||
- Overview: reference/cli/index.md
|
||||
@@ -139,19 +137,7 @@ nav:
|
||||
- reference/cli/vars.md
|
||||
- reference/cli/vms.md
|
||||
|
||||
- clan.core (NixOS Options):
|
||||
- Overview: reference/clan.core/index.md
|
||||
- reference/clan.core/backups.md
|
||||
- reference/clan.core/deployment.md
|
||||
- reference/clan.core/facts.md
|
||||
- reference/clan.core/networking.md
|
||||
- reference/clan.core/postgresql.md
|
||||
- reference/clan.core/settings.md
|
||||
- reference/clan.core/sops.md
|
||||
- reference/clan.core/state.md
|
||||
- reference/clan.core/vars.md
|
||||
|
||||
- Developer-api: api.md
|
||||
- HTTP API: api.md
|
||||
|
||||
- Decisions:
|
||||
- Architecture Decisions: decisions/README.md
|
||||
@@ -162,7 +148,35 @@ nav:
|
||||
- 05-deployment-parameters: decisions/05-deployment-parameters.md
|
||||
- Template: decisions/_template.md
|
||||
- Glossary: reference/glossary.md
|
||||
- Browse Options: "/options"
|
||||
- Services:
|
||||
- Introduction to ClanServices: reference/clanServices/index.md
|
||||
- Official:
|
||||
- reference/clanServices/admin.md
|
||||
- reference/clanServices/borgbackup.md
|
||||
- reference/clanServices/certificates.md
|
||||
- reference/clanServices/coredns.md
|
||||
- reference/clanServices/data-mesher.md
|
||||
- reference/clanServices/dyndns.md
|
||||
- reference/clanServices/emergency-access.md
|
||||
- reference/clanServices/garage.md
|
||||
- reference/clanServices/hello-world.md
|
||||
- reference/clanServices/importer.md
|
||||
- reference/clanServices/localbackup.md
|
||||
- reference/clanServices/matrix-synapse.md
|
||||
- reference/clanServices/mycelium.md
|
||||
- reference/clanServices/monitoring.md
|
||||
- reference/clanServices/packages.md
|
||||
- reference/clanServices/sshd.md
|
||||
- reference/clanServices/syncthing.md
|
||||
- reference/clanServices/trusted-nix-caches.md
|
||||
- reference/clanServices/users.md
|
||||
- reference/clanServices/wifi.md
|
||||
- reference/clanServices/wireguard.md
|
||||
- reference/clanServices/yggdrasil.md
|
||||
- reference/clanServices/zerotier.md
|
||||
- Community: community/services/index.md
|
||||
|
||||
- Search Clan Options: "/options"
|
||||
|
||||
docs_dir: site
|
||||
site_dir: out
|
||||
@@ -220,7 +234,6 @@ extra:
|
||||
|
||||
plugins:
|
||||
- search
|
||||
- macros
|
||||
- redoc-tag
|
||||
- redirects:
|
||||
redirect_maps:
|
||||
|
||||
@@ -37,7 +37,6 @@ pkgs.stdenv.mkDerivation {
|
||||
++ (with pkgs.python3Packages; [
|
||||
mkdocs
|
||||
mkdocs-material
|
||||
mkdocs-macros
|
||||
mkdocs-redoc-tag
|
||||
mkdocs-redirects
|
||||
]);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
buildClanOptions = self'.legacyPackages.clan-internals-docs;
|
||||
# Simply evaluated options (JSON)
|
||||
# { clanCore = «derivation JSON»; clanModules = { ${name} = «derivation JSON» }; }
|
||||
jsonDocs = pkgs.callPackage ./get-module-docs.nix {
|
||||
@@ -73,8 +72,7 @@
|
||||
# A file that contains the links to all clanModule docs
|
||||
export CLAN_MODULES_VIA_SERVICE=${clanModulesViaService}
|
||||
export CLAN_SERVICE_INTERFACE=${self'.legacyPackages.clan-service-module-interface}/share/doc/nixos/options.json
|
||||
|
||||
export BUILD_CLAN_PATH=${buildClanOptions}/share/doc/nixos/options.json
|
||||
export CLAN_OPTIONS_PATH=${self'.legacyPackages.clan-options}/share/doc/nixos/options.json
|
||||
|
||||
mkdir $out
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
let
|
||||
inherit (lib)
|
||||
mapAttrsToList
|
||||
flip
|
||||
mapAttrs
|
||||
mkOption
|
||||
types
|
||||
@@ -41,10 +40,7 @@
|
||||
prefix = [ ];
|
||||
}).config.manifest;
|
||||
|
||||
loadFile = file: if builtins.pathExists file then builtins.readFile file else "";
|
||||
|
||||
settingsModules =
|
||||
module: flip mapAttrs (getRoles module) (_roleName: roleConfig: roleConfig.interface);
|
||||
settingsModules = module: mapAttrs (_roleName: roleConfig: roleConfig.interface) (getRoles module);
|
||||
|
||||
# Map each letter to its capitalized version
|
||||
capitalizeChar =
|
||||
@@ -99,7 +95,7 @@
|
||||
|
||||
**${manifest.description}**
|
||||
|
||||
${loadFile (module._file + "/../README.md")}
|
||||
${lib.optionalString (manifest ? readme) manifest.readme}
|
||||
|
||||
${
|
||||
if manifest.categories != [ ] then
|
||||
@@ -115,7 +111,7 @@
|
||||
instances.${name} = lib.mkOption {
|
||||
inherit description;
|
||||
type = types.submodule {
|
||||
options.roles = flip mapAttrs (settingsModules module) (
|
||||
options.roles = mapAttrs (
|
||||
roleName: roleSettingsModule:
|
||||
mkOption {
|
||||
type = types.submodule {
|
||||
@@ -138,7 +134,7 @@
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
) (settingsModules module);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
@@ -40,7 +41,7 @@ from clan_lib.services.modules import (
|
||||
# Get environment variables
|
||||
CLAN_CORE_PATH = Path(os.environ["CLAN_CORE_PATH"])
|
||||
CLAN_CORE_DOCS = Path(os.environ["CLAN_CORE_DOCS"])
|
||||
BUILD_CLAN_PATH = os.environ.get("BUILD_CLAN_PATH")
|
||||
CLAN_OPTIONS_PATH = Path(os.environ["CLAN_OPTIONS_PATH"])
|
||||
|
||||
# Options how to author clan.modules
|
||||
# perInstance, perMachine, ...
|
||||
@@ -326,7 +327,7 @@ Each `clanService`:
|
||||
|
||||
See [Migration Guide](../../guides/migrations/migrate-inventory-services.md) for help on migrating.
|
||||
|
||||
Learn how to use `clanServices` in practice in the [Using clanServices guide](../../guides/clanServices.md).
|
||||
Learn how to use `clanServices` in practice in the [Using clanServices guide](../../guides/inventory/clanServices.md).
|
||||
"""
|
||||
|
||||
with indexfile.open("w") as of:
|
||||
@@ -442,6 +443,84 @@ Typically needed by module authors to define roles, behavior and metadata for di
|
||||
of.write(output)
|
||||
|
||||
|
||||
def produce_inventory_docs() -> None:
|
||||
if not CLAN_OPTIONS_PATH:
|
||||
msg = f"Environment variables are not set correctly: CLAN_OPTIONS_PATH={CLAN_OPTIONS_PATH}. Expected a path to the optionsJSON"
|
||||
raise ClanError(msg)
|
||||
|
||||
if not OUT:
|
||||
msg = f"Environment variables are not set correctly: $out={OUT}"
|
||||
raise ClanError(msg)
|
||||
|
||||
output = """# Inventory
|
||||
This provides an overview of the available options of the `inventory` model.
|
||||
|
||||
It can be set via the `inventory` attribute of the [`clan`](./clan.md#inventory) function, or via the [`clan.inventory`](./clan.md#inventory) attribute of flake-parts.
|
||||
|
||||
"""
|
||||
# Inventory options are already included under the clan attribute
|
||||
# We just omitted them in the clan docs, because we want a separate output for the inventory model
|
||||
with Path(CLAN_OPTIONS_PATH).open() as f:
|
||||
options: dict[str, dict[str, Any]] = json.load(f)
|
||||
|
||||
clan_root_option = options_to_tree(options)
|
||||
# Find the inventory options
|
||||
inventory_opt: None | Option = None
|
||||
for opt in clan_root_option.suboptions:
|
||||
if opt.name == "inventory":
|
||||
inventory_opt = opt
|
||||
break
|
||||
|
||||
if not inventory_opt:
|
||||
print("No inventory options found.")
|
||||
sys.exit(1)
|
||||
# Render the inventory options
|
||||
# This for loop excludes the root node
|
||||
for option in inventory_opt.suboptions:
|
||||
output += options_docs_from_tree(option, init_level=2)
|
||||
|
||||
outfile = Path(OUT) / "options/clan_inventory.md"
|
||||
outfile.parent.mkdir(parents=True, exist_ok=True)
|
||||
with Path.open(outfile, "w") as of:
|
||||
of.write(output)
|
||||
|
||||
|
||||
def produce_clan_options_docs() -> None:
|
||||
if not CLAN_OPTIONS_PATH:
|
||||
msg = f"Environment variables are not set correctly: CLAN_OPTIONS_PATH={CLAN_OPTIONS_PATH}. Expected a path to the optionsJSON"
|
||||
raise ClanError(msg)
|
||||
|
||||
if not OUT:
|
||||
msg = f"Environment variables are not set correctly: $out={OUT}"
|
||||
raise ClanError(msg)
|
||||
|
||||
output = """# Clan Options
|
||||
This provides an overview of the available options
|
||||
|
||||
Those can be set via [`clan-core.lib.clan`](./clan.md#inventory) function,
|
||||
or via the [`clan`](./clan.md) attribute of flake-parts.
|
||||
|
||||
"""
|
||||
# Inventory options are already included under the clan attribute
|
||||
# We just omitted them in the clan docs, because we want a separate output for the inventory model
|
||||
with Path(CLAN_OPTIONS_PATH).open() as f:
|
||||
options: dict[str, dict[str, Any]] = json.load(f)
|
||||
|
||||
clan_root_option = options_to_tree(options)
|
||||
# Render the inventory options
|
||||
# This for loop excludes the root node
|
||||
# Exclude inventory options
|
||||
for option in clan_root_option.suboptions:
|
||||
if "inventory" in option.name:
|
||||
continue
|
||||
output += options_docs_from_tree(option, init_level=2)
|
||||
|
||||
outfile = Path(OUT) / "options/clan.md"
|
||||
outfile.parent.mkdir(parents=True, exist_ok=True)
|
||||
with Path.open(outfile, "w") as of:
|
||||
of.write(output)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Option:
|
||||
name: str
|
||||
@@ -556,6 +635,7 @@ def options_docs_from_tree(
|
||||
|
||||
if __name__ == "__main__":
|
||||
produce_clan_core_docs()
|
||||
|
||||
produce_inventory_docs()
|
||||
produce_clan_options_docs()
|
||||
produce_clan_service_author_docs()
|
||||
produce_clan_service_docs()
|
||||
|
||||
27
docs/site/community/services/index.md
Normal file
27
docs/site/community/services/index.md
Normal file
@@ -0,0 +1,27 @@
|
||||
Services provided by the community
|
||||
|
||||
!!! tip "Add your own!"
|
||||
|
||||
Have you built a service or a tool for? Open a PR adding a link to this page!
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [Your Service Foo](https://example.com) :octicons-link-external-16:
|
||||
|
||||
---
|
||||
|
||||
Does this and that
|
||||
|
||||
- [Your Service Foo](https://example.com) :octicons-link-external-16:
|
||||
|
||||
---
|
||||
|
||||
Does this and that
|
||||
|
||||
- [Your Service Foo](https://example.com) :octicons-link-external-16:
|
||||
|
||||
---
|
||||
|
||||
Does this and that
|
||||
|
||||
</div>
|
||||
@@ -5,7 +5,7 @@ This guide provides an example setup for a single-disk ZFS system with native en
|
||||
This configuration only applies to `systemd-boot` enabled systems and **requires** UEFI booting.
|
||||
|
||||
!!! Info "Secure Boot"
|
||||
This guide is compatible with systems that have [secure boot disabled](../guides/secure-boot.md). If you encounter boot issues, check if secure boot needs to be disabled in your UEFI settings.
|
||||
This guide is compatible with systems that have [secure boot disabled](./secure-boot.md). If you encounter boot issues, check if secure boot needs to be disabled in your UEFI settings.
|
||||
|
||||
Replace the highlighted lines with your own disk-id.
|
||||
You can find our your disk-id by executing:
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
Machines can be added using the following methods
|
||||
|
||||
- Create a file `machines/{machine_name}/configuration.nix` (See: [File Autoincludes](../../concepts/autoincludes.md))
|
||||
- Create a file `machines/{machine_name}/configuration.nix` (See: [File Autoincludes](../inventory/autoincludes.md))
|
||||
- Imperative via cli command: `clan machines create`
|
||||
- Editing nix expressions in flake.nix See [`clan-core.lib.clan`](/options/?scope=Flake Options (clan.nix file))
|
||||
|
||||
See the complete [list](../../concepts/autoincludes.md) of auto-loaded files.
|
||||
See the complete [list](../inventory/autoincludes.md) of auto-loaded files.
|
||||
|
||||
## Create a machine
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ In Clan Services are multi-Host & role-based:
|
||||
|
||||
- You can use tags instead of explicit machine names.
|
||||
|
||||
To learn more: [Guide about clanService](../clanServices.md)
|
||||
To learn more: [Guide about clanService](../inventory/clanServices.md)
|
||||
|
||||
!!! Important
|
||||
It is recommended to add at least one networking service such as `zerotier` that allows to reach all your clan machines from your setup computer across the globe.
|
||||
@@ -41,7 +41,7 @@ To learn more: [Guide about clanService](../clanServices.md)
|
||||
```
|
||||
|
||||
1. See [reference/clanServices](../../reference/clanServices/index.md) for all available services and how to configure them.
|
||||
Or read [authoring/clanServices](../../guides/services/community.md) if you want to bring your own
|
||||
Or read [authoring/clanServices](../services/community.md) if you want to bring your own
|
||||
|
||||
2. Replace `__YOUR_CONTROLLER_` with the *name* of your machine.
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ Clan needs to know where it can reach your hosts. For testing purpose set
|
||||
}
|
||||
```
|
||||
|
||||
See our guide on for properly [configuring machines networking](../networking.md)
|
||||
See our guide on for properly [configuring machines networking](../networking/networking.md)
|
||||
|
||||
## Next Steps
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ sudo umount /dev/sdb1
|
||||
|
||||
## Boot From USB Stick
|
||||
|
||||
- To use, boot from the Clan USB drive with **secure boot turned off**. For step by step instructions go to [Disabling Secure Boot](../../guides/secure-boot.md)
|
||||
- To use, boot from the Clan USB drive with **secure boot turned off**. For step by step instructions go to [Disabling Secure Boot](../secure-boot.md)
|
||||
|
||||
## (Optional) Connect to Wifi Manually
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Now that you have created a machine, added some services, and set up secrets, this guide will walk you through how to deploy it.
|
||||
|
||||
|
||||
### Step 0. Prerequisites
|
||||
### Prerequisites
|
||||
- [x] RAM > 2GB
|
||||
- [x] **Two Computers**: You need one computer that you're getting ready (we'll call this the Target Computer) and another one to set it up from (we'll call this the Setup Computer). Make sure both can talk to each other over the network using SSH.
|
||||
- [x] **Machine configuration**: See our basic [adding and configuring machine guide](./add-machines.md)
|
||||
@@ -45,7 +45,7 @@ This is an example of the booted installer.
|
||||
│ │Onion address: 6evxy5yhzytwpnhc2vpscrbti3iktxdhpnf6yim6bbs25p4v6beemzyd.onion │ │
|
||||
│ │Multicast DNS: nixos-installer.local │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ Press 'Ctrl-C' for console access │
|
||||
│ Press 'Ctrl-C' for console access │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -75,12 +75,12 @@ This is an example of the booted installer.
|
||||
|
||||
There are two ways to deploy your machine:
|
||||
|
||||
### Generating a Hardware Report
|
||||
|
||||
The following command will generate a hardware report with [nixos-facter](https://github.com/nix-community/nixos-facter) and writes it back into your machine folder. The `--phases kexec` flag makes sure we are not yet formatting anything, instead if the target system is not a NixOS machine it will use [kexec](https://wiki.archlinux.org/title/Kexec) to switch to a NixOS kernel.
|
||||
|
||||
=== "Password"
|
||||
### Generating a Hardware Report
|
||||
|
||||
The following command will generate a hardware report with [nixos-facter](https://github.com/nix-community/nixos-facter) and writes it back into your machine folder. The `--phases kexec` flag makes sure we are not yet formatting anything, instead if the target system is not a NixOS machine it will use [kexec](https://wiki.archlinux.org/title/Kexec) to switch to a NixOS kernel.
|
||||
|
||||
**Password**
|
||||
|
||||
```terminal
|
||||
clan machines install [MACHINE] \
|
||||
@@ -90,11 +90,10 @@ There are two ways to deploy your machine:
|
||||
```
|
||||
|
||||
=== "QR Code"
|
||||
### Generating a Hardware Report
|
||||
**QR Code**
|
||||
|
||||
The following command will generate a hardware report with [nixos-facter](https://github.com/nix-community/nixos-facter) and writes it back into your machine folder. The `--phases kexec` flag makes sure we are not yet formatting anything, instead if the target system is not a NixOS machine it will use [kexec](https://wiki.archlinux.org/title/Kexec) to switch to a NixOS kernel.
|
||||
**Using a JSON String or File Path**:
|
||||
|
||||
#### Using a JSON String or File Path
|
||||
Copy the JSON string contained in the QR Code and provide its path or paste it directly:
|
||||
```terminal
|
||||
clan machines install [MACHINE] --json [JSON] \
|
||||
@@ -102,7 +101,8 @@ There are two ways to deploy your machine:
|
||||
--phases kexec
|
||||
```
|
||||
|
||||
#### Using an Image Containing the QR Code
|
||||
**Using an Image Containing the QR Code**:
|
||||
|
||||
Provide the path to an image file containing the QR code displayed by the installer:
|
||||
```terminal
|
||||
clan machines install [MACHINE] --png [PATH] \
|
||||
@@ -112,3 +112,5 @@ There are two ways to deploy your machine:
|
||||
|
||||
|
||||
If you are using our template `[MACHINE]` would be `jon`
|
||||
|
||||
[Next Step (Choose Disk Format)](./choose-disk.md){ .md-button .md-button--primary }
|
||||
@@ -2,7 +2,7 @@
|
||||
# Update Machines
|
||||
|
||||
The Clan command line interface enables you to update machines remotely over SSH.
|
||||
In this guide we will teach you how to set a `targetHost` in Nix,
|
||||
In this guide we will teach you how to set a `targetHost` in Nix,
|
||||
and how to define a remote builder for your machine closures.
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Ensure that the root login is secured and only used when necessary.
|
||||
|
||||
## Multiple Target Hosts
|
||||
|
||||
You can now experiment with a new interface that allows you to define multiple `targetHost` addresses for different VPNs. Learn more and try it out in our [networking guide](../networking.md).
|
||||
You can now experiment with a new interface that allows you to define multiple `targetHost` addresses for different VPNs. Learn more and try it out in our [networking guide](../networking/networking.md).
|
||||
|
||||
## Updating Machine Configurations
|
||||
|
||||
@@ -65,7 +65,7 @@ During an update, clan will ssh into the `buildHost` and run `nixos-rebuild` fro
|
||||
|
||||
|
||||
```{.nix hl_lines="5" .no-copy}
|
||||
buildClan {
|
||||
clan {
|
||||
# ...
|
||||
machines = {
|
||||
"jon" = {
|
||||
@@ -101,7 +101,7 @@ To exclude machines from being updated when running `clan machines update` witho
|
||||
one can set the `clan.deployment.requireExplicitUpdate` option to true:
|
||||
|
||||
```{.nix hl_lines="5" .no-copy}
|
||||
buildClan {
|
||||
clan {
|
||||
# ...
|
||||
machines = {
|
||||
"jon" = {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# Using the Inventory
|
||||
|
||||
Clan's inventory system is a composable way to define and deploy services across
|
||||
machines.
|
||||
|
||||
@@ -70,7 +68,7 @@ inventory.instances = {
|
||||
## Module Settings
|
||||
|
||||
Each role might expose configurable options. See clan's [clanServices
|
||||
reference](../reference/clanServices/index.md) for all available options.
|
||||
reference](../../reference/clanServices/index.md) for all available options.
|
||||
|
||||
Settings can be set in per-machine or per-role. The latter is applied to all
|
||||
machines that are assigned to that role.
|
||||
@@ -157,13 +155,13 @@ inventory.instances = {
|
||||
|
||||
You can use services exposed by Clan's core module library, `clan-core`.
|
||||
|
||||
🔗 See: [List of Available Services in clan-core](../reference/clanServices/index.md)
|
||||
🔗 See: [List of Available Services in clan-core](../../reference/clanServices/index.md)
|
||||
|
||||
## Defining Your Own Service
|
||||
|
||||
You can also author your own `clanService` modules.
|
||||
|
||||
🔗 Learn how to write your own service: [Authoring a service](../guides/services/community.md)
|
||||
🔗 Learn how to write your own service: [Authoring a service](../services/community.md)
|
||||
|
||||
You might expose your service module from your flake — this makes it easy for other people to also use your module in their clan.
|
||||
|
||||
@@ -179,7 +177,7 @@ ______________________________________________________________________
|
||||
|
||||
## What's Next?
|
||||
|
||||
- [Author your own clanService →](../guides/services/community.md)
|
||||
- [Migrate from clanModules →](../guides/migrations/migrate-inventory-services.md)
|
||||
- [Author your own clanService →](../services/community.md)
|
||||
- [Migrate from clanModules →](../migrations/migrate-inventory-services.md)
|
||||
|
||||
<!-- TODO: * [Understand the architecture →](../explanation/clan-architecture.md) -->
|
||||
@@ -17,13 +17,13 @@ The following tutorial will walk through setting up a Backup service where the t
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [x] [Add some machines](../guides/getting-started/add-machines.md) to your Clan.
|
||||
- [x] [Add some machines](../getting-started/add-machines.md) to your Clan.
|
||||
|
||||
## Services
|
||||
|
||||
The inventory defines `instances` of clan services. Membership of `machines` is defined via `roles` exclusively.
|
||||
|
||||
See each [modules documentation](../reference/clanServices/index.md) for its available roles.
|
||||
See each [modules documentation](../../reference/clanServices/index.md) for its available roles.
|
||||
|
||||
### Adding services to machines
|
||||
|
||||
@@ -7,7 +7,7 @@ This guide explains how to manage macOS machines using Clan.
|
||||
Currently, Clan supports the following features for macOS:
|
||||
|
||||
- `clan machines update` for existing [nix-darwin](https://github.com/nix-darwin/nix-darwin) installations
|
||||
- Support for [vars](../guides/vars/vars-overview.md)
|
||||
- Support for [vars](./vars/vars-overview.md)
|
||||
|
||||
## Add Your Machine to Your Clan Flake
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Migrating from using `clanModules` to `clanServices`
|
||||
|
||||
**Audience**: This is a guide for **people using `clanModules`**.
|
||||
If you are a **module author** and need to migrate your modules please consult our **new** [clanServices authoring guide](../../guides/services/community.md)
|
||||
If you are a **module author** and need to migrate your modules please consult our **new** [clanServices authoring guide](../services/community.md)
|
||||
|
||||
## What's Changing?
|
||||
|
||||
@@ -353,7 +353,7 @@ roles.client.extraModules = [ self.nixosModules.borgbackup ];
|
||||
|
||||
# Or inline module definition
|
||||
roles.client.extraModules = [
|
||||
{ config, ... }: {
|
||||
{
|
||||
# Your module configuration here
|
||||
}
|
||||
];
|
||||
@@ -378,6 +378,6 @@ instances = {
|
||||
|
||||
## Further reference
|
||||
|
||||
* [Inventory Concept](../../concepts/inventory.md)
|
||||
* [Authoring a 'clan.service' module](../../guides/services/community.md)
|
||||
* [ClanServices](../clanServices.md)
|
||||
* [Inventory Concept](../inventory/inventory.md)
|
||||
* [Authoring a 'clan.service' module](../services/community.md)
|
||||
* [ClanServices](../inventory/clanServices.md)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user