1
0

Compare commits

...

8 Commits

17 changed files with 247 additions and 10 deletions

View File

@ -5,6 +5,9 @@
networking.networkmanager.extraConfig = '' networking.networkmanager.extraConfig = ''
[connectivity] [connectivity]
uri=http://ping.clerie.de/nm-check.txt uri=http://ping.clerie.de/nm-check.txt
[global-dns]
searches=net.clerie.de
''; '';
} }

View File

@ -121,6 +121,27 @@
"url": "https://git.clerie.de/clerie/fieldpoc.git" "url": "https://git.clerie.de/clerie/fieldpoc.git"
} }
}, },
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"ssh-to-age",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709336216,
"narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"inputs": { "inputs": {
"systems": "systems" "systems": "systems"
@ -228,6 +249,22 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-stable": {
"locked": {
"lastModified": 1713434076,
"narHash": "sha256-+/p5edwlkqKZc6GDAQl+92Hoe1f3NNbUF9uj+X9H3pU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "8494ae076b7878d61a7d2d25e89a847fe8f8364c",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1665732960, "lastModified": 1665732960,
@ -246,11 +283,11 @@
}, },
"nixpkgs_3": { "nixpkgs_3": {
"locked": { "locked": {
"lastModified": 1713297878, "lastModified": 1713537308,
"narHash": "sha256-hOkzkhLT59wR8VaMbh1ESjtZLbGi+XNaBN6h49SPqEc=", "narHash": "sha256-XtTSSIB2DA6tOv+l0FhvfDMiyCmhoRbNB+0SeInZkbk=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "66adc1e47f8784803f2deb6cacd5e07264ec2d5c", "rev": "5c24cf2f0a12ad855f444c30b2421d044120c66f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -271,7 +308,9 @@
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_3", "nixpkgs": "nixpkgs_3",
"nixpkgs-krypton": "nixpkgs-krypton", "nixpkgs-krypton": "nixpkgs-krypton",
"solid-xmpp-alarm": "solid-xmpp-alarm" "solid-xmpp-alarm": "solid-xmpp-alarm",
"sops-nix": "sops-nix",
"ssh-to-age": "ssh-to-age"
} }
}, },
"solid-xmpp-alarm": { "solid-xmpp-alarm": {
@ -294,6 +333,48 @@
"url": "https://git.clerie.de/clerie/solid-xmpp-alarm.git" "url": "https://git.clerie.de/clerie/solid-xmpp-alarm.git"
} }
}, },
"sops-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1713532771,
"narHash": "sha256-vfKxhYVMzG2tg48/1rewBoSLCrKIjQsG1j7Nm/Y2gf4=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "a929a011a09db735abc45a8a45d1ff7fdee62755",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "sops-nix",
"type": "github"
}
},
"ssh-to-age": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1712553767,
"narHash": "sha256-hg6lBgxmTJ2hc1EFUoiA6BLA2QZGIfoBIxub9FK3x6M=",
"owner": "Mic92",
"repo": "ssh-to-age",
"rev": "5842a0023432eca39537060f38cbff7c9c2123c7",
"type": "github"
},
"original": {
"owner": "Mic92",
"repo": "ssh-to-age",
"type": "github"
}
},
"systems": { "systems": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,

View File

@ -28,8 +28,16 @@
url = "git+https://git.clerie.de/clerie/solid-xmpp-alarm.git"; url = "git+https://git.clerie.de/clerie/solid-xmpp-alarm.git";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
sops-nix = {
url = "github:Mic92/sops-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
ssh-to-age = {
url = "github:Mic92/ssh-to-age";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = { self, agenix, nixpkgs, nixos-hardware, chaosevents, fernglas, nixos-exporter, solid-xmpp-alarm, ... }@inputs: let outputs = { self, agenix, nixpkgs, nixos-hardware, chaosevents, fernglas, nixos-exporter, solid-xmpp-alarm, ssh-to-age, ... }@inputs: let
lib = import ./lib inputs; lib = import ./lib inputs;
helper = lib.flake-helper; helper = lib.flake-helper;
in { in {
@ -111,6 +119,8 @@
agenix; agenix;
inherit (chaosevents.packages.${system}) inherit (chaosevents.packages.${system})
chaosevents; chaosevents;
inherit (ssh-to-age.packages.${system})
ssh-to-age;
}) })
]; ];
}; };
@ -120,6 +130,8 @@
clerie-system-upgrade clerie-system-upgrade
clerie-merge-nixfiles-update clerie-merge-nixfiles-update
clerie-update-nixfiles clerie-update-nixfiles
clerie-sops
clerie-sops-config
chromium-incognito chromium-incognito
iot-data iot-data
nix-remove-result-links nix-remove-result-links
@ -134,6 +146,8 @@
uptimestatus; uptimestatus;
}); });
inherit lib self;
hydraJobs = { hydraJobs = {
inherit (self) inherit (self)
packages; packages;

View File

@ -141,5 +141,17 @@
} }
''; '';
clerie.system-auto-upgrade = {
allowReboot = true;
autoUpgrade = true;
};
clerie.monitoring = {
enable = true;
id = "399";
pubkey = "K7NkCFKSnMIgC0D5wejSpty56AYacfxE+feMsfWtHSo=";
bird = true;
};
system.stateVersion = "21.03"; system.stateVersion = "21.03";
} }

View File

@ -0,0 +1,9 @@
age-encryption.org/v1
-> ssh-ed25519 HwR33w 8zOolyGJvZ/2INs4yS7pFci+ktyEjOsGaff7+5HkEh4
HWXI2uYLIfutJ9PrJbwuH02GLNF/bJLVAd1prLbSk6o
-> ssh-ed25519 RyOjvA Fp4D7amm2EPSp5VyN7N99S10U3p1ITe+nhY+UVs64W8
xWfbN92OvHDrAvwYtnJfcwKuGtN68fN82/otWYbDiFs
-> '&&2PA(-grease O @2r[ u
5pJJ/ZfFB46scMhGo7wQY4r5gH2UZxZvt6sCOlyJ4uy+VVj8FZAShrBo
--- NncgnJg/91wjSyXj21jb0SkMuSsN3MciRpeI2pmKjco
ý€œ¤1¡UÂ/HwwŸ¾ÇòÏÏÐ@<40>QþSþX<C3BE>tŸo[Z†c<E280A0>šq\ÿòbWǤՅER¨Š«é .Eð5»F4„IC<49>½3èÈΘ÷º

View File

@ -40,6 +40,19 @@
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [ 80 443 ];
clerie.system-auto-upgrade = {
allowReboot = true;
autoUpgrade = true;
};
sops.secrets.wg-monitoring = {};
clerie.monitoring = {
enable = true;
id = "391";
pubkey = "Rfu2JLxAk0seAZgt43sOEAF69Z9uQaOjeNgM4jJF0h4=";
};
system.stateVersion = "23.05"; system.stateVersion = "23.05";
} }

View File

@ -0,0 +1,26 @@
{
"wg-monitoring": "ENC[AES256_GCM,data:kG/PCFQv4pRaup3sKOZNkwoJQ5Fdo/k5UUTh8/fedq87gA8yF7esZySUYc4=,iv:JYlaGotwiIiXVnfz98pjL1j2YwNtgoTmmk//9bABqz4=,tag:v7Csuvn1EjOxWnD2YHQ7kA==,type:str]",
"sops": {
"kms": null,
"gcp_kms": null,
"azure_kv": null,
"hc_vault": null,
"age": [
{
"recipient": "age1d3scmrwmhl5wzfq632sjg679kae3vsn8q5lmx05xrltnh5jt0yls6xnm00",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvM1hpMUJ4d2xvUWgxcFRs\nTGwyYW5vQWdwL1JObm1BR3J4OFB2Z09HQkIwCnh1TVlvUFNmOXVvdFZLL1AwNC9p\nNUxMV3ZsMW53RElXcU0veGQ2NCtyQmsKLS0tIG01Q3lIbDR0ZEQ2dDlONlhlSGho\nbU1LdzZlOGtmVmJKQjNiTE5RWVlyakkK2dm5BQ2P1cZVpFKLtARm1E9aoGM9j351\nbYmmdtTnXrgVM0rZuexiM+G+3MjZEFvGI+RkrFcGcY3WSKy0OQSlfg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2024-04-20T21:14:46Z",
"mac": "ENC[AES256_GCM,data:WdiOdmBc6EabnWM5Wkxj3W7a+qDJr4wQQEMR39bZabTMuW+8Y/p/eX5YxUL7U6XisI5c6JPIGcGYU7gaLWSvQ9uh6eFn/NZm+3WmyVXzAUjYDC2I8pm9DKAbPUU95zMmgSQDGJYr8ZFzfTDFepCn1poaxJ7TDpfD7tUfaDwDq34=,iv:vm6BHsXkb9pjKDeI/oXU7lYg4uHuFhE9g5s/JXDu5/o=,tag:hGGz8JKjBZ84Nx/3xT+p4Q==,type:str]",
"pgp": [
{
"created_at": "2024-04-20T21:14:21Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMA5OzEzXewpmPARAAgc9leAf7bGiTcp9NJIjjQvoOCOllkpm6p/2nMoQZtdGY\nmA0L68jRwBhPZ6XSu1OfRCArWDDoUPTWIU0Oc/ev5yxJY9gyhQWQ9ddfJqKKHN2d\nUapLgcyS0vJNbUC5M1Se9M24s7MpLekMeohM/ohbm+/rr6Dro3qlBaf5jaYRZv2l\n1ciKK+A8WxfFKNPdZiKwSB2nrj5pS9v/bdkenUJSZq+cvg7btropXOslniMGGKvG\nPt5BauBYgCVSmjN+ZPdHHDA4C50mLTrQs+EB9R9XLv1ro6r1VcRmaQS332KTN9h1\nXFSp4fn7p/xOw8gcTcg1DuhLTxP5UWYTK/N/CqtozgiKf8jpEb50CFzp6JjKdd3S\nCyzSGnyWfWu1OU8UzsN+1uQDdiqhtflFI73UZuRNmffdnNwCUHP/0ViDIvyT+Kr/\n9XDjIEGZi0biOlFeXg6mb08D/vYbPp7gMShhLyTIWvlXVfiaEWMNlrz2a0iXBZDF\nKM2UVAX1J/3kq7eS6KgteedwTJgeF/la+shXQKVicJPhQSSnJtf7GibV+IybjS6j\nGuzvbTPLY1VRwhcr01Y2MsGTS1kuKvuYkmfbK2V9/ot0ioNVppiS7ivb5DrNglCR\noL7mdWITTkfKnHOVczquU0CvMdHoOOjE2xEIrGB+kLZG96h0bsppc6Dg3cDSZXKF\nAgwDvZ9WSAhwutIBD/94d2rtBuXPAIyGHc1EYUBE1NpPdK7FoFJf3an1PuxO4nb8\nQrFc/6sFtUQCAwT/Sau9d7JRj8vO6819ygyRQt6e5zzvbd9xd/mAyFgkKCvWlWZG\nXQttvkiINVQEMrYvyxCJwyTBLvwpv9gZhhouMZ/6NUrmZYOVZ78Jo4oILfS1W/OK\nmUruUbUdE9hVuA/VKbJ0W9vkg5Tm/sOp0lW1iITUQ8SDrDaXkyG9ceALxnTd5xCN\nZxPWY8GNEMOQZgnUeeN8nOoCOih1LSHrFhwKGyrZQo+anGHHSuUxPNkiKIeDHUdc\nNzxcnTyPnKfTSDOf88gqyC4UC4fcrQUVHdF2qJlWkfpSle0FGT6s2stvuiVLV8Yl\nN/O3/aVe5oT+XwsK4m+PAk2QBGBN3ivqfE9M4U/3AY8PRUI60qyLi7DOg+cnIfyQ\nfu8gWc69di2PhJi4Xy4Q9+kMUi5pAufpZdDME6HYT5EPBaO3oTWeMIi8kMHrc9e1\nXCHjmYKD6h9zv9XBSpBLZf2DguHUlMlBmx4JSX4R4q/eO/SQE1NjTkygD8RwnzA/\nBs5ZZ3lR1E4qpHTaLEp1j2LTORXdk5AoMhXyMzbTEjceCCVQM5TVMG5CrnPBpF6T\nv3G3SNIytz5jaRkh9QQZje2dFtGk1f1lrR7/uvDzvKDY5fZMuXw5yfB18dIw8IUC\nDAM1GWv08EiACgEP/iNb902syK7YGSXlz8lzlQY/uuUgoNN+12+CAOMP94tmnOhA\ndIo02zsnQ7JdOsguqm/hzl0aXOHNYbk78uq/fljnl7Vgackc8KNKZ4tI0kvDwO1W\nj+bISGeRcEkgOw8w2XbQkBBOWtT0Tea6lo3RwsOUR9O4uWifI083TSUFLKIe+2L7\nvciXuWt9iGYISUnt7nOOLWT1otCrZj0CnCyGNN0QPuN0PnUdq3rTF7OAEQXPXbp7\nzGpszkhwOv1rZ//wNX3kxw3CBuu10Z6RK/zX1jQpvRxo+nU3ACNhxH92q5dhinvj\nbm3uZd6N9GN/bjdd2ZnWuwSeovZqb4i8Abfk5te6KKpIUEm8166Wux8oHvVBpJgZ\nrXvP0WcyQJtFbAuJDw9GW1KIvz3disFvfGK4A0oFFk5YXVJqmIeUEz7fgVAIH9Um\nFFtc8c+qW6lMEJYTqZlrt9EkoochwLeI6zSONkDpCcXif7C/s8F7vvzrS0BNyQ5G\nMQqNdf/b6I5Ue2X0K6suIx6c54ThmsgtkM+Zcg77C9xF97kRZffFnB+PIsxYUUhq\noZ/QspiiqWkFRDA+1+3fwRN4bv3biCWRlIUm4YPV7Kxzo/Ycem3XZUd86vQZvq18\nsD+XT4tueGTcoyFDXg5a/IVEJ10B5v2ipr4j76wFZ29QOeMr+QnOQinj+eAm1GgB\nCQIQHL1VhjubcxdoWwKW5JvAEAsKTGUeAamWcPPA0n4/msnaR6kcTDLF1QjN/8E3\nz7WdHVikJDk/Bdmzx7HdmoRSckeZf2bk6DKtfUYNB7CbUWppwLIdRCNKGYgTf8vi\nRZi1vIZRrA==\n=EbyO\n-----END PGP MESSAGE-----",
"fp": "0C982F87B7AFBA0F504F90A2629E741947C87928"
}
],
"unencrypted_suffix": "_unencrypted",
"version": "3.8.1"
}
}

View File

@ -0,0 +1,9 @@
age-encryption.org/v1
-> ssh-ed25519 HwR33w JKCBhuwIMcH042SNcp+OQjgvpMogmXH9who0wy9Jh2g
waaOvyKbg8AVEQ8BnLONus0y237GK8do0nOWovYv/Hg
-> ssh-ed25519 7zj2eQ cMRXtuy4Jsl4X/qstN3wxztrEfCh+lz48+jn9cEO614
/LcwitDqSk7yEFqUeJvpWo+6lqTI8UjuBi03JxRTx/A
-> .-grease sMU_}
NOvvGJmEfeBYR6Q
--- ju0+LEUzdv2AW1Zaf1/YBo5+5ZKc+XhYUOt/p/NqYWU
Ä"'oč©®9@1źF&Ż'VÇ︪whĆ$3kj®<E280BA>v¦őę&ŰOŔ$}śN€Wp[ôČeÚM ˙eĉĚCďE@ÖĚüÚSc1

View File

@ -74,6 +74,7 @@ in {
services.prometheus = { services.prometheus = {
enable = true; enable = true;
enableReload = true;
listenAddress = "[::1]"; listenAddress = "[::1]";
scrapeConfigs = let scrapeConfigs = let
relabelAddressToInstance = { relabelAddressToInstance = {

View File

@ -0,0 +1,13 @@
inputs:
with inputs.nixpkgs.lib;
rec {
monitoringIdForHost = host: let
evalResult = builtins.tryEval (attrByPath [ "clerie" "monitoring" "id" ] null host.config);
in
if evalResult.success then evalResult.value else null;
monitoringIdsByHost = hosts: filterAttrs (name: id: id != null) (mapAttrs (name: host: monitoringIdForHost host) hosts);
hostsByMonitoringIds = hosts: mapAttrs' (name: id: nameValuePair id name) (monitoringIdsByHost hosts);
monitoringIds = hosts: attrNames (hostsByMonitoringIds hosts);
}

View File

@ -14,6 +14,7 @@ let
generateColmenaHost generateColmenaHost
mapToColmenaHosts mapToColmenaHosts
buildHosts; buildHosts;
clerie-monitoring-ids = callLibs ./clerie-monitoring-ids.nix;
}; };
in in

View File

@ -1,4 +1,4 @@
{ self, nixpkgs, agenix, bij, chaosevents, fernglas, fieldpoc, nixos-exporter, solid-xmpp-alarm, ... }@inputs: { self, nixpkgs, agenix, bij, chaosevents, fernglas, fieldpoc, nixos-exporter, solid-xmpp-alarm, sops-nix, ... }@inputs:
rec { rec {
generateNixosSystem = { generateNixosSystem = {
@ -43,6 +43,7 @@ rec {
fieldpoc.nixosModules.default fieldpoc.nixosModules.default
nixos-exporter.nixosModules.default nixos-exporter.nixosModules.default
solid-xmpp-alarm.nixosModules.solid-xmpp-alarm solid-xmpp-alarm.nixosModules.solid-xmpp-alarm
sops-nix.nixosModules.sops
(../hosts + "/${name}/configuration.nix") (../hosts + "/${name}/configuration.nix")
# Automatically load secrets from the hosts secrets directory # Automatically load secrets from the hosts secrets directory
({ lib, ... }: let ({ lib, ... }: let
@ -52,6 +53,10 @@ rec {
file = secretsPath + "/${filename}"; file = secretsPath + "/${filename}";
}) (lib.filterAttrs (name: type: (type == "regular") && (lib.hasSuffix ".age" name) ) (if builtins.pathExists secretsPath then builtins.readDir secretsPath else {})); }) (lib.filterAttrs (name: type: (type == "regular") && (lib.hasSuffix ".age" name) ) (if builtins.pathExists secretsPath then builtins.readDir secretsPath else {}));
}) })
# Automatically load secrets from sops file for host
({ ... }: {
sops.defaultSopsFile = ../hosts + "/${name}/secrets.json";
})
]; ];
}; };

View File

@ -44,12 +44,10 @@ let
export RESTIC_PROGRESS_FPS=0.1 export RESTIC_PROGRESS_FPS=0.1
export RESTIC_CACHE_DIR=/var/cache/restic export RESTIC_CACHE_DIR=/var/cache/restic
restic snapshots || restic init restic snapshots --latest 1 || restic init
restic backup ${optionalString (jobOptions.exclude != []) "--exclude-file ${pkgs.writeText "clerie-backup-${jobName}-${targetName}-excludes" (concatStringsSep "\n" jobOptions.exclude)}"} ${escapeShellArgs jobOptions.paths} restic backup ${optionalString (jobOptions.exclude != []) "--exclude-file ${pkgs.writeText "clerie-backup-${jobName}-${targetName}-excludes" (concatStringsSep "\n" jobOptions.exclude)}"} ${escapeShellArgs jobOptions.paths}
restic check
${optionalString (config.clerie.monitoring.enable) '' ${optionalString (config.clerie.monitoring.enable) ''
echo "clerie_backup_last_successful_run_time{backup_job=\"${jobName}\", backup_target=\"${targetName}\"} $(date +%s)" > /var/lib/prometheus-node-exporter/textfiles/clerie-backup-${jobName}-${targetName}.prom echo "clerie_backup_last_successful_run_time{backup_job=\"${jobName}\", backup_target=\"${targetName}\"} $(date +%s)" > /var/lib/prometheus-node-exporter/textfiles/clerie-backup-${jobName}-${targetName}.prom
''} ''}

View File

@ -54,7 +54,9 @@ in
publicKey = "eyhJKV41E1F0gZHBNqyzUnj72xg5f3bdDduVtpPN4AY="; publicKey = "eyhJKV41E1F0gZHBNqyzUnj72xg5f3bdDduVtpPN4AY=";
} }
]; ];
privateKeyFile = if cfg.privateKeyFile == null then config.age.secrets.wg-monitoring.path else cfg.privateKeyFile; privateKeyFile = if cfg.privateKeyFile != null then cfg.privateKeyFile else
if builtins.elem "wg-monitoring" (attrNames config.sops.secrets) then config.sops.secrets.wg-monitoring.path else
config.age.secrets.wg-monitoring.path;
}; };
}; };

View File

@ -0,0 +1,37 @@
{ pkgs, lib, ... }:
with lib;
let
hosts = builtins.attrNames (builtins.readDir ../../hosts);
mkAgeKey = hostname: ssh_pub_file:
pkgs.runCommand "${hostname}.age" {
buildInputs = [ pkgs.ssh-to-age ];
} ''
ssh-to-age -i ${ssh_pub_file} -o $out
'';
ageKeysForHost = hostname: let
ssh_pub_file = ../../hosts + "/${hostname}/ssh.pub";
in
if builtins.pathExists ssh_pub_file then [
(fileContents (mkAgeKey hostname ssh_pub_file))
] else [];
mkCreationRules = hosts:
map (hostname: {
path_regex = escapeRegex "hosts/${hostname}/secrets.json";
key_groups = [{
pgp = [
(fileContents (pkgs.clerie-keys + "/gpg/clerie@clerie.de.fingerprint.txt"))
];
age = ageKeysForHost hostname;
}];
}) hosts;
sops_config = {
creation_rules = mkCreationRules hosts;
};
in
pkgs.writeText "sops.json" (builtins.toJSON sops_config)

View File

@ -0,0 +1,11 @@
{ pkgs, ... }:
pkgs.writeShellApplication {
name = "clerie-sops";
runtimeInputs = with pkgs; [
sops
];
text = ''
exec sops --config ${pkgs.clerie-sops-config} "$@"
'';
}

View File

@ -2,6 +2,8 @@ final: prev: {
clerie-keys = final.callPackage ./clerie-keys {}; clerie-keys = final.callPackage ./clerie-keys {};
clerie-system-upgrade = final.callPackage ./clerie-system-upgrade/clerie-system-upgrade.nix {}; clerie-system-upgrade = final.callPackage ./clerie-system-upgrade/clerie-system-upgrade.nix {};
clerie-merge-nixfiles-update = final.callPackage ./clerie-update-nixfiles/clerie-merge-nixfiles-update.nix {}; clerie-merge-nixfiles-update = final.callPackage ./clerie-update-nixfiles/clerie-merge-nixfiles-update.nix {};
clerie-sops = final.callPackage ./clerie-sops/clerie-sops.nix {};
clerie-sops-config = final.callPackage ./clerie-sops/clerie-sops-config.nix {};
clerie-update-nixfiles = final.callPackage ./clerie-update-nixfiles/clerie-update-nixfiles.nix {}; clerie-update-nixfiles = final.callPackage ./clerie-update-nixfiles/clerie-update-nixfiles.nix {};
chromium-incognito = final.callPackage ./chromium-incognito {}; chromium-incognito = final.callPackage ./chromium-incognito {};
iot-data = final.python3.pkgs.callPackage ./iot-data {}; iot-data = final.python3.pkgs.callPackage ./iot-data {};