From 8114ec012c69e7ac058cb0192607aa8f02f0cb12 Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Fri, 10 Jul 2026 17:14:15 -0400 Subject: [PATCH 01/10] Update inputs --- flake.lock | 170 +++++++++++++++++++++++++++++------------------------ 1 file changed, 94 insertions(+), 76 deletions(-) diff --git a/flake.lock b/flake.lock index 5aba3d3..ed87177 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ ] }, "locked": { - "lastModified": 1778054136, - "narHash": "sha256-cHQkWpJqeKdQjEtu9oazDhb6QbiVU4lKYNYSrkAINQg=", + "lastModified": 1782299217, + "narHash": "sha256-TqhsEw7SheE8QPpRUiCPA4UpL6qCgRstxkR6dIFD0zs=", "owner": "nialov", "repo": "actions.nix", - "rev": "91db1c323f9dd60920feb057274bf8fbffcbbe1b", + "rev": "25d2104c420cceacbf5b3935e2dd1dbfabe01d8c", "type": "github" }, "original": { @@ -34,11 +34,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1781150914, - "narHash": "sha256-I2cjqxsVyoqAKl1/egoIDV5h96ACOdf9RQZz+2dBvAk=", + "lastModified": 1783346450, + "narHash": "sha256-AyXLhsc2drC+lunm+TB6Xs6XMMJ/m4B1YjMM1N8JXhU=", "owner": "zhaofengli", "repo": "attic", - "rev": "295a33a1e4a5138868e6f45dc75ed68a05c0300f", + "rev": "7a19204df10d606c5070e6bb72615c3461900c05", "type": "github" }, "original": { @@ -85,11 +85,11 @@ "stable": "stable" }, "locked": { - "lastModified": 1762034856, - "narHash": "sha256-QVey3iP3UEoiFVXgypyjTvCrsIlA4ecx6Acaz5C8/PQ=", + "lastModified": 1783265280, + "narHash": "sha256-n+TVzNkFtsW+ghl7JeFJYwIbXaZ2tn/WgjVMXwlzybI=", "owner": "zhaofengli", "repo": "colmena", - "rev": "349b035a5027f23d88eeb3bc41085d7ee29f18ed", + "rev": "e4250e61da7e007e19e8e17d8675b88ad27d6c06", "type": "github" }, "original": { @@ -126,11 +126,11 @@ }, "crane": { "locked": { - "lastModified": 1751562746, - "narHash": "sha256-smpugNIkmDeicNz301Ll1bD7nFOty97T79m4GUMUczA=", + "lastModified": 1781825982, + "narHash": "sha256-SlXKwIRIhrOSAcTjCB3ftPLzJWZStQIPS7J1FlZPnKk=", "owner": "ipetkov", "repo": "crane", - "rev": "aed2020fd3dc26e1e857d4107a5a67a33ab6c1fd", + "rev": "469fd08d0bcf6926321fa973c6777fbc87785dd7", "type": "github" }, "original": { @@ -279,11 +279,11 @@ "flake-compat_2": { "flake": false, "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", "owner": "edolstra", "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", "type": "github" }, "original": { @@ -295,11 +295,11 @@ "flake-compat_3": { "flake": false, "locked": { - "lastModified": 1650374568, - "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", "owner": "edolstra", "repo": "flake-compat", - "rev": "b4a34015c698c7793d592d66adbab377907a2be8", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", "type": "github" }, "original": { @@ -348,11 +348,11 @@ ] }, "locked": { - "lastModified": 1768135262, - "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", + "lastModified": 1778716662, + "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", + "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", "type": "github" }, "original": { @@ -369,11 +369,11 @@ ] }, "locked": { - "lastModified": 1751413152, - "narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=", + "lastModified": 1778716662, + "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "77826244401ea9de6e3bac47c2db46005e1f30b5", + "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", "type": "github" }, "original": { @@ -451,11 +451,11 @@ "nixpkgs-lib": "nixpkgs-lib_2" }, "locked": { - "lastModified": 1778716662, - "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", + "lastModified": 1782949081, + "narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", + "rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e", "type": "github" }, "original": { @@ -513,12 +513,15 @@ } }, "flake-utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1659877975, - "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -627,11 +630,11 @@ ] }, "locked": { - "lastModified": 1769069492, - "narHash": "sha256-Efs3VUPelRduf3PpfPP2ovEB4CXT7vHf8W+xc49RL/U=", + "lastModified": 1781733627, + "narHash": "sha256-U3yTuGBnmXvXoQI3qkpfEDsn9RovQPAjN7ndRco+3u0=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "a1ef738813b15cf8ec759bdff5761b027e3e1d23", + "rev": "3bbec39bc90eadfa031e6f3b77272f3f60803e39", "type": "github" }, "original": { @@ -691,11 +694,11 @@ ] }, "locked": { - "lastModified": 1781052891, - "narHash": "sha256-MGVuJUHO+eMf5vYuEuCRc+CUKObOudO2ptvw690P9Hk=", + "lastModified": 1783288480, + "narHash": "sha256-H/blql4kDC0HY3ephQO86deTaLt2UfFvhYzZsHTz6pk=", "owner": "nix-community", "repo": "haumea", - "rev": "7f2452e720b07570cebda6c17c0357e9b5429012", + "rev": "3bc16acb4e17a32fcc04045ff2a4ac56a8cefcf6", "type": "github" }, "original": { @@ -733,11 +736,11 @@ ] }, "locked": { - "lastModified": 1729742964, - "narHash": "sha256-B4mzTcQ0FZHdpeWcpDYPERtyjJd/NIuaQ9+BV1h+MpA=", + "lastModified": 1737420293, + "narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=", "owner": "nix-community", "repo": "nix-github-actions", - "rev": "e04df33f62cdcf93d73e9a04142464753a16db67", + "rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9", "type": "github" }, "original": { @@ -823,11 +826,11 @@ ] }, "locked": { - "lastModified": 1779799925, - "narHash": "sha256-kMBQRZjb2A+qVpuNCiRoqMhDElkP/jR2m9Lu7PAt7M4=", + "lastModified": 1781506385, + "narHash": "sha256-kvTBHLiqB911yf2D9VThIRfB6Ai/E2H9+mVF0wR+9AY=", "owner": "numtide", "repo": "nix-vm-test", - "rev": "d41d806a5c9699ab9cbac5a698aac889c83fa57e", + "rev": "2071ebc1f5b2a2e0211a2ca38c4e678092df76a5", "type": "github" }, "original": { @@ -1027,11 +1030,11 @@ "treefmt-nix": "treefmt-nix_2" }, "locked": { - "lastModified": 1781076331, - "narHash": "sha256-c1Uh6wQV3gglqm/Ybg7F4zqZwhMIQQ+7Kr933e1kJuQ=", + "lastModified": 1782890500, + "narHash": "sha256-UwamW3kYf/7vSsYq2VRb3VBq8A1hvOiLzXVnJeKVS38=", "owner": "numtide", "repo": "nixos-anywhere", - "rev": "e260e08bf1af4f91b4ae0cf9aef476add785d879", + "rev": "4dfb813db065afb0aba1f61658ef77993d382db1", "type": "github" }, "original": { @@ -1083,11 +1086,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1781168557, - "narHash": "sha256-LOnLQ2tpYF9gqIDDr3+j3DbpJJr/QCH6zPRT2GzEUOE=", + "lastModified": 1783692676, + "narHash": "sha256-6FXlRphexzMo3HpoN0NxEl7uQoE8llWeNJrD8NMA/CY=", "owner": "nixos", "repo": "nixos-hardware", - "rev": "6358ff76821101c178e3ab4919a62799bfe3652e", + "rev": "4471c6a218fe813ad4838c400866c8845d3eba6b", "type": "github" }, "original": { @@ -1137,11 +1140,11 @@ ] }, "locked": { - "lastModified": 1780569049, - "narHash": "sha256-MQhLlgMaWeCh+qerB6+E4MJ5unyN1rfAwRyCdiO22Dk=", + "lastModified": 1782383811, + "narHash": "sha256-UFSWbDEltShkthOfvlAyxDq4L7dLHcsuJzHbgu79lHM=", "owner": "nix-community", "repo": "nixos-images", - "rev": "ff529ab18aa403fa83c47cb2bc2246b789d1c803", + "rev": "45c188c452d274e003c9acc6b43fab911fa6cfa5", "type": "github" }, "original": { @@ -1168,11 +1171,11 @@ }, "nixos-stable_2": { "locked": { - "lastModified": 1780902259, - "narHash": "sha256-q8yYEC5f1mFlQO9RGna4LTc9QrcvWunX6FYp83munkQ=", + "lastModified": 1782691344, + "narHash": "sha256-i5nw9BYYsMDAaOC4J+JmTof6b2GhlyH076awYRNrTV8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bd0ff2d3eac24699c3664d5966b9ef36f388e2ca", + "rev": "1f01958ffb5b3545c96d9ef2f4e24c5e5e1eb846", "type": "github" }, "original": { @@ -1215,11 +1218,11 @@ }, "nixpkgs-lib_2": { "locked": { - "lastModified": 1777168982, - "narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=", + "lastModified": 1782614948, + "narHash": "sha256-ePjCwr1sNm9NYUqywL7QfK3JnlS015msC+eBu2zKlp8=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14", + "rev": "db3f255737b94216eb71cce308e2912cf6bc2d7c", "type": "github" }, "original": { @@ -1260,11 +1263,11 @@ }, "nixpkgs-master_2": { "locked": { - "lastModified": 1781292705, - "narHash": "sha256-4QSn+LMkRqaQ7yOtH5hhH/07kU6sFKXAzu1+7nNe2WE=", + "lastModified": 1783716565, + "narHash": "sha256-mTNJGKx0g51qonmkitrfAfC05427WHk3LLgnTnx/dQg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f2aef91bc12cdbee849eb841043117b6f3948903", + "rev": "ca0dda25a583b465f5c19cb214e155c97a7c11c0", "type": "github" }, "original": { @@ -1275,11 +1278,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1780902259, - "narHash": "sha256-q8yYEC5f1mFlQO9RGna4LTc9QrcvWunX6FYp83munkQ=", + "lastModified": 1782116945, + "narHash": "sha256-G3tw/IXmaH6IQ2upZvhuN9sG8CkuX+BLuJDpE8hz0Ds=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bd0ff2d3eac24699c3664d5966b9ef36f388e2ca", + "rev": "34268251cf5547d39063f2c5ea9a196246f7f3a6", "type": "github" }, "original": { @@ -1320,11 +1323,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1781074563, - "narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=", + "lastModified": 1783522502, + "narHash": "sha256-iffAls3iaNTyJC2faYcUXSI+Gp02cDjYl+MygxKl2GI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca", + "rev": "0bb7ec54c8483066ec9d7720e780a5caa71f8612", "type": "github" }, "original": { @@ -1343,11 +1346,11 @@ "treefmt": "treefmt_2" }, "locked": { - "lastModified": 1782167286, - "narHash": "sha256-OjtHkfljYzAxV/gqWnLSI0vriUfvZj4/6WHMelUcDKw=", + "lastModified": 1782171250, + "narHash": "sha256-hP7dipoqpP0dQeS0Z0CcMkp0+n++29qqscqCe1htvbE=", "owner": "ethnt", "repo": "plex_exporter", - "rev": "e33d47462d3eaac8b1aaedd660437823ccde55b8", + "rev": "60b2366b47631afbd6f5065e3b8211cb7f33d377", "type": "github" }, "original": { @@ -1404,11 +1407,11 @@ ] }, "locked": { - "lastModified": 1780547341, - "narHash": "sha256-Gq8KNx5A7hBB3uGJaj6eQfLDIz5YdLu92gqBcvHvoUo=", + "lastModified": 1783174389, + "narHash": "sha256-aCWC8ngycU7OdJrU2+Je3qf+1a2ykuBvpPhZT/9tXMc=", "owner": "Mic92", "repo": "sops-nix", - "rev": "9ed65852b6257fbeae4355bc24ecfea307ca759a", + "rev": "f1406619a3884cd5c47992a70b8b35c9c0fcb4c9", "type": "github" }, "original": { @@ -1419,16 +1422,16 @@ }, "stable": { "locked": { - "lastModified": 1750133334, - "narHash": "sha256-urV51uWH7fVnhIvsZIELIYalMYsyr2FCalvlRTzqWRw=", + "lastModified": 1783021296, + "narHash": "sha256-WYOmcI0zSkkU4VpR7xda8o0AWNC9xuqkEM7n4tKjJY8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "36ab78dab7da2e4e27911007033713bab534187b", + "rev": "d3474199ff806484bfccd1fdef7afc27fb8d74b5", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-25.05", + "ref": "release-26.05", "repo": "nixpkgs", "type": "github" } @@ -1449,6 +1452,21 @@ "type": "github" } }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "treefmt": { "inputs": { "nixpkgs": [ From 0d4a0930bb5edbc9295e67fd0a6b34b01edfbb6c Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Fri, 10 Jul 2026 17:14:22 -0400 Subject: [PATCH 02/10] Format code with `nixfmt` --- flake.nix | 15 +- hosts/bastion/configuration.nix | 21 +- hosts/bastion/profiles/authelia/default.nix | 169 ++-- hosts/bastion/profiles/caddy/default.nix | 12 +- hosts/builder/configuration.nix | 47 +- hosts/builder/disk-config.nix | 8 +- hosts/builder/hardware-configuration.nix | 10 +- hosts/controller/configuration.nix | 44 +- hosts/controller/disk-config.nix | 8 +- hosts/controller/hardware-configuration.nix | 10 +- hosts/default.nix | 56 +- hosts/dill/configuration.nix | 84 +- hosts/dill/disk-config.nix | 8 +- hosts/dill/hardware-configuration.nix | 11 +- hosts/fennel/configuration.nix | 16 +- hosts/htpc/configuration.nix | 53 +- hosts/htpc/disk-config.nix | 8 +- hosts/matrix/configuration.nix | 55 +- hosts/matrix/disk-config.nix | 8 +- hosts/matrix/hardware-configuration.nix | 10 +- hosts/monitor/configuration.nix | 11 +- hosts/monitor/profiles/authelia/default.nix | 131 +-- hosts/monitor/profiles/grafana/default.nix | 785 ++++++++++-------- hosts/monitor/profiles/prometheus.nix | 423 +++++----- hosts/omnibus/configuration.nix | 90 +- hosts/omnibus/disk-config.nix | 147 ++-- hosts/omnibus/hardware-configuration.nix | 11 +- lib/default.nix | 5 +- lib/src/generators.nix | 124 +-- lib/src/utils.nix | 32 +- modules/deploy/ansible.nix | 31 +- modules/deploy/configuration.nix | 33 +- modules/deploy/shell.nix | 57 +- modules/deploy/terraform.nix | 6 +- modules/development/ci.nix | 313 +++---- modules/development/flake-root.nix | 19 +- modules/development/shell.nix | 49 +- modules/development/treefmt.nix | 21 +- modules/nixos/deployment/options.nix | 4 +- .../services/attic-watch-store/default.nix | 16 +- modules/nixos/services/bichon/default.nix | 10 +- modules/nixos/services/caddy/default.nix | 120 +-- modules/nixos/services/declutarr/default.nix | 27 +- modules/nixos/services/fileflows/node.nix | 29 +- modules/nixos/services/fileflows/server.nix | 34 +- modules/nixos/services/incus/default.nix | 221 ++--- modules/nixos/services/mazanoke/default.nix | 21 +- modules/nixos/services/postgresql/default.nix | 21 +- modules/nixos/services/profilarr/default.nix | 83 +- .../default.nix | 14 +- .../default.nix | 20 +- modules/nixos/services/restic/default.nix | 81 +- modules/nixos/services/termix/default.nix | 9 +- modules/nixos/services/thanos/default.nix | 34 +- modules/nixos/services/tracearr/default.nix | 86 +- .../services/unifi-os-server/default.nix | 103 +-- modules/nixos/services/wizarr/default.nix | 13 +- modules/overlays/default.nix | 57 +- modules/packages/bichon/default.nix | 140 ++-- modules/packages/declutarr/default.nix | 10 +- modules/packages/fileflows/default.nix | 17 +- modules/packages/profilarr-parser/default.nix | 7 +- modules/packages/profilarr/default.nix | 68 +- modules/packages/tracearr/default.nix | 24 +- .../unifi-os-server-image/default.nix | 27 +- modules/profiles/backups/restic/common.nix | 15 +- modules/profiles/backups/restic/system.nix | 93 ++- .../communications/mosquitto/default.nix | 40 +- .../communications/postfix/default.nix | 3 +- modules/profiles/core/caching.nix | 5 +- modules/profiles/core/nix-config.nix | 31 +- modules/profiles/databases/postgresql.nix | 8 +- modules/profiles/default.nix | 3 +- modules/profiles/filesystems/blockbuster.nix | 8 +- modules/profiles/filesystems/files/backup.nix | 29 +- .../profiles/filesystems/files/personal.nix | 29 +- .../profiles/filesystems/files/services.nix | 29 +- modules/profiles/filesystems/zfs.nix | 3 +- modules/profiles/hardware/intel-graphics.nix | 10 +- modules/profiles/hardware/nvme.nix | 7 +- modules/profiles/hardware/rpi4.nix | 5 +- .../home-automation/frigate/default.nix | 31 +- .../components/ha_nationalgrid.nix | 13 +- .../home-assistant/default.nix | 50 +- .../home-assistant/packages/aionatgrid.nix | 16 +- .../home-assistant/postgresql.nix | 17 +- modules/profiles/hypervisors/incus.nix | 46 +- .../media-management/bazarr/default.nix | 33 +- .../media-management/declutarr/default.nix | 30 +- .../media-management/fileflows/node.nix | 4 +- .../media-management/immich/default.nix | 13 +- .../media-management/profilarr/default.nix | 3 +- .../media-management/prowlarr/default.nix | 8 +- .../media-management/radarr/default.nix | 53 +- .../media-management/radarr/postgresql.nix | 43 +- .../media-management/sabnzbd/default.nix | 15 +- .../media-management/sonarr/default.nix | 55 +- .../media-management/sonarr/postgresql.nix | 43 +- modules/profiles/monitoring/loki/default.nix | 33 +- .../profiles/monitoring/thanos/default.nix | 25 +- .../profiles/networking/blocky/default.nix | 56 +- modules/profiles/networking/blocky/redis.nix | 8 +- modules/profiles/networking/mosh.nix | 10 +- modules/profiles/networking/printing.nix | 24 +- modules/profiles/networking/quad9.nix | 8 +- .../networking/speedtest-tracker/default.nix | 10 +- .../profiles/networking/tailscale/default.nix | 11 +- modules/profiles/networking/unifi.nix | 3 +- .../nix/remote-builders/e10-builder.nix | 33 +- .../profiles/observability/gatus/default.nix | 764 +++++++++-------- .../observability/gatus/postgresql.nix | 10 +- modules/profiles/power/common.nix | 15 +- .../profiles/security/authelia/default.nix | 71 +- .../profiles/security/authelia/postgresql.nix | 14 +- modules/profiles/security/authelia/redis.nix | 22 +- modules/profiles/security/lldap/default.nix | 4 +- .../profiles/security/lldap/postgresql.nix | 10 +- modules/profiles/services/atticd/default.nix | 6 +- modules/profiles/services/bentopdf.nix | 10 +- .../services/cachix-watch-store/default.nix | 4 +- modules/profiles/services/glance/default.nix | 465 ++++++----- .../profiles/services/karakeep/default.nix | 6 +- .../profiles/services/miniflux/default.nix | 8 +- modules/profiles/services/netbox/default.nix | 19 +- .../profiles/services/paperless/default.nix | 5 +- .../services/paperless/postgresql.nix | 32 +- modules/profiles/services/paperless/redis.nix | 26 +- modules/profiles/sharing/nfs-server.nix | 28 +- modules/profiles/sharing/samba.nix | 13 +- .../prometheus-plex-exporter/default.nix | 11 +- .../prometheus-unpoller-exporter/common.nix | 5 +- .../prometheus-unpoller-exporter/satan.nix | 22 +- modules/profiles/telemetry/vector/common.nix | 5 +- modules/profiles/users/ethan.nix | 3 +- modules/profiles/users/nicole.nix | 3 +- modules/profiles/users/proxmox.nix | 3 +- modules/profiles/users/root.nix | 3 +- modules/profiles/virtualisation/docker.nix | 19 +- modules/profiles/web-servers/caddy.nix | 11 +- modules/suites.nix | 5 +- 140 files changed, 3944 insertions(+), 2927 deletions(-) diff --git a/flake.nix b/flake.nix index ed80fab..839c107 100644 --- a/flake.nix +++ b/flake.nix @@ -60,7 +60,8 @@ plex-exporter.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = inputs@{ self, flake-parts, ... }: + outputs = + inputs@{ self, flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } { imports = [ ./lib @@ -83,7 +84,11 @@ ./hosts ]; - systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ]; + systems = [ + "x86_64-linux" + "aarch64-linux" + "aarch64-darwin" + ]; perSystem = { system, ... }: { _module.args.pkgs = import inputs.nixpkgs { @@ -92,8 +97,10 @@ # TODO: Make this on a per-system basis, and maybe per-package config = { allowUnfree = true; - permittedInsecurePackages = - [ "dotnet-sdk-6.0.428" "aspnetcore-runtime-6.0.36" ]; + permittedInsecurePackages = [ + "dotnet-sdk-6.0.428" + "aspnetcore-runtime-6.0.36" + ]; }; overlays = [ diff --git a/hosts/bastion/configuration.nix b/hosts/bastion/configuration.nix index b063db4..718ad4f 100644 --- a/hosts/bastion/configuration.nix +++ b/hosts/bastion/configuration.nix @@ -1,7 +1,20 @@ -{ suites, profiles, secrets, ... }: { - imports = with suites; - core ++ aws ++ web ++ (with profiles; [ security.lldap.default ]) - ++ [ ./profiles/authelia ./profiles/caddy ] +{ + suites, + profiles, + secrets, + ... +}: +{ + imports = + with suites; + core + ++ aws + ++ web + ++ (with profiles; [ security.lldap.default ]) + ++ [ + ./profiles/authelia + ./profiles/caddy + ] ++ [ secrets.hosts.bastion.configuration ]; deployment.tags = [ "@external" ]; diff --git a/hosts/bastion/profiles/authelia/default.nix b/hosts/bastion/profiles/authelia/default.nix index 03a8688..a7c979e 100644 --- a/hosts/bastion/profiles/authelia/default.nix +++ b/hosts/bastion/profiles/authelia/default.nix @@ -1,35 +1,38 @@ -{ config, lib, profiles, ... }: { +{ + config, + lib, + profiles, + ... +}: +{ imports = [ profiles.security.authelia.default ]; - sops.secrets = let - secretConfig = { - sopsFile = ./secrets.yml; - format = "yaml"; - owner = - config.services.authelia.instances.${config.networking.hostName}.user; + sops.secrets = + let + secretConfig = { + sopsFile = ./secrets.yml; + format = "yaml"; + owner = config.services.authelia.instances.${config.networking.hostName}.user; + }; + in + { + bastion_authelia_ldap_password = secretConfig; + bastion_authelia_jwt_secret = secretConfig; + bastion_authelia_storage_encryption_key = secretConfig; + bastion_authelia_session_secret = secretConfig; + bastion_authelia_oidc_hmac_secret = secretConfig; + bastion_authelia_issuer_private_key = secretConfig; }; - in { - bastion_authelia_ldap_password = secretConfig; - bastion_authelia_jwt_secret = secretConfig; - bastion_authelia_storage_encryption_key = secretConfig; - bastion_authelia_session_secret = secretConfig; - bastion_authelia_oidc_hmac_secret = secretConfig; - bastion_authelia_issuer_private_key = secretConfig; - }; services.authelia.instances.${config.networking.hostName} = { secrets = { jwtSecretFile = config.sops.secrets.bastion_authelia_jwt_secret.path; - storageEncryptionKeyFile = - config.sops.secrets.bastion_authelia_storage_encryption_key.path; - sessionSecretFile = - config.sops.secrets.bastion_authelia_session_secret.path; + storageEncryptionKeyFile = config.sops.secrets.bastion_authelia_storage_encryption_key.path; + sessionSecretFile = config.sops.secrets.bastion_authelia_session_secret.path; # NOTE: These need to be commented out if there are no OIDC clients present, otherwise Authelia will fail to start - oidcHmacSecretFile = - config.sops.secrets.bastion_authelia_oidc_hmac_secret.path; - oidcIssuerPrivateKeyFile = - config.sops.secrets.bastion_authelia_issuer_private_key.path; + oidcHmacSecretFile = config.sops.secrets.bastion_authelia_oidc_hmac_secret.path; + oidcIssuerPrivateKeyFile = config.sops.secrets.bastion_authelia_issuer_private_key.path; }; environmentVariables.AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE = @@ -37,9 +40,7 @@ settings = { authentication_backend.ldap = { - address = "ldap://localhost:${ - toString config.services.lldap.settings.ldap_port - }"; + address = "ldap://localhost:${toString config.services.lldap.settings.ldap_port}"; base_dn = "dc=e10,dc=camp"; users_filter = "(&({username_attribute}={input})(objectClass=person))"; groups_filter = "(member={dn})"; @@ -49,17 +50,19 @@ identity_providers.oidc = { claims_policies = { karakeep.id_token = [ "email" ]; - legacy.id_token = - [ "email" "email_verified" "preferred_username" "name" ]; + legacy.id_token = [ + "email" + "email_verified" + "preferred_username" + "name" + ]; }; clients = [ { client_name = "Paperless"; - client_id = - "viHFkj_wnehAVrf2U-2cE1~RDKGEO2iawDGTJuOSLKiEt_vKBiADlhSLyjI1LsA8T6DO0Vy8"; - client_secret = - "$pbkdf2-sha512$310000$qb7YshuNG.nvIev7OWvSyg$/nWmyxm0xxZG1mbCczkI9.Oi6lbrXd.BbsNXJU91p5nSYJGHTuN2OryQksEMK9ypCst.UYn6.q7HK/2YBstE.A"; + client_id = "viHFkj_wnehAVrf2U-2cE1~RDKGEO2iawDGTJuOSLKiEt_vKBiADlhSLyjI1LsA8T6DO0Vy8"; + client_secret = "$pbkdf2-sha512$310000$qb7YshuNG.nvIev7OWvSyg$/nWmyxm0xxZG1mbCczkI9.Oi6lbrXd.BbsNXJU91p5nSYJGHTuN2OryQksEMK9ypCst.UYn6.q7HK/2YBstE.A"; public = false; authorization_policy = "two_factor"; require_pkce = true; @@ -67,7 +70,12 @@ redirect_uris = [ "https://paperless.e10.camp/accounts/oidc/authelia/login/callback/" ]; - scopes = [ "openid" "profile" "email" "groups" ]; + scopes = [ + "openid" + "profile" + "email" + "groups" + ]; response_types = [ "code" ]; grant_types = [ "authorization_code" ]; access_token_signed_response_alg = "none"; @@ -75,11 +83,9 @@ token_endpoint_auth_method = "client_secret_basic"; } { - client_id = - "DpimJHTYr-K1ba5dFHj6mlRPXxkQCTN3E3RGljCmVXlGs.AcDdWwG9sysfV~Bv3vq7Z1rEEm"; + client_id = "DpimJHTYr-K1ba5dFHj6mlRPXxkQCTN3E3RGljCmVXlGs.AcDdWwG9sysfV~Bv3vq7Z1rEEm"; client_name = "Immich"; - client_secret = - "$pbkdf2-sha512$310000$Fu.EoQ7p6UrQw9Z9mtY6sQ$YTh3csT6xxlXE1YotyWX2HNI0H6wRgq3x0jnkHWu93UYtHUlCRfkeBVKcbplx0sPCwBVVYeyA4gLeByyaL.iZg"; + client_secret = "$pbkdf2-sha512$310000$Fu.EoQ7p6UrQw9Z9mtY6sQ$YTh3csT6xxlXE1YotyWX2HNI0H6wRgq3x0jnkHWu93UYtHUlCRfkeBVKcbplx0sPCwBVVYeyA4gLeByyaL.iZg"; public = false; authorization_policy = "two_factor"; require_pkce = false; @@ -89,7 +95,11 @@ "https://immich.e10.camp/user-settings" "app.immich:///oauth-callback" ]; - scopes = [ "openid" "profile" "email" ]; + scopes = [ + "openid" + "profile" + "email" + ]; response_types = [ "code" ]; grant_types = [ "authorization_code" ]; access_token_signed_response_alg = "none"; @@ -97,17 +107,19 @@ token_endpoint_auth_method = "client_secret_post"; } { - client_id = - "gY0aO8QGJT.~UbRntqa72YTm54DSUHr3HeBu4zMBlWwMwlJwLtbhXflUCAczeC-snr9I_5tZ"; + client_id = "gY0aO8QGJT.~UbRntqa72YTm54DSUHr3HeBu4zMBlWwMwlJwLtbhXflUCAczeC-snr9I_5tZ"; client_name = "Netbox"; - client_secret = - "$pbkdf2-sha512$310000$Hn6tjZ1j.w4M3MK7H5rrDQ$cP1amA8.XD5kvnbgS8VOa8bcHaucuYuiS/ohdpt5gyAIHA7rN9expBt2377rkwd7qAUHO0F8YMjVPx0ihHBLKQ"; + client_secret = "$pbkdf2-sha512$310000$Hn6tjZ1j.w4M3MK7H5rrDQ$cP1amA8.XD5kvnbgS8VOa8bcHaucuYuiS/ohdpt5gyAIHA7rN9expBt2377rkwd7qAUHO0F8YMjVPx0ihHBLKQ"; public = false; authorization_policy = "two_factor"; require_pkce = false; pkce_challenge_method = ""; redirect_uris = [ "https://netbox.e10.camp/oauth/complete/oidc/" ]; - scopes = [ "openid" "profile" "email" ]; + scopes = [ + "openid" + "profile" + "email" + ]; response_types = [ "code" ]; grant_types = [ "authorization_code" ]; access_token_signed_response_alg = "none"; @@ -115,34 +127,37 @@ token_endpoint_auth_method = "client_secret_basic"; } { - client_id = - "BhZjM_kfrPU38DOigEa9HToE2XTdYsmSMOxUBmUOgxLkZr4xMB45u2E8QoJYlqe3hwJMReZy"; + client_id = "BhZjM_kfrPU38DOigEa9HToE2XTdYsmSMOxUBmUOgxLkZr4xMB45u2E8QoJYlqe3hwJMReZy"; client_name = "Termix"; - client_secret = - "$pbkdf2-sha512$310000$sH.OLrn2ClPUYSaNhDQgog$IZOLyiRi4qmukot3qQWwZF39z6UnuzZrJWxC6sEjslM3T8ZuRUOBfHN6y7lUuyvZB8FO2MnxG1rrHBx3wwMi/w"; + client_secret = "$pbkdf2-sha512$310000$sH.OLrn2ClPUYSaNhDQgog$IZOLyiRi4qmukot3qQWwZF39z6UnuzZrJWxC6sEjslM3T8ZuRUOBfHN6y7lUuyvZB8FO2MnxG1rrHBx3wwMi/w"; public = false; authorization_policy = "two_factor"; consent_mode = "implicit"; claims_policy = "legacy"; grant_types = [ "authorization_code" ]; response_types = [ "code" ]; - scopes = [ "openid" "profile" "email" ]; + scopes = [ + "openid" + "profile" + "email" + ]; redirect_uris = [ "https://termix.e10.camp/users/oidc/callback" ]; token_endpoint_auth_method = "client_secret_post"; } { - client_id = - "4_PUhlKbm03-XaIAR-tBOzaCkf6dQfhgBY-xnrewL5jsOCp0UXPsbSvnaxgLXEp6kKsqjqND"; + client_id = "4_PUhlKbm03-XaIAR-tBOzaCkf6dQfhgBY-xnrewL5jsOCp0UXPsbSvnaxgLXEp6kKsqjqND"; client_name = "Karakeep"; - client_secret = - "$pbkdf2-sha512$310000$XuC9/i/.AWXy/G4A/aOazw$ZozktGPjpHfhmjEzdhNsjeLMw/XhbRK/ePqRPfzbTA04pEOlFTOon2s.yWYyuQv5wzCp0QUGHz2gkczfZsetyQ"; + client_secret = "$pbkdf2-sha512$310000$XuC9/i/.AWXy/G4A/aOazw$ZozktGPjpHfhmjEzdhNsjeLMw/XhbRK/ePqRPfzbTA04pEOlFTOon2s.yWYyuQv5wzCp0QUGHz2gkczfZsetyQ"; public = false; authorization_policy = "two_factor"; require_pkce = false; pkce_challenge_method = ""; - redirect_uris = - "https://karakeep.e10.camp/api/auth/callback/custom"; - scopes = [ "openid" "profile" "email" ]; + redirect_uris = "https://karakeep.e10.camp/api/auth/callback/custom"; + scopes = [ + "openid" + "profile" + "email" + ]; response_types = [ "code" ]; grant_types = [ "authorization_code" ]; access_token_signed_response_alg = "none"; @@ -151,17 +166,19 @@ claims_policy = "karakeep"; } { - client_id = - "a8Jy2n_CgUOu~nTlLlkgZQV7xJmhq5aW1N0eNePghiFL0Su5jysCJKOpaEpjvRd7yhhz589E"; + client_id = "a8Jy2n_CgUOu~nTlLlkgZQV7xJmhq5aW1N0eNePghiFL0Su5jysCJKOpaEpjvRd7yhhz589E"; client_name = "Profilarr"; - client_secret = - "$pbkdf2-sha512$310000$BY/Aff8ySoJwVwoW5D7rrQ$7NFYYLhlaRyMLQzcheulIVtQtC5YP6rbW7mbMOSsGWBaPs.It/O8lBgKQ3uhlP7wkC0fgjBBqHvk8PEXZ1oTLA"; + client_secret = "$pbkdf2-sha512$310000$BY/Aff8ySoJwVwoW5D7rrQ$7NFYYLhlaRyMLQzcheulIVtQtC5YP6rbW7mbMOSsGWBaPs.It/O8lBgKQ3uhlP7wkC0fgjBBqHvk8PEXZ1oTLA"; public = false; authorization_policy = "two_factor"; require_pkce = false; pkce_challenge_method = ""; redirect_uris = "https://profilarr.e10.camp/auth/oidc/callback"; - scopes = [ "openid" "profile" "email" ]; + scopes = [ + "openid" + "profile" + "email" + ]; response_types = [ "code" ]; grant_types = [ "authorization_code" ]; access_token_signed_response_alg = "none"; @@ -169,8 +186,7 @@ token_endpoint_auth_method = "client_secret_post"; } { - client_id = - "NE-kA1k.XTEv8Qe6oywlhfJHJVmLHg0474m3zD2nMjTm.ddl9rnK.Toq1WwetMP-BjYq4K0X"; + client_id = "NE-kA1k.XTEv8Qe6oywlhfJHJVmLHg0474m3zD2nMjTm.ddl9rnK.Toq1WwetMP-BjYq4K0X"; client_name = "Incus (Dill)"; public = true; authorization_policy = "two_factor"; @@ -178,9 +194,17 @@ pkce_challenge_method = ""; redirect_uris = [ "https://incus.dill.e10.camp/oidc/callback" ]; audience = [ "https://incus.dill.e10.camp" ]; - scopes = [ "openid" "profile" "email" "offline_access" ]; + scopes = [ + "openid" + "profile" + "email" + "offline_access" + ]; response_types = [ "code" ]; - grant_types = [ "authorization_code" "refresh_token" ]; + grant_types = [ + "authorization_code" + "refresh_token" + ]; access_token_signed_response_alg = "RS256"; userinfo_signed_response_alg = "none"; token_endpoint_auth_method = "none"; @@ -188,11 +212,13 @@ ]; }; - session.cookies = [{ - domain = "e10.camp"; - authelia_url = "https://auth.e10.camp"; - expiration = "1y"; - }]; + session.cookies = [ + { + domain = "e10.camp"; + authelia_url = "https://auth.e10.camp"; + expiration = "1y"; + } + ]; access_control.rules = lib.mkBefore [ { @@ -208,7 +234,10 @@ { domain = "fileflows.e10.camp"; policy = "bypass"; - resources = [ "^/manifest.json" "^/api([/?].*)?$" ]; + resources = [ + "^/manifest.json" + "^/api([/?].*)?$" + ]; } { domain = "fileflows.e10.camp"; diff --git a/hosts/bastion/profiles/caddy/default.nix b/hosts/bastion/profiles/caddy/default.nix index d8e0db5..4f5c84d 100644 --- a/hosts/bastion/profiles/caddy/default.nix +++ b/hosts/bastion/profiles/caddy/default.nix @@ -125,22 +125,19 @@ "requests.e10.video" = { host = hosts.htpc; inherit (hosts.htpc.config.services.seerr) port; - acme.environmentFile = - config.sops.secrets.e10_video_lego_route53_credentials.path; + acme.environmentFile = config.sops.secrets.e10_video_lego_route53_credentials.path; }; "join.e10.video" = { host = hosts.htpc; inherit (hosts.htpc.config.services.wizarr) port; - acme.environmentFile = - config.sops.secrets.e10_video_lego_route53_credentials.path; + acme.environmentFile = config.sops.secrets.e10_video_lego_route53_credentials.path; }; "tautulli.e10.camp" = { host = hosts.htpc; inherit (hosts.htpc.config.services.tautulli) port; - acme.environmentFile = - config.sops.secrets.e10_video_lego_route53_credentials.path; + acme.environmentFile = config.sops.secrets.e10_video_lego_route53_credentials.path; }; "cache.builder.e10.camp" = { @@ -290,8 +287,7 @@ "hass.e10.camp" = { host = hosts.controller; - port = - hosts.controller.config.services.home-assistant.config.http.server_port; + port = hosts.controller.config.services.home-assistant.config.http.server_port; }; "frigate.e10.camp" = { diff --git a/hosts/builder/configuration.nix b/hosts/builder/configuration.nix index f925a58..0c6a954 100644 --- a/hosts/builder/configuration.nix +++ b/hosts/builder/configuration.nix @@ -1,21 +1,30 @@ { suites, profiles, ... }: { - imports = with suites; - core ++ proxmox-vm ++ [ + imports = + with suites; + core + ++ proxmox-vm + ++ [ profiles.emulation.aarch64-linux profiles.remote-builder.builder profiles.remote-builder.substituter profiles.services.attic-watch-store.default profiles.services.cachix-watch-store.default - ] ++ [ ./hardware-configuration.nix ./disk-config.nix ]; + ] + ++ [ + ./hardware-configuration.nix + ./disk-config.nix + ]; - boot.loader.grub.devices = - [ "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0" ]; + boot.loader.grub.devices = [ "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0" ]; satan.address = "10.10.2.102"; deployment = { buildOnTarget = true; - tags = [ "@vm" "@build-on-target" ]; + tags = [ + "@vm" + "@build-on-target" + ]; }; nix.gc.automatic = false; @@ -31,17 +40,21 @@ interfaces = { vlan10.ipv4 = { - routes = [{ - address = "0.0.0.0"; - prefixLength = 0; - via = "10.10.0.1"; - options.src = "10.10.2.102"; - options.onlink = ""; - }]; - addresses = [{ - address = "10.10.2.102"; - prefixLength = 24; - }]; + routes = [ + { + address = "0.0.0.0"; + prefixLength = 0; + via = "10.10.0.1"; + options.src = "10.10.2.102"; + options.onlink = ""; + } + ]; + addresses = [ + { + address = "10.10.2.102"; + prefixLength = 24; + } + ]; }; }; }; diff --git a/hosts/builder/disk-config.nix b/hosts/builder/disk-config.nix index 7c3808e..a49b7a6 100644 --- a/hosts/builder/disk-config.nix +++ b/hosts/builder/disk-config.nix @@ -1,6 +1,10 @@ _: -let disks = { scsi = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"; }; -in { +let + disks = { + scsi = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"; + }; +in +{ disko.devices = { disk = { root = { diff --git a/hosts/builder/hardware-configuration.nix b/hosts/builder/hardware-configuration.nix index d6dd7f8..78efe8e 100644 --- a/hosts/builder/hardware-configuration.nix +++ b/hosts/builder/hardware-configuration.nix @@ -1,7 +1,13 @@ { boot = { - initrd.availableKernelModules = - [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + initrd.availableKernelModules = [ + "ata_piix" + "uhci_hcd" + "virtio_pci" + "virtio_scsi" + "sd_mod" + "sr_mod" + ]; initrd.kernelModules = [ ]; kernelModules = [ "kvm-intel" ]; diff --git a/hosts/controller/configuration.nix b/hosts/controller/configuration.nix index 274e130..5ba8d94 100644 --- a/hosts/controller/configuration.nix +++ b/hosts/controller/configuration.nix @@ -1,6 +1,9 @@ { profiles, suites, ... }: { - imports = with suites; - core ++ proxmox-vm ++ [ + imports = + with suites; + core + ++ proxmox-vm + ++ [ profiles.communications.mosquitto.default profiles.hardware.bluetooth profiles.home-automation.home-assistant.default @@ -13,14 +16,23 @@ profiles.telemetry.prometheus-nut-exporter profiles.telemetry.prometheus-smokeping-exporter profiles.telemetry.prometheus-unpoller-exporter.satan - ] ++ [ ./disk-config.nix ./hardware-configuration.nix ]; + ] + ++ [ + ./disk-config.nix + ./hardware-configuration.nix + ]; deployment = { buildOnTarget = false; - tags = [ "@vm" "@build-on-target" ]; + tags = [ + "@vm" + "@build-on-target" + ]; }; - services.resolved.settings.Resolve = { DNSStubListener = "no"; }; + services.resolved.settings.Resolve = { + DNSStubListener = "no"; + }; networking = { defaultGateway = { @@ -36,15 +48,19 @@ }; interfaces = { - vlan2.ipv4.addresses = [{ - address = "10.2.1.2"; - prefixLength = 24; - }]; - - ens18.ipv4.addresses = [{ - address = "192.168.1.2"; - prefixLength = 24; - }]; + vlan2.ipv4.addresses = [ + { + address = "10.2.1.2"; + prefixLength = 24; + } + ]; + + ens18.ipv4.addresses = [ + { + address = "192.168.1.2"; + prefixLength = 24; + } + ]; }; }; diff --git a/hosts/controller/disk-config.nix b/hosts/controller/disk-config.nix index 071a6c7..721e53a 100644 --- a/hosts/controller/disk-config.nix +++ b/hosts/controller/disk-config.nix @@ -1,6 +1,10 @@ _: -let disks = { sda = "/dev/sda"; }; -in { +let + disks = { + sda = "/dev/sda"; + }; +in +{ disko.devices = { disk = { sda = { diff --git a/hosts/controller/hardware-configuration.nix b/hosts/controller/hardware-configuration.nix index e6aa6df..82c6753 100644 --- a/hosts/controller/hardware-configuration.nix +++ b/hosts/controller/hardware-configuration.nix @@ -1,7 +1,13 @@ { lib, ... }: { boot = { - initrd.availableKernelModules = - [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + initrd.availableKernelModules = [ + "ata_piix" + "uhci_hcd" + "virtio_pci" + "virtio_scsi" + "sd_mod" + "sr_mod" + ]; initrd.kernelModules = [ ]; kernelModules = [ "kvm-intel" ]; extraModulePackages = [ ]; diff --git a/hosts/default.nix b/hosts/default.nix index 29d428c..ed873fa 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -10,17 +10,23 @@ let loader = haumea.lib.loaders.path; }; - nixosModules = l.attrValues (flattenTree (haumea.lib.load { - src = ../modules/nixos; - loader = haumea.lib.loaders.path; - })); + nixosModules = l.attrValues ( + flattenTree ( + haumea.lib.load { + src = ../modules/nixos; + loader = haumea.lib.loaders.path; + } + ) + ); - commonModules = with inputs; + commonModules = + with inputs; [ plex-exporter.nixosModules.plex-exporter sops-nix.nixosModules.sops disko.nixosModules.disko - ] ++ nixosModules; + ] + ++ nixosModules; # https://github.com/zhaofengli/colmena/issues/60#issuecomment-1047199551 extraModules = with inputs; [ @@ -31,20 +37,44 @@ let suites = import ../modules/suites.nix { inherit profiles; }; - mkHost = hostname: - { system, configuration ? ./${hostname}/configuration.nix, ... }: - withSystem system (_: + mkHost = + hostname: + { + system, + configuration ? ./${hostname}/configuration.nix, + ... + }: + withSystem system ( + _: let baseConfiguration = _: { networking.hostName = hostname; }; - modules = commonModules ++ [ baseConfiguration configuration ]; + modules = commonModules ++ [ + baseConfiguration + configuration + ]; specialArgs = { - inherit inputs profiles suites secrets; + inherit + inputs + profiles + suites + secrets + ; flake = self; hosts = self.nixosConfigurations; }; - in l.nixosSystem { inherit specialArgs modules system extraModules; }); + in + l.nixosSystem { + inherit + specialArgs + modules + system + extraModules + ; + } + ); -in { +in +{ flake.nixosConfigurations = { monitor = mkHost "monitor" { system = "aarch64-linux"; }; omnibus = mkHost "omnibus" { system = "x86_64-linux"; }; diff --git a/hosts/dill/configuration.nix b/hosts/dill/configuration.nix index b3e61cd..e494004 100644 --- a/hosts/dill/configuration.nix +++ b/hosts/dill/configuration.nix @@ -1,11 +1,24 @@ -{ suites, profiles, hosts, ... }: { - imports = with suites; - core ++ nuc - ++ [ profiles.hypervisors.incus profiles.hardware.intel-graphics ] - ++ [ ./hardware-configuration.nix ./disk-config.nix ]; +{ + suites, + profiles, + hosts, + ... +}: +{ + imports = + with suites; + core + ++ nuc + ++ [ + profiles.hypervisors.incus + profiles.hardware.intel-graphics + ] + ++ [ + ./hardware-configuration.nix + ./disk-config.nix + ]; - boot.loader.grub.devices = - [ "/dev/disk/by-id/nvme-CT4000P3SSD8_2322E6DDD8FE" ]; + boot.loader.grub.devices = [ "/dev/disk/by-id/nvme-CT4000P3SSD8_2322E6DDD8FE" ]; deployment = { deployable = true; @@ -18,30 +31,31 @@ core.https_address = ":8443"; oidc = { issuer = "https://auth.e10.camp"; - client.id = - "NE-kA1k.XTEv8Qe6oywlhfJHJVmLHg0474m3zD2nMjTm.ddl9rnK.Toq1WwetMP-BjYq4K0X"; + client.id = "NE-kA1k.XTEv8Qe6oywlhfJHJVmLHg0474m3zD2nMjTm.ddl9rnK.Toq1WwetMP-BjYq4K0X"; audience = "https://incus.dill.e10.camp"; }; }; - instances = [{ - name = "fennel"; - image = hosts.fennel.config.system.build.qemuImage; - metadata = hosts.fennel.config.system.build.metadata; - vm = true; - profiles = [ "default" ]; - kind = "instance"; - config = { - "limits.cpu" = 16; - "limits.memory" = "8GiB"; - }; - devices = { - eth0 = { - type = "nic"; - nictype = "bridged"; - parent = "vmbr10"; + instances = [ + { + name = "fennel"; + image = hosts.fennel.config.system.build.qemuImage; + metadata = hosts.fennel.config.system.build.metadata; + vm = true; + profiles = [ "default" ]; + kind = "instance"; + config = { + "limits.cpu" = 16; + "limits.memory" = "8GiB"; }; - }; - }]; + devices = { + eth0 = { + type = "nic"; + nictype = "bridged"; + parent = "vmbr10"; + }; + }; + } + ]; }; networking = { @@ -85,13 +99,15 @@ "30-vmbr10" = { matchConfig.Name = "vmbr10"; address = [ "10.10.4.0/24" ]; - routes = [{ - routeConfig = { - Destination = "0.0.0.0/0"; - Gateway = "10.10.0.1"; - GatewayOnLink = true; - }; - }]; + routes = [ + { + routeConfig = { + Destination = "0.0.0.0/0"; + Gateway = "10.10.0.1"; + GatewayOnLink = true; + }; + } + ]; networkConfig.LinkLocalAddressing = "no"; linkConfig.RequiredForOnline = "no"; }; diff --git a/hosts/dill/disk-config.nix b/hosts/dill/disk-config.nix index 7ea1947..b1ed73d 100644 --- a/hosts/dill/disk-config.nix +++ b/hosts/dill/disk-config.nix @@ -1,6 +1,10 @@ _: -let disks = { nvme = "/dev/disk/by-id/nvme-CT4000P3SSD8_2322E6DDD8FE"; }; -in { +let + disks = { + nvme = "/dev/disk/by-id/nvme-CT4000P3SSD8_2322E6DDD8FE"; + }; +in +{ disko.devices = { disk = { root = { diff --git a/hosts/dill/hardware-configuration.nix b/hosts/dill/hardware-configuration.nix index d0b0bad..5fbde3b 100644 --- a/hosts/dill/hardware-configuration.nix +++ b/hosts/dill/hardware-configuration.nix @@ -1,8 +1,15 @@ { lib, ... }: { boot = { initrd = { - availableKernelModules = - [ "xhci_pci" "thunderbolt" "ahci" "nvme" "usbhid" "uas" "sd_mod" ]; + availableKernelModules = [ + "xhci_pci" + "thunderbolt" + "ahci" + "nvme" + "usbhid" + "uas" + "sd_mod" + ]; kernelModules = [ ]; }; diff --git a/hosts/fennel/configuration.nix b/hosts/fennel/configuration.nix index 52c70b8..eebcfeb 100644 --- a/hosts/fennel/configuration.nix +++ b/hosts/fennel/configuration.nix @@ -16,13 +16,15 @@ systemd.network.networks."10-enp5s0" = { matchConfig.Name = "enp5s0"; address = [ "10.10.4.101/24" ]; - routes = [{ - routeConfig = { - Destination = "0.0.0.0/0"; - Gateway = "10.10.0.1"; - GatewayOnLink = true; - }; - }]; + routes = [ + { + routeConfig = { + Destination = "0.0.0.0/0"; + Gateway = "10.10.0.1"; + GatewayOnLink = true; + }; + } + ]; networkConfig.DHCP = "no"; }; diff --git a/hosts/htpc/configuration.nix b/hosts/htpc/configuration.nix index 4fa4323..86c1dae 100644 --- a/hosts/htpc/configuration.nix +++ b/hosts/htpc/configuration.nix @@ -1,6 +1,16 @@ -{ suites, profiles, pkgs, secrets, ... }: { - imports = with suites; - core ++ proxmox-vm ++ [ +{ + suites, + profiles, + pkgs, + secrets, + ... +}: +{ + imports = + with suites; + core + ++ proxmox-vm + ++ [ profiles.filesystems.blockbuster profiles.filesystems.files.personal profiles.hardware.nvidia @@ -24,11 +34,18 @@ profiles.telemetry.prometheus-dcgm-exporter profiles.telemetry.prometheus-plex-exporter.default profiles.virtualisation.docker - ] ++ [ ./hardware-configuration.nix ./disk-config.nix ] + ] + ++ [ + ./hardware-configuration.nix + ./disk-config.nix + ] ++ [ secrets.hosts.htpc.configuration ]; deployment = { - tags = [ "@vm" "@build-on-target" ]; + tags = [ + "@vm" + "@build-on-target" + ]; buildOnTarget = true; }; @@ -47,17 +64,21 @@ interfaces = { vlan10.ipv4 = { - routes = [{ - address = "0.0.0.0"; - prefixLength = 0; - via = "10.10.0.1"; - options.src = "10.10.2.101"; - options.onlink = ""; - }]; - addresses = [{ - address = "10.10.2.101"; - prefixLength = 24; - }]; + routes = [ + { + address = "0.0.0.0"; + prefixLength = 0; + via = "10.10.0.1"; + options.src = "10.10.2.101"; + options.onlink = ""; + } + ]; + addresses = [ + { + address = "10.10.2.101"; + prefixLength = 24; + } + ]; }; }; }; diff --git a/hosts/htpc/disk-config.nix b/hosts/htpc/disk-config.nix index 7c3808e..a49b7a6 100644 --- a/hosts/htpc/disk-config.nix +++ b/hosts/htpc/disk-config.nix @@ -1,6 +1,10 @@ _: -let disks = { scsi = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"; }; -in { +let + disks = { + scsi = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"; + }; +in +{ disko.devices = { disk = { root = { diff --git a/hosts/matrix/configuration.nix b/hosts/matrix/configuration.nix index cb2b328..7b3737b 100644 --- a/hosts/matrix/configuration.nix +++ b/hosts/matrix/configuration.nix @@ -1,6 +1,15 @@ -{ lib, suites, profiles, ... }: { - imports = with suites; - core ++ proxmox-vm ++ [ +{ + lib, + suites, + profiles, + ... +}: +{ + imports = + with suites; + core + ++ proxmox-vm + ++ [ profiles.databases.postgresql profiles.emulation.aarch64-linux profiles.filesystems.blockbuster @@ -24,16 +33,22 @@ profiles.telemetry.prometheus-nut-exporter profiles.virtualisation.docker profiles.web-servers.caddy - ] ++ [ ./hardware-configuration.nix ./disk-config.nix ]; + ] + ++ [ + ./hardware-configuration.nix + ./disk-config.nix + ]; - boot.loader.grub.devices = - [ "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0" ]; + boot.loader.grub.devices = [ "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0" ]; satan.address = "10.10.3.101"; deployment = { buildOnTarget = true; - tags = [ "@vm" "@build-on-target" ]; + tags = [ + "@vm" + "@build-on-target" + ]; }; networking = { @@ -48,17 +63,21 @@ interfaces = { vlan10.ipv4 = { - routes = [{ - address = "0.0.0.0"; - prefixLength = 0; - via = "10.10.0.1"; - options.src = "10.10.3.101"; - options.onlink = ""; - }]; - addresses = [{ - address = "10.10.3.101"; - prefixLength = 24; - }]; + routes = [ + { + address = "0.0.0.0"; + prefixLength = 0; + via = "10.10.0.1"; + options.src = "10.10.3.101"; + options.onlink = ""; + } + ]; + addresses = [ + { + address = "10.10.3.101"; + prefixLength = 24; + } + ]; }; }; }; diff --git a/hosts/matrix/disk-config.nix b/hosts/matrix/disk-config.nix index 7c3808e..a49b7a6 100644 --- a/hosts/matrix/disk-config.nix +++ b/hosts/matrix/disk-config.nix @@ -1,6 +1,10 @@ _: -let disks = { scsi = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"; }; -in { +let + disks = { + scsi = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0"; + }; +in +{ disko.devices = { disk = { root = { diff --git a/hosts/matrix/hardware-configuration.nix b/hosts/matrix/hardware-configuration.nix index d6affe7..1594d7f 100644 --- a/hosts/matrix/hardware-configuration.nix +++ b/hosts/matrix/hardware-configuration.nix @@ -1,7 +1,13 @@ { boot = { - initrd.availableKernelModules = - [ "ata-piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + initrd.availableKernelModules = [ + "ata-piix" + "uhci_hcd" + "virtio_pci" + "virtio_scsi" + "sd_mod" + "sr_mod" + ]; initrd.kernelModules = [ ]; kernelModules = [ "kvm-intel" ]; diff --git a/hosts/monitor/configuration.nix b/hosts/monitor/configuration.nix index 3892f7b..2b16f75 100644 --- a/hosts/monitor/configuration.nix +++ b/hosts/monitor/configuration.nix @@ -1,6 +1,10 @@ { profiles, suites, ... }: { - imports = with suites; - core ++ aws ++ web ++ [ + imports = + with suites; + core + ++ aws + ++ web + ++ [ profiles.communications.grafana-to-ntfy.default profiles.communications.ntfy profiles.monitoring.loki.default @@ -10,7 +14,8 @@ profiles.observability.grafana profiles.observability.uptime-kuma profiles.telemetry.prometheus-redis-exporter - ] ++ [ + ] + ++ [ ./profiles/authelia ./profiles/caddy.nix ./profiles/prometheus.nix diff --git a/hosts/monitor/profiles/authelia/default.nix b/hosts/monitor/profiles/authelia/default.nix index 7453f73..60d9425 100644 --- a/hosts/monitor/profiles/authelia/default.nix +++ b/hosts/monitor/profiles/authelia/default.nix @@ -1,24 +1,31 @@ -{ config, lib, profiles, ... }: { +{ + config, + lib, + profiles, + ... +}: +{ imports = [ profiles.security.authelia.default ]; sops = { - secrets = let - secretConfig = { - sopsFile = ./secrets.yml; - format = "yaml"; - owner = - config.services.authelia.instances.${config.networking.hostName}.user; + secrets = + let + secretConfig = { + sopsFile = ./secrets.yml; + format = "yaml"; + owner = config.services.authelia.instances.${config.networking.hostName}.user; + }; + in + { + monitor_authelia_jwt_secret = secretConfig; + monitor_authelia_storage_encryption_key = secretConfig; + monitor_authelia_session_secret = secretConfig; + monitor_authelia_oidc_hmac_secret = secretConfig; + monitor_authelia_issuer_private_key = secretConfig; + monitor_authelia_users_admin_password_hash = secretConfig; + monitor_authelia_users_ethan_password_hash = secretConfig; + monitor_authelia_users_gatus_password_hash = secretConfig; }; - in { - monitor_authelia_jwt_secret = secretConfig; - monitor_authelia_storage_encryption_key = secretConfig; - monitor_authelia_session_secret = secretConfig; - monitor_authelia_oidc_hmac_secret = secretConfig; - monitor_authelia_issuer_private_key = secretConfig; - monitor_authelia_users_admin_password_hash = secretConfig; - monitor_authelia_users_ethan_password_hash = secretConfig; - monitor_authelia_users_gatus_password_hash = secretConfig; - }; templates."authelia/users.yml" = { content = lib.generators.toYAML { } { @@ -27,8 +34,7 @@ disabled = false; displayname = "Administrator"; email = "admin@e10.camp"; - password = - config.sops.placeholder.monitor_authelia_users_admin_password_hash; + password = config.sops.placeholder.monitor_authelia_users_admin_password_hash; groups = [ "admin" ]; }; @@ -36,8 +42,7 @@ disabled = false; displayname = "Ethan Turkeltaub"; email = "ethan@turkeltaub.me"; - password = - config.sops.placeholder.monitor_authelia_users_ethan_password_hash; + password = config.sops.placeholder.monitor_authelia_users_ethan_password_hash; groups = [ "admin" ]; }; @@ -45,30 +50,24 @@ disabled = false; displayname = "Gatus"; email = "monitor@e10.camp"; - password = - config.sops.placeholder.monitor_authelia_users_gatus_password_hash; + password = config.sops.placeholder.monitor_authelia_users_gatus_password_hash; groups = [ "service" ]; }; }; }; - owner = - config.services.authelia.instances.${config.networking.hostName}.user; + owner = config.services.authelia.instances.${config.networking.hostName}.user; }; }; services.authelia.instances.${config.networking.hostName} = { secrets = { jwtSecretFile = config.sops.secrets.monitor_authelia_jwt_secret.path; - storageEncryptionKeyFile = - config.sops.secrets.monitor_authelia_storage_encryption_key.path; - sessionSecretFile = - config.sops.secrets.monitor_authelia_session_secret.path; + storageEncryptionKeyFile = config.sops.secrets.monitor_authelia_storage_encryption_key.path; + sessionSecretFile = config.sops.secrets.monitor_authelia_session_secret.path; # NOTE: These need to be commented out if there are no OIDC clients present, otherwise Authelia will fail to start - oidcHmacSecretFile = - config.sops.secrets.monitor_authelia_oidc_hmac_secret.path; - oidcIssuerPrivateKeyFile = - config.sops.secrets.monitor_authelia_issuer_private_key.path; + oidcHmacSecretFile = config.sops.secrets.monitor_authelia_oidc_hmac_secret.path; + oidcIssuerPrivateKeyFile = config.sops.secrets.monitor_authelia_issuer_private_key.path; }; settings = { @@ -88,38 +87,50 @@ }; }; - session.cookies = [{ - domain = "e10.camp"; - authelia_url = "https://auth.monitor.e10.camp"; - inactivity = "1M"; - expiration = "3M"; - remember_me = "1y"; - }]; + session.cookies = [ + { + domain = "e10.camp"; + authelia_url = "https://auth.monitor.e10.camp"; + inactivity = "1M"; + expiration = "3M"; + remember_me = "1y"; + } + ]; identity_providers.oidc = { claims_policies = { - grafana.id_token = [ "email" "name" "groups" "preferred_username" ]; + grafana.id_token = [ + "email" + "name" + "groups" + "preferred_username" + ]; }; - clients = [{ - client_id = - "1vukV4u1uEh~p-HGYBHhB-xv.ZyyKW3tI2Cco5F1f_jaI9Qamn_oc4rLoy7nqx3h3IwnsB5."; - client_name = "Grafana"; - claims_policy = "grafana"; - client_secret = - "$pbkdf2-sha512$310000$IT.5orFA6bKiL/AWi.rP5Q$oDajcRBqmnCuZZxa6L1/o3BrfQDPYAS/YOl2e2dIGbyoXaRTgNptf66ah6NHpwgGNm/hyAvuYHej3.jybdsvUQ"; - public = false; - authorization_policy = "two_factor"; - require_pkce = true; - pkce_challenge_method = "S256"; - redirect_uris = [ "https://grafana.e10.camp/login/generic_oauth" ]; - scopes = [ "openid" "profile" "groups" "email" ]; - response_types = [ "code" ]; - grant_types = [ "authorization_code" ]; - access_token_signed_response_alg = "none"; - userinfo_signed_response_alg = "none"; - token_endpoint_auth_method = "client_secret_basic"; - }]; + clients = [ + { + client_id = "1vukV4u1uEh~p-HGYBHhB-xv.ZyyKW3tI2Cco5F1f_jaI9Qamn_oc4rLoy7nqx3h3IwnsB5."; + client_name = "Grafana"; + claims_policy = "grafana"; + client_secret = "$pbkdf2-sha512$310000$IT.5orFA6bKiL/AWi.rP5Q$oDajcRBqmnCuZZxa6L1/o3BrfQDPYAS/YOl2e2dIGbyoXaRTgNptf66ah6NHpwgGNm/hyAvuYHej3.jybdsvUQ"; + public = false; + authorization_policy = "two_factor"; + require_pkce = true; + pkce_challenge_method = "S256"; + redirect_uris = [ "https://grafana.e10.camp/login/generic_oauth" ]; + scopes = [ + "openid" + "profile" + "groups" + "email" + ]; + response_types = [ "code" ]; + grant_types = [ "authorization_code" ]; + access_token_signed_response_alg = "none"; + userinfo_signed_response_alg = "none"; + token_endpoint_auth_method = "client_secret_basic"; + } + ]; }; access_control.rules = lib.mkAfter [ diff --git a/hosts/monitor/profiles/grafana/default.nix b/hosts/monitor/profiles/grafana/default.nix index 73006ca..af3da22 100644 --- a/hosts/monitor/profiles/grafana/default.nix +++ b/hosts/monitor/profiles/grafana/default.nix @@ -1,18 +1,20 @@ { config, hosts, ... }: { - sops.secrets = let - sopsConfig = { - sopsFile = ./secrets.yml; - format = "yaml"; - mode = "0700"; - owner = "grafana"; + sops.secrets = + let + sopsConfig = { + sopsFile = ./secrets.yml; + format = "yaml"; + mode = "0700"; + owner = "grafana"; + }; + in + { + grafana_secret_key = sopsConfig; + grafana_to_ntfy_password = sopsConfig; + grafana_smtp2go_username = sopsConfig; + grafana_smtp2go_password = sopsConfig; + grafana_authelia_client_secret = sopsConfig; }; - in { - grafana_secret_key = sopsConfig; - grafana_to_ntfy_password = sopsConfig; - grafana_smtp2go_username = sopsConfig; - grafana_smtp2go_password = sopsConfig; - grafana_authelia_client_secret = sopsConfig; - }; services.grafana = { settings = { @@ -21,17 +23,14 @@ root_url = "https://grafana.e10.camp"; }; - security.secret_key = - "$__file{${config.sops.secrets.grafana_secret_key.path}}"; + security.secret_key = "$__file{${config.sops.secrets.grafana_secret_key.path}}"; "auth.generic_oauth" = { enabled = true; name = "Authelia"; icon = "signin"; - client_id = - "1vukV4u1uEh~p-HGYBHhB-xv.ZyyKW3tI2Cco5F1f_jaI9Qamn_oc4rLoy7nqx3h3IwnsB5."; - client_secret = - "$__file{${config.sops.secrets.grafana_authelia_client_secret.path}}"; + client_id = "1vukV4u1uEh~p-HGYBHhB-xv.ZyyKW3tI2Cco5F1f_jaI9Qamn_oc4rLoy7nqx3h3IwnsB5."; + client_secret = "$__file{${config.sops.secrets.grafana_authelia_client_secret.path}}"; scopes = "openid profile email groups"; empty_scopes = "false"; auth_url = "https://auth.monitor.e10.camp/api/oidc/authorization"; @@ -41,16 +40,14 @@ groups_attribute_path = "groups"; name_attribute_path = "name"; use_pkce = "true"; - role_attribute_path = - "contains(groups[*], 'admin') && 'Admin' || contains(groups[*], 'editor') && 'Editor' || 'Viewer'"; + role_attribute_path = "contains(groups[*], 'admin') && 'Admin' || contains(groups[*], 'editor') && 'Editor' || 'Viewer'"; }; smtp = { enabled = true; host = "mail.smtp2go.com:2525"; user = "$__file{${config.sops.secrets.grafana_smtp2go_username.path}}"; - password = - "$__file{${config.sops.secrets.grafana_smtp2go_password.path}}"; + password = "$__file{${config.sops.secrets.grafana_smtp2go_password.path}}"; startTLS_policy = "MandatoryStartTLS"; skip_verify = true; from_address = "monitor@e10.camp"; @@ -66,18 +63,13 @@ name = "Thanos"; type = "prometheus"; access = "proxy"; - url = "http://${hosts.monitor.config.networking.hostName}:${ - toString config.services.thanos.query.http.port - }"; + url = "http://${hosts.monitor.config.networking.hostName}:${toString config.services.thanos.query.http.port}"; } { name = "Loki"; type = "loki"; access = "proxy"; - url = "http://${hosts.monitor.config.networking.hostName}:${ - toString - config.services.loki.configuration.server.http_listen_port - }"; + url = "http://${hosts.monitor.config.networking.hostName}:${toString config.services.loki.configuration.server.http_listen_port}"; } { name = "PostgreSQL"; @@ -168,25 +160,30 @@ contactPoints = [ { name = "Email"; - receivers = [{ - uid = "1"; - type = "email"; - settings = { addresses = "ethan+e10@turkeltaub.dev"; }; - }]; + receivers = [ + { + uid = "1"; + type = "email"; + settings = { + addresses = "ethan+e10@turkeltaub.dev"; + }; + } + ]; } { name = "Ntfy"; - receivers = [{ - uid = "20"; - type = "webhook"; - settings = { - httpMethod = "POST"; - url = "http://0.0.0.0:8000"; - username = "admin"; - password = - "$__file{${config.sops.secrets.grafana_to_ntfy_password.path}}"; - }; - }]; + receivers = [ + { + uid = "20"; + type = "webhook"; + settings = { + httpMethod = "POST"; + url = "http://0.0.0.0:8000"; + username = "admin"; + password = "$__file{${config.sops.secrets.grafana_to_ntfy_password.path}}"; + }; + } + ]; } ]; }; @@ -194,352 +191,408 @@ policies.settings = { apiVersion = 1; - policies = [{ - orgId = 1; - receiver = "Email"; - group_by = [ "grafana_folder" "alertname" ]; - routes = [{ - receiver = "Ntfy"; - object_matchers = [[ "severity" "=" "critical" ]]; - }]; - }]; + policies = [ + { + orgId = 1; + receiver = "Email"; + group_by = [ + "grafana_folder" + "alertname" + ]; + routes = [ + { + receiver = "Ntfy"; + object_matchers = [ + [ + "severity" + "=" + "critical" + ] + ]; + } + ]; + } + ]; }; rules.settings = { apiVersion = 1; - groups = [{ - orgId = 1; - name = "Default"; - interval = "60s"; - folder = "Homelab"; - rules = [ - { - uid = "a0513fe1-c679-4411-8512-d52334814942"; - title = "Rack UPS is on battery power"; - condition = "C"; - data = [ - { - refId = "A"; - relativeTimeRange = { - from = 600; - to = 0; - }; - datasourceUid = "P5DCFC7561CCDE821"; - model = { - datasource = { - type = "prometheus"; - uid = "P5DCFC7561CCDE821"; - }; - editorMode = "code"; - expr = '' - network_ups_tools_ups_status{instance="matrix:9199",flag="OB"} - ''; - instant = true; - intervalMs = 1000; - legendFormat = "__auto"; - maxDataPoints = 43200; - range = false; + groups = [ + { + orgId = 1; + name = "Default"; + interval = "60s"; + folder = "Homelab"; + rules = [ + { + uid = "a0513fe1-c679-4411-8512-d52334814942"; + title = "Rack UPS is on battery power"; + condition = "C"; + data = [ + { refId = "A"; - }; - } - { - refId = "C"; - relativeTimeRange = { - from = 600; - to = 0; - }; - datasourceUid = "__expr__"; - model = { - conditions = [{ - evaluator = { - params = [ 0 ]; - type = "gt"; - }; - operator = { type = "and"; }; - query = { params = [ "C" ]; }; - reducer = { - params = [ ]; - type = "last"; + relativeTimeRange = { + from = 600; + to = 0; + }; + datasourceUid = "P5DCFC7561CCDE821"; + model = { + datasource = { + type = "prometheus"; + uid = "P5DCFC7561CCDE821"; }; - type = "query"; - }]; - datasource = { - type = "__expr__"; - uid = "__expr__"; + editorMode = "code"; + expr = '' + network_ups_tools_ups_status{instance="matrix:9199",flag="OB"} + ''; + instant = true; + intervalMs = 1000; + legendFormat = "__auto"; + maxDataPoints = 43200; + range = false; + refId = "A"; }; - expression = "A"; - intervalMs = 1000; - maxDataPoints = 43200; + } + { refId = "C"; - type = "threshold"; - }; - } - ]; - noDataState = "OK"; - execErrState = "Error"; - for = "30s"; - annotations = { - description = ""; - runbook_url = ""; - summary = ""; - }; - labels = { severity = "critical"; }; - isPaused = false; - } - { - uid = "3792C8F7-C2FF-4EB9-A268-AB22038F151A"; - title = "Networking UPS is on battery power"; - condition = "C"; - data = [ - { - refId = "A"; - relativeTimeRange = { - from = 600; - to = 0; - }; - datasourceUid = "P5DCFC7561CCDE821"; - model = { - datasource = { - type = "prometheus"; - uid = "P5DCFC7561CCDE821"; + relativeTimeRange = { + from = 600; + to = 0; }; - editorMode = "code"; - expr = '' - network_ups_tools_ups_status{instance="controller:9199",flag="OB"} - ''; - instant = true; - intervalMs = 1000; - legendFormat = "__auto"; - maxDataPoints = 43200; - range = false; - refId = "A"; - }; - } - { - refId = "C"; - relativeTimeRange = { - from = 600; - to = 0; - }; - datasourceUid = "__expr__"; - model = { - conditions = [{ - evaluator = { - params = [ 0 ]; - type = "gt"; + datasourceUid = "__expr__"; + model = { + conditions = [ + { + evaluator = { + params = [ 0 ]; + type = "gt"; + }; + operator = { + type = "and"; + }; + query = { + params = [ "C" ]; + }; + reducer = { + params = [ ]; + type = "last"; + }; + type = "query"; + } + ]; + datasource = { + type = "__expr__"; + uid = "__expr__"; }; - operator = { type = "and"; }; - query = { params = [ "C" ]; }; - reducer = { - params = [ ]; - type = "last"; + expression = "A"; + intervalMs = 1000; + maxDataPoints = 43200; + refId = "C"; + type = "threshold"; + }; + } + ]; + noDataState = "OK"; + execErrState = "Error"; + for = "30s"; + annotations = { + description = ""; + runbook_url = ""; + summary = ""; + }; + labels = { + severity = "critical"; + }; + isPaused = false; + } + { + uid = "3792C8F7-C2FF-4EB9-A268-AB22038F151A"; + title = "Networking UPS is on battery power"; + condition = "C"; + data = [ + { + refId = "A"; + relativeTimeRange = { + from = 600; + to = 0; + }; + datasourceUid = "P5DCFC7561CCDE821"; + model = { + datasource = { + type = "prometheus"; + uid = "P5DCFC7561CCDE821"; }; - type = "query"; - }]; - datasource = { - type = "__expr__"; - uid = "__expr__"; + editorMode = "code"; + expr = '' + network_ups_tools_ups_status{instance="controller:9199",flag="OB"} + ''; + instant = true; + intervalMs = 1000; + legendFormat = "__auto"; + maxDataPoints = 43200; + range = false; + refId = "A"; }; - expression = "A"; - intervalMs = 1000; - maxDataPoints = 43200; + } + { refId = "C"; - type = "threshold"; - }; - } - ]; - noDataState = "OK"; - execErrState = "Error"; - for = "30s"; - annotations = { - description = ""; - runbook_url = ""; - summary = ""; - }; - labels = { severity = "critical"; }; - isPaused = false; - } - { - uid = "e1a38758-5093-49e2-8041-ae81225b1ca5"; - title = "Packet loss is greater than 1%"; - condition = "C"; - data = [ - { - refId = "A"; - relativeTimeRange = { - from = 600; - to = 0; - }; - datasourceUid = "P5DCFC7561CCDE821"; - model = { - datasource = { - type = "prometheus"; - uid = "P5DCFC7561CCDE821"; + relativeTimeRange = { + from = 600; + to = 0; }; - editorMode = "code"; - expr = '' - (smokeping_requests_total{host="1.1.1.1", job="smokeping_controller"} - smokeping_response_duration_seconds_count{host="1.1.1.1", job="smokeping_controller"})/smokeping_requests_total{host="1.1.1.1", job="smokeping_controller"} - ''; - instant = false; - intervalMs = 1000; - legendFormat = "__auto"; - maxDataPoints = 43200; - range = true; - refId = "A"; - }; - } - { - refId = "B"; - relativeTimeRange = { - from = 600; - to = 0; - }; - datasourceUid = "__expr__"; - model = { - conditions = [{ - evaluator = { - params = [ 0 0 ]; - type = "gt"; + datasourceUid = "__expr__"; + model = { + conditions = [ + { + evaluator = { + params = [ 0 ]; + type = "gt"; + }; + operator = { + type = "and"; + }; + query = { + params = [ "C" ]; + }; + reducer = { + params = [ ]; + type = "last"; + }; + type = "query"; + } + ]; + datasource = { + type = "__expr__"; + uid = "__expr__"; }; - operator = { type = "and"; }; - query = { params = [ ]; }; - reducer = { - params = [ ]; - type = "avg"; + expression = "A"; + intervalMs = 1000; + maxDataPoints = 43200; + refId = "C"; + type = "threshold"; + }; + } + ]; + noDataState = "OK"; + execErrState = "Error"; + for = "30s"; + annotations = { + description = ""; + runbook_url = ""; + summary = ""; + }; + labels = { + severity = "critical"; + }; + isPaused = false; + } + { + uid = "e1a38758-5093-49e2-8041-ae81225b1ca5"; + title = "Packet loss is greater than 1%"; + condition = "C"; + data = [ + { + refId = "A"; + relativeTimeRange = { + from = 600; + to = 0; + }; + datasourceUid = "P5DCFC7561CCDE821"; + model = { + datasource = { + type = "prometheus"; + uid = "P5DCFC7561CCDE821"; }; - type = "query"; - }]; - datasource = { - name = "Expression"; - type = "__expr__"; - uid = "__expr__"; + editorMode = "code"; + expr = '' + (smokeping_requests_total{host="1.1.1.1", job="smokeping_controller"} - smokeping_response_duration_seconds_count{host="1.1.1.1", job="smokeping_controller"})/smokeping_requests_total{host="1.1.1.1", job="smokeping_controller"} + ''; + instant = false; + intervalMs = 1000; + legendFormat = "__auto"; + maxDataPoints = 43200; + range = true; + refId = "A"; }; - expression = "A"; - intervalMs = 1000; - maxDataPoints = 43200; - reducer = "mean"; + } + { refId = "B"; - type = "reduce"; - }; - } - { - refId = "C"; - relativeTimeRange = { - from = 600; - to = 0; - }; - datasourceUid = "__expr__"; - model = { - conditions = [{ - evaluator = { - params = [ 1.0e-2 ]; - type = "gt"; - }; - operator = { type = "and"; }; - query = { params = [ ]; }; - reducer = { - params = [ ]; - type = "avg"; + relativeTimeRange = { + from = 600; + to = 0; + }; + datasourceUid = "__expr__"; + model = { + conditions = [ + { + evaluator = { + params = [ + 0 + 0 + ]; + type = "gt"; + }; + operator = { + type = "and"; + }; + query = { + params = [ ]; + }; + reducer = { + params = [ ]; + type = "avg"; + }; + type = "query"; + } + ]; + datasource = { + name = "Expression"; + type = "__expr__"; + uid = "__expr__"; }; - type = "query"; - }]; - datasource = { - name = "Expression"; - type = "__expr__"; - uid = "__expr__"; + expression = "A"; + intervalMs = 1000; + maxDataPoints = 43200; + reducer = "mean"; + refId = "B"; + type = "reduce"; }; - expression = "B"; - intervalMs = 1000; - maxDataPoints = 43200; + } + { refId = "C"; - type = "threshold"; - }; - } - ]; - noDataState = "NoData"; - execErrState = "Error"; - for = "5m"; - annotations = { - description = ""; - runbook_url = ""; - summary = ""; - }; - labels = { severity = "critical"; }; - isPaused = false; - } - { - uid = "C6AC6046-EBEF-49E8-A810-A124B01AC3D1"; - title = "ZFS pool degraded"; - condition = "C"; - data = [ - { - refId = "A"; - relativeTimeRange = { - from = 600; - to = 0; - }; - datasourceUid = "P5DCFC7561CCDE821"; - model = { - datasource = { - type = "prometheus"; - uid = "P5DCFC7561CCDE821"; + relativeTimeRange = { + from = 600; + to = 0; }; - editorMode = "code"; - expr = "zfs_pool_health"; - instant = true; - intervalMs = 1000; - legendFormat = "__auto"; - maxDataPoints = 43200; - range = false; - refId = "A"; - }; - } - { - refId = "C"; - relativeTimeRange = { - from = 0; - to = 0; - }; - datasourceUid = "__expr__"; - model = { - conditions = [{ - evaluator = { - params = [ 0 ]; - type = "gt"; + datasourceUid = "__expr__"; + model = { + conditions = [ + { + evaluator = { + params = [ 1.0e-2 ]; + type = "gt"; + }; + operator = { + type = "and"; + }; + query = { + params = [ ]; + }; + reducer = { + params = [ ]; + type = "avg"; + }; + type = "query"; + } + ]; + datasource = { + name = "Expression"; + type = "__expr__"; + uid = "__expr__"; }; - operator = { type = "and"; }; - query = { params = [ "C" ]; }; - reducer = { - params = [ ]; - type = "last"; + expression = "B"; + intervalMs = 1000; + maxDataPoints = 43200; + refId = "C"; + type = "threshold"; + }; + } + ]; + noDataState = "NoData"; + execErrState = "Error"; + for = "5m"; + annotations = { + description = ""; + runbook_url = ""; + summary = ""; + }; + labels = { + severity = "critical"; + }; + isPaused = false; + } + { + uid = "C6AC6046-EBEF-49E8-A810-A124B01AC3D1"; + title = "ZFS pool degraded"; + condition = "C"; + data = [ + { + refId = "A"; + relativeTimeRange = { + from = 600; + to = 0; + }; + datasourceUid = "P5DCFC7561CCDE821"; + model = { + datasource = { + type = "prometheus"; + uid = "P5DCFC7561CCDE821"; }; - type = "query"; - }]; - datasource = { - type = "__expr__"; - uid = "__expr__"; + editorMode = "code"; + expr = "zfs_pool_health"; + instant = true; + intervalMs = 1000; + legendFormat = "__auto"; + maxDataPoints = 43200; + range = false; + refId = "A"; }; - expression = "A"; - intervalMs = 1000; - maxDataPoints = 43200; + } + { refId = "C"; - type = "threshold"; - }; - } - ]; - noDataState = "NoData"; - execErrState = "Error"; - for = "1m"; - annotations = { - pool = ''{{index $labels "pool"}}''; - summary = "ZFS pool {{pool}} unhealthy"; - }; - labels = { }; - isPaused = false; - notification_settings = { receiver = "Ntfy"; }; - } - ]; - }]; + relativeTimeRange = { + from = 0; + to = 0; + }; + datasourceUid = "__expr__"; + model = { + conditions = [ + { + evaluator = { + params = [ 0 ]; + type = "gt"; + }; + operator = { + type = "and"; + }; + query = { + params = [ "C" ]; + }; + reducer = { + params = [ ]; + type = "last"; + }; + type = "query"; + } + ]; + datasource = { + type = "__expr__"; + uid = "__expr__"; + }; + expression = "A"; + intervalMs = 1000; + maxDataPoints = 43200; + refId = "C"; + type = "threshold"; + }; + } + ]; + noDataState = "NoData"; + execErrState = "Error"; + for = "1m"; + annotations = { + pool = ''{{index $labels "pool"}}''; + summary = "ZFS pool {{pool}} unhealthy"; + }; + labels = { }; + isPaused = false; + notification_settings = { + receiver = "Ntfy"; + }; + } + ]; + } + ]; }; }; }; diff --git a/hosts/monitor/profiles/prometheus.nix b/hosts/monitor/profiles/prometheus.nix index 5cbd793..cc135ae 100644 --- a/hosts/monitor/profiles/prometheus.nix +++ b/hosts/monitor/profiles/prometheus.nix @@ -1,288 +1,289 @@ -{ profiles, hosts, lib, ... }: { +{ + profiles, + hosts, + lib, + ... +}: +{ imports = [ profiles.monitoring.prometheus ]; services.prometheus.scrapeConfigs = [ { job_name = "host_router"; - static_configs = [{ targets = [ "router:9100" ]; }]; + static_configs = [ { targets = [ "router:9100" ]; } ]; } { job_name = "host_anise"; - static_configs = [{ targets = [ "anise:9100" ]; }]; + static_configs = [ { targets = [ "anise:9100" ]; } ]; } { job_name = "host_basil"; - static_configs = [{ targets = [ "basil:9100" ]; }]; + static_configs = [ { targets = [ "basil:9100" ]; } ]; } { job_name = "host_cardamom"; - static_configs = [{ targets = [ "cardamom:9100" ]; }]; + static_configs = [ { targets = [ "cardamom:9100" ]; } ]; } { job_name = "host_satan"; - static_configs = [{ targets = [ "satan:9100" ]; }]; + static_configs = [ { targets = [ "satan:9100" ]; } ]; } { job_name = "host_elderflower"; - static_configs = [{ targets = [ "elderflower:9100" ]; }]; + static_configs = [ { targets = [ "elderflower:9100" ]; } ]; } { job_name = "node_builder"; - static_configs = [{ - targets = [ - "${hosts.builder.config.networking.hostName}:${ - toString - hosts.builder.config.services.prometheus.exporters.node.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.builder.config.networking.hostName}:${toString hosts.builder.config.services.prometheus.exporters.node.port}" + ]; + } + ]; } { job_name = "blocky"; - static_configs = [{ - targets = [ - "${hosts.controller.config.networking.hostName}:${ - toString hosts.controller.config.services.blocky.settings.ports.http - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.controller.config.networking.hostName}:${toString hosts.controller.config.services.blocky.settings.ports.http}" + ]; + } + ]; } { job_name = "node_bastion"; - static_configs = [{ - targets = [ - "${hosts.bastion.config.networking.hostName}:${ - toString - hosts.bastion.config.services.prometheus.exporters.node.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.bastion.config.networking.hostName}:${toString hosts.bastion.config.services.prometheus.exporters.node.port}" + ]; + } + ]; } { job_name = "node_controller"; - static_configs = [{ - targets = [ - "${hosts.controller.config.networking.hostName}:${ - toString - hosts.controller.config.services.prometheus.exporters.node.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.controller.config.networking.hostName}:${toString hosts.controller.config.services.prometheus.exporters.node.port}" + ]; + } + ]; } { job_name = "node_monitor"; - static_configs = [{ - targets = [ - "${hosts.monitor.config.networking.hostName}:${ - toString - hosts.monitor.config.services.prometheus.exporters.node.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.monitor.config.networking.hostName}:${toString hosts.monitor.config.services.prometheus.exporters.node.port}" + ]; + } + ]; } { job_name = "node_omnibus"; - static_configs = [{ - targets = [ - "${hosts.omnibus.config.networking.hostName}:${ - toString - hosts.omnibus.config.services.prometheus.exporters.node.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.omnibus.config.networking.hostName}:${toString hosts.omnibus.config.services.prometheus.exporters.node.port}" + ]; + } + ]; } { job_name = "node_htpc"; - static_configs = [{ - targets = [ - "${hosts.htpc.config.networking.hostName}:${ - toString hosts.htpc.config.services.prometheus.exporters.node.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.prometheus.exporters.node.port}" + ]; + } + ]; } { job_name = "node_matrix"; - static_configs = [{ - targets = [ - "${hosts.matrix.config.networking.hostName}:${ - toString hosts.matrix.config.services.prometheus.exporters.node.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.matrix.config.networking.hostName}:${toString hosts.matrix.config.services.prometheus.exporters.node.port}" + ]; + } + ]; } { job_name = "smartctl_omnibus"; - static_configs = [{ - targets = [ - "${hosts.omnibus.config.networking.hostName}:${ - toString - hosts.omnibus.config.services.prometheus.exporters.smartctl.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.omnibus.config.networking.hostName}:${toString hosts.omnibus.config.services.prometheus.exporters.smartctl.port}" + ]; + } + ]; } { job_name = "zfs_omnibus"; - static_configs = [{ - targets = [ - "${hosts.omnibus.config.networking.hostName}:${ - toString hosts.omnibus.config.services.prometheus.exporters.zfs.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.omnibus.config.networking.hostName}:${toString hosts.omnibus.config.services.prometheus.exporters.zfs.port}" + ]; + } + ]; } { job_name = "nut_matrix"; metrics_path = "/ups_metrics"; - static_configs = [{ - targets = [ - "${hosts.matrix.config.networking.hostName}:${ - toString hosts.matrix.config.services.prometheus.exporters.nut.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.matrix.config.networking.hostName}:${toString hosts.matrix.config.services.prometheus.exporters.nut.port}" + ]; + } + ]; } { job_name = "nut_controller"; metrics_path = "/ups_metrics"; - static_configs = [{ - targets = [ - "${hosts.controller.config.networking.hostName}:${ - toString - hosts.controller.config.services.prometheus.exporters.nut.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.controller.config.networking.hostName}:${toString hosts.controller.config.services.prometheus.exporters.nut.port}" + ]; + } + ]; } { job_name = "smokeping_controller"; metrics_path = "/metrics"; - static_configs = [{ - targets = [ - "${hosts.controller.config.networking.hostName}:${ - toString - hosts.controller.config.services.prometheus.exporters.smokeping.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.controller.config.networking.hostName}:${toString hosts.controller.config.services.prometheus.exporters.smokeping.port}" + ]; + } + ]; scrape_interval = "5s"; } { job_name = "satan_controller"; metrics_path = "/metrics"; - static_configs = [{ - targets = [ - "${hosts.controller.config.networking.hostName}:${ - toString - hosts.controller.config.services.prometheus.exporters.unpoller.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.controller.config.networking.hostName}:${toString hosts.controller.config.services.prometheus.exporters.unpoller.port}" + ]; + } + ]; } { job_name = "sonarr"; metrics_path = "/metrics"; - static_configs = [{ - targets = [ - "${hosts.htpc.config.networking.hostName}:${ - toString - hosts.htpc.config.services.prometheus.exporters.exportarr-sonarr.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.prometheus.exporters.exportarr-sonarr.port}" + ]; + } + ]; } { job_name = "radarr"; metrics_path = "/metrics"; - static_configs = [{ - targets = [ - "${hosts.htpc.config.networking.hostName}:${ - toString - hosts.htpc.config.services.prometheus.exporters.exportarr-radarr.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.prometheus.exporters.exportarr-radarr.port}" + ]; + } + ]; } { job_name = "bazarr"; metrics_path = "/metrics"; - static_configs = [{ - targets = [ - "${hosts.htpc.config.networking.hostName}:${ - toString - hosts.htpc.config.services.prometheus.exporters.exportarr-bazarr.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.prometheus.exporters.exportarr-bazarr.port}" + ]; + } + ]; } { job_name = "prowlarr"; metrics_path = "/metrics"; - static_configs = [{ - targets = [ - "${hosts.htpc.config.networking.hostName}:${ - toString - hosts.htpc.config.services.prometheus.exporters.exportarr-prowlarr.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.prometheus.exporters.exportarr-prowlarr.port}" + ]; + } + ]; } { job_name = "plex"; metrics_path = "/metrics"; - static_configs = [{ - targets = [ - "${hosts.htpc.config.networking.hostName}:${ - toString hosts.htpc.config.services.plex-exporter.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.plex-exporter.port}" + ]; + } + ]; } { job_name = "sabnzbd"; metrics_path = "/metrics"; - static_configs = [{ - targets = [ - "${hosts.htpc.config.networking.hostName}:${ - toString - hosts.htpc.config.services.prometheus.exporters.exportarr-sabnzbd.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.prometheus.exporters.exportarr-sabnzbd.port}" + ]; + } + ]; } { job_name = "authelia_bastion"; metrics_path = "/metrics"; - static_configs = - [{ targets = [ "${hosts.bastion.config.networking.hostName}:9959" ]; }]; + static_configs = [ { targets = [ "${hosts.bastion.config.networking.hostName}:9959" ]; } ]; } { job_name = "caddy_bastion"; metrics_path = "/metrics"; - static_configs = - [{ targets = [ "${hosts.bastion.config.networking.hostName}:2019" ]; }]; + static_configs = [ { targets = [ "${hosts.bastion.config.networking.hostName}:2019" ]; } ]; } { job_name = "caddy_matrix"; metrics_path = "/metrics"; - static_configs = - [{ targets = [ "${hosts.matrix.config.networking.hostName}:2019" ]; }]; + static_configs = [ { targets = [ "${hosts.matrix.config.networking.hostName}:2019" ]; } ]; } { job_name = "caddy_monitor"; metrics_path = "/metrics"; - static_configs = - [{ targets = [ "${hosts.monitor.config.networking.hostName}:2019" ]; }]; + static_configs = [ { targets = [ "${hosts.monitor.config.networking.hostName}:2019" ]; } ]; } { job_name = "pve"; metrics_path = "/pve"; - static_configs = - [{ targets = [ "anise" "basil" "cardamom" "elderflower" ]; }]; + static_configs = [ + { + targets = [ + "anise" + "basil" + "cardamom" + "elderflower" + ]; + } + ]; params = { module = [ "default" ]; - node = [ "anise" "basil" "cardamom" "elderflower" ]; + node = [ + "anise" + "basil" + "cardamom" + "elderflower" + ]; }; relabel_configs = [ { @@ -295,17 +296,14 @@ } { target_label = "__address__"; - replacement = "${hosts.monitor.config.networking.hostName}:${ - toString - hosts.monitor.config.services.prometheus.exporters.pve.port - }"; + replacement = "${hosts.monitor.config.networking.hostName}:${toString hosts.monitor.config.services.prometheus.exporters.pve.port}"; } ]; } { job_name = "redis"; metrics_path = "/scrape"; - static_configs = [{ targets = [ "redis://controller:6379" ]; }]; + static_configs = [ { targets = [ "redis://controller:6379" ]; } ]; relabel_configs = [ { source_labels = [ "__address__" ]; @@ -317,61 +315,64 @@ } { target_label = "__address__"; - replacement = "${hosts.monitor.config.networking.hostName}:${ - toString - hosts.monitor.config.services.prometheus.exporters.redis.port - }"; + replacement = "${hosts.monitor.config.networking.hostName}:${toString hosts.monitor.config.services.prometheus.exporters.redis.port}"; } ]; } { job_name = "htpc_gpu"; - static_configs = [{ - targets = [ - "${hosts.htpc.config.networking.hostName}:${ - toString - hosts.htpc.config.services.prometheus.exporters.dcgm-exporter.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.prometheus.exporters.dcgm-exporter.port}" + ]; + } + ]; } { job_name = "gatus"; - static_configs = [{ - targets = [ - "${hosts.monitor.config.networking.hostName}:${ - toString hosts.monitor.config.services.gatus.settings.web.port - }" - ]; - }]; + static_configs = [ + { + targets = [ + "${hosts.monitor.config.networking.hostName}:${toString hosts.monitor.config.services.gatus.settings.web.port}" + ]; + } + ]; scrape_interval = "30s"; } { job_name = "frigate"; metrics_path = "/api/metrics"; - static_configs = [{ targets = [ "htpc:5000" ]; }]; + static_configs = [ { targets = [ "htpc:5000" ]; } ]; scrape_interval = "15s"; } { job_name = "speedtest-tracker"; metrics_path = "/prometheus"; - static_configs = [{ targets = [ "speedtest-tracker.e10.camp" ]; }]; + static_configs = [ { targets = [ "speedtest-tracker.e10.camp" ]; } ]; scrape_interval = "45m"; } - ] ++ lib.flatten (lib.mapAttrsToList (_: host: - lib.mapAttrsToList (name: backup: - lib.optional backup.exporter.enable { - job_name = "restic_${host.config.networking.hostName}_${ + ] + ++ lib.flatten ( + lib.mapAttrsToList ( + _: host: + lib.mapAttrsToList ( + name: backup: + lib.optional backup.exporter.enable { + job_name = "restic_${host.config.networking.hostName}_${ builtins.replaceStrings [ "-" ] [ "_" ] name }"; - metrics_path = "/"; - scrape_interval = "30s"; - static_configs = [{ - targets = [ - "${host.config.networking.hostName}:${ - toString backup.exporter.port - }" + metrics_path = "/"; + scrape_interval = "30s"; + static_configs = [ + { + targets = [ + "${host.config.networking.hostName}:${toString backup.exporter.port}" + ]; + } ]; - }]; - }) host.config.services.restic.backups) hosts); + } + ) host.config.services.restic.backups + ) hosts + ); } diff --git a/hosts/omnibus/configuration.nix b/hosts/omnibus/configuration.nix index 6c26782..ae44a13 100644 --- a/hosts/omnibus/configuration.nix +++ b/hosts/omnibus/configuration.nix @@ -1,6 +1,16 @@ -{ config, pkgs, suites, profiles, ... }: { - imports = with suites; - core ++ proxmox-vm ++ [ +{ + config, + pkgs, + suites, + profiles, + ... +}: +{ + imports = + with suites; + core + ++ proxmox-vm + ++ [ profiles.backups.restic-rest.default profiles.communications.postfix.default profiles.databases.postgresql @@ -17,14 +27,20 @@ profiles.users.files profiles.users.nicole profiles.users.proxmox - ] ++ [ ./hardware-configuration.nix ./disk-config.nix ]; + ] + ++ [ + ./hardware-configuration.nix + ./disk-config.nix + ]; - boot.loader.grub.devices = - [ "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0" ]; + boot.loader.grub.devices = [ "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0" ]; deployment = { buildOnTarget = true; - tags = [ "@vm" "@build-on-target" ]; + tags = [ + "@vm" + "@build-on-target" + ]; }; satan.address = "10.10.1.101"; @@ -40,34 +56,34 @@ interfaces = { vlan10.ipv4 = { - routes = [{ - address = "0.0.0.0"; - prefixLength = 0; - via = "10.10.0.1"; - options.src = "10.10.1.101"; - options.onlink = ""; - }]; - addresses = [{ - address = "10.10.1.101"; - prefixLength = 24; - }]; + routes = [ + { + address = "0.0.0.0"; + prefixLength = 0; + via = "10.10.0.1"; + options.src = "10.10.1.101"; + options.onlink = ""; + } + ]; + addresses = [ + { + address = "10.10.1.101"; + prefixLength = 24; + } + ]; }; }; }; - services.nfs.server.exports = let - blockbusterOptions = - "rw,sync,no_subtree_check,insecure,crossmnt,all_squash,anonuid=${ - toString config.users.users.blockbuster.uid - },anongid=${toString config.users.groups.blockbuster.gid}"; - filesOptions = - "rw,sync,no_subtree_check,insecure,crossmnt,all_squash,anonuid=${ - toString config.users.users.files.uid - },anongid=${toString config.users.groups.files.gid}"; - in '' - ${config.disko.devices.zpool.blockbuster.datasets.root.mountpoint} 192.168.0.0/16(${blockbusterOptions}) 100.0.0.0/8(${blockbusterOptions}) 10.10.0.0/16(${blockbusterOptions}) - ${config.disko.devices.zpool.files.datasets.root.mountpoint} 192.168.0.0/16(${filesOptions}) 100.0.0.0/8(${filesOptions}) 10.10.0.0/16(${filesOptions}) - ''; + services.nfs.server.exports = + let + blockbusterOptions = "rw,sync,no_subtree_check,insecure,crossmnt,all_squash,anonuid=${toString config.users.users.blockbuster.uid},anongid=${toString config.users.groups.blockbuster.gid}"; + filesOptions = "rw,sync,no_subtree_check,insecure,crossmnt,all_squash,anonuid=${toString config.users.users.files.uid},anongid=${toString config.users.groups.files.gid}"; + in + '' + ${config.disko.devices.zpool.blockbuster.datasets.root.mountpoint} 192.168.0.0/16(${blockbusterOptions}) 100.0.0.0/8(${blockbusterOptions}) 10.10.0.0/16(${blockbusterOptions}) + ${config.disko.devices.zpool.files.datasets.root.mountpoint} 192.168.0.0/16(${filesOptions}) 100.0.0.0/8(${filesOptions}) 10.10.0.0/16(${filesOptions}) + ''; services.samba.settings = { proxmox = { @@ -107,10 +123,8 @@ services.restic.backups.files-rsync-net = { initialize = true; - repository = - "sftp://de2228@de2228.rsync.net/${config.networking.hostName}/files"; - extraOptions = - [ "sftp.args='-i ${config.sops.secrets.rsync_net_ssh_key.path}'" ]; + repository = "sftp://de2228@de2228.rsync.net/${config.networking.hostName}/files"; + extraOptions = [ "sftp.args='-i ${config.sops.secrets.rsync_net_ssh_key.path}'" ]; passwordFile = config.sops.secrets.restic_backup_password.path; paths = [ "/data/files" ]; exclude = [ @@ -123,7 +137,11 @@ Persistent = true; RandomizedDelaySec = "1h"; }; - pruneOpts = [ "--keep-daily 1" "--keep-weekly 1" "--keep-monthly 1" ]; + pruneOpts = [ + "--keep-daily 1" + "--keep-weekly 1" + "--keep-monthly 1" + ]; }; system.stateVersion = "24.05"; diff --git a/hosts/omnibus/disk-config.nix b/hosts/omnibus/disk-config.nix index e820b00..e182d0e 100644 --- a/hosts/omnibus/disk-config.nix +++ b/hosts/omnibus/disk-config.nix @@ -17,99 +17,102 @@ let hdd6 = "/dev/disk/by-id/ata-ST20000NM007D-3DJ103_ZVT5MMBQ"; hdd7 = "/dev/disk/by-id/ata-WDC_WD181KFGX-68CKWN0_PNG2ZUJP"; }; -in { +in +{ disko.devices = { - disk = let - addToZfsPool = { device, pool }: { - inherit device; - - type = "disk"; - content = { - type = "gpt"; - partitions = { - zfs = { - size = "100%"; - content = { - inherit pool; - type = "zfs"; + disk = + let + addToZfsPool = { device, pool }: { + inherit device; + + type = "disk"; + content = { + type = "gpt"; + partitions = { + zfs = { + size = "100%"; + content = { + inherit pool; + type = "zfs"; + }; }; }; }; }; - }; - in { - root = { - type = "disk"; - device = disks.scsi; - content = { - type = "gpt"; - partitions = { - boot = { - size = "1M"; - type = "EF02"; - }; + in + { + root = { + type = "disk"; + device = disks.scsi; + content = { + type = "gpt"; + partitions = { + boot = { + size = "1M"; + type = "EF02"; + }; - ESP = { - size = "1G"; - type = "EF00"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; }; - }; - zfs = { - size = "100%"; - content = { - type = "zfs"; - pool = "zroot"; + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; }; }; }; }; - }; - hdd0 = addToZfsPool { - device = disks.hdd0; - pool = "files"; - }; + hdd0 = addToZfsPool { + device = disks.hdd0; + pool = "files"; + }; - hdd1 = addToZfsPool { - device = disks.hdd1; - pool = "files"; - }; + hdd1 = addToZfsPool { + device = disks.hdd1; + pool = "files"; + }; - hdd2 = addToZfsPool { - device = disks.hdd2; - pool = "blockbuster"; - }; + hdd2 = addToZfsPool { + device = disks.hdd2; + pool = "blockbuster"; + }; - hdd3 = addToZfsPool { - device = disks.hdd3; - pool = "blockbuster"; - }; + hdd3 = addToZfsPool { + device = disks.hdd3; + pool = "blockbuster"; + }; - hdd4 = addToZfsPool { - device = disks.hdd4; - pool = "blockbuster"; - }; + hdd4 = addToZfsPool { + device = disks.hdd4; + pool = "blockbuster"; + }; - hdd5 = addToZfsPool { - device = disks.hdd5; - pool = "blockbuster"; - }; + hdd5 = addToZfsPool { + device = disks.hdd5; + pool = "blockbuster"; + }; - hdd6 = addToZfsPool { - device = disks.hdd6; - pool = "blockbuster"; - }; + hdd6 = addToZfsPool { + device = disks.hdd6; + pool = "blockbuster"; + }; - hdd7 = addToZfsPool { - device = disks.hdd7; - pool = "blockbuster"; + hdd7 = addToZfsPool { + device = disks.hdd7; + pool = "blockbuster"; + }; }; - }; zpool = { zroot = { diff --git a/hosts/omnibus/hardware-configuration.nix b/hosts/omnibus/hardware-configuration.nix index 1ee6157..9b1ce98 100644 --- a/hosts/omnibus/hardware-configuration.nix +++ b/hosts/omnibus/hardware-configuration.nix @@ -1,7 +1,14 @@ { boot = { - initrd.availableKernelModules = - [ "ata_piix" "uhci_hcd" "sym53c8xx" "mpt3sas" "nvme" "sd_mod" "sr_mod" ]; + initrd.availableKernelModules = [ + "ata_piix" + "uhci_hcd" + "sym53c8xx" + "mpt3sas" + "nvme" + "sd_mod" + "sr_mod" + ]; kernelModules = [ "kvm-intel" ]; extraModulePackages = [ ]; diff --git a/lib/default.nix b/lib/default.nix index 8f094de..c0af7d0 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -5,4 +5,7 @@ let src = ./src; inputs = { inherit (inputs.nixpkgs) lib; }; }; -in { flake.lib = lib; } +in +{ + flake.lib = lib; +} diff --git a/lib/src/generators.nix b/lib/src/generators.nix index bcc1671..2120241 100644 --- a/lib/src/generators.nix +++ b/lib/src/generators.nix @@ -7,32 +7,42 @@ let inherit (lib.generators) toINIWithGlobalSection mkKeyValueDefault; inherit (builtins) isAttrs isString; - toXML = { spacing ? 2, rootName ? "Root", xmlns ? { - xsi = "http://www.w3.org/2001/XMLSchema-instance"; - xsd = "http://www.w3.org/2001/XMLSchema"; - }, }: + toXML = + { + spacing ? 2, + rootName ? "Root", + xmlns ? { + xsi = "http://www.w3.org/2001/XMLSchema-instance"; + xsd = "http://www.w3.org/2001/XMLSchema"; + }, + }: let indent = level: fixedWidthString (level * spacing) " " ""; - makeXmlns = if xmlns != { } then - concatStringsSep " " - (mapAttrsToList (name: value: ''xmlns:${name}="${value}"'') xmlns) - else - ""; + makeXmlns = + if xmlns != { } then + concatStringsSep " " (mapAttrsToList (name: value: ''xmlns:${name}="${value}"'') xmlns) + else + ""; - escapeValue = value: + escapeValue = + value: if (builtins.match ".*.*" value) != null then value else - builtins.replaceStrings [ "&" "<" ">" "'" ''"'' ] [ - "&" - "<" - ">" - "'" - """ - ] value; + builtins.replaceStrings + [ "&" "<" ">" "'" ''"'' ] + [ + "&" + "<" + ">" + "'" + """ + ] + value; - makeValue = level: value: + makeValue = + level: value: if builtins.isBool value then (if value then "true" else "false") else if builtins.isInt value then @@ -48,58 +58,76 @@ let else if builtins.isList value then if value == [ ] then "" - else '' + else + '' - ${concatStringsSep "\n" (map (value: - if builtins.isAttrs value then - attrsToXML (level + 1) "" value - else - throw "List elements must be attribute sets") value)} - ${indent level}'' + ${concatStringsSep "\n" ( + map ( + value: + if builtins.isAttrs value then + attrsToXML (level + 1) "" value + else + throw "List elements must be attribute sets" + ) value + )} + ${indent level}'' else throw "Unsupported type for value: ${builtins.typeOf value}"; - makeTag = level: tagName: value: + makeTag = + level: tagName: value: let val = makeValue level value; ind = indent level; - in if val == "" then - "${ind}<${tagName} />" - else - "${ind}<${tagName}>${val}"; + in + if val == "" then "${ind}<${tagName} />" else "${ind}<${tagName}>${val}"; - makeElements = level: attrs: - concatStringsSep "\n" (mapAttrsToList (tagName: value: - if builtins.isAttrs value then - attrsToXML level tagName value - else - makeTag level tagName value) attrs); + makeElements = + level: attrs: + concatStringsSep "\n" ( + mapAttrsToList ( + tagName: value: + if builtins.isAttrs value then attrsToXML level tagName value else makeTag level tagName value + ) attrs + ); - attrsToXML = level: tagName: value: - let ind = indent level; - in if tagName == "" then + attrsToXML = + level: tagName: value: + let + ind = indent level; + in + if tagName == "" then makeElements level value - else if builtins.isAttrs value then '' - ${ind}<${tagName}> - ${makeElements (level + 1) value} - ${ind}'' else + else if builtins.isAttrs value then + '' + ${ind}<${tagName}> + ${makeElements (level + 1) value} + ${ind}'' + else makeTag level tagName value; - in attrs: '' + in + attrs: '' <${rootName} ${makeXmlns}> ${attrsToXML 1 "" attrs} ''; - toINI = { globalSection, sections }: + toINI = + { globalSection, sections }: toINIWithGlobalSection { - mkKeyValue = k: v: + mkKeyValue = + k: v: if isAttrs v then '' [[${k}]] - '' + toINIWithGlobalSection { } { globalSection = v; } + '' + + toINIWithGlobalSection { } { globalSection = v; } else mkKeyValueDefault { mkValueString = v: if isString v then "${v}" else toString v; } "=" k v; } { inherit globalSection sections; }; -in { inherit toXML toINI; } +in +{ + inherit toXML toINI; +} diff --git a/lib/src/utils.nix b/lib/src/utils.nix index 9521b0f..1b149c8 100644 --- a/lib/src/utils.nix +++ b/lib/src/utils.nix @@ -7,23 +7,31 @@ let # # Type: # tree :: { [ name :: string ] :: ( leaf :: (T | ( branch :: ( leaf | tree )))), ... } -> { string -> leaf } - flattenTree = tree: + flattenTree = + tree: let - inherit (builtins) concatStringsSep isPath isAttrs foldl' attrNames; + inherit (builtins) + concatStringsSep + isPath + isAttrs + foldl' + attrNames + ; # Takes an accumulator attribute set, a path in the form of a list of strings, and a value of what is at that # path (either an attribute set, meaning a subdirectory; a path, meaning it's a file; or nothing, meaning it's an # empty directory). Will turn the path into a dot-separated string (`foo/bar/biz` turns into `foo.bar.biz`) and # will recurse over the subdirectory if it's an attribute set, add to our accumulator if it's a file, or just # return the accumulator if it's neither - flatten = acc: path: leaf: + flatten = + acc: path: leaf: # If the value is a path, then format the path as a dot-separated string and add this path and value to the if isPath leaf then (acc // { "${concatStringsSep "." path}" = leaf; }) - # If the value is a set of attributes, this means there is a subtree -- run again for those attributes + # If the value is a set of attributes, this means there is a subtree -- run again for those attributes else if isAttrs leaf then (recurse acc path leaf) - # If it's not a value or a path (meaning null), just return the accumulated results without doing anything + # If it's not a value or a path (meaning null), just return the accumulated results without doing anything else acc; @@ -34,10 +42,14 @@ let # # `flatten` against that path and leaf # let op = acc: leaf: (flatten (acc (path ++ [ leaf ]) tree.${leaf})); # in foldl' (op acc (attrNames tree)); - recurse = acc: path: leaf: - foldl' (acc: key: flatten acc (path ++ [ key ]) leaf.${key}) acc - (attrNames leaf); + recurse = + acc: path: leaf: + foldl' (acc: key: flatten acc (path ++ [ key ]) leaf.${key}) acc (attrNames leaf); # Call `recurse`, starting with an empty accumulator, an empty path, and a tree to run the function against - in recurse { } [ ] tree; -in { inherit flattenTree; } + in + recurse { } [ ] tree; +in +{ + inherit flattenTree; +} diff --git a/modules/deploy/ansible.nix b/modules/deploy/ansible.nix index b4fcf90..050d447 100644 --- a/modules/deploy/ansible.nix +++ b/modules/deploy/ansible.nix @@ -1,17 +1,22 @@ { - perSystem = { config, lib, pkgs, ... }: { - devShells.ansible = pkgs.mkShell { - nativeBuildInputs = with pkgs; [ - ansible - ansible-lint - python313Packages.httpx - ]; + perSystem = + { + config, + lib, + pkgs, + ... + }: + { + devShells.ansible = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ + ansible + ansible-lint + python313Packages.httpx + ]; - shellHook = '' - export ANSIBLE_HOME="$(${ - lib.getExe config.flake-root.package - })/deploy/ansible"; - ''; + shellHook = '' + export ANSIBLE_HOME="$(${lib.getExe config.flake-root.package})/deploy/ansible"; + ''; + }; }; - }; } diff --git a/modules/deploy/configuration.nix b/modules/deploy/configuration.nix index ae79723..bbefc04 100644 --- a/modules/deploy/configuration.nix +++ b/modules/deploy/configuration.nix @@ -1,31 +1,34 @@ -{ self, lib, withSystem, inputs, ... }: +{ + self, + lib, + withSystem, + inputs, + ... +}: with lib; let - deployableConfigurations = - filterAttrs (_: c: c.config.deployment.deployable) self.nixosConfigurations; + deployableConfigurations = filterAttrs ( + _: c: c.config.deployment.deployable + ) self.nixosConfigurations; mkColmenaMeta = configurations: { meta = { nixpkgs = withSystem "x86_64-linux" (ctx: ctx.pkgs); - nodeNixpkgs = - mapAttrs (_: configuration: configuration.pkgs) configurations; - nodeSpecialArgs = - mapAttrs (_: configuration: configuration._module.specialArgs) - configurations; + nodeNixpkgs = mapAttrs (_: configuration: configuration.pkgs) configurations; + nodeSpecialArgs = mapAttrs (_: configuration: configuration._module.specialArgs) configurations; }; }; - mkColmenaNodes = configurations: - (mapAttrs - (_name: configuration: { imports = configuration._module.args.modules; }) - configurations); + mkColmenaNodes = + configurations: + (mapAttrs (_name: configuration: { imports = configuration._module.args.modules; }) configurations); - mkColmenaOutput = configurations: - (mkColmenaMeta configurations // mkColmenaNodes configurations); + mkColmenaOutput = configurations: (mkColmenaMeta configurations // mkColmenaNodes configurations); -in { +in +{ flake = { colmena = mkColmenaOutput deployableConfigurations; colmenaHive = inputs.colmena.lib.makeHive self.outputs.colmena; diff --git a/modules/deploy/shell.nix b/modules/deploy/shell.nix index dc76c20..2acc961 100644 --- a/modules/deploy/shell.nix +++ b/modules/deploy/shell.nix @@ -1,31 +1,40 @@ { self, inputs, ... }: -let l = inputs.nixpkgs.lib // builtins; -in { +let + l = inputs.nixpkgs.lib // builtins; +in +{ perSystem = { pkgs, inputs', ... }: { - devShells.deploy = let - sshConfig = let - hostConfigurations = l.concatStringsSep "\n" (l.attrValues (l.mapAttrs - (name: configuration: '' - Host ${name} - Hostname ${configuration.config.deployment.targetHost} - '') self.nixosConfigurations)); - in pkgs.writeText "ssh_config" '' - ${hostConfigurations} + devShells.deploy = + let + sshConfig = + let + hostConfigurations = l.concatStringsSep "\n" ( + l.attrValues ( + l.mapAttrs (name: configuration: '' + Host ${name} + Hostname ${configuration.config.deployment.targetHost} + '') self.nixosConfigurations + ) + ); + in + pkgs.writeText "ssh_config" '' + ${hostConfigurations} - Host * - User root - IdentityFile keys/id_rsa - ''; + Host * + User root + IdentityFile keys/id_rsa + ''; - in pkgs.mkShell { - nativeBuildInputs = with inputs'; [ - colmena.packages.colmena - nixos-anywhere.packages.nixos-anywhere - ]; + in + pkgs.mkShell { + nativeBuildInputs = with inputs'; [ + colmena.packages.colmena + nixos-anywhere.packages.nixos-anywhere + ]; - shellHook = '' - export SSH_CONFIG_FILE=${sshConfig} - ''; - }; + shellHook = '' + export SSH_CONFIG_FILE=${sshConfig} + ''; + }; }; } diff --git a/modules/deploy/terraform.nix b/modules/deploy/terraform.nix index 5f46179..4b183ff 100644 --- a/modules/deploy/terraform.nix +++ b/modules/deploy/terraform.nix @@ -1,8 +1,10 @@ { - perSystem = { config, pkgs, ... }: + perSystem = + { config, pkgs, ... }: let tflintWithPlugins = pkgs.tflint.withPlugins (p: [ p.tflint-ruleset-aws ]); - in { + in + { packages = { tf = pkgs.writeShellScriptBin "tf" '' set -euo pipefail diff --git a/modules/development/ci.nix b/modules/development/ci.nix index cbc2159..7146da6 100644 --- a/modules/development/ci.nix +++ b/modules/development/ci.nix @@ -1,168 +1,183 @@ { self, inputs, ... }: -let l = inputs.nixpkgs.lib // builtins; -in { +let + l = inputs.nixpkgs.lib // builtins; +in +{ imports = [ inputs.actions-nix.flakeModules.default ]; - flake.actions-nix.workflows = let - actions = { - checkout = "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd"; - install-lix = - "samueldr/lix-gha-installer-action@7b7f14d320d6aacfb65bd1ef761566b3b69e474c"; - ssh-agent = - "webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555"; - attic = "ryanccn/attic-action@1887fd507f03327c96c64cca30118c96eb17fdad"; - cachix = "cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c"; - }; - setup = [ - { - name = "Checkout code"; - uses = actions.checkout; - } - { - name = "Install Lix"; - uses = actions.install-lix; - "with" = { - extra_nix_config = '' - accept-flake-config = true - max-jobs = auto - ''; - }; - } - { - name = "Add SSH keys to ssh-agent"; - uses = actions.ssh-agent; - "with" = { ssh-private-key = "\${{ secrets.SECRETS_DEPLOY_KEY }}"; }; - } - { - name = "Setup Attic cache"; - uses = actions.attic; - "with" = { - cache = "e10"; - endpoint = "https://cache.e10.camp"; - token = "\${{ secrets.ATTIC_TOKEN }}"; - }; - } - { - name = "Use Cachix store"; - uses = actions.cachix; - "with" = { - authToken = "\${{ secrets.CACHIX_AUTH_TOKEN }}"; - installCommand = - "nix profile install github:NixOS/nixpkgs/nixpkgs-unstable#cachix"; - name = "e10"; - }; - } - ]; - in { - ".github/workflows/check.yml" = { - name = "Check"; - jobs = { - check = { - name = "Check flake"; - steps = setup ++ [{ + flake.actions-nix.workflows = + let + actions = { + checkout = "actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd"; + install-lix = "samueldr/lix-gha-installer-action@7b7f14d320d6aacfb65bd1ef761566b3b69e474c"; + ssh-agent = "webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555"; + attic = "ryanccn/attic-action@1887fd507f03327c96c64cca30118c96eb17fdad"; + cachix = "cachix/cachix-action@1eb2ef646ac0255473d23a5907ad7b04ce94065c"; + }; + setup = [ + { + name = "Checkout code"; + uses = actions.checkout; + } + { + name = "Install Lix"; + uses = actions.install-lix; + "with" = { + extra_nix_config = '' + accept-flake-config = true + max-jobs = auto + ''; + }; + } + { + name = "Add SSH keys to ssh-agent"; + uses = actions.ssh-agent; + "with" = { + ssh-private-key = "\${{ secrets.SECRETS_DEPLOY_KEY }}"; + }; + } + { + name = "Setup Attic cache"; + uses = actions.attic; + "with" = { + cache = "e10"; + endpoint = "https://cache.e10.camp"; + token = "\${{ secrets.ATTIC_TOKEN }}"; + }; + } + { + name = "Use Cachix store"; + uses = actions.cachix; + "with" = { + authToken = "\${{ secrets.CACHIX_AUTH_TOKEN }}"; + installCommand = "nix profile install github:NixOS/nixpkgs/nixpkgs-unstable#cachix"; + name = "e10"; + }; + } + ]; + in + { + ".github/workflows/check.yml" = { + name = "Check"; + jobs = { + check = { name = "Check flake"; - run = "nix flake check --impure --accept-flake-config --show-trace"; - }]; + steps = setup ++ [ + { + name = "Check flake"; + run = "nix flake check --impure --accept-flake-config --show-trace"; + } + ]; + }; }; }; - }; - ".github/workflows/hosts.yml" = { - name = "Build hosts"; - jobs = { - buildX86System = { - name = "Build host system (x86)"; - "runs-on" = "ubuntu-latest"; - "if" = '' - github.ref == 'refs/heads/main' || - contains(github.event.head_commit.message, '[build]') - ''; - strategy.matrix.host = l.attrNames (l.filterAttrs - (_: host: host.config.nixpkgs.system == "x86_64-linux") - self.nixosConfigurations); - steps = setup ++ [ - { - name = "Clean up storage"; - run = '' - sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL - sudo docker image prune --all --force - sudo docker builder prune -a - ''; - } - { - name = "Build \${{ matrix.host }} host system"; - run = '' - nix build .#nixosConfigurations.''${{ matrix.host }}.config.system.build.toplevel --accept-flake-config --show-trace - ''; - } - ]; - }; - buildARMSystem = { - name = "Build host system (ARM)"; - "runs-on" = "ubuntu-24.04-arm"; - "if" = '' - github.ref == 'refs/heads/main' || - contains(github.event.head_commit.message, '[build]') - ''; - strategy.matrix.host = l.attrNames (l.filterAttrs - (_: host: host.config.nixpkgs.system == "aarch64-linux") - self.nixosConfigurations); - steps = setup ++ [{ - name = "Build \${{ matrix.host }} host system"; - run = '' - nix build .#nixosConfigurations.''${{ matrix.host }}.config.system.build.toplevel --accept-flake-config --show-trace + ".github/workflows/hosts.yml" = { + name = "Build hosts"; + jobs = { + buildX86System = { + name = "Build host system (x86)"; + "runs-on" = "ubuntu-latest"; + "if" = '' + github.ref == 'refs/heads/main' || + contains(github.event.head_commit.message, '[build]') ''; - }]; - }; - buildQEMUImage = { - name = "Build QEMU image"; - "runs-on" = "ubuntu-latest"; - "if" = '' - github.ref == 'refs/heads/main' || - contains(github.event.head_commit.message, '[build]') - ''; - strategy.matrix.host = l.attrNames - (l.filterAttrs (_: host: host.config.deployment.incusVirtualMachine) - self.nixosConfigurations); - steps = setup ++ [{ - name = "Build \${{ matrix.host }} host QEMU image and metadata"; - run = '' - nix build .#nixosConfigurations.''${{ matrix.host }}.config.system.build.qemuImage .#nixosConfigurations.''${{ matrix.host }}.config.system.build.metadata --accept-flake-config --show-trace + strategy.matrix.host = l.attrNames ( + l.filterAttrs (_: host: host.config.nixpkgs.system == "x86_64-linux") self.nixosConfigurations + ); + steps = setup ++ [ + { + name = "Clean up storage"; + run = '' + sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL + sudo docker image prune --all --force + sudo docker builder prune -a + ''; + } + { + name = "Build \${{ matrix.host }} host system"; + run = '' + nix build .#nixosConfigurations.''${{ matrix.host }}.config.system.build.toplevel --accept-flake-config --show-trace + ''; + } + ]; + }; + buildARMSystem = { + name = "Build host system (ARM)"; + "runs-on" = "ubuntu-24.04-arm"; + "if" = '' + github.ref == 'refs/heads/main' || + contains(github.event.head_commit.message, '[build]') + ''; + strategy.matrix.host = l.attrNames ( + l.filterAttrs (_: host: host.config.nixpkgs.system == "aarch64-linux") self.nixosConfigurations + ); + steps = setup ++ [ + { + name = "Build \${{ matrix.host }} host system"; + run = '' + nix build .#nixosConfigurations.''${{ matrix.host }}.config.system.build.toplevel --accept-flake-config --show-trace + ''; + } + ]; + }; + buildQEMUImage = { + name = "Build QEMU image"; + "runs-on" = "ubuntu-latest"; + "if" = '' + github.ref == 'refs/heads/main' || + contains(github.event.head_commit.message, '[build]') ''; - }]; + strategy.matrix.host = l.attrNames ( + l.filterAttrs (_: host: host.config.deployment.incusVirtualMachine) self.nixosConfigurations + ); + steps = setup ++ [ + { + name = "Build \${{ matrix.host }} host QEMU image and metadata"; + run = '' + nix build .#nixosConfigurations.''${{ matrix.host }}.config.system.build.qemuImage .#nixosConfigurations.''${{ matrix.host }}.config.system.build.metadata --accept-flake-config --show-trace + ''; + } + ]; + }; }; }; - }; - ".github/workflows/packages.yml" = { - name = "Build packages"; - on.push.paths = [ "flake.lock" "modules/packages/**/*.nix" ]; - jobs.buildPackage = { - name = "Build package"; - runs-on = "\${{ matrix.os }}"; - strategy.matrix = { - package = l.filter (name: name != "render-workflows") - (l.attrNames self.packages.x86_64-linux); - architecture = [ "x86_64-linux" "aarch64-linux" ]; - include = [ - { - architecture = "x86_64-linux"; - os = "ubuntu-24.04"; - } + ".github/workflows/packages.yml" = { + name = "Build packages"; + on.push.paths = [ + "flake.lock" + "modules/packages/**/*.nix" + ]; + jobs.buildPackage = { + name = "Build package"; + runs-on = "\${{ matrix.os }}"; + strategy.matrix = { + package = l.filter (name: name != "render-workflows") (l.attrNames self.packages.x86_64-linux); + architecture = [ + "x86_64-linux" + "aarch64-linux" + ]; + include = [ + { + architecture = "x86_64-linux"; + os = "ubuntu-24.04"; + } + { + architecture = "aarch64-linux"; + os = "ubuntu-24.04-arm"; + } + ]; + }; + steps = setup ++ [ { - architecture = "aarch64-linux"; - os = "ubuntu-24.04-arm"; + name = "Build \${{ matrix.package }} (\${{ matrix.architecture }}) package"; + run = '' + nix build .#packages.''${{ matrix.architecture }}.''${{ matrix.package }} --keep-going --print-build-logs --show-trace --verbose + ''; } ]; }; - steps = setup ++ [{ - name = - "Build \${{ matrix.package }} (\${{ matrix.architecture }}) package"; - run = '' - nix build .#packages.''${{ matrix.architecture }}.''${{ matrix.package }} --keep-going --print-build-logs --show-trace --verbose - ''; - }]; }; }; - }; } diff --git a/modules/development/flake-root.nix b/modules/development/flake-root.nix index 8c3d55a..2fa68d4 100644 --- a/modules/development/flake-root.nix +++ b/modules/development/flake-root.nix @@ -1,11 +1,18 @@ { inputs, ... }: { imports = [ inputs.flake-root.flakeModule ]; - perSystem = { config, lib, pkgs, ... }: { - devShells.flake-root = pkgs.mkShell { - shellHook = '' - export FLAKE_ROOT="$(${lib.getExe config.flake-root.package})" - ''; + perSystem = + { + config, + lib, + pkgs, + ... + }: + { + devShells.flake-root = pkgs.mkShell { + shellHook = '' + export FLAKE_ROOT="$(${lib.getExe config.flake-root.package})" + ''; + }; }; - }; } diff --git a/modules/development/shell.nix b/modules/development/shell.nix index 0457739..24d3ce0 100644 --- a/modules/development/shell.nix +++ b/modules/development/shell.nix @@ -1,9 +1,17 @@ { self, ... }: { perSystem = { pkgs, system, ... }: { devShells.default = pkgs.mkShell { - inputsFrom = let - shellNames = [ "ansible" "deploy" "flake-root" "terraform" "treefmt" ]; - in map (shell: self.devShells.${system}.${shell}) shellNames; + inputsFrom = + let + shellNames = [ + "ansible" + "deploy" + "flake-root" + "terraform" + "treefmt" + ]; + in + map (shell: self.devShells.${system}.${shell}) shellNames; nativeBuildInputs = with pkgs; [ attic-client @@ -17,28 +25,27 @@ statix ]; - shellHook = let - sops = pkgs.lib.getExe' pkgs.sops "sops"; - setSopsValueToEnvironmentVariable = key: secretsFile: '' - export ${key}=$(${sops} -d --extract '["${key}"]' ${secretsFile}) - ''; - in '' - export SOPS_AGE_KEY_FILE=$HOME/.config/sops/age/keys.txt + shellHook = + let + sops = pkgs.lib.getExe' pkgs.sops "sops"; + setSopsValueToEnvironmentVariable = key: secretsFile: '' + export ${key}=$(${sops} -d --extract '["${key}"]' ${secretsFile}) + ''; + in + '' + export SOPS_AGE_KEY_FILE=$HOME/.config/sops/age/keys.txt - ${setSopsValueToEnvironmentVariable "AWS_ACCESS_KEY_ID" - "./secrets.json"} - ${setSopsValueToEnvironmentVariable "AWS_SECRET_ACCESS_KEY" - "./secrets.json"} + ${setSopsValueToEnvironmentVariable "AWS_ACCESS_KEY_ID" "./secrets.json"} + ${setSopsValueToEnvironmentVariable "AWS_SECRET_ACCESS_KEY" "./secrets.json"} - export AWS_REGION="us-east-2" + export AWS_REGION="us-east-2" - ${setSopsValueToEnvironmentVariable "OMNIBUS_PASSWORD" "./secrets.json"} - ${setSopsValueToEnvironmentVariable "OPNSENSE_API_KEY" "./secrets.json"} - ${setSopsValueToEnvironmentVariable "OPNSENSE_API_SECRET" - "./secrets.json"} + ${setSopsValueToEnvironmentVariable "OMNIBUS_PASSWORD" "./secrets.json"} + ${setSopsValueToEnvironmentVariable "OPNSENSE_API_KEY" "./secrets.json"} + ${setSopsValueToEnvironmentVariable "OPNSENSE_API_SECRET" "./secrets.json"} - export TAILSCALE_AUTH_KEY=$(${sops} -d --extract '["tailscale_auth_key"]' ./modules/profiles/networking/tailscale/secrets.json) - ''; + export TAILSCALE_AUTH_KEY=$(${sops} -d --extract '["tailscale_auth_key"]' ./modules/profiles/networking/tailscale/secrets.json) + ''; }; }; } diff --git a/modules/development/treefmt.nix b/modules/development/treefmt.nix index d50816d..c8979cb 100644 --- a/modules/development/treefmt.nix +++ b/modules/development/treefmt.nix @@ -1,7 +1,8 @@ { inputs, ... }: { imports = [ inputs.treefmt.flakeModule ]; - perSystem = { config, pkgs, ... }: + perSystem = + { config, pkgs, ... }: let settings = { projectRootFile = "flake.nix"; @@ -9,10 +10,7 @@ actionlint.enable = true; deadnix.enable = true; terraform.enable = true; - nixfmt = { - enable = true; - package = pkgs.nixfmt-classic; - }; + nixfmt.enable = true; statix.enable = true; prettier.enable = true; }; @@ -25,14 +23,19 @@ ]; }; }; - in { - treefmt = { config = settings; }; + in + { + treefmt = { + config = settings; + }; formatter = inputs.treefmt.lib.mkWrapper pkgs settings; devShells.treefmt = pkgs.mkShell { - nativeBuildInputs = [ config.treefmt.build.wrapper ] - ++ (builtins.attrValues config.treefmt.build.programs); + nativeBuildInputs = [ + config.treefmt.build.wrapper + ] + ++ (builtins.attrValues config.treefmt.build.programs); }; }; } diff --git a/modules/nixos/deployment/options.nix b/modules/nixos/deployment/options.nix index 5e6b5f7..ca96eaa 100644 --- a/modules/nixos/deployment/options.nix +++ b/modules/nixos/deployment/options.nix @@ -17,5 +17,7 @@ with lib; }; }; - config = { deployment.targetHost = mkDefault config.networking.hostName; }; + config = { + deployment.targetHost = mkDefault config.networking.hostName; + }; } diff --git a/modules/nixos/services/attic-watch-store/default.nix b/modules/nixos/services/attic-watch-store/default.nix index f96c3d5..26aea1b 100644 --- a/modules/nixos/services/attic-watch-store/default.nix +++ b/modules/nixos/services/attic-watch-store/default.nix @@ -1,9 +1,16 @@ -{ config, pkgs, lib, ... }: +{ + config, + pkgs, + lib, + ... +}: with lib; -let cfg = config.services.attic-watch-store; -in { +let + cfg = config.services.attic-watch-store; +in +{ options.services.attic-watch-store = { enable = mkEnableOption "Enable Attic watch store daemon"; @@ -107,7 +114,6 @@ in { }; }; - users.groups = - mkIf (cfg.group == "attic-watch-store") { attic-watch-store.gid = 3450; }; + users.groups = mkIf (cfg.group == "attic-watch-store") { attic-watch-store.gid = 3450; }; }; } diff --git a/modules/nixos/services/bichon/default.nix b/modules/nixos/services/bichon/default.nix index 440f614..04341f5 100644 --- a/modules/nixos/services/bichon/default.nix +++ b/modules/nixos/services/bichon/default.nix @@ -1,4 +1,9 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; @@ -9,7 +14,8 @@ let BICHON_HTTP_PORT = toString cfg.port; BICHON_BIND_IP = cfg.listenAddress; }; -in { +in +{ options.services.bichon = { enable = mkEnableOption "Enable Bichon"; diff --git a/modules/nixos/services/caddy/default.nix b/modules/nixos/services/caddy/default.nix index 16486ff..3f7ac7d 100644 --- a/modules/nixos/services/caddy/default.nix +++ b/modules/nixos/services/caddy/default.nix @@ -2,70 +2,81 @@ with lib; -let cfg = config.services.caddy; -in { +let + cfg = config.services.caddy; +in +{ options.services.caddy = { proxies = mkOption { - type = types.attrsOf (types.submodule { - options = { - host = mkOption { type = types.attrs; }; - port = mkOption { type = types.oneOf [ types.port types.str ]; }; - extraReverseProxyConfig = mkOption { - type = types.lines; - default = ""; - }; - extraConfig = mkOption { - type = types.lines; - default = ""; - }; - protected = mkOption { - type = types.bool; - default = false; - }; - skipTLSVerify = mkOption { - type = types.bool; - default = false; - }; - acme = mkOption { - type = types.submodule { - options = { - generate = mkOption { - type = types.bool; - default = false; - }; - provider = mkOption { - type = types.str; - default = null; - }; - environmentFile = mkOption { - type = types.path; - default = null; + type = types.attrsOf ( + types.submodule { + options = { + host = mkOption { type = types.attrs; }; + port = mkOption { + type = types.oneOf [ + types.port + types.str + ]; + }; + extraReverseProxyConfig = mkOption { + type = types.lines; + default = ""; + }; + extraConfig = mkOption { + type = types.lines; + default = ""; + }; + protected = mkOption { + type = types.bool; + default = false; + }; + skipTLSVerify = mkOption { + type = types.bool; + default = false; + }; + acme = mkOption { + type = types.submodule { + options = { + generate = mkOption { + type = types.bool; + default = false; + }; + provider = mkOption { + type = types.str; + default = null; + }; + environmentFile = mkOption { + type = types.path; + default = null; + }; }; }; + default = { }; }; - default = { }; }; - }; - }); + } + ); default = { }; }; }; config = mkIf cfg.enable { - services.caddy.virtualHosts = mapAttrs (name: value: + services.caddy.virtualHosts = mapAttrs ( + name: value: let - resolvedHost = if config.networking.hostName - == value.host.config.networking.hostName then - "localhost" - else - value.host.config.networking.hostName; + resolvedHost = + if config.networking.hostName == value.host.config.networking.hostName then + "localhost" + else + value.host.config.networking.hostName; autheliaForwardAuth = '' forward_auth localhost:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } ''; - in { + in + { logFormat = '' output file ${config.services.caddy.logDir}/access-${name}.log { roll_size 1GiB @@ -78,19 +89,18 @@ in { reverse_proxy ${resolvedHost}:${toString value.port} { ${value.extraReverseProxyConfig} - ${ - optionalString value.skipTLSVerify '' - transport http { - tls_insecure_skip_verify - } - '' - } + ${optionalString value.skipTLSVerify '' + transport http { + tls_insecure_skip_verify + } + ''} } ${value.extraConfig} ''; - } // lib.optionalAttrs value.acme.generate { useACMEHost = name; }) - cfg.proxies; + } + // lib.optionalAttrs value.acme.generate { useACMEHost = name; } + ) cfg.proxies; security.acme.certs = mapAttrs (name: value: { domain = name; diff --git a/modules/nixos/services/declutarr/default.nix b/modules/nixos/services/declutarr/default.nix index 39e3554..4502172 100644 --- a/modules/nixos/services/declutarr/default.nix +++ b/modules/nixos/services/declutarr/default.nix @@ -1,15 +1,19 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; let cfg = config.services.declutarr; format = pkgs.formats.yaml { }; - configFile = if cfg.config != null then - format.generate "configuration.yaml" cfg.config - else - cfg.configFile; -in { + configFile = + if cfg.config != null then format.generate "configuration.yaml" cfg.config else cfg.configFile; +in +{ options.services.declutarr = { enable = mkEnableOption "Enable Declutarr"; @@ -50,11 +54,12 @@ in { }; config = mkIf cfg.enable { - assertions = [{ - assertion = !(cfg.config != null && cfg.configFile != null); - message = - "Only one of `config` or `configFile` can be configured at the same time"; - }]; + assertions = [ + { + assertion = !(cfg.config != null && cfg.configFile != null); + message = "Only one of `config` or `configFile` can be configured at the same time"; + } + ]; systemd.tmpfiles.settings."10-declutarr" = { ${cfg.dataDir} = { diff --git a/modules/nixos/services/fileflows/node.nix b/modules/nixos/services/fileflows/node.nix index 89c331d..b27918e 100644 --- a/modules/nixos/services/fileflows/node.nix +++ b/modules/nixos/services/fileflows/node.nix @@ -1,9 +1,16 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; -let cfg = config.services.fileflows.node; -in { +let + cfg = config.services.fileflows.node; +in +{ options.services.fileflows.node = { enable = mkEnableOption "Enable FileFlows node"; @@ -59,17 +66,16 @@ in { }; "${cfg.binDir}"."L+".argument = "${ - pkgs.symlinkJoin { - name = "fileflows-node-extra-pkgs"; - paths = cfg.extraPkgs; - } - }/bin"; + pkgs.symlinkJoin { + name = "fileflows-node-extra-pkgs"; + paths = cfg.extraPkgs; + } + }/bin"; }; systemd.services.fileflows-server = { description = "FileFlows node"; - script = - "${cfg.package}/bin/node --no-gui --systemd-service --server ${cfg.serverUrl}"; + script = "${cfg.package}/bin/node --no-gui --systemd-service --server ${cfg.serverUrl}"; environment.FILEFLOWS_SERVER_BASE_DIR = cfg.dataDir; serviceConfig = { @@ -101,7 +107,6 @@ in { groups = mkIf (cfg.group == "fileflows") { fileflows = { }; }; }; - networking.firewall = - mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; } diff --git a/modules/nixos/services/fileflows/server.nix b/modules/nixos/services/fileflows/server.nix index a130726..15cc4f4 100644 --- a/modules/nixos/services/fileflows/server.nix +++ b/modules/nixos/services/fileflows/server.nix @@ -1,9 +1,16 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; -let cfg = config.services.fileflows.server; -in { +let + cfg = config.services.fileflows.server; +in +{ options.services.fileflows.server = { enable = mkEnableOption "Enable FileFlows server"; @@ -54,8 +61,7 @@ in { openFirewall = mkOption { type = types.bool; - description = - "Open ports in the firewall for the FileFlows web interface"; + description = "Open ports in the firewall for the FileFlows web interface"; default = false; }; }; @@ -70,19 +76,16 @@ in { }; "${cfg.binDir}"."L+".argument = "${ - pkgs.symlinkJoin { - name = "fileflows-server-extra-pkgs"; - paths = cfg.extraPkgs; - } - }/bin"; + pkgs.symlinkJoin { + name = "fileflows-server-extra-pkgs"; + paths = cfg.extraPkgs; + } + }/bin"; }; systemd.services.fileflows-server = { description = "FileFlows server"; - script = - "${cfg.package}/bin/server --no-gui --systemd-service --urls=http://[::]:${ - toString cfg.port - }"; + script = "${cfg.package}/bin/server --no-gui --systemd-service --urls=http://[::]:${toString cfg.port}"; environment.FILEFLOWS_SERVER_BASE_DIR = cfg.dataDir; serviceConfig = { @@ -114,7 +117,6 @@ in { groups = mkIf (cfg.group == "fileflows") { fileflows = { }; }; }; - networking.firewall = - mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; } diff --git a/modules/nixos/services/incus/default.nix b/modules/nixos/services/incus/default.nix index b65a38b..dce36c6 100644 --- a/modules/nixos/services/incus/default.nix +++ b/modules/nixos/services/incus/default.nix @@ -1,4 +1,9 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; let @@ -7,97 +12,106 @@ let isLocal = instance: lib.isDerivation instance.image; - imageAlias = instance: - if isLocal instance then instance.name else instance.image; - - applyDir = pkgs.linkFarm "incus-apply-config" (map (instance: { - name = "${instance.name}.yml"; - path = format.generate "${instance.name}.yml" { - inherit (instance) kind; - inherit (instance) name; - image = imageAlias instance; - inherit (instance) profiles; - inherit (instance) vm; - inherit (instance) config; - inherit (instance) devices; - }; - }) cfg.instances); + imageAlias = instance: if isLocal instance then instance.name else instance.image; + + applyDir = pkgs.linkFarm "incus-apply-config" ( + map (instance: { + name = "${instance.name}.yml"; + path = format.generate "${instance.name}.yml" { + inherit (instance) kind; + inherit (instance) name; + image = imageAlias instance; + inherit (instance) profiles; + inherit (instance) vm; + inherit (instance) config; + inherit (instance) devices; + }; + }) cfg.instances + ); - importScript = lib.concatMapStrings (instance: + importScript = lib.concatMapStrings ( + instance: lib.optionalString (isLocal instance) '' - if ! incus image info ${ - lib.escapeShellArg instance.name - } &>/dev/null; then + if ! incus image info ${lib.escapeShellArg instance.name} &>/dev/null; then incus image import \ ${instance.metadata}/tarball/*.tar.xz \ ${instance.image}/nixos.qcow2 \ --alias ${lib.escapeShellArg instance.name} fi - '') cfg.instances; - - flatten = prefix: attrs: - lib.foldlAttrs (acc: name: value: - let path = if prefix == "" then name else "${prefix}.${name}"; - in acc // (if builtins.isAttrs value then - flatten path value - else { - ${path} = value; - })) { } attrs; -in { + '' + ) cfg.instances; + + flatten = + prefix: attrs: + lib.foldlAttrs ( + acc: name: value: + let + path = if prefix == "" then name else "${prefix}.${name}"; + in + acc + // ( + if builtins.isAttrs value then + flatten path value + else + { + ${path} = value; + } + ) + ) { } attrs; +in +{ options.virtualisation.incus = { instances = mkOption { - type = types.listOf (types.submodule { - options = { - kind = mkOption { - type = types.str; - default = "instance"; - }; - - name = mkOption { - type = types.str; - description = "Name of the instance"; - }; - - image = mkOption { - type = types.either types.str types.package; - description = - "Image to use (either a local QEMU image or a reference to a remote image)"; - }; - - metadata = mkOption { - type = types.nullOr types.package; - default = null; - description = - "Image metadata derivation (required when image is a local derivation)."; - }; - - profiles = mkOption { - type = types.listOf types.str; - description = - "Which Incus profiles should be used for this instance"; - default = [ "default" ]; - }; - - vm = mkOption { - type = types.bool; - description = - "If this instance should be a VM instead of a container"; - default = false; - }; - - config = mkOption { - inherit (format) type; - description = "Freeform configuration for this instance"; - default = { }; - }; - - devices = mkOption { - inherit (format) type; - description = "Freeform device overrides for this instance"; - default = { }; + type = types.listOf ( + types.submodule { + options = { + kind = mkOption { + type = types.str; + default = "instance"; + }; + + name = mkOption { + type = types.str; + description = "Name of the instance"; + }; + + image = mkOption { + type = types.either types.str types.package; + description = "Image to use (either a local QEMU image or a reference to a remote image)"; + }; + + metadata = mkOption { + type = types.nullOr types.package; + default = null; + description = "Image metadata derivation (required when image is a local derivation)."; + }; + + profiles = mkOption { + type = types.listOf types.str; + description = "Which Incus profiles should be used for this instance"; + default = [ "default" ]; + }; + + vm = mkOption { + type = types.bool; + description = "If this instance should be a VM instead of a container"; + default = false; + }; + + config = mkOption { + inherit (format) type; + description = "Freeform configuration for this instance"; + default = { }; + }; + + devices = mkOption { + inherit (format) type; + description = "Freeform device overrides for this instance"; + default = { }; + }; }; - }; - }); + } + ); default = [ ]; }; @@ -111,8 +125,7 @@ in { config = mkIf cfg.enable { assertions = map (instance: { assertion = !isLocal instance || instance.metadata != null; - message = '' - virtualisation.incus.instances: instance "${instance.name}" has a local image derivation but no metadata set.''; + message = ''virtualisation.incus.instances: instance "${instance.name}" has a local image derivation but no metadata set.''; }) cfg.instances; systemd.services.incus-apply = { @@ -123,22 +136,30 @@ in { serviceConfig = { Type = "oneshot"; RemainAfterExit = true; - ExecStart = lib.getExe (pkgs.writeShellApplication { - name = "incus-apply-exec"; - runtimeInputs = - [ config.virtualisation.incus.package pkgs.incus-apply ]; - text = let - configLines = lib.concatStringsSep "\n" (lib.mapAttrsToList - (k: v: "incus config set ${lib.escapeShellArg "${k}=${v}"}") - (flatten "" cfg.config)); - in '' - ${configLines} - - ${importScript} - - incus-apply ${applyDir} --yes --quiet - ''; - }); + ExecStart = lib.getExe ( + pkgs.writeShellApplication { + name = "incus-apply-exec"; + runtimeInputs = [ + config.virtualisation.incus.package + pkgs.incus-apply + ]; + text = + let + configLines = lib.concatStringsSep "\n" ( + lib.mapAttrsToList (k: v: "incus config set ${lib.escapeShellArg "${k}=${v}"}") ( + flatten "" cfg.config + ) + ); + in + '' + ${configLines} + + ${importScript} + + incus-apply ${applyDir} --yes --quiet + ''; + } + ); }; }; }; diff --git a/modules/nixos/services/mazanoke/default.nix b/modules/nixos/services/mazanoke/default.nix index 24b2a43..47fa7ff 100644 --- a/modules/nixos/services/mazanoke/default.nix +++ b/modules/nixos/services/mazanoke/default.nix @@ -1,9 +1,16 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; -let cfg = config.services.mazanoke; -in { +let + cfg = config.services.mazanoke; +in +{ options.services.mazanoke = { enable = mkEnableOption "Enable Mazanoke"; @@ -44,10 +51,7 @@ in { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { - ExecStart = - "${lib.getExe pkgs.darkhttpd} ${cfg.package}/share/mazanoke --port ${ - toString cfg.port - }"; + ExecStart = "${lib.getExe pkgs.darkhttpd} ${cfg.package}/share/mazanoke --port ${toString cfg.port}"; Restart = "always"; User = cfg.user; Group = cfg.group; @@ -63,7 +67,6 @@ in { groups = mkIf (cfg.group == "mazanoke") { mazanoke = { }; }; }; - networking.firewall = - mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; } diff --git a/modules/nixos/services/postgresql/default.nix b/modules/nixos/services/postgresql/default.nix index 1267901..fb940d9 100644 --- a/modules/nixos/services/postgresql/default.nix +++ b/modules/nixos/services/postgresql/default.nix @@ -1,21 +1,28 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; -let cfg = config.services.postgresql; +let + cfg = config.services.postgresql; -in { +in +{ options.services.postgresql = { initialScriptText = mkOption { type = types.lines; - description = - "SQL to run on the initial start of PostgreSQL. This will get packaged into `services.postgresql.initialScript`"; + description = "SQL to run on the initial start of PostgreSQL. This will get packaged into `services.postgresql.initialScript`"; default = ""; }; }; config = mkIf cfg.enable { - services.postgresql.initialScript = mkDefault - (pkgs.writeText "postgresql-initial-script" cfg.initialScriptText); + services.postgresql.initialScript = mkDefault ( + pkgs.writeText "postgresql-initial-script" cfg.initialScriptText + ); }; } diff --git a/modules/nixos/services/profilarr/default.nix b/modules/nixos/services/profilarr/default.nix index a2ddbf8..3ce749e 100644 --- a/modules/nixos/services/profilarr/default.nix +++ b/modules/nixos/services/profilarr/default.nix @@ -1,9 +1,16 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; -let cfg = config.services.profilarr; -in { +let + cfg = config.services.profilarr; +in +{ options.services.profilarr = { enable = mkEnableOption "Enable Profilarr"; @@ -61,8 +68,7 @@ in { https = mkOption { type = types.bool; - description = - "If the Profilarr parser should be exposed with HTTPS"; + description = "If the Profilarr parser should be exposed with HTTPS"; default = false; }; @@ -93,8 +99,7 @@ in { clientSecretFile = mkOption { type = types.str; - description = - "File containing client secret for Profilarr OIDC authentication"; + description = "File containing client secret for Profilarr OIDC authentication"; }; discoveryURL = mkOption { @@ -126,10 +131,12 @@ in { PORT = toString cfg.port; ORIGIN = cfg.origin; TZ = config.time.timeZone; - } // lib.optionalAttrs cfg.parser.enable { + } + // lib.optionalAttrs cfg.parser.enable { PARSER_HOST = cfg.parser.listenAddress; PARSER_PORT = toString cfg.parser.port; - } // lib.optionalAttrs cfg.oidc.enable { + } + // lib.optionalAttrs cfg.oidc.enable { AUTH = "oidc"; OIDC_CLIENT_ID = cfg.oidc.clientID; OIDC_DISCOVERY_URL = cfg.oidc.discoveryURL; @@ -139,20 +146,24 @@ in { Type = "simple"; User = cfg.user; Group = cfg.group; - ExecStart = lib.getExe (pkgs.writeShellApplication { - name = "profilarr-exec-start"; - text = let - oidcClientSecret = lib.optionalString cfg.oidc.enable '' - export OIDC_CLIENT_SECRET - - OIDC_CLIENT_SECRET=$(cat ${cfg.oidc.clientSecretFile}) - ''; - in '' - ${oidcClientSecret} - - ${lib.getExe' cfg.package "profilarr"} - ''; - }); + ExecStart = lib.getExe ( + pkgs.writeShellApplication { + name = "profilarr-exec-start"; + text = + let + oidcClientSecret = lib.optionalString cfg.oidc.enable '' + export OIDC_CLIENT_SECRET + + OIDC_CLIENT_SECRET=$(cat ${cfg.oidc.clientSecretFile}) + ''; + in + '' + ${oidcClientSecret} + + ${lib.getExe' cfg.package "profilarr"} + ''; + } + ); Restart = "on-failure"; RestartSec = 5; @@ -164,20 +175,25 @@ in { systemd.services.profilarr-parser = mkIf cfg.parser.enable { description = "Profilarr - parser"; - wantedBy = [ "multi-user.target" "profilarr.service" ]; + wantedBy = [ + "multi-user.target" + "profilarr.service" + ]; after = [ "network.target" ]; serviceConfig = { Type = "simple"; User = cfg.user; Group = cfg.group; - ExecStart = let - urls = "${ + ExecStart = + let + urls = "${ if cfg.parser.https then "https" else "http" }://${cfg.parser.listenAddress}:${toString cfg.parser.port}"; - in '' - ${lib.getExe' cfg.parser.package "profilarr-parser"} --urls ${urls} - ''; + in + '' + ${lib.getExe' cfg.parser.package "profilarr-parser"} --urls ${urls} + ''; Restart = "on-failure"; RestartSec = 5; }; @@ -192,10 +208,13 @@ in { uid = 978; }; - groups = mkIf (cfg.group == "profilarr") { profilarr = { gid = 978; }; }; + groups = mkIf (cfg.group == "profilarr") { + profilarr = { + gid = 978; + }; + }; }; - networking.firewall = - mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; } diff --git a/modules/nixos/services/prometheus-exporters-dcgm-exporter/default.nix b/modules/nixos/services/prometheus-exporters-dcgm-exporter/default.nix index 6611175..fa4994e 100644 --- a/modules/nixos/services/prometheus-exporters-dcgm-exporter/default.nix +++ b/modules/nixos/services/prometheus-exporters-dcgm-exporter/default.nix @@ -2,9 +2,11 @@ with lib; -let cfg = config.services.prometheus.exporters.dcgm-exporter; +let + cfg = config.services.prometheus.exporters.dcgm-exporter; -in { +in +{ options.services.prometheus.exporters.dcgm-exporter = { enable = mkEnableOption "Enable dcgm exporter"; @@ -28,10 +30,12 @@ in { NVIDIA_DRIVER_CAPABILITIES = "compute,video,utility"; NVIDIA_VISIBLE_DEVICES = "all"; }; - extraOptions = [ "--cap-add=SYS_ADMIN" "--device=nvidia.com/gpu=all" ]; + extraOptions = [ + "--cap-add=SYS_ADMIN" + "--device=nvidia.com/gpu=all" + ]; }; - networking.firewall = - mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; } diff --git a/modules/nixos/services/prometheus-exporters-exportarr-sabnzbd/default.nix b/modules/nixos/services/prometheus-exporters-exportarr-sabnzbd/default.nix index 54eda38..427a297 100644 --- a/modules/nixos/services/prometheus-exporters-exportarr-sabnzbd/default.nix +++ b/modules/nixos/services/prometheus-exporters-exportarr-sabnzbd/default.nix @@ -1,10 +1,17 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; -let cfg = config.services.prometheus.exporters.exportarr-sabnzbd; +let + cfg = config.services.prometheus.exporters.exportarr-sabnzbd; -in { +in +{ options.services.prometheus.exporters.exportarr-sabnzbd = { enable = mkEnableOption "Enable sabnzbd exportarr"; @@ -36,13 +43,10 @@ in { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; script = '' - ${getExe cfg.package} sabnzbd --port ${ - toString cfg.port - } --url ${cfg.url} --api-key-file ${cfg.apiKeyFile} + ${getExe cfg.package} sabnzbd --port ${toString cfg.port} --url ${cfg.url} --api-key-file ${cfg.apiKeyFile} ''; }; - networking.firewall = - mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; } diff --git a/modules/nixos/services/restic/default.nix b/modules/nixos/services/restic/default.nix index bc62b14..d682e82 100644 --- a/modules/nixos/services/restic/default.nix +++ b/modules/nixos/services/restic/default.nix @@ -1,49 +1,60 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; { options.services.restic.backups = mkOption { - type = types.attrsOf (types.submodule (_: { - options.exporter = mkOption { - type = types.submodule { - options = { - enable = mkEnableOption "Enable Prometheus exporter"; - port = mkOption { - type = types.port; - default = 9754; + type = types.attrsOf ( + types.submodule (_: { + options.exporter = mkOption { + type = types.submodule { + options = { + enable = mkEnableOption "Enable Prometheus exporter"; + port = mkOption { + type = types.port; + default = 9754; + }; }; }; + default = { }; }; - default = { }; - }; - })); + }) + ); }; config = { - systemd.services = mkMerge (mapAttrsToList (name: backup: - optionalAttrs backup.exporter.enable { - "prometheus-restic-exporter-${name}" = { - enable = true; - wantedBy = [ "multi-user.target" ]; - wants = [ "network-online.target" ]; - script = '' - export RESTIC_PASSWORD_FILE=$CREDENTIALS_DIRECTORY/RESTIC_PASSWORD_FILE - ${pkgs.prometheus-restic-exporter}/bin/restic-exporter.py - ''; - environment = { - LISTEN_ADDRESS = "0.0.0.0"; - LISTEN_PORT = toString backup.exporter.port; - REFRESH_INTERVAL = "60"; - RESTIC_CACHE_DIR = "$CACHE_DIRECTORY"; - RESTIC_REPOSITORY = backup.repository; - }; - serviceConfig = { - CacheDirectory = "restic-exporter"; - EnvironmentFile = backup.environmentFile; - LoadCredential = [ "RESTIC_PASSWORD_FILE:${backup.passwordFile}" ]; + systemd.services = mkMerge ( + mapAttrsToList ( + name: backup: + optionalAttrs backup.exporter.enable { + "prometheus-restic-exporter-${name}" = { + enable = true; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + script = '' + export RESTIC_PASSWORD_FILE=$CREDENTIALS_DIRECTORY/RESTIC_PASSWORD_FILE + ${pkgs.prometheus-restic-exporter}/bin/restic-exporter.py + ''; + environment = { + LISTEN_ADDRESS = "0.0.0.0"; + LISTEN_PORT = toString backup.exporter.port; + REFRESH_INTERVAL = "60"; + RESTIC_CACHE_DIR = "$CACHE_DIRECTORY"; + RESTIC_REPOSITORY = backup.repository; + }; + serviceConfig = { + CacheDirectory = "restic-exporter"; + EnvironmentFile = backup.environmentFile; + LoadCredential = [ "RESTIC_PASSWORD_FILE:${backup.passwordFile}" ]; + }; }; - }; - }) config.services.restic.backups); + } + ) config.services.restic.backups + ); }; } diff --git a/modules/nixos/services/termix/default.nix b/modules/nixos/services/termix/default.nix index 7291234..1bcdea9 100644 --- a/modules/nixos/services/termix/default.nix +++ b/modules/nixos/services/termix/default.nix @@ -2,8 +2,10 @@ with lib; -let cfg = config.services.termix; -in { +let + cfg = config.services.termix; +in +{ options.services.termix = { enable = mkEnableOption "Enable Termix"; @@ -46,8 +48,7 @@ in { TZ = config.time.timeZone; ENABLE_SSL = toString false; }; - environmentFiles = - lib.optional (cfg.environmentFile != null) cfg.environmentFile; + environmentFiles = lib.optional (cfg.environmentFile != null) cfg.environmentFile; volumes = [ "${cfg.dataDir}:/app/data:rw" ]; ports = [ "${toString cfg.port}:8095" ]; }; diff --git a/modules/nixos/services/thanos/default.nix b/modules/nixos/services/thanos/default.nix index 7e2a924..dfda85c 100644 --- a/modules/nixos/services/thanos/default.nix +++ b/modules/nixos/services/thanos/default.nix @@ -4,7 +4,11 @@ with lib; let cfg = config.services.thanos; - mkAddressPortOption = { defaultAddress ? "0.0.0.0", defaultPort ? 10100 }: + mkAddressPortOption = + { + defaultAddress ? "0.0.0.0", + defaultPort ? 10100, + }: mkOption { type = types.submodule { options = { @@ -20,7 +24,8 @@ let }; }; }; -in { +in +{ options.services.thanos = { sidecar = { http = mkAddressPortOption { defaultPort = 19190; }; @@ -37,35 +42,30 @@ in { grpc = mkAddressPortOption { defaultPort = 10902; }; }; - compact = { http = mkAddressPortOption { defaultPort = 19193; }; }; + compact = { + http = mkAddressPortOption { defaultPort = 19193; }; + }; }; config = { services.thanos = { sidecar = mkIf cfg.sidecar.enable { - http-address = - "${cfg.sidecar.http.address}:${toString cfg.sidecar.http.port}"; - grpc-address = - "${cfg.sidecar.grpc.address}:${toString cfg.sidecar.grpc.port}"; + http-address = "${cfg.sidecar.http.address}:${toString cfg.sidecar.http.port}"; + grpc-address = "${cfg.sidecar.grpc.address}:${toString cfg.sidecar.grpc.port}"; }; store = mkIf cfg.store.enable { - http-address = - "${cfg.store.http.address}:${toString cfg.store.http.port}"; - grpc-address = - "${cfg.store.grpc.address}:${toString cfg.store.grpc.port}"; + http-address = "${cfg.store.http.address}:${toString cfg.store.http.port}"; + grpc-address = "${cfg.store.grpc.address}:${toString cfg.store.grpc.port}"; }; query = mkIf cfg.query.enable { - http-address = - "${cfg.query.http.address}:${toString cfg.query.http.port}"; - grpc-address = - "${cfg.query.grpc.address}:${toString cfg.query.grpc.port}"; + http-address = "${cfg.query.http.address}:${toString cfg.query.http.port}"; + grpc-address = "${cfg.query.grpc.address}:${toString cfg.query.grpc.port}"; }; compact = mkIf cfg.compact.enable { - http-address = - "${cfg.compact.http.address}:${toString cfg.compact.http.port}"; + http-address = "${cfg.compact.http.address}:${toString cfg.compact.http.port}"; }; }; }; diff --git a/modules/nixos/services/tracearr/default.nix b/modules/nixos/services/tracearr/default.nix index fc39891..0039548 100644 --- a/modules/nixos/services/tracearr/default.nix +++ b/modules/nixos/services/tracearr/default.nix @@ -1,9 +1,16 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: with lib; -let cfg = config.services.tracearr; -in { +let + cfg = config.services.tracearr; +in +{ options.services.tracearr = { enable = mkEnableOption "Enable Tracearr"; @@ -103,24 +110,32 @@ in { }; }; - services.postgresql = mkIf cfg.database.createLocally { - enable = true; - ensureDatabases = [ cfg.database.name ]; - ensureUsers = [{ - name = cfg.database.user; - ensureDBOwnership = true; - }]; - } // mkIf cfg.database.enableTimescaleDB { - extensions = ps: with ps; [ timescaledb timescaledb_toolkit ]; - settings = { - shared_preload_libraries = [ "timescaledb" ]; - max_locks_per_transaction = 256; + services.postgresql = + mkIf cfg.database.createLocally { + enable = true; + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [ + { + name = cfg.database.user; + ensureDBOwnership = true; + } + ]; + } + // mkIf cfg.database.enableTimescaleDB { + extensions = + ps: with ps; [ + timescaledb + timescaledb_toolkit + ]; + settings = { + shared_preload_libraries = [ "timescaledb" ]; + max_locks_per_transaction = 256; + }; + initialScriptText = lib.mkAfter '' + CREATE EXTENSION IF NOT EXISTS timescaledb; + CREATE EXTENSION IF NOT EXISTS timescaledb_toolkit; + ''; }; - initialScriptText = lib.mkAfter '' - CREATE EXTENSION IF NOT EXISTS timescaledb; - CREATE EXTENSION IF NOT EXISTS timescaledb_toolkit; - ''; - }; services.redis = mkIf cfg.redis.createLocally { servers.${cfg.redis.name} = { @@ -132,21 +147,23 @@ in { systemd.services.tracearr = { enable = true; - wants = [ "network-online.target" ] - ++ (lib.optional cfg.database.createLocally "postgresql.service") - ++ (lib.optional cfg.redis.createLocally - "redis-${cfg.redis.name}.service"); - after = [ "network-online.target" ] - ++ (lib.optional cfg.database.createLocally "postgresql.service") - ++ (lib.optional cfg.redis.createLocally - "redis-${cfg.redis.name}.service"); + wants = [ + "network-online.target" + ] + ++ (lib.optional cfg.database.createLocally "postgresql.service") + ++ (lib.optional cfg.redis.createLocally "redis-${cfg.redis.name}.service"); + after = [ + "network-online.target" + ] + ++ (lib.optional cfg.database.createLocally "postgresql.service") + ++ (lib.optional cfg.redis.createLocally "redis-${cfg.redis.name}.service"); wantedBy = [ "multi-user.target" ]; environment = { - DATABASE_URL = if cfg.database.url != null then - cfg.database.url - else - (mkIf cfg.database.createLocally - "postgres:///${cfg.database.name}?host=/run/postgresql&user=${cfg.database.user}"); + DATABASE_URL = + if cfg.database.url != null then + cfg.database.url + else + (mkIf cfg.database.createLocally "postgres:///${cfg.database.name}?host=/run/postgresql&user=${cfg.database.user}"); REDIS_URL = "redis://${cfg.redis.host}:${toString cfg.redis.port}"; PORT = toString cfg.port; APP_VERSION = cfg.package.version; @@ -172,7 +189,6 @@ in { groups.${cfg.group} = { }; }; - networking.firewall = - mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; } diff --git a/modules/nixos/services/unifi-os-server/default.nix b/modules/nixos/services/unifi-os-server/default.nix index c4ffb50..55e61b0 100644 --- a/modules/nixos/services/unifi-os-server/default.nix +++ b/modules/nixos/services/unifi-os-server/default.nix @@ -1,16 +1,35 @@ -{ config, lib, pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: let inherit (lib) - head importJSON mkEnableOption mkIf mkOption optional optionals types; + head + importJSON + mkEnableOption + mkIf + mkOption + optional + optionals + types + ; cfg = config.services.unifi-os-server; imageFile = "${cfg.package}/image.tar"; imageManifest = importJSON "${cfg.package}/manifest.json"; - imageTag = - cfg.package.passthru.imageTag or (head (head imageManifest).RepoTags); - - stateSubdirs = [ "persistent" "data" "srv" "unifi" "mongodb" "log" ]; + imageTag = cfg.package.passthru.imageTag or (head (head imageManifest).RepoTags); + + stateSubdirs = [ + "persistent" + "data" + "srv" + "unifi" + "mongodb" + "log" + ]; mkStateRule = subdir: "d ${cfg.stateDir}/${subdir} 0755 root root -"; @@ -68,23 +87,19 @@ let "${ucorePreStartFix}:/etc/systemd/system/unifi-core.service.d/prestart-fix.conf:ro" "${nginxPreStartFix}:/etc/systemd/system/nginx.service.d/prestart-fix.conf:ro" "${mongoPreStartFix}:/etc/systemd/system/mongodb.service.d/prestart-fix.conf:ro" - ] ++ optional cfg.debugLogging - "${ucoreDebug}:/etc/systemd/system/unifi-core.service.d/debug.conf:ro"; - - portMappings = optional (cfg.ports.ui != null) "${toString cfg.ports.ui}:443" - ++ optional (cfg.ports.uapDeviceInform != null) - "${toString cfg.ports.uapDeviceInform}:8080" - ++ optional (cfg.ports.controllerHttps != null) - "${toString cfg.ports.controllerHttps}:8443" - ++ optional (cfg.ports.mobileSpeedTest != null) - "${toString cfg.ports.mobileSpeedTest}:6789" - ++ optional (cfg.ports.httpCaptivePortal != null) - "${toString cfg.ports.httpCaptivePortal}:8880" - ++ optional (cfg.ports.httpsCaptivePortal != null) - "${toString cfg.ports.httpsCaptivePortal}:8843" + ] + ++ optional cfg.debugLogging "${ucoreDebug}:/etc/systemd/system/unifi-core.service.d/debug.conf:ro"; + + portMappings = + optional (cfg.ports.ui != null) "${toString cfg.ports.ui}:443" + ++ optional (cfg.ports.uapDeviceInform != null) "${toString cfg.ports.uapDeviceInform}:8080" + ++ optional (cfg.ports.controllerHttps != null) "${toString cfg.ports.controllerHttps}:8443" + ++ optional (cfg.ports.mobileSpeedTest != null) "${toString cfg.ports.mobileSpeedTest}:6789" + ++ optional (cfg.ports.httpCaptivePortal != null) "${toString cfg.ports.httpCaptivePortal}:8880" + ++ optional (cfg.ports.httpsCaptivePortal != null) "${toString cfg.ports.httpsCaptivePortal}:8843" ++ optional (cfg.ports.stun != null) "${toString cfg.ports.stun}:3478/udp" - ++ optional (cfg.ports.deviceDiscovery != null) - "${toString cfg.ports.deviceDiscovery}:10001/udp" ++ cfg.extraPorts; + ++ optional (cfg.ports.deviceDiscovery != null) "${toString cfg.ports.deviceDiscovery}:10001/udp" + ++ cfg.extraPorts; serviceTCPPorts = builtins.filter (port: port != null) [ cfg.ports.uapDeviceInform @@ -99,15 +114,15 @@ let cfg.ports.deviceDiscovery ]; -in { +in +{ options.services.unifi-os-server = { enable = mkEnableOption "UniFi OS Server container (podman)"; package = mkOption { type = types.package; default = pkgs.unifi-os-server-image; - description = - "Package containing the extracted UniFi OS Server OCI archive."; + description = "Package containing the extracted UniFi OS Server OCI archive."; }; stateDir = mkOption { @@ -119,8 +134,7 @@ in { debugLogging = mkOption { type = types.bool; default = false; - description = - "Whether to capture unifi-core stdout and stderr in the state directory."; + description = "Whether to capture unifi-core stdout and stderr in the state directory."; }; uosSystemIP = mkOption { @@ -163,15 +177,13 @@ in { httpCaptivePortal = mkOption { type = types.nullOr types.port; default = 8880; - description = - "Host port used for UniFi HTTP captive portal traffic."; + description = "Host port used for UniFi HTTP captive portal traffic."; }; httpsCaptivePortal = mkOption { type = types.nullOr types.port; default = 8843; - description = - "Host port used for UniFi HTTPS captive portal traffic."; + description = "Host port used for UniFi HTTPS captive portal traffic."; }; stun = mkOption { @@ -194,22 +206,19 @@ in { extraPorts = mkOption { type = types.listOf types.str; default = [ ]; - description = - "Additional port mappings passed to podman in `host:container[/protocol]` form."; + description = "Additional port mappings passed to podman in `host:container[/protocol]` form."; }; openFirewallUiPort = mkOption { type = types.bool; default = false; - description = - "Whether to open the UniFi OS Server web UI port in the firewall."; + description = "Whether to open the UniFi OS Server web UI port in the firewall."; }; openFirewallServicePorts = mkOption { type = types.bool; default = false; - description = - "Whether to open UniFi OS Server service ports in the firewall."; + description = "Whether to open UniFi OS Server service ports in the firewall."; }; environment = mkOption { @@ -235,13 +244,11 @@ in { assertions = [ { assertion = config.virtualisation.podman.enable; - message = - "services.unifi-os-server requires virtualisation.podman.enable = true."; + message = "services.unifi-os-server requires virtualisation.podman.enable = true."; } { assertion = config.virtualisation.oci-containers.backend == "podman"; - message = '' - services.unifi-os-server requires virtualisation.oci-containers.backend = "podman".''; + message = ''services.unifi-os-server requires virtualisation.oci-containers.backend = "podman".''; } ]; @@ -252,8 +259,7 @@ in { allowedUDPPorts = optionals cfg.openFirewallServicePorts serviceUDPPorts; }; - systemd.tmpfiles.rules = [ "d ${cfg.stateDir} 0755 root root -" ] - ++ map mkStateRule stateSubdirs; + systemd.tmpfiles.rules = [ "d ${cfg.stateDir} 0755 root root -" ] ++ map mkStateRule stateSubdirs; systemd.services.podman-unifi-os-server = { restartTriggers = [ cfg.package ]; @@ -279,11 +285,9 @@ in { PRODUCT_NAME = "uosserver"; UOS_SYSTEM_IP = cfg.uosSystemIP; UOS_SERVER_VERSION = cfg.package.version; - FIRMWARE_PLATFORM = if pkgs.stdenv.hostPlatform.isAarch64 then - "linux-arm64" - else - "linux-x64"; - } // cfg.environment; + FIRMWARE_PLATFORM = if pkgs.stdenv.hostPlatform.isAarch64 then "linux-arm64" else "linux-x64"; + } + // cfg.environment; volumes = requiredVolumeMounts ++ cfg.extraVolumes; @@ -291,7 +295,8 @@ in { "--systemd=always" "--add-host=host.docker.internal:host-gateway" "--pids-limit=8192" - ] ++ cfg.extraOptions; + ] + ++ cfg.extraOptions; }; }; } diff --git a/modules/nixos/services/wizarr/default.nix b/modules/nixos/services/wizarr/default.nix index 855f330..491d1d8 100644 --- a/modules/nixos/services/wizarr/default.nix +++ b/modules/nixos/services/wizarr/default.nix @@ -2,9 +2,11 @@ with lib; -let cfg = config.services.wizarr; +let + cfg = config.services.wizarr; -in { +in +{ options.services.wizarr = { enable = mkEnableOption "Enable Wizarr"; @@ -32,12 +34,13 @@ in { virtualisation.oci-containers.containers.wizarr = { image = "ghcr.io/wizarrrr/wizarr"; - environment = { TZ = config.time.timeZone; }; + environment = { + TZ = config.time.timeZone; + }; ports = [ "${toString cfg.port}:5690" ]; volumes = [ "${cfg.dataDir}:/data/database" ]; }; - networking.firewall = - mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; }; }; } diff --git a/modules/overlays/default.nix b/modules/overlays/default.nix index 4cdadf0..357cbb4 100644 --- a/modules/overlays/default.nix +++ b/modules/overlays/default.nix @@ -2,28 +2,49 @@ imports = [ inputs.flake-parts.flakeModules.easyOverlay ]; perSystem = { system, self', ... }: { - overlayAttrs = let - nixpkgs-master = import inputs.nixpkgs-master { - inherit system; + overlayAttrs = + let + nixpkgs-master = import inputs.nixpkgs-master { + inherit system; - config = { - allowUnfree = true; - permittedInsecurePackages = - [ "dotnet-sdk-6.0.428" "aspnetcore-runtime-6.0.36" ]; + config = { + allowUnfree = true; + permittedInsecurePackages = [ + "dotnet-sdk-6.0.428" + "aspnetcore-runtime-6.0.36" + ]; + }; }; - }; - in { - inherit (nixpkgs-master) - gatus prowlarr radarr sabnzbd sonarr netbox plex immich; + in + { + inherit (nixpkgs-master) + gatus + prowlarr + radarr + sabnzbd + sonarr + netbox + plex + immich + ; - # inherit (nixpkgs-master.python312Packages) pymdown-extensions onnx; + # inherit (nixpkgs-master.python312Packages) pymdown-extensions onnx; - # This is to pick up bugfix here: https://github.com/thanos-io/thanos/issues/7923 - inherit (nixpkgs-master) thanos; + # This is to pick up bugfix here: https://github.com/thanos-io/thanos/issues/7923 + inherit (nixpkgs-master) thanos; - inherit (self'.packages) - bichon declutarr fileflows mazanoke profilarr profilarr-parser - prometheus-plex-exporter tracearr unifi-os-server-image incus-apply; - }; + inherit (self'.packages) + bichon + declutarr + fileflows + mazanoke + profilarr + profilarr-parser + prometheus-plex-exporter + tracearr + unifi-os-server-image + incus-apply + ; + }; }; } diff --git a/modules/packages/bichon/default.nix b/modules/packages/bichon/default.nix index 3f5bfa9..db97744 100644 --- a/modules/packages/bichon/default.nix +++ b/modules/packages/bichon/default.nix @@ -1,77 +1,99 @@ -{ stdenv, lib, rustPlatform, fetchFromGitHub, fetchPnpmDeps, nodejs_22, pnpm -, pnpmConfigHook, typescript, pkg-config, git, openssl }: - -rustPlatform.buildRustPackage (let - pname = "bichon"; - version = "1.5.2"; - source = fetchFromGitHub { - owner = "rustmailer"; - repo = "bichon"; - rev = version; - hash = "sha256-QvAUM1fncnbmXGJ4fhq7c4ZvE4rquMQqdqq6RlOIBxI="; - }; - frontend = stdenv.mkDerivation (finalAttrs: { - pname = "${pname}-frontend"; - inherit version; +{ + stdenv, + lib, + rustPlatform, + fetchFromGitHub, + fetchPnpmDeps, + nodejs_22, + pnpm, + pnpmConfigHook, + typescript, + pkg-config, + git, + openssl, +}: + +rustPlatform.buildRustPackage ( + let + pname = "bichon"; + version = "1.5.2"; + source = fetchFromGitHub { + owner = "rustmailer"; + repo = "bichon"; + rev = version; + hash = "sha256-QvAUM1fncnbmXGJ4fhq7c4ZvE4rquMQqdqq6RlOIBxI="; + }; + frontend = stdenv.mkDerivation (finalAttrs: { + pname = "${pname}-frontend"; + inherit version; - src = source; + src = source; - sourceRoot = "${finalAttrs.src.name}/web"; + sourceRoot = "${finalAttrs.src.name}/web"; - nativeBuildInputs = [ nodejs_22 pnpm pnpmConfigHook typescript ]; + nativeBuildInputs = [ + nodejs_22 + pnpm + pnpmConfigHook + typescript + ]; - pnpmDeps = fetchPnpmDeps { - inherit (finalAttrs) pname version src; - fetcherVersion = 3; - hash = "sha256-7EkSYTUXOtYewvOoKJiOSNmpowJj27/Ea8PAcebJCzA="; - sourceRoot = "${finalAttrs.src.name}/web"; - }; + pnpmDeps = fetchPnpmDeps { + inherit (finalAttrs) pname version src; + fetcherVersion = 3; + hash = "sha256-7EkSYTUXOtYewvOoKJiOSNmpowJj27/Ea8PAcebJCzA="; + sourceRoot = "${finalAttrs.src.name}/web"; + }; - patchPhase = '' - export CI=true - ''; + patchPhase = '' + export CI=true + ''; - buildPhase = '' - runHook preBuild + buildPhase = '' + runHook preBuild - pnpm build + pnpm build - runHook postBuild - ''; + runHook postBuild + ''; - installPhase = '' - runHook preInstall + installPhase = '' + runHook preInstall - mkdir -p $out - cp -r dist $out/ + mkdir -p $out + cp -r dist $out/ - runHook postInstall - ''; - }); -in { - inherit pname version; + runHook postInstall + ''; + }); + in + { + inherit pname version; - src = source; + src = source; - cargoHash = "sha256-keEOzDf2DSOC2g8mLMuZhi1FwCaBXzo1yk0WmIcTFuI="; + cargoHash = "sha256-keEOzDf2DSOC2g8mLMuZhi1FwCaBXzo1yk0WmIcTFuI="; - nativeBuildInputs = [ pkg-config git ]; + nativeBuildInputs = [ + pkg-config + git + ]; - buildInputs = [ openssl ]; + buildInputs = [ openssl ]; - preBuild = '' - mkdir -p web - cp -r "${frontend}/dist" web/dist - ''; + preBuild = '' + mkdir -p web + cp -r "${frontend}/dist" web/dist + ''; - doCheck = false; + doCheck = false; - meta = with lib; { - description = - "Lightweight, high-performance Rust email archiver with WebUI"; - homepage = "https://github.com/rustmailer/bichon"; - license = licenses.agpl3Plus; - platforms = platforms.linux; - mainProgram = "bichon-server"; - }; -}) + meta = with lib; { + description = "Lightweight, high-performance Rust email archiver with WebUI"; + homepage = "https://github.com/rustmailer/bichon"; + license = licenses.agpl3Plus; + platforms = platforms.linux; + mainProgram = "bichon-server"; + }; + } +) diff --git a/modules/packages/declutarr/default.nix b/modules/packages/declutarr/default.nix index c8cd731..c9135ff 100644 --- a/modules/packages/declutarr/default.nix +++ b/modules/packages/declutarr/default.nix @@ -1,4 +1,9 @@ -{ lib, fetchFromGitHub, makeWrapper, python3Packages }: +{ + lib, + fetchFromGitHub, + makeWrapper, + python3Packages, +}: python3Packages.buildPythonApplication rec { name = "declutarr"; @@ -49,8 +54,7 @@ python3Packages.buildPythonApplication rec { doCheck = false; meta = with lib; { - description = - "Watches radarr, sonarr, lidarr, readarr and whisparr download queues and removes downloads if they become stalled or no longer needed."; + description = "Watches radarr, sonarr, lidarr, readarr and whisparr download queues and removes downloads if they become stalled or no longer needed."; homepage = "https://github.com/ManiMatter/decluttarr"; license = licenses.gpl3Only; platforms = platforms.linux; diff --git a/modules/packages/fileflows/default.nix b/modules/packages/fileflows/default.nix index c3fef7f..58c73bc 100644 --- a/modules/packages/fileflows/default.nix +++ b/modules/packages/fileflows/default.nix @@ -1,8 +1,18 @@ -{ lib, stdenvNoCC, fetchzip, dotnetCorePackages, sqlite, libz, writeShellScript +{ + lib, + stdenvNoCC, + fetchzip, + dotnetCorePackages, + sqlite, + libz, + writeShellScript, }: let dotnet = dotnetCorePackages.aspnetcore_8_0; - buildInputs = [ sqlite libz ]; + buildInputs = [ + sqlite + libz + ]; server-script = writeShellScript "fileflows-server-unsubstituted.sh" '' export LD_LIBRARY_PATH="${lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH" @@ -40,7 +50,8 @@ let cd Node exec "${dotnet}/bin/dotnet" FileFlows.Node.dll "$@" ''; -in stdenvNoCC.mkDerivation rec { +in +stdenvNoCC.mkDerivation rec { pname = "fileflows"; version = "26.5.9.7184"; diff --git a/modules/packages/profilarr-parser/default.nix b/modules/packages/profilarr-parser/default.nix index ee5ff68..ed44e15 100644 --- a/modules/packages/profilarr-parser/default.nix +++ b/modules/packages/profilarr-parser/default.nix @@ -1,4 +1,9 @@ -{ lib, buildDotnetModule, dotnetCorePackages, fetchFromGitHub }: +{ + lib, + buildDotnetModule, + dotnetCorePackages, + fetchFromGitHub, +}: buildDotnetModule rec { pname = "profilarr-parser"; diff --git a/modules/packages/profilarr/default.nix b/modules/packages/profilarr/default.nix index d7e336f..3dc8217 100644 --- a/modules/packages/profilarr/default.nix +++ b/modules/packages/profilarr/default.nix @@ -1,5 +1,16 @@ -{ lib, stdenv, fetchFromGitHub, deno, cacert, makeWrapper, autoPatchelfHook -, sqlite, git, gnutar, gzip }: +{ + lib, + stdenv, + fetchFromGitHub, + deno, + cacert, + makeWrapper, + autoPatchelfHook, + sqlite, + git, + gnutar, + gzip, +}: let version = "2.0.8"; @@ -15,11 +26,14 @@ let pname = "profilarr-deno-deps"; inherit version src; - nativeBuildInputs = [ deno cacert sqlite ]; + nativeBuildInputs = [ + deno + cacert + sqlite + ]; SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; - DENO_SQLITE_PATH = - "${sqlite.out}/lib/libsqlite3${stdenv.hostPlatform.extensions.sharedLibrary}"; + DENO_SQLITE_PATH = "${sqlite.out}/lib/libsqlite3${stdenv.hostPlatform.extensions.sharedLibrary}"; buildPhase = '' runHook preBuild @@ -50,25 +64,37 @@ let dontFixup = true; outputHashMode = "recursive"; - outputHash = { - x86_64-linux = "sha256-a+80eXiDgWzLKefqqF9hnquBr4RLhUucTUOJc6inCMs="; - aarch64-linux = "sha256-z4zIEEekyQRSLTkXLmIM5JA8vZBKUMGGtUuvtD0Xq0g="; - }.${stdenv.hostPlatform.system} or (throw - "profilarr: unsupported system ${stdenv.hostPlatform.system}"); + outputHash = + { + x86_64-linux = "sha256-a+80eXiDgWzLKefqqF9hnquBr4RLhUucTUOJc6inCMs="; + aarch64-linux = "sha256-z4zIEEekyQRSLTkXLmIM5JA8vZBKUMGGtUuvtD0Xq0g="; + } + .${stdenv.hostPlatform.system} + or (throw "profilarr: unsupported system ${stdenv.hostPlatform.system}"); }; -in stdenv.mkDerivation { +in +stdenv.mkDerivation { pname = "profilarr"; inherit version src; - nativeBuildInputs = [ deno makeWrapper autoPatchelfHook cacert ]; - buildInputs = [ stdenv.cc.cc.lib sqlite ]; + nativeBuildInputs = [ + deno + makeWrapper + autoPatchelfHook + cacert + ]; + buildInputs = [ + stdenv.cc.cc.lib + sqlite + ]; - autoPatchelfIgnoreMissingDeps = - [ "libc.musl-x86_64.so.1" "libc.musl-aarch64.so.1" ]; + autoPatchelfIgnoreMissingDeps = [ + "libc.musl-x86_64.so.1" + "libc.musl-aarch64.so.1" + ]; - DENO_SQLITE_PATH = - "${sqlite.out}/lib/libsqlite3${stdenv.hostPlatform.extensions.sharedLibrary}"; + DENO_SQLITE_PATH = "${sqlite.out}/lib/libsqlite3${stdenv.hostPlatform.extensions.sharedLibrary}"; postPatch = '' substituteInPlace svelte.config.js \ @@ -110,7 +136,13 @@ in stdenv.mkDerivation { makeWrapper ${lib.getExe deno} $out/bin/profilarr \ --run "cd $out/lib/profilarr" \ --add-flags "run -A dist/build/mod.ts" \ - --prefix PATH : ${lib.makeBinPath [ git gnutar gzip ]} \ + --prefix PATH : ${ + lib.makeBinPath [ + git + gnutar + gzip + ] + } \ --set-default DENO_DIR "$out/share/deno-dir" \ --set-default DENO_NO_UPDATE_CHECK 1 \ --set-default DENO_SQLITE_PATH "$DENO_SQLITE_PATH" \ diff --git a/modules/packages/tracearr/default.nix b/modules/packages/tracearr/default.nix index 415246f..3f5d920 100644 --- a/modules/packages/tracearr/default.nix +++ b/modules/packages/tracearr/default.nix @@ -1,5 +1,14 @@ -{ lib, stdenv, pnpm_10, fetchPnpmDeps, pnpmConfigHook, makeWrapper, nodejs -, fetchFromGitHub, turbo, }: +{ + lib, + stdenv, + pnpm_10, + fetchPnpmDeps, + pnpmConfigHook, + makeWrapper, + nodejs, + fetchFromGitHub, + turbo, +}: stdenv.mkDerivation (finalAttrs: { pname = "tracearr"; version = "1.4.28"; @@ -22,7 +31,13 @@ stdenv.mkDerivation (finalAttrs: { env.NODE_ENV = "production"; - nativeBuildInputs = [ makeWrapper nodejs pnpmConfigHook pnpm_10 turbo ]; + nativeBuildInputs = [ + makeWrapper + nodejs + pnpmConfigHook + pnpm_10 + turbo + ]; buildInputs = [ nodejs ]; @@ -70,8 +85,7 @@ stdenv.mkDerivation (finalAttrs: { ''; meta = { - description = - "Real-time monitoring for Plex, Jellyfin, and Emby servers. Track streams, analyze playback, and detect account sharing from a single dashboard."; + description = "Real-time monitoring for Plex, Jellyfin, and Emby servers. Track streams, analyze playback, and detect account sharing from a single dashboard."; mainProgram = "tracearr"; homepage = "https://tracearr.com"; license = lib.licenses.agpl3Plus; diff --git a/modules/packages/unifi-os-server-image/default.nix b/modules/packages/unifi-os-server-image/default.nix index dd9d06c..6029f2f 100644 --- a/modules/packages/unifi-os-server-image/default.nix +++ b/modules/packages/unifi-os-server-image/default.nix @@ -1,27 +1,31 @@ -{ lib, pkgs, }: +{ lib, pkgs }: let imageVersion = "f77bca81ecbf"; installerVersion = "5.1.15"; - url = - "https://fw-download.ubnt.com/data/unifi-os-server/24e0-linux-x64-5.1.15-926621de-c9d7-48cd-8921-a0ff3eebd3f4.15-x64"; + url = "https://fw-download.ubnt.com/data/unifi-os-server/24e0-linux-x64-5.1.15-926621de-c9d7-48cd-8921-a0ff3eebd3f4.15-x64"; sha256 = "sha256-BMjkAes0Mw/pnZTzWqNR4ODpeJXw2aS0Wf80+1DK0rs="; # TODO: Can remove when this fix is merged # https://github.com/nixos/nixpkgs/pull/530407 binwalk = pkgs.binwalk.override { - uefi-firmware-parser = - pkgs.python3Packages.uefi-firmware-parser.overridePythonAttrs (old: { - build-system = (old.build-system or [ ]) - ++ [ pkgs.python3Packages.setuptools-scm ]; - }); + uefi-firmware-parser = pkgs.python3Packages.uefi-firmware-parser.overridePythonAttrs (old: { + build-system = (old.build-system or [ ]) ++ [ pkgs.python3Packages.setuptools-scm ]; + }); }; -in pkgs.stdenvNoCC.mkDerivation { +in +pkgs.stdenvNoCC.mkDerivation { pname = "unifi-os-server"; version = installerVersion; src = pkgs.fetchurl { inherit url sha256; }; - nativeBuildInputs = [ binwalk ] ++ (with pkgs; [ coreutils findutils ]); + nativeBuildInputs = [ + binwalk + ] + ++ (with pkgs; [ + coreutils + findutils + ]); dontUnpack = true; @@ -55,8 +59,7 @@ in pkgs.stdenvNoCC.mkDerivation { meta = with lib; { description = "UniFi OS Server installer package"; - homepage = - "https://help.ui.com/hc/en-us/articles/34210126298775-Self-Hosting-UniFi"; + homepage = "https://help.ui.com/hc/en-us/articles/34210126298775-Self-Hosting-UniFi"; license = licenses.unfree; platforms = platforms.linux; sourceProvenance = with sourceTypes; [ binaryNativeCode ]; diff --git a/modules/profiles/backups/restic/common.nix b/modules/profiles/backups/restic/common.nix index ec08362..c5c06a5 100644 --- a/modules/profiles/backups/restic/common.nix +++ b/modules/profiles/backups/restic/common.nix @@ -1,4 +1,10 @@ -{ config, pkgs, lib, ... }: { +{ + config, + pkgs, + lib, + ... +}: +{ sops = { secrets = { restic_backup_password = { @@ -62,8 +68,11 @@ }; }; }; - } // lib.mapAttrs' (name: _: + } + // lib.mapAttrs' ( + name: _: lib.nameValuePair "restic-backups-${name}" { unitConfig.OnFailure = "restic-notify-failure@%n.service"; - }) config.services.restic.backups; + } + ) config.services.restic.backups; } diff --git a/modules/profiles/backups/restic/system.nix b/modules/profiles/backups/restic/system.nix index acbe5ac..b19eae3 100644 --- a/modules/profiles/backups/restic/system.nix +++ b/modules/profiles/backups/restic/system.nix @@ -1,49 +1,56 @@ { config, lib, ... }: { imports = [ ./common.nix ]; - services.restic.backups = let - sharedOptions = { - initialize = true; - passwordFile = config.sops.secrets.restic_backup_password.path; - paths = [ "/etc" "/var/lib" "/srv" "/root" ]; - exclude = [ - "**/.cache" - "**/.nix-profile" - "**/*.log" - "/var/lib/containers" - "/var/lib/docker" - "/var/lib/libvirt" - "/var/lib/postgresql" - "/var/lib/private" - "/var/lib/systemd" - "/var/logs" - ]; - timerConfig = { - OnCalendar = "03:30"; - Persistent = true; - RandomizedDelaySec = "1h"; + services.restic.backups = + let + sharedOptions = { + initialize = true; + passwordFile = config.sops.secrets.restic_backup_password.path; + paths = [ + "/etc" + "/var/lib" + "/srv" + "/root" + ]; + exclude = [ + "**/.cache" + "**/.nix-profile" + "**/*.log" + "/var/lib/containers" + "/var/lib/docker" + "/var/lib/libvirt" + "/var/lib/postgresql" + "/var/lib/private" + "/var/lib/systemd" + "/var/logs" + ]; + timerConfig = { + OnCalendar = "03:30"; + Persistent = true; + RandomizedDelaySec = "1h"; + }; + pruneOpts = [ + "--keep-daily 3" + "--keep-weekly 2" + "--keep-monthly 2" + ]; + exporter.enable = true; }; - pruneOpts = [ "--keep-daily 3" "--keep-weekly 2" "--keep-monthly 2" ]; - exporter.enable = true; - }; - in { - system-omnibus = lib.recursiveUpdate { - repository = - "rest:http://omnibus:8000/${config.networking.hostName}/system"; - environmentFile = - config.sops.templates.omnibus_rest_server_environment_file.path; - exporter.port = 9753; - } sharedOptions; + in + { + system-omnibus = lib.recursiveUpdate { + repository = "rest:http://omnibus:8000/${config.networking.hostName}/system"; + environmentFile = config.sops.templates.omnibus_rest_server_environment_file.path; + exporter.port = 9753; + } sharedOptions; - system-rsync-net = lib.recursiveUpdate { - repository = - "sftp://de2228@de2228.rsync.net/${config.networking.hostName}/system"; - extraOptions = - [ "sftp.args='-i ${config.sops.secrets.rsync_net_ssh_key.path}'" ]; - exporter = { - enable = true; - port = 9754; - }; - } sharedOptions; - }; + system-rsync-net = lib.recursiveUpdate { + repository = "sftp://de2228@de2228.rsync.net/${config.networking.hostName}/system"; + extraOptions = [ "sftp.args='-i ${config.sops.secrets.rsync_net_ssh_key.path}'" ]; + exporter = { + enable = true; + port = 9754; + }; + } sharedOptions; + }; } diff --git a/modules/profiles/communications/mosquitto/default.nix b/modules/profiles/communications/mosquitto/default.nix index af7354c..4c25f06 100644 --- a/modules/profiles/communications/mosquitto/default.nix +++ b/modules/profiles/communications/mosquitto/default.nix @@ -8,24 +8,30 @@ services.mosquitto = { enable = true; persistence = true; - listeners = [{ - users = { - hass = { - passwordFile = config.sops.secrets.mosquitto_hass_password.path; - acl = [ "readwrite frigate/#" "readwrite jetkvm/#" ]; + listeners = [ + { + users = { + hass = { + passwordFile = config.sops.secrets.mosquitto_hass_password.path; + acl = [ + "readwrite frigate/#" + "readwrite jetkvm/#" + ]; + }; + frigate = { + passwordFile = config.sops.secrets.mosquitto_frigate_password.path; + acl = [ "readwrite frigate/#" ]; + }; + jetkvm = { + passwordFile = config.sops.secrets.mosquitto_jetkvm_password.path; + acl = [ "readwrite jetkvm/#" ]; + }; }; - frigate = { - passwordFile = config.sops.secrets.mosquitto_frigate_password.path; - acl = [ "readwrite frigate/#" ]; - }; - jetkvm = { - passwordFile = config.sops.secrets.mosquitto_jetkvm_password.path; - acl = [ "readwrite jetkvm/#" ]; - }; - }; - }]; + } + ]; }; - networking.firewall.allowedTCPPorts = - map (listener: listener.port) config.services.mosquitto.listeners; + networking.firewall.allowedTCPPorts = map ( + listener: listener.port + ) config.services.mosquitto.listeners; } diff --git a/modules/profiles/communications/postfix/default.nix b/modules/profiles/communications/postfix/default.nix index 5504539..a78fe61 100644 --- a/modules/profiles/communications/postfix/default.nix +++ b/modules/profiles/communications/postfix/default.nix @@ -13,8 +13,7 @@ smtp_use_tls = "yes"; smtp_sas_auth_enable = "yes"; smtp_sasl_security_options = ""; - smtp_sasl_password_maps = - "texthash:${config.sops.secrets.postfix_sasl_password.path}"; + smtp_sasl_password_maps = "texthash:${config.sops.secrets.postfix_sasl_password.path}"; }; }; }; diff --git a/modules/profiles/core/caching.nix b/modules/profiles/core/caching.nix index 8ea1307..f641c32 100644 --- a/modules/profiles/core/caching.nix +++ b/modules/profiles/core/caching.nix @@ -1,5 +1,8 @@ { pkgs, ... }: { - environment.systemPackages = with pkgs; [ attic-client cachix ]; + environment.systemPackages = with pkgs; [ + attic-client + cachix + ]; nix.settings = { substituters = [ diff --git a/modules/profiles/core/nix-config.nix b/modules/profiles/core/nix-config.nix index 18229fc..45b1b4f 100644 --- a/modules/profiles/core/nix-config.nix +++ b/modules/profiles/core/nix-config.nix @@ -1,9 +1,17 @@ -{ flake, pkgs, lib, ... }: { +{ + flake, + pkgs, + lib, + ... +}: +{ nixpkgs = { config = { allowUnfree = true; - permittedInsecurePackages = - [ "dotnet-sdk-6.0.428" "aspnetcore-runtime-6.0.36" ]; + permittedInsecurePackages = [ + "dotnet-sdk-6.0.428" + "aspnetcore-runtime-6.0.36" + ]; }; overlays = [ flake.overlays.default @@ -28,10 +36,21 @@ settings = { allowed-users = [ "@wheel" ]; - experimental-features = [ "nix-command" "flakes" ]; + experimental-features = [ + "nix-command" + "flakes" + ]; sandbox = true; - system-features = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; - trusted-users = [ "root" "@wheel" ]; + system-features = [ + "nixos-test" + "benchmark" + "big-parallel" + "kvm" + ]; + trusted-users = [ + "root" + "@wheel" + ]; }; }; } diff --git a/modules/profiles/databases/postgresql.nix b/modules/profiles/databases/postgresql.nix index 3a9733e..77c367f 100644 --- a/modules/profiles/databases/postgresql.nix +++ b/modules/profiles/databases/postgresql.nix @@ -1,7 +1,10 @@ { pkgs, lib, ... }: { services.postgresql = { enable = true; - package = pkgs.postgresql_15.withPackages (p: [ p.postgis p.timescaledb ]); + package = pkgs.postgresql_15.withPackages (p: [ + p.postgis + p.timescaledb + ]); enableTCPIP = true; authentication = '' local all all trust @@ -15,8 +18,7 @@ services.postgresqlBackup = { enable = true; - databases = lib.mkDefault - [ ]; # Set individually so the service produces individual SQL files + databases = lib.mkDefault [ ]; # Set individually so the service produces individual SQL files startAt = "*-*-* 00:15:00"; }; diff --git a/modules/profiles/default.nix b/modules/profiles/default.nix index 5dff64e..1d79e2c 100644 --- a/modules/profiles/default.nix +++ b/modules/profiles/default.nix @@ -2,7 +2,8 @@ let inherit (self) inputs; inherit (inputs) haumea; -in haumea.lib.load { +in +haumea.lib.load { src = ./.; loader = haumea.lib.loaders.path; } diff --git a/modules/profiles/filesystems/blockbuster.nix b/modules/profiles/filesystems/blockbuster.nix index 55c9cb2..c1b5aa5 100644 --- a/modules/profiles/filesystems/blockbuster.nix +++ b/modules/profiles/filesystems/blockbuster.nix @@ -2,9 +2,11 @@ imports = [ profiles.users.blockbuster ]; fileSystems."/mnt/blockbuster" = { - device = - "${hosts.omnibus.config.satan.address}:${hosts.omnibus.config.disko.devices.zpool.blockbuster.datasets.root.mountpoint}"; + device = "${hosts.omnibus.config.satan.address}:${hosts.omnibus.config.disko.devices.zpool.blockbuster.datasets.root.mountpoint}"; fsType = "nfs"; - options = [ "x-systemd.automount" "exec" ]; + options = [ + "x-systemd.automount" + "exec" + ]; }; } diff --git a/modules/profiles/filesystems/files/backup.nix b/modules/profiles/filesystems/files/backup.nix index a70e8a4..ad77787 100644 --- a/modules/profiles/filesystems/files/backup.nix +++ b/modules/profiles/filesystems/files/backup.nix @@ -1,16 +1,21 @@ { config, hosts, ... }: { imports = [ ./common.nix ]; - fileSystems."/mnt/files/backup" = let - # Use local network if local, otherwise use Tailscale - host = if builtins.elem "@external" config.deployment.tags then - hosts.omnibus.config.networking.hostName - else - hosts.omnibus.config.satan.address; - in { - device = - "${host}:${hosts.omnibus.config.disko.devices.zpool.files.datasets.root.mountpoint}/backup"; - fsType = "nfs"; - options = [ "x-systemd.automount" "exec" ]; - }; + fileSystems."/mnt/files/backup" = + let + # Use local network if local, otherwise use Tailscale + host = + if builtins.elem "@external" config.deployment.tags then + hosts.omnibus.config.networking.hostName + else + hosts.omnibus.config.satan.address; + in + { + device = "${host}:${hosts.omnibus.config.disko.devices.zpool.files.datasets.root.mountpoint}/backup"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "exec" + ]; + }; } diff --git a/modules/profiles/filesystems/files/personal.nix b/modules/profiles/filesystems/files/personal.nix index 2b6e75e..994f01d 100644 --- a/modules/profiles/filesystems/files/personal.nix +++ b/modules/profiles/filesystems/files/personal.nix @@ -1,16 +1,21 @@ { config, hosts, ... }: { imports = [ ./common.nix ]; - fileSystems."/mnt/files/personal" = let - # Use local network if local, otherwise use Tailscale - host = if builtins.elem "@external" config.deployment.tags then - hosts.omnibus.config.networking.hostName - else - hosts.omnibus.config.satan.address; - in { - device = - "${host}:${hosts.omnibus.config.disko.devices.zpool.files.datasets.root.mountpoint}/personal"; - fsType = "nfs"; - options = [ "x-systemd.automount" "exec" ]; - }; + fileSystems."/mnt/files/personal" = + let + # Use local network if local, otherwise use Tailscale + host = + if builtins.elem "@external" config.deployment.tags then + hosts.omnibus.config.networking.hostName + else + hosts.omnibus.config.satan.address; + in + { + device = "${host}:${hosts.omnibus.config.disko.devices.zpool.files.datasets.root.mountpoint}/personal"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "exec" + ]; + }; } diff --git a/modules/profiles/filesystems/files/services.nix b/modules/profiles/filesystems/files/services.nix index 40e509a..335b81a 100644 --- a/modules/profiles/filesystems/files/services.nix +++ b/modules/profiles/filesystems/files/services.nix @@ -1,16 +1,21 @@ { config, hosts, ... }: { imports = [ ./common.nix ]; - fileSystems."/mnt/files/services" = let - # Use local network if local, otherwise use Tailscale - host = if builtins.elem "@external" config.deployment.tags then - hosts.omnibus.config.networking.hostName - else - hosts.omnibus.config.satan.address; - in { - device = - "${host}:${hosts.omnibus.config.disko.devices.zpool.files.datasets.root.mountpoint}/services"; - fsType = "nfs"; - options = [ "x-systemd.automount" "exec" ]; - }; + fileSystems."/mnt/files/services" = + let + # Use local network if local, otherwise use Tailscale + host = + if builtins.elem "@external" config.deployment.tags then + hosts.omnibus.config.networking.hostName + else + hosts.omnibus.config.satan.address; + in + { + device = "${host}:${hosts.omnibus.config.disko.devices.zpool.files.datasets.root.mountpoint}/services"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "exec" + ]; + }; } diff --git a/modules/profiles/filesystems/zfs.nix b/modules/profiles/filesystems/zfs.nix index 4c0b462..a221584 100644 --- a/modules/profiles/filesystems/zfs.nix +++ b/modules/profiles/filesystems/zfs.nix @@ -1,6 +1,5 @@ { config, lib, ... }: { - networking.hostId = - lib.substring 0 8 (builtins.hashString "sha256" config.networking.hostName); + networking.hostId = lib.substring 0 8 (builtins.hashString "sha256" config.networking.hostName); boot = { zfs = { diff --git a/modules/profiles/hardware/intel-graphics.nix b/modules/profiles/hardware/intel-graphics.nix index b3ee8e3..aca586f 100644 --- a/modules/profiles/hardware/intel-graphics.nix +++ b/modules/profiles/hardware/intel-graphics.nix @@ -3,10 +3,16 @@ hardware.graphics = { enable = true; - extraPackages = with pkgs; [ intel-compute-runtime intel-media-driver ]; + extraPackages = with pkgs; [ + intel-compute-runtime + intel-media-driver + ]; }; - environment.systemPackages = with pkgs; [ libva-utils intel-gpu-tools ]; + environment.systemPackages = with pkgs; [ + libva-utils + intel-gpu-tools + ]; services.xserver.videoDrivers = [ "intel" ]; } diff --git a/modules/profiles/hardware/nvme.nix b/modules/profiles/hardware/nvme.nix index 2dfaa15..12b6e55 100644 --- a/modules/profiles/hardware/nvme.nix +++ b/modules/profiles/hardware/nvme.nix @@ -1 +1,6 @@ -{ pkgs, ... }: { environment.systemPackages = with pkgs; [ nvme-cli nvme-rs ]; } +{ pkgs, ... }: { + environment.systemPackages = with pkgs; [ + nvme-cli + nvme-rs + ]; +} diff --git a/modules/profiles/hardware/rpi4.nix b/modules/profiles/hardware/rpi4.nix index 3c9903e..f3d2839 100644 --- a/modules/profiles/hardware/rpi4.nix +++ b/modules/profiles/hardware/rpi4.nix @@ -9,5 +9,8 @@ }; }; - environment.systemPackages = with pkgs; [ libraspberrypi raspberrypi-eeprom ]; + environment.systemPackages = with pkgs; [ + libraspberrypi + raspberrypi-eeprom + ]; } diff --git a/modules/profiles/home-automation/frigate/default.nix b/modules/profiles/home-automation/frigate/default.nix index 4474fa2..d78e791 100644 --- a/modules/profiles/home-automation/frigate/default.nix +++ b/modules/profiles/home-automation/frigate/default.nix @@ -1,4 +1,9 @@ -{ config, hosts, pkgs, ... }: +{ + config, + hosts, + pkgs, + ... +}: let cameraAddress = "192.168.1.102"; cameraUsername = "viewer"; @@ -25,7 +30,11 @@ let user = "frigate"; password = "{FRIGATE_MQTT_PASSWORD}"; }; - detectors = { onnx_0 = { type = "onnx"; }; }; + detectors = { + onnx_0 = { + type = "onnx"; + }; + }; model = { model_type = "yolox"; width = 416; @@ -43,7 +52,10 @@ let { path = "rtsp://127.0.0.1:8554/kitchen"; input_args = "preset-rtsp-restream"; - roles = [ "audio" "record" ]; + roles = [ + "audio" + "record" + ]; } { path = "rtsp://127.0.0.1:8554/kitchen_sub"; @@ -77,7 +89,8 @@ let detect.enabled = true; objects.filters.person.min_score = 0.8; }; -in { +in +{ sops = { secrets = { frigate_mqtt_password.sopsFile = ./secrets.json; @@ -114,8 +127,7 @@ in { "/mnt/files/services/frigate:/media/frigate" ]; devices = [ "/dev/dri:/dev/dri" ]; - environmentFiles = - [ config.sops.templates."frigate/environment_file".path ]; + environmentFiles = [ config.sops.templates."frigate/environment_file".path ]; ports = [ "8971:8971" "8554:8554" @@ -135,5 +147,10 @@ in { ]; }; - networking.firewall.allowedTCPPorts = [ 1984 5000 8090 8971 ]; + networking.firewall.allowedTCPPorts = [ + 1984 + 5000 + 8090 + 8971 + ]; } diff --git a/modules/profiles/home-automation/home-assistant/components/ha_nationalgrid.nix b/modules/profiles/home-automation/home-assistant/components/ha_nationalgrid.nix index f57ddf9..650845c 100644 --- a/modules/profiles/home-automation/home-assistant/components/ha_nationalgrid.nix +++ b/modules/profiles/home-automation/home-assistant/components/ha_nationalgrid.nix @@ -1,7 +1,14 @@ -{ fetchFromGitHub, home-assistant, buildHomeAssistantComponent, aionatgrid }: +{ + fetchFromGitHub, + home-assistant, + buildHomeAssistantComponent, + aionatgrid, +}: -let pythonPkgs = home-assistant.python3Packages; -in buildHomeAssistantComponent rec { +let + pythonPkgs = home-assistant.python3Packages; +in +buildHomeAssistantComponent rec { owner = "RyanMorash"; domain = "national_grid"; version = "0.1.1"; diff --git a/modules/profiles/home-automation/home-assistant/default.nix b/modules/profiles/home-automation/home-assistant/default.nix index b55beb5..d7f7248 100644 --- a/modules/profiles/home-automation/home-assistant/default.nix +++ b/modules/profiles/home-automation/home-assistant/default.nix @@ -1,4 +1,11 @@ -{ config, pkgs, lib, profiles, ... }: { +{ + config, + pkgs, + lib, + profiles, + ... +}: +{ imports = [ profiles.services.matter-server ] ++ [ ./postgresql.nix ]; sops = { @@ -64,8 +71,8 @@ "zha" ]; - extraPackages = python3Packages: - with python3Packages; [ + extraPackages = + python3Packages: with python3Packages; [ # HomeKit Bridge aiohomekit base36 @@ -76,17 +83,19 @@ pyqrcode ]; - customComponents = with pkgs.home-assistant-custom-components; - [ frigate hass_web_proxy ] ++ [ - (pkgs.home-assistant.python3Packages.callPackage - ./components/ha_nationalgrid.nix { - aionatgrid = pkgs.home-assistant.python3Packages.callPackage - ./packages/aionatgrid.nix { }; - }) + customComponents = + with pkgs.home-assistant-custom-components; + [ + frigate + hass_web_proxy + ] + ++ [ + (pkgs.home-assistant.python3Packages.callPackage ./components/ha_nationalgrid.nix { + aionatgrid = pkgs.home-assistant.python3Packages.callPackage ./packages/aionatgrid.nix { }; + }) ]; - customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; - [ advanced-camera-card ]; + customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; [ advanced-camera-card ]; config = { default_config = { }; @@ -120,10 +129,17 @@ networking.firewall = { allowedUDPPorts = [ 5353 ]; - allowedTCPPorts = [ 8123 1400 21063 21064 ]; - allowedTCPPortRanges = [{ - from = 21063; - to = 21068; - }]; + allowedTCPPorts = [ + 8123 + 1400 + 21063 + 21064 + ]; + allowedTCPPortRanges = [ + { + from = 21063; + to = 21068; + } + ]; }; } diff --git a/modules/profiles/home-automation/home-assistant/packages/aionatgrid.nix b/modules/profiles/home-automation/home-assistant/packages/aionatgrid.nix index adaadac..54dbc2a 100644 --- a/modules/profiles/home-automation/home-assistant/packages/aionatgrid.nix +++ b/modules/profiles/home-automation/home-assistant/packages/aionatgrid.nix @@ -1,5 +1,11 @@ -{ buildPythonPackage, fetchFromGitHub, setuptools, aiohttp, typing-extensions -, pyjwt }: +{ + buildPythonPackage, + fetchFromGitHub, + setuptools, + aiohttp, + typing-extensions, + pyjwt, +}: buildPythonPackage rec { pname = "aionatgrid"; @@ -17,5 +23,9 @@ buildPythonPackage rec { pyproject = true; build-system = [ setuptools ]; - dependencies = [ aiohttp typing-extensions pyjwt ]; + dependencies = [ + aiohttp + typing-extensions + pyjwt + ]; } diff --git a/modules/profiles/home-automation/home-assistant/postgresql.nix b/modules/profiles/home-automation/home-assistant/postgresql.nix index e14803c..0091250 100644 --- a/modules/profiles/home-automation/home-assistant/postgresql.nix +++ b/modules/profiles/home-automation/home-assistant/postgresql.nix @@ -3,10 +3,12 @@ services.postgresql = { ensureDatabases = [ "hass" ]; - ensureUsers = [{ - name = "hass"; - ensureDBOwnership = true; - }]; + ensureUsers = [ + { + name = "hass"; + ensureDBOwnership = true; + } + ]; }; services.postgresqlBackup.databases = [ "hass" ]; @@ -16,7 +18,12 @@ config.recorder = { db_url = "postgresql:///hass?host=/run/postgresql"; - exclude = { entities = [ "sun.sun" "sensor.date" ]; }; + exclude = { + entities = [ + "sun.sun" + "sensor.date" + ]; + }; }; }; } diff --git a/modules/profiles/hypervisors/incus.nix b/modules/profiles/hypervisors/incus.nix index 60f55d0..3ad2bfb 100644 --- a/modules/profiles/hypervisors/incus.nix +++ b/modules/profiles/hypervisors/incus.nix @@ -4,28 +4,34 @@ ui.enable = true; preseed = { networks = [ ]; - profiles = [{ - devices = { - eth0 = { - name = "eth0"; - type = "nic"; - nictype = "bridged"; - parent = "vmbr0"; + profiles = [ + { + devices = { + eth0 = { + name = "eth0"; + type = "nic"; + nictype = "bridged"; + parent = "vmbr0"; + }; + root = { + path = "/"; + pool = "default"; + size = "32GiB"; + type = "disk"; + }; }; - root = { - path = "/"; - pool = "default"; - size = "32GiB"; - type = "disk"; + name = "default"; + } + ]; + storage_pools = [ + { + config = { + source = "/var/lib/incus/storage-pools/default"; }; - }; - name = "default"; - }]; - storage_pools = [{ - config = { source = "/var/lib/incus/storage-pools/default"; }; - driver = "dir"; - name = "default"; - }]; + driver = "dir"; + name = "default"; + } + ]; }; }; diff --git a/modules/profiles/media-management/bazarr/default.nix b/modules/profiles/media-management/bazarr/default.nix index e6f3bcf..c1f1e00 100644 --- a/modules/profiles/media-management/bazarr/default.nix +++ b/modules/profiles/media-management/bazarr/default.nix @@ -51,7 +51,9 @@ username = ""; vip = false; }; - analytics = { enabled = false; }; + analytics = { + enabled = false; + }; anidb = { api_client = ""; api_client_ver = 1; @@ -61,8 +63,12 @@ anidb_api_client_ver = 1; search_threshold = 6; }; - anticaptcha = { anti_captcha_key = ""; }; - assrt = { token = ""; }; + anticaptcha = { + anti_captcha_key = ""; + }; + assrt = { + token = ""; + }; auth = { apikey = config.sops.placeholder.bazarr_api_key; password = ""; @@ -80,12 +86,16 @@ hour = 3; retention = 31; }; - betaseries = { token = ""; }; + betaseries = { + token = ""; + }; cinemaz = { cookies = ""; user_agent = ""; }; - cors = { enabled = false; }; + cors = { + enabled = false; + }; deathbycaptcha = { password = ""; username = ""; @@ -246,7 +256,9 @@ update_movie_library = false; update_series_library = false; }; - podnapisi = { verify_ssl = true; }; + podnapisi = { + verify_ssl = true; + }; postgresql = { database = ""; enabled = false; @@ -256,7 +268,10 @@ username = ""; }; proxy = { - exclude = [ "localhost" "127.0.0.1" ]; + exclude = [ + "localhost" + "127.0.0.1" + ]; password = ""; port = ""; type = null; @@ -315,7 +330,9 @@ sync_only_monitored_series = true; use_ffprobe_cache = true; }; - subdl = { api_key = ""; }; + subdl = { + api_key = ""; + }; subf2m = { user_agent = ""; verify_ssl = true; diff --git a/modules/profiles/media-management/declutarr/default.nix b/modules/profiles/media-management/declutarr/default.nix index 0dac329..9950ae4 100644 --- a/modules/profiles/media-management/declutarr/default.nix +++ b/modules/profiles/media-management/declutarr/default.nix @@ -33,22 +33,28 @@ }; instances = { - sonarr = [{ - base_url = "https://sonarr.e10.camp"; - api_key = config.sops.placeholder.sonarr_api_key; - }]; + sonarr = [ + { + base_url = "https://sonarr.e10.camp"; + api_key = config.sops.placeholder.sonarr_api_key; + } + ]; - radarr = [{ - base_url = "https://radarr.e10.camp"; - api_key = config.sops.placeholder.radarr_api_key; - }]; + radarr = [ + { + base_url = "https://radarr.e10.camp"; + api_key = config.sops.placeholder.radarr_api_key; + } + ]; }; download_clients = { - sabnzbd = [{ - base_url = "https://sabnzbd.e10.camp"; - api_key = config.sops.placeholder.sabnzbd_api_key; - }]; + sabnzbd = [ + { + base_url = "https://sabnzbd.e10.camp"; + api_key = config.sops.placeholder.sabnzbd_api_key; + } + ]; }; }; owner = config.services.declutarr.user; diff --git a/modules/profiles/media-management/fileflows/node.nix b/modules/profiles/media-management/fileflows/node.nix index e8a4d91..9992d02 100644 --- a/modules/profiles/media-management/fileflows/node.nix +++ b/modules/profiles/media-management/fileflows/node.nix @@ -1,9 +1,7 @@ { hosts, ... }: { services.fileflows.node = { enable = true; - serverUrl = "http://${hosts.htpc.config.networking.hostName}:${ - toString hosts.htpc.config.services.fileflows.server.port - }"; + serverUrl = "http://${hosts.htpc.config.networking.hostName}:${toString hosts.htpc.config.services.fileflows.server.port}"; libraryDirs = [ "/mnt/blockbuster/media" ]; }; } diff --git a/modules/profiles/media-management/immich/default.nix b/modules/profiles/media-management/immich/default.nix index 637f217..5bb7d77 100644 --- a/modules/profiles/media-management/immich/default.nix +++ b/modules/profiles/media-management/immich/default.nix @@ -9,20 +9,20 @@ templates."immich/config.json" = { content = builtins.toJSON { - server = { externalDomain = "https://immich.e10.camp"; }; + server = { + externalDomain = "https://immich.e10.camp"; + }; oauth = { autoLaunch = false; autoRegister = true; buttonText = "Login with Authelia"; - clientId = - "DpimJHTYr-K1ba5dFHj6mlRPXxkQCTN3E3RGljCmVXlGs.AcDdWwG9sysfV~Bv3vq7Z1rEEm"; + clientId = "DpimJHTYr-K1ba5dFHj6mlRPXxkQCTN3E3RGljCmVXlGs.AcDdWwG9sysfV~Bv3vq7Z1rEEm"; clientSecret = config.sops.placeholder.immich_oauth_client_secret; defaultStorageQuota = null; enabled = true; issuerUrl = "https://auth.e10.camp/.well-known/openid-configuration"; mobileOverrideEnabled = true; - mobileRedirectUri = - "https://immich.e10.camp/api/oauth/mobile-redirect"; + mobileRedirectUri = "https://immich.e10.camp/api/oauth/mobile-redirect"; scope = "openid email profile"; signingAlgorithm = "RS256"; storageLabelClaim = "preferred_username"; @@ -46,8 +46,7 @@ }; }; - services.postgresqlBackup.databases = - [ config.services.immich.database.name ]; + services.postgresqlBackup.databases = [ config.services.immich.database.name ]; systemd.tmpfiles.rules = [ "d '${config.services.immich.mediaLocation}' 0777 ${config.services.immich.user} ${config.services.immich.group} - -" diff --git a/modules/profiles/media-management/profilarr/default.nix b/modules/profiles/media-management/profilarr/default.nix index 228f3a5..5135989 100644 --- a/modules/profiles/media-management/profilarr/default.nix +++ b/modules/profiles/media-management/profilarr/default.nix @@ -14,8 +14,7 @@ }; oidc = { enable = true; - clientID = - "a8Jy2n_CgUOu~nTlLlkgZQV7xJmhq5aW1N0eNePghiFL0Su5jysCJKOpaEpjvRd7yhhz589E"; + clientID = "a8Jy2n_CgUOu~nTlLlkgZQV7xJmhq5aW1N0eNePghiFL0Su5jysCJKOpaEpjvRd7yhhz589E"; clientSecretFile = config.sops.secrets.profilarr_oidc_client_secret.path; discoveryURL = "https://auth.e10.camp/.well-known/openid-configuration"; }; diff --git a/modules/profiles/media-management/prowlarr/default.nix b/modules/profiles/media-management/prowlarr/default.nix index e8f912b..268d47b 100644 --- a/modules/profiles/media-management/prowlarr/default.nix +++ b/modules/profiles/media-management/prowlarr/default.nix @@ -1,5 +1,7 @@ { config, ... }: { - sops.secrets.prowlarr_api_key = { sopsFile = ./secrets.json; }; + sops.secrets.prowlarr_api_key = { + sopsFile = ./secrets.json; + }; services.prowlarr = { enable = true; @@ -11,7 +13,9 @@ url = "https://prowlarr.e10.camp"; openFirewall = true; apiKeyFile = config.sops.secrets.prowlarr_api_key.path; - environment = { PROWLARR__BACKFILL = "true"; }; + environment = { + PROWLARR__BACKFILL = "true"; + }; port = 9711; }; } diff --git a/modules/profiles/media-management/radarr/default.nix b/modules/profiles/media-management/radarr/default.nix index 114d588..59323db 100644 --- a/modules/profiles/media-management/radarr/default.nix +++ b/modules/profiles/media-management/radarr/default.nix @@ -8,31 +8,34 @@ }; templates."radarr/config.xml" = { - content = flake.lib.generators.toXML { - rootName = "Config"; - xmlns = { }; - } { - ApiKey = "${config.sops.placeholder.radarr_api_key}"; - AuthenticationMethod = "Forms"; - AuthenticationRequired = "Enabled"; - BindAddress = "*"; - Branch = "master"; - EnableSsl = false; - InstanceName = "Radarr"; - LaunchBrowser = false; - LogLevel = "info"; - Port = config.services.radarr.port; - PostgresHost = "localhost"; - PostgresLogDb = "radarr_logs"; - PostgresMainDb = "radarr"; - PostgresPassword = ""; - PostgresPort = config.services.postgresql.settings.port; - PostgresUser = "radarr"; - SslCertPassword = null; - SslCertPath = null; - SslPort = 9898; - UrlBase = null; - }; + content = + flake.lib.generators.toXML + { + rootName = "Config"; + xmlns = { }; + } + { + ApiKey = "${config.sops.placeholder.radarr_api_key}"; + AuthenticationMethod = "Forms"; + AuthenticationRequired = "Enabled"; + BindAddress = "*"; + Branch = "master"; + EnableSsl = false; + InstanceName = "Radarr"; + LaunchBrowser = false; + LogLevel = "info"; + Port = config.services.radarr.port; + PostgresHost = "localhost"; + PostgresLogDb = "radarr_logs"; + PostgresMainDb = "radarr"; + PostgresPassword = ""; + PostgresPort = config.services.postgresql.settings.port; + PostgresUser = "radarr"; + SslCertPassword = null; + SslCertPath = null; + SslPort = 9898; + UrlBase = null; + }; path = "${config.services.radarr.dataDir}/config.xml"; owner = config.services.radarr.user; inherit (config.services.radarr) group; diff --git a/modules/profiles/media-management/radarr/postgresql.nix b/modules/profiles/media-management/radarr/postgresql.nix index 4fa59c6..5e6e977 100644 --- a/modules/profiles/media-management/radarr/postgresql.nix +++ b/modules/profiles/media-management/radarr/postgresql.nix @@ -1,14 +1,26 @@ -{ config, pkgs, lib, profiles, ... }: { +{ + config, + pkgs, + lib, + profiles, + ... +}: +{ imports = [ profiles.databases.postgresql ]; services.postgresqlBackup.databases = [ "radarr" ]; services.postgresql = { - ensureDatabases = [ "radarr" "radarr_logs" ]; - ensureUsers = [{ - name = "radarr"; - ensureDBOwnership = true; - }]; + ensureDatabases = [ + "radarr" + "radarr_logs" + ]; + ensureUsers = [ + { + name = "radarr"; + ensureDBOwnership = true; + } + ]; initialScriptText = lib.mkAfter '' ALTER DATABASE radarr_logs OWNER TO radarr; @@ -24,13 +36,18 @@ after = [ "postgresql.service" ]; wants = [ "postgresql.service" ]; serviceConfig = { - ExecStart = lib.getExe (pkgs.writeShellApplication { - name = "radarr-logs-cleanup"; - runtimeInputs = [ pkgs.sudo config.services.postgresql.package ]; - text = '' - sudo -u postgres psql --dbname="radarr_logs" --command="DELETE FROM \"Logs\" WHERE \"Time\" < now() - interval '24 hours'" - ''; - }); + ExecStart = lib.getExe ( + pkgs.writeShellApplication { + name = "radarr-logs-cleanup"; + runtimeInputs = [ + pkgs.sudo + config.services.postgresql.package + ]; + text = '' + sudo -u postgres psql --dbname="radarr_logs" --command="DELETE FROM \"Logs\" WHERE \"Time\" < now() - interval '24 hours'" + ''; + } + ); }; }; diff --git a/modules/profiles/media-management/sabnzbd/default.nix b/modules/profiles/media-management/sabnzbd/default.nix index f552232..69102ef 100644 --- a/modules/profiles/media-management/sabnzbd/default.nix +++ b/modules/profiles/media-management/sabnzbd/default.nix @@ -2,7 +2,8 @@ let downloadDir = "/data/local/tmp/sabnzbd/inter"; completeDir = "/data/local/tmp/sabnzbd/dst"; -in { +in +{ sops = { secrets = { sabnzbd_admin_password = { @@ -92,10 +93,8 @@ in { }; servers = { "news-us.newsgroup.ninja" = { - username = - config.sops.placeholder.sabnzbd_newsgroup_ninja_username; - password = - config.sops.placeholder.sabnzbd_newsgroup_ninja_password; + username = config.sops.placeholder.sabnzbd_newsgroup_ninja_username; + password = config.sops.placeholder.sabnzbd_newsgroup_ninja_password; }; "news.supernews.com" = { username = config.sops.placeholder.sabnzbd_supernews_username; @@ -110,10 +109,8 @@ in { password = config.sops.placeholder.sabnzbd_newshosting_password; }; "news.newsgroupdirect.com" = { - username = - config.sops.placeholder.sabnzbd_newsgroup_direct_username; - password = - config.sops.placeholder.sabnzbd_newsgroup_direct_password; + username = config.sops.placeholder.sabnzbd_newsgroup_direct_username; + password = config.sops.placeholder.sabnzbd_newsgroup_direct_password; }; "news.eweka.nl" = { username = config.sops.placeholder.sabnzbd_eweka_username; diff --git a/modules/profiles/media-management/sonarr/default.nix b/modules/profiles/media-management/sonarr/default.nix index e84a15e..3e86733 100644 --- a/modules/profiles/media-management/sonarr/default.nix +++ b/modules/profiles/media-management/sonarr/default.nix @@ -8,32 +8,35 @@ }; templates."sonarr/config.xml" = { - content = flake.lib.generators.toXML { - rootName = "Config"; - xmlns = { }; - } { - ApiKey = "${config.sops.placeholder.sonarr_api_key}"; - AuthenticationMethod = "Forms"; - AuthenticationRequired = "Enabled"; - BindAddress = "*"; - Branch = "main"; - EnableSsl = false; - InstanceName = "Sonarr"; - LaunchBrowser = true; - LogLevel = "info"; - Port = config.services.sonarr.port; - PostgresHost = "localhost"; - PostgresLogDb = "sonarr_logs"; - PostgresMainDb = "sonarr"; - PostgresPassword = ""; - PostgresPort = config.services.postgresql.settings.port; - PostgresUser = "sonarr"; - SslCertPassword = null; - SslCertPath = null; - SslPort = 9898; - UpdateMechanism = "builtin"; - UrlBase = null; - }; + content = + flake.lib.generators.toXML + { + rootName = "Config"; + xmlns = { }; + } + { + ApiKey = "${config.sops.placeholder.sonarr_api_key}"; + AuthenticationMethod = "Forms"; + AuthenticationRequired = "Enabled"; + BindAddress = "*"; + Branch = "main"; + EnableSsl = false; + InstanceName = "Sonarr"; + LaunchBrowser = true; + LogLevel = "info"; + Port = config.services.sonarr.port; + PostgresHost = "localhost"; + PostgresLogDb = "sonarr_logs"; + PostgresMainDb = "sonarr"; + PostgresPassword = ""; + PostgresPort = config.services.postgresql.settings.port; + PostgresUser = "sonarr"; + SslCertPassword = null; + SslCertPath = null; + SslPort = 9898; + UpdateMechanism = "builtin"; + UrlBase = null; + }; path = "${config.services.sonarr.dataDir}/config.xml"; owner = config.services.sonarr.user; diff --git a/modules/profiles/media-management/sonarr/postgresql.nix b/modules/profiles/media-management/sonarr/postgresql.nix index 35b852c..e1ae0ea 100644 --- a/modules/profiles/media-management/sonarr/postgresql.nix +++ b/modules/profiles/media-management/sonarr/postgresql.nix @@ -1,14 +1,26 @@ -{ config, pkgs, lib, profiles, ... }: { +{ + config, + pkgs, + lib, + profiles, + ... +}: +{ imports = [ profiles.databases.postgresql ]; services.postgresqlBackup.databases = [ "sonarr" ]; services.postgresql = { - ensureDatabases = [ "sonarr" "sonarr_logs" ]; - ensureUsers = [{ - name = "sonarr"; - ensureDBOwnership = true; - }]; + ensureDatabases = [ + "sonarr" + "sonarr_logs" + ]; + ensureUsers = [ + { + name = "sonarr"; + ensureDBOwnership = true; + } + ]; initialScriptText = lib.mkAfter '' ALTER DATABASE sonarr_logs OWNER TO sonarr; @@ -24,13 +36,18 @@ after = [ "postgresql.service" ]; wants = [ "postgresql.service" ]; serviceConfig = { - ExecStart = lib.getExe (pkgs.writeShellApplication { - name = "sonarr-logs-cleanup"; - runtimeInputs = [ pkgs.sudo config.services.postgresql.package ]; - text = '' - sudo -u postgres psql --dbname="sonarr_logs" --command="DELETE FROM \"Logs\" WHERE \"Time\" < now() - interval '24 hours'" - ''; - }); + ExecStart = lib.getExe ( + pkgs.writeShellApplication { + name = "sonarr-logs-cleanup"; + runtimeInputs = [ + pkgs.sudo + config.services.postgresql.package + ]; + text = '' + sudo -u postgres psql --dbname="sonarr_logs" --command="DELETE FROM \"Logs\" WHERE \"Time\" < now() - interval '24 hours'" + ''; + } + ); }; }; diff --git a/modules/profiles/monitoring/loki/default.nix b/modules/profiles/monitoring/loki/default.nix index 65da89a..c7514b5 100644 --- a/modules/profiles/monitoring/loki/default.nix +++ b/modules/profiles/monitoring/loki/default.nix @@ -25,15 +25,22 @@ services.loki = { enable = true; - extraFlags = [ "-config.expand-env=true" "-log.level=warn" ]; + extraFlags = [ + "-config.expand-env=true" + "-log.level=warn" + ]; configuration = { auth_enabled = false; - server = { http_listen_port = 3100; }; + server = { + http_listen_port = 3100; + }; ingester = { lifecycler = { address = "0.0.0.0"; ring = { - kvstore = { store = "memberlist"; }; + kvstore = { + store = "memberlist"; + }; replication_factor = 1; }; final_sleep = "0s"; @@ -68,16 +75,19 @@ } ]; }; - compactor = { working_directory = "/var/lib/loki/compactor"; }; + compactor = { + working_directory = "/var/lib/loki/compactor"; + }; storage_config = { tsdb_shipper = { active_index_directory = "/var/lib/loki/tsdb/index"; cache_location = "/var/lib/loki/tsdb/cache"; }; - filesystem = { directory = "/var/lib/loki/chunks"; }; + filesystem = { + directory = "/var/lib/loki/chunks"; + }; aws = { - s3 = - "s3://\${AWS_ACCESS_KEY_ID}:\${AWS_SECRET_ACCESS_KEY}@us-east-2/storage.loki.e10.camp"; + s3 = "s3://\${AWS_ACCESS_KEY_ID}:\${AWS_SECRET_ACCESS_KEY}@us-east-2/storage.loki.e10.camp"; }; }; memberlist = { @@ -120,17 +130,14 @@ }; systemd.services.loki = { - serviceConfig.EnvironmentFile = - config.sops.templates."loki/environment_file".path; + serviceConfig.EnvironmentFile = config.sops.templates."loki/environment_file".path; wants = [ "sops-nix.service" ]; after = [ "sops-nix.service" ]; }; networking.firewall = { - allowedTCPPorts = - [ config.services.loki.configuration.server.http_listen_port ]; - allowedUDPPorts = - [ config.services.loki.configuration.server.http_listen_port ]; + allowedTCPPorts = [ config.services.loki.configuration.server.http_listen_port ]; + allowedUDPPorts = [ config.services.loki.configuration.server.http_listen_port ]; }; services.restic.backups = { diff --git a/modules/profiles/monitoring/thanos/default.nix b/modules/profiles/monitoring/thanos/default.nix index 5910ba2..a6d6800 100644 --- a/modules/profiles/monitoring/thanos/default.nix +++ b/modules/profiles/monitoring/thanos/default.nix @@ -32,8 +32,7 @@ endpoint = "s3.us-east-2.amazonaws.com"; region = "us-east-2"; access_key = config.sops.placeholder.thanos_storage_aws_access_key_id; - secret_key = - config.sops.placeholder.thanos_storage_aws_secret_access_key; + secret_key = config.sops.placeholder.thanos_storage_aws_secret_access_key; }; }; mode = "0777"; @@ -82,15 +81,17 @@ }; }; - systemd.services = let - additionalServiceConfig = { - wants = [ "sops-nix.service" ]; - after = [ "sops-nix.service" ]; + systemd.services = + let + additionalServiceConfig = { + wants = [ "sops-nix.service" ]; + after = [ "sops-nix.service" ]; + }; + in + { + thanos-sidecar = additionalServiceConfig; + thanos-store = additionalServiceConfig; + thanos-query = additionalServiceConfig; + thanos-compact = additionalServiceConfig; }; - in { - thanos-sidecar = additionalServiceConfig; - thanos-store = additionalServiceConfig; - thanos-query = additionalServiceConfig; - thanos-compact = additionalServiceConfig; - }; } diff --git a/modules/profiles/networking/blocky/default.nix b/modules/profiles/networking/blocky/default.nix index 934e17a..30c4d83 100644 --- a/modules/profiles/networking/blocky/default.nix +++ b/modules/profiles/networking/blocky/default.nix @@ -1,5 +1,8 @@ { pkgs, lib, ... }: { - imports = [ ./postgresql.nix ./redis.nix ]; + imports = [ + ./postgresql.nix + ./redis.nix + ]; environment.systemPackages = [ pkgs.blocky ]; @@ -25,8 +28,7 @@ "basil.satan.network" = "10.10.2.0"; "cardamom.satan.network" = "10.10.3.0"; "elderflower.satan.network" = "10.2.1.0"; - "matrix.local" = - "10.10.3.101"; # TODO: Required for Bonjour printer sharing + "matrix.local" = "10.10.3.101"; # TODO: Required for Bonjour printer sharing }; }; blocking = { @@ -38,7 +40,9 @@ }; concurrency = 16; }; - denylists = { ads = [ "https://big.oisd.nl/domainswild" ]; }; + denylists = { + ads = [ "https://big.oisd.nl/domainswild" ]; + }; allowlists = { ads = [ (pkgs.writeText "ads-allowlist.txt" '' @@ -49,7 +53,9 @@ '') ]; }; - clientGroupsBlock = { default = [ "ads" ]; }; + clientGroupsBlock = { + default = [ "ads" ]; + }; }; caching = { prefetching = true; @@ -61,22 +67,29 @@ }; clientLookup = { upstream = "192.168.1.1:5335"; - singleNameOrder = [ 1 2 ]; + singleNameOrder = [ + 1 + 2 + ]; }; conditional = { - mapping = let - reverseDnsServer = "192.168.1.1:5335"; - addresses = [ - "arpa" - "1.168.192.in-addr.arpa" - "168.192.in-addr.arpa" - "10.10.in-addr.arpa" - "." - ]; - in builtins.listToAttrs (map (name: { - inherit name; - value = reverseDnsServer; - }) addresses); + mapping = + let + reverseDnsServer = "192.168.1.1:5335"; + addresses = [ + "arpa" + "1.168.192.in-addr.arpa" + "168.192.in-addr.arpa" + "10.10.in-addr.arpa" + "." + ]; + in + builtins.listToAttrs ( + map (name: { + inherit name; + value = reverseDnsServer; + }) addresses + ); }; prometheus = { enable = true; @@ -92,6 +105,9 @@ }; }; - networking.firewall.allowedTCPPorts = [ 53 4022 ]; + networking.firewall.allowedTCPPorts = [ + 53 + 4022 + ]; networking.firewall.allowedUDPPorts = [ 53 ]; } diff --git a/modules/profiles/networking/blocky/redis.nix b/modules/profiles/networking/blocky/redis.nix index ab95482..027bac0 100644 --- a/modules/profiles/networking/blocky/redis.nix +++ b/modules/profiles/networking/blocky/redis.nix @@ -4,12 +4,12 @@ openFirewall = true; bind = "0.0.0.0"; port = 6379; - settings = { protected-mode = false; }; + settings = { + protected-mode = false; + }; }; services.blocky.settings.redis = { - address = "${config.services.redis.servers.blocky.bind}:${ - toString config.services.redis.servers.blocky.port - }"; + address = "${config.services.redis.servers.blocky.bind}:${toString config.services.redis.servers.blocky.port}"; }; } diff --git a/modules/profiles/networking/mosh.nix b/modules/profiles/networking/mosh.nix index b31c81f..54eb2d1 100644 --- a/modules/profiles/networking/mosh.nix +++ b/modules/profiles/networking/mosh.nix @@ -4,8 +4,10 @@ # withUtempter = true; }; - networking.firewall.allowedUDPPortRanges = [{ - from = 60000; - to = 61000; - }]; + networking.firewall.allowedUDPPortRanges = [ + { + from = 60000; + to = 61000; + } + ]; } diff --git a/modules/profiles/networking/printing.nix b/modules/profiles/networking/printing.nix index 19ea2d1..404618f 100644 --- a/modules/profiles/networking/printing.nix +++ b/modules/profiles/networking/printing.nix @@ -9,12 +9,14 @@ }; hardware.printers = { - ensurePrinters = [{ - name = "Brother_HL-L2300D"; - location = "Office"; - deviceUri = "usb://Brother/HL-L2300D%20series?serial=U63878H0N332161"; - model = "drv:///brlaser.drv/brl2300d.ppd"; - }]; + ensurePrinters = [ + { + name = "Brother_HL-L2300D"; + location = "Office"; + deviceUri = "usb://Brother/HL-L2300D%20series?serial=U63878H0N332161"; + model = "drv:///brlaser.drv/brl2300d.ppd"; + } + ]; ensureDefaultPrinter = "Brother_HL-L2300D"; }; @@ -27,8 +29,14 @@ enable = true; nssmdns4 = true; openFirewall = true; - allowInterfaces = [ "ens18" "vlan10" ]; - denyInterfaces = [ "docker0" "veth*" ]; + allowInterfaces = [ + "ens18" + "vlan10" + ]; + denyInterfaces = [ + "docker0" + "veth*" + ]; publish = { enable = true; userServices = true; diff --git a/modules/profiles/networking/quad9.nix b/modules/profiles/networking/quad9.nix index 84a7b81..c6b7fc4 100644 --- a/modules/profiles/networking/quad9.nix +++ b/modules/profiles/networking/quad9.nix @@ -1,4 +1,8 @@ { - networking.nameservers = - [ "9.9.9.9" "149.112.112.112" "2620:fe::fe" "2620:fe::9" ]; + networking.nameservers = [ + "9.9.9.9" + "149.112.112.112" + "2620:fe::fe" + "2620:fe::9" + ]; } diff --git a/modules/profiles/networking/speedtest-tracker/default.nix b/modules/profiles/networking/speedtest-tracker/default.nix index 2675b9e..e8bbce9 100644 --- a/modules/profiles/networking/speedtest-tracker/default.nix +++ b/modules/profiles/networking/speedtest-tracker/default.nix @@ -16,8 +16,10 @@ virtualHost = "speedtest-tracker"; }; - services.nginx.virtualHosts."speedtest-tracker".listen = [{ - addr = "0.0.0.0"; - port = 8881; - }]; + services.nginx.virtualHosts."speedtest-tracker".listen = [ + { + addr = "0.0.0.0"; + port = 8881; + } + ]; } diff --git a/modules/profiles/networking/tailscale/default.nix b/modules/profiles/networking/tailscale/default.nix index 27618a5..32c7154 100644 --- a/modules/profiles/networking/tailscale/default.nix +++ b/modules/profiles/networking/tailscale/default.nix @@ -1,11 +1,18 @@ { config, lib, ... }: { - sops.secrets = { tailscale_auth_key = { sopsFile = ./secrets.json; }; }; + sops.secrets = { + tailscale_auth_key = { + sopsFile = ./secrets.json; + }; + }; services.tailscale = { enable = true; authKeyFile = config.sops.secrets.tailscale_auth_key.path; useRoutingFeatures = lib.mkDefault "client"; - extraUpFlags = [ "--hostname=${config.networking.hostName}" "--reset" ]; + extraUpFlags = [ + "--hostname=${config.networking.hostName}" + "--reset" + ]; openFirewall = true; }; diff --git a/modules/profiles/networking/unifi.nix b/modules/profiles/networking/unifi.nix index f92e63e..7a154f4 100644 --- a/modules/profiles/networking/unifi.nix +++ b/modules/profiles/networking/unifi.nix @@ -1,8 +1,7 @@ { config, ... }: { services.unifi-os-server = { enable = true; - uosSystemIP = - (builtins.head config.networking.interfaces.ens18.ipv4.addresses).address; + uosSystemIP = (builtins.head config.networking.interfaces.ens18.ipv4.addresses).address; openFirewallUiPort = true; openFirewallServicePorts = true; }; diff --git a/modules/profiles/nix/remote-builders/e10-builder.nix b/modules/profiles/nix/remote-builders/e10-builder.nix index 1392a91..c8b6f35 100644 --- a/modules/profiles/nix/remote-builders/e10-builder.nix +++ b/modules/profiles/nix/remote-builders/e10-builder.nix @@ -9,18 +9,27 @@ }; }; - nix.buildMachines = [{ - inherit (hosts.builder.config.networking) hostName; + nix.buildMachines = [ + { + inherit (hosts.builder.config.networking) hostName; - system = "x86_64-linux"; - protocol = "ssh-ng"; - maxJobs = 8; - speedFactor = 1; - supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; - mandatoryFeatures = [ ]; - sshUser = hosts.builder.config.users.users.builder.name; - sshKey = config.sops.secrets.builder_private_key.path; - }]; + system = "x86_64-linux"; + protocol = "ssh-ng"; + maxJobs = 8; + speedFactor = 1; + supportedFeatures = [ + "nixos-test" + "benchmark" + "big-parallel" + "kvm" + ]; + mandatoryFeatures = [ ]; + sshUser = hosts.builder.config.users.users.builder.name; + sshKey = config.sops.secrets.builder_private_key.path; + } + ]; - nix.settings = { builders-use-substitutes = true; }; + nix.settings = { + builders-use-substitutes = true; + }; } diff --git a/modules/profiles/observability/gatus/default.nix b/modules/profiles/observability/gatus/default.nix index ce69884..5225e71 100644 --- a/modules/profiles/observability/gatus/default.nix +++ b/modules/profiles/observability/gatus/default.nix @@ -1,7 +1,8 @@ let # Toggle for turning all endpoints off for maintenance maintenance = false; -in { config, lib, ... }: { +in +{ config, lib, ... }: { imports = [ ./postgresql.nix ]; sops = { @@ -50,370 +51,403 @@ in { config, lib, ... }: { target = "1.1.1.1:53"; interval = "30s"; }; - endpoints = let - mkEndpoint = { name, url, group, interval ? "60s" - , conditions ? [ "[STATUS] == 200" ], protected ? false - , extraConfig ? { } }: - ({ - inherit name url group interval conditions; - enabled = !maintenance; - alerts = [{ - enabled = true; - type = "ntfy"; - description = "healthcheck failed"; - send-on-resolved = true; - }]; - } // extraConfig // lib.optionalAttrs protected { - headers = { Authorization = "Basic $AUTHELIA_BASIC_AUTH"; }; - }); - bastion = [ - (mkEndpoint { - name = "Caddy"; - url = "http://bastion:2019/config"; - group = "Bastion"; - }) - (mkEndpoint { - name = "Authelia"; - url = "https://auth.e10.camp"; - group = "Bastion"; - }) - (mkEndpoint { - name = "LLDAP"; - url = "https://ldap.e10.camp"; - group = "Bastion"; - }) - (mkEndpoint { - name = "Prometheus Node Exporter"; - url = "http://bastion:9100"; - group = "Bastion"; - }) - ]; - omnibus = [ - (mkEndpoint { - name = "Prometheus Node Exporter"; - url = "http://omnibus:9100"; - group = "Omnibus"; - }) - (mkEndpoint { - name = "Prometheus SMART Exporter"; - url = "http://omnibus:9633"; - group = "Omnibus"; - }) - (mkEndpoint { - name = "Prometheus ZFS Exporter"; - url = "http://omnibus:9134"; - group = "Omnibus"; - }) - (mkEndpoint { - name = "NFS"; - url = "tcp://omnibus:111"; - group = "Omnibus"; - conditions = [ "[CONNECTED] == true" ]; - }) - (mkEndpoint { - name = "Samba"; - url = "tcp://omnibus:445"; - group = "Omnibus"; - conditions = [ "[CONNECTED] == true" ]; - }) - (mkEndpoint { - name = "Attic"; - url = "https://cache.e10.camp"; - group = "Omnibus"; - }) - ]; - htpc = [ - (mkEndpoint { - name = "Plex"; - url = "https://e10.video/web/index.html"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Sonarr"; - url = "https://sonarr.e10.camp"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Radarr"; - url = "https://radarr.e10.camp"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Prowlarr"; - url = "https://prowlarr.e10.camp"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Profilarr"; - url = "https://profilarr.e10.camp"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Tautulli"; - url = "https://tautulli.e10.camp"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Tracearr"; - url = "https://tracearr.e10.camp"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Wizarr"; - url = "https://join.e10.video"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Bazarr"; - url = "https://bazarr.e10.camp"; - group = "HTPC"; - }) - (mkEndpoint { - name = "SABnzbd"; - url = "https://sabnzbd.e10.camp"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Seerr"; - url = "https://requests.e10.video"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Prometheus DCGM Exporter"; - url = "http://htpc:9400"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Prometheus Plex Exporter"; - url = "http://htpc:9000/metrics"; - group = "HTPC"; - }) - (mkEndpoint { - name = "Prometheus Node Exporter"; - url = "http://htpc:9100"; - group = "HTPC"; - }) - (mkEndpoint { - name = "FileFlows"; - url = "https://fileflows.e10.camp"; - group = "HTPC"; - protected = true; - }) - (mkEndpoint { - name = "Frigate"; - url = "https://frigate.e10.camp"; - group = "HTPC"; - }) - ]; - matrix = [ - (mkEndpoint { - name = "e10.land"; - url = "https://e10.land"; - group = "Matrix"; - }) - (mkEndpoint { - name = "Prometheus Node Exporter"; - url = "http://matrix:9100"; - group = "Matrix"; - }) - (mkEndpoint { - name = "Netbox"; - url = "https://netbox.e10.camp"; - group = "Matrix"; - }) - (mkEndpoint { - name = "Immich"; - url = "https://immich.e10.camp"; - group = "Matrix"; - }) - (mkEndpoint { - name = "CUPS"; - url = "http://matrix:631"; - group = "Matrix"; - }) - (mkEndpoint { - name = "Mazanoke"; - url = "https://mazanoke.e10.camp"; - group = "Matrix"; - protected = true; - }) - (mkEndpoint { - name = "Miniflux"; - url = "https://feeds.e10.camp"; - group = "Matrix"; - }) - (mkEndpoint { - name = "Paperless"; - url = "https://paperless.e10.camp"; - group = "Matrix"; - }) - (mkEndpoint { - name = "BentoPDF"; - url = "https://pdf.e10.camp"; - group = "Matrix"; - protected = true; - }) - (mkEndpoint { - name = "Prometheus NUT Exporter"; - url = "http://matrix:9199"; - group = "Matrix"; - }) - (mkEndpoint { - name = "Caddy"; - url = "http://matrix:2019/config"; - group = "Matrix"; - }) - (mkEndpoint { - name = "Glance"; - url = "https://glance.e10.camp"; - group = "Matrix"; - protected = true; - }) - (mkEndpoint { - name = "Change Detection"; - url = "https://change-detection.e10.camp"; - group = "Matrix"; - protected = true; - }) - (mkEndpoint { - name = "Bichon"; - url = "https://bichon.e10.camp"; - group = "Matrix"; - }) - (mkEndpoint { - name = "Karakeep"; - url = "https://karakeep.e10.camp"; - group = "Matrix"; - }) - ]; - builder = [ - (mkEndpoint { - name = "nix-serve"; - url = "https://cache.builder.e10.camp"; - group = "Builder"; - conditions = [ "[STATUS] == 404" ]; - }) - (mkEndpoint { - name = "Prometheus Node Exporter"; - url = "http://builder:9100"; - group = "Builder"; - }) - ]; - controller = [ - (mkEndpoint { - name = "Blocky (DNS)"; - url = "tcp://controller:53"; - group = "Controller"; - interval = "30s"; - conditions = [ "[CONNECTED] == true" ]; - }) - (mkEndpoint { - name = "Blocky (API)"; - url = "http://controller:4022/api/blocking/status"; - group = "Controller"; - interval = "30s"; - conditions = [ "[STATUS] == 200" "[BODY].enabled == true" ]; - }) - (mkEndpoint { - name = "Home Assistant"; - url = "https://hass.e10.camp"; - group = "Controller"; - }) - (mkEndpoint { - name = "UniFi Controller"; - url = "https://controller:11443"; - group = "Controller"; - extraConfig.client.insecure = true; - }) - (mkEndpoint { - name = "Speedtest Tracker"; - url = "https://speedtest-tracker.e10.camp"; - group = "Controller"; - }) - (mkEndpoint { - name = "Prometheus Node Exporter"; - url = "http://controller:9100"; - group = "Controller"; - }) - (mkEndpoint { - name = "Prometheus NUT Exporter"; - url = "http://controller:9199"; - group = "Controller"; - }) - (mkEndpoint { - name = "Prometheus Smokeping Exporter"; - url = "http://controller:9199"; - group = "Controller"; - }) - (mkEndpoint { - name = "Prometheus Unpoller Exporter"; - url = "http://controller:9130"; - group = "Controller"; - }) - (mkEndpoint { - name = "Termix"; - url = "http://termix.e10.camp"; - group = "Controller"; - }) - ]; - monitor = [ - (mkEndpoint { - name = "Authelia"; - url = "https://auth.monitor.e10.camp"; - group = "Monitor"; - }) - (mkEndpoint { - name = "Caddy"; - url = "http://monitor:2019/config"; - group = "Monitor"; - }) - (mkEndpoint { - name = "Grafana"; - url = "https://grafana.e10.camp"; - group = "Monitor"; - }) - (mkEndpoint { - name = "Loki"; - url = "tcp://monitor:3100"; - group = "Monitor"; - conditions = [ "[CONNECTED] == true" ]; - }) - (mkEndpoint { - name = "Prometheus"; - url = "tcp://monitor:9090"; - group = "Monitor"; - conditions = [ "[CONNECTED] == true" ]; - }) - (mkEndpoint { - name = "rsyslogd"; - url = "tcp://monitor:514"; - group = "Monitor"; - conditions = [ "[CONNECTED] == true" ]; - }) - (mkEndpoint { - name = "Prometheus Node Exporter"; - url = "http://monitor:9100"; - group = "Monitor"; - }) - ]; - pikvm = [ - (mkEndpoint { - name = "PiKVM"; - url = "https://pikvm"; - group = "PiKVM"; - extraConfig.client.insecure = true; - }) - ]; - elderflower-kvm = [ - (mkEndpoint { - name = "JetKVM"; - url = "http://elderflower-kvm"; - group = "Elderflower (KVM)"; - extraConfig.client.insecure = true; - }) - ]; - in bastion ++ omnibus ++ htpc ++ matrix ++ builder ++ controller - ++ monitor ++ pikvm ++ elderflower-kvm; + endpoints = + let + mkEndpoint = + { + name, + url, + group, + interval ? "60s", + conditions ? [ "[STATUS] == 200" ], + protected ? false, + extraConfig ? { }, + }: + ( + { + inherit + name + url + group + interval + conditions + ; + enabled = !maintenance; + alerts = [ + { + enabled = true; + type = "ntfy"; + description = "healthcheck failed"; + send-on-resolved = true; + } + ]; + } + // extraConfig + // lib.optionalAttrs protected { + headers = { + Authorization = "Basic $AUTHELIA_BASIC_AUTH"; + }; + } + ); + bastion = [ + (mkEndpoint { + name = "Caddy"; + url = "http://bastion:2019/config"; + group = "Bastion"; + }) + (mkEndpoint { + name = "Authelia"; + url = "https://auth.e10.camp"; + group = "Bastion"; + }) + (mkEndpoint { + name = "LLDAP"; + url = "https://ldap.e10.camp"; + group = "Bastion"; + }) + (mkEndpoint { + name = "Prometheus Node Exporter"; + url = "http://bastion:9100"; + group = "Bastion"; + }) + ]; + omnibus = [ + (mkEndpoint { + name = "Prometheus Node Exporter"; + url = "http://omnibus:9100"; + group = "Omnibus"; + }) + (mkEndpoint { + name = "Prometheus SMART Exporter"; + url = "http://omnibus:9633"; + group = "Omnibus"; + }) + (mkEndpoint { + name = "Prometheus ZFS Exporter"; + url = "http://omnibus:9134"; + group = "Omnibus"; + }) + (mkEndpoint { + name = "NFS"; + url = "tcp://omnibus:111"; + group = "Omnibus"; + conditions = [ "[CONNECTED] == true" ]; + }) + (mkEndpoint { + name = "Samba"; + url = "tcp://omnibus:445"; + group = "Omnibus"; + conditions = [ "[CONNECTED] == true" ]; + }) + (mkEndpoint { + name = "Attic"; + url = "https://cache.e10.camp"; + group = "Omnibus"; + }) + ]; + htpc = [ + (mkEndpoint { + name = "Plex"; + url = "https://e10.video/web/index.html"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Sonarr"; + url = "https://sonarr.e10.camp"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Radarr"; + url = "https://radarr.e10.camp"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Prowlarr"; + url = "https://prowlarr.e10.camp"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Profilarr"; + url = "https://profilarr.e10.camp"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Tautulli"; + url = "https://tautulli.e10.camp"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Tracearr"; + url = "https://tracearr.e10.camp"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Wizarr"; + url = "https://join.e10.video"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Bazarr"; + url = "https://bazarr.e10.camp"; + group = "HTPC"; + }) + (mkEndpoint { + name = "SABnzbd"; + url = "https://sabnzbd.e10.camp"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Seerr"; + url = "https://requests.e10.video"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Prometheus DCGM Exporter"; + url = "http://htpc:9400"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Prometheus Plex Exporter"; + url = "http://htpc:9000/metrics"; + group = "HTPC"; + }) + (mkEndpoint { + name = "Prometheus Node Exporter"; + url = "http://htpc:9100"; + group = "HTPC"; + }) + (mkEndpoint { + name = "FileFlows"; + url = "https://fileflows.e10.camp"; + group = "HTPC"; + protected = true; + }) + (mkEndpoint { + name = "Frigate"; + url = "https://frigate.e10.camp"; + group = "HTPC"; + }) + ]; + matrix = [ + (mkEndpoint { + name = "e10.land"; + url = "https://e10.land"; + group = "Matrix"; + }) + (mkEndpoint { + name = "Prometheus Node Exporter"; + url = "http://matrix:9100"; + group = "Matrix"; + }) + (mkEndpoint { + name = "Netbox"; + url = "https://netbox.e10.camp"; + group = "Matrix"; + }) + (mkEndpoint { + name = "Immich"; + url = "https://immich.e10.camp"; + group = "Matrix"; + }) + (mkEndpoint { + name = "CUPS"; + url = "http://matrix:631"; + group = "Matrix"; + }) + (mkEndpoint { + name = "Mazanoke"; + url = "https://mazanoke.e10.camp"; + group = "Matrix"; + protected = true; + }) + (mkEndpoint { + name = "Miniflux"; + url = "https://feeds.e10.camp"; + group = "Matrix"; + }) + (mkEndpoint { + name = "Paperless"; + url = "https://paperless.e10.camp"; + group = "Matrix"; + }) + (mkEndpoint { + name = "BentoPDF"; + url = "https://pdf.e10.camp"; + group = "Matrix"; + protected = true; + }) + (mkEndpoint { + name = "Prometheus NUT Exporter"; + url = "http://matrix:9199"; + group = "Matrix"; + }) + (mkEndpoint { + name = "Caddy"; + url = "http://matrix:2019/config"; + group = "Matrix"; + }) + (mkEndpoint { + name = "Glance"; + url = "https://glance.e10.camp"; + group = "Matrix"; + protected = true; + }) + (mkEndpoint { + name = "Change Detection"; + url = "https://change-detection.e10.camp"; + group = "Matrix"; + protected = true; + }) + (mkEndpoint { + name = "Bichon"; + url = "https://bichon.e10.camp"; + group = "Matrix"; + }) + (mkEndpoint { + name = "Karakeep"; + url = "https://karakeep.e10.camp"; + group = "Matrix"; + }) + ]; + builder = [ + (mkEndpoint { + name = "nix-serve"; + url = "https://cache.builder.e10.camp"; + group = "Builder"; + conditions = [ "[STATUS] == 404" ]; + }) + (mkEndpoint { + name = "Prometheus Node Exporter"; + url = "http://builder:9100"; + group = "Builder"; + }) + ]; + controller = [ + (mkEndpoint { + name = "Blocky (DNS)"; + url = "tcp://controller:53"; + group = "Controller"; + interval = "30s"; + conditions = [ "[CONNECTED] == true" ]; + }) + (mkEndpoint { + name = "Blocky (API)"; + url = "http://controller:4022/api/blocking/status"; + group = "Controller"; + interval = "30s"; + conditions = [ + "[STATUS] == 200" + "[BODY].enabled == true" + ]; + }) + (mkEndpoint { + name = "Home Assistant"; + url = "https://hass.e10.camp"; + group = "Controller"; + }) + (mkEndpoint { + name = "UniFi Controller"; + url = "https://controller:11443"; + group = "Controller"; + extraConfig.client.insecure = true; + }) + (mkEndpoint { + name = "Speedtest Tracker"; + url = "https://speedtest-tracker.e10.camp"; + group = "Controller"; + }) + (mkEndpoint { + name = "Prometheus Node Exporter"; + url = "http://controller:9100"; + group = "Controller"; + }) + (mkEndpoint { + name = "Prometheus NUT Exporter"; + url = "http://controller:9199"; + group = "Controller"; + }) + (mkEndpoint { + name = "Prometheus Smokeping Exporter"; + url = "http://controller:9199"; + group = "Controller"; + }) + (mkEndpoint { + name = "Prometheus Unpoller Exporter"; + url = "http://controller:9130"; + group = "Controller"; + }) + (mkEndpoint { + name = "Termix"; + url = "http://termix.e10.camp"; + group = "Controller"; + }) + ]; + monitor = [ + (mkEndpoint { + name = "Authelia"; + url = "https://auth.monitor.e10.camp"; + group = "Monitor"; + }) + (mkEndpoint { + name = "Caddy"; + url = "http://monitor:2019/config"; + group = "Monitor"; + }) + (mkEndpoint { + name = "Grafana"; + url = "https://grafana.e10.camp"; + group = "Monitor"; + }) + (mkEndpoint { + name = "Loki"; + url = "tcp://monitor:3100"; + group = "Monitor"; + conditions = [ "[CONNECTED] == true" ]; + }) + (mkEndpoint { + name = "Prometheus"; + url = "tcp://monitor:9090"; + group = "Monitor"; + conditions = [ "[CONNECTED] == true" ]; + }) + (mkEndpoint { + name = "rsyslogd"; + url = "tcp://monitor:514"; + group = "Monitor"; + conditions = [ "[CONNECTED] == true" ]; + }) + (mkEndpoint { + name = "Prometheus Node Exporter"; + url = "http://monitor:9100"; + group = "Monitor"; + }) + ]; + pikvm = [ + (mkEndpoint { + name = "PiKVM"; + url = "https://pikvm"; + group = "PiKVM"; + extraConfig.client.insecure = true; + }) + ]; + elderflower-kvm = [ + (mkEndpoint { + name = "JetKVM"; + url = "http://elderflower-kvm"; + group = "Elderflower (KVM)"; + extraConfig.client.insecure = true; + }) + ]; + in + bastion + ++ omnibus + ++ htpc + ++ matrix + ++ builder + ++ controller + ++ monitor + ++ pikvm + ++ elderflower-kvm; }; }; } diff --git a/modules/profiles/observability/gatus/postgresql.nix b/modules/profiles/observability/gatus/postgresql.nix index c65d333..4f4bab8 100644 --- a/modules/profiles/observability/gatus/postgresql.nix +++ b/modules/profiles/observability/gatus/postgresql.nix @@ -3,10 +3,12 @@ services.postgresql = { ensureDatabases = [ "gatus" ]; - ensureUsers = [{ - name = "gatus"; - ensureDBOwnership = true; - }]; + ensureUsers = [ + { + name = "gatus"; + ensureDBOwnership = true; + } + ]; }; services.postgresqlBackup.databases = [ "gatus" ]; diff --git a/modules/profiles/power/common.nix b/modules/profiles/power/common.nix index 14b5ed4..d3e923b 100644 --- a/modules/profiles/power/common.nix +++ b/modules/profiles/power/common.nix @@ -13,17 +13,22 @@ mode = "netserver"; upsd = { - listen = [{ - address = "0.0.0.0"; - port = 3493; - }]; + listen = [ + { + address = "0.0.0.0"; + port = 3493; + } + ]; }; users = { leader = { upsmon = "primary"; passwordFile = config.sops.secrets.upsmon_password.path; - actions = [ "SET" "FSD" ]; + actions = [ + "SET" + "FSD" + ]; instcmds = [ "ALL" ]; }; diff --git a/modules/profiles/security/authelia/default.nix b/modules/profiles/security/authelia/default.nix index fa1a46a..c8a056a 100644 --- a/modules/profiles/security/authelia/default.nix +++ b/modules/profiles/security/authelia/default.nix @@ -1,16 +1,20 @@ { config, lib, ... }: { - imports = [ ./postgresql.nix ./redis.nix ]; + imports = [ + ./postgresql.nix + ./redis.nix + ]; - sops.secrets = let - secretConfig = { - sopsFile = ./secrets.json; - owner = - config.services.authelia.instances.${config.networking.hostName}.user; + sops.secrets = + let + secretConfig = { + sopsFile = ./secrets.json; + owner = config.services.authelia.instances.${config.networking.hostName}.user; + }; + in + { + authelia_smtp2go_username = secretConfig; + authelia_smtp2go_password = secretConfig; }; - in { - authelia_smtp2go_username = secretConfig; - authelia_smtp2go_password = secretConfig; - }; environment.systemPackages = [ config.services.authelia.instances.${config.networking.hostName}.package @@ -28,7 +32,10 @@ authn_strategies = [ { name = "HeaderAuthorization"; - schemes = [ "Basic" "Bearer" ]; + schemes = [ + "Basic" + "Bearer" + ]; } { name = "CookieSession"; } ]; @@ -48,11 +55,17 @@ access_control = { default_policy = "bypass"; - networks = [{ - name = "internal"; - networks = - [ "10.0.0.0/8" "172.16.0.0/12" "192.168.0.0/18" "100.0.0.0/8" ]; - }]; + networks = [ + { + name = "internal"; + networks = [ + "10.0.0.0/8" + "172.16.0.0/12" + "192.168.0.0/18" + "100.0.0.0/8" + ]; + } + ]; }; storage.postgres = { @@ -66,8 +79,7 @@ session = { redis = { host = "0.0.0.0"; - port = toString - config.services.redis.servers."authelia-${config.networking.hostName}".port; + port = toString config.services.redis.servers."authelia-${config.networking.hostName}".port; }; }; @@ -87,20 +99,21 @@ }; environmentVariables = { - AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = - config.sops.secrets.authelia_smtp2go_password.path; + AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = config.sops.secrets.authelia_smtp2go_password.path; }; }; - systemd.services."authelia-${config.networking.hostName}" = let - deps = [ - "postgresql.service" - "redis-authelia-${config.networking.hostName}.service" - ]; - in { - requires = deps; - after = deps; - }; + systemd.services."authelia-${config.networking.hostName}" = + let + deps = [ + "postgresql.service" + "redis-authelia-${config.networking.hostName}.service" + ]; + in + { + requires = deps; + after = deps; + }; networking.firewall.allowedTCPPorts = [ 9959 ]; } diff --git a/modules/profiles/security/authelia/postgresql.nix b/modules/profiles/security/authelia/postgresql.nix index ac40404..a075905 100644 --- a/modules/profiles/security/authelia/postgresql.nix +++ b/modules/profiles/security/authelia/postgresql.nix @@ -1,9 +1,17 @@ -{ profiles, lib, config, ... }: { +{ + profiles, + lib, + config, + ... +}: +{ imports = [ profiles.databases.postgresql ]; services.postgresql = - let instances = lib.attrNames config.services.authelia.instances; - in { + let + instances = lib.attrNames config.services.authelia.instances; + in + { ensureDatabases = map (name: "authelia-${name}") instances; ensureUsers = map (name: _: { name = "authelia-${name}"; diff --git a/modules/profiles/security/authelia/redis.nix b/modules/profiles/security/authelia/redis.nix index 4f30e81..6ed8239 100644 --- a/modules/profiles/security/authelia/redis.nix +++ b/modules/profiles/security/authelia/redis.nix @@ -1,12 +1,14 @@ { config, lib, ... }: { - services.redis.servers = lib.listToAttrs (lib.imap0 (index: name: { - name = "authelia-${name}"; - value = { - enable = true; - openFirewall = true; - bind = "0.0.0.0"; - port = 6380 + index; - settings.protected-mode = false; - }; - }) (lib.attrNames config.services.authelia.instances)); + services.redis.servers = lib.listToAttrs ( + lib.imap0 (index: name: { + name = "authelia-${name}"; + value = { + enable = true; + openFirewall = true; + bind = "0.0.0.0"; + port = 6380 + index; + settings.protected-mode = false; + }; + }) (lib.attrNames config.services.authelia.instances) + ); } diff --git a/modules/profiles/security/lldap/default.nix b/modules/profiles/security/lldap/default.nix index c11b40c..370f7b8 100644 --- a/modules/profiles/security/lldap/default.nix +++ b/modules/profiles/security/lldap/default.nix @@ -50,5 +50,7 @@ ]; }; - users.groups.ldap = { gid = 979; }; + users.groups.ldap = { + gid = 979; + }; } diff --git a/modules/profiles/security/lldap/postgresql.nix b/modules/profiles/security/lldap/postgresql.nix index e46802e..0178cde 100644 --- a/modules/profiles/security/lldap/postgresql.nix +++ b/modules/profiles/security/lldap/postgresql.nix @@ -3,9 +3,11 @@ services.postgresql = { ensureDatabases = [ "lldap" ]; - ensureUsers = [{ - name = "lldap"; - ensureDBOwnership = true; - }]; + ensureUsers = [ + { + name = "lldap"; + ensureDBOwnership = true; + } + ]; }; } diff --git a/modules/profiles/services/atticd/default.nix b/modules/profiles/services/atticd/default.nix index cb2fe66..5870aaa 100644 --- a/modules/profiles/services/atticd/default.nix +++ b/modules/profiles/services/atticd/default.nix @@ -1,6 +1,8 @@ { config, ... }: -let storagePath = "/data/files/services/atticd/storage"; -in { +let + storagePath = "/data/files/services/atticd/storage"; +in +{ imports = [ ./postgresql.nix ]; sops.secrets = { diff --git a/modules/profiles/services/bentopdf.nix b/modules/profiles/services/bentopdf.nix index 764ff8d..5ea5957 100644 --- a/modules/profiles/services/bentopdf.nix +++ b/modules/profiles/services/bentopdf.nix @@ -6,10 +6,12 @@ nginx = { enable = true; virtualHost = { - listen = [{ - addr = "0.0.0.0"; - port = 4152; - }]; + listen = [ + { + addr = "0.0.0.0"; + port = 4152; + } + ]; }; }; }; diff --git a/modules/profiles/services/cachix-watch-store/default.nix b/modules/profiles/services/cachix-watch-store/default.nix index 92c5c4d..01eec03 100644 --- a/modules/profiles/services/cachix-watch-store/default.nix +++ b/modules/profiles/services/cachix-watch-store/default.nix @@ -1,5 +1,7 @@ { config, ... }: { - sops.secrets.cachix_auth_token = { sopsFile = ./secrets.json; }; + sops.secrets.cachix_auth_token = { + sopsFile = ./secrets.json; + }; services.cachix-watch-store = { enable = true; diff --git a/modules/profiles/services/glance/default.nix b/modules/profiles/services/glance/default.nix index eb029d4..1f44726 100644 --- a/modules/profiles/services/glance/default.nix +++ b/modules/profiles/services/glance/default.nix @@ -1,8 +1,12 @@ { config, lib, ... }: { sops = { secrets = { - glance_authelia_basic_auth_username = { sopsFile = ./secrets.json; }; - glance_authelia_basic_auth_password = { sopsFile = ./secrets.json; }; + glance_authelia_basic_auth_username = { + sopsFile = ./secrets.json; + }; + glance_authelia_basic_auth_password = { + sopsFile = ./secrets.json; + }; }; templates."glance/environment_file" = { @@ -22,227 +26,242 @@ host = "0.0.0.0"; port = 5588; }; - pages = [{ - name = "Home"; - columns = [ - { - size = "full"; - widgets = [ - { - type = "monitor"; - cache = "1m"; - title = "Services"; - sites = let - mkSite = - { title, url, check-url ? null, icon, basicAuth ? false }: { - inherit title url check-url icon; - basic-auth = lib.mkIf basicAuth { - username = "\${AUTHELIA_BASIC_AUTH_USERNAME}"; - password = "\${AUTHELIA_BASIC_AUTH_PASSWORD}"; - }; - }; - in [ - (mkSite { - title = "Authelia"; - url = "https://auth.e10.camp"; - icon = "di:authelia"; - }) - (mkSite { - title = "Authelia (Monitor)"; - url = "https://auth.monitor.e10.camp"; - icon = "di:authelia"; - }) - (mkSite { - title = "Bazarr"; - url = "https://bazarr.e10.camp"; - icon = "di:bazarr"; - }) - (mkSite { - title = "BentoPDF"; - url = "https://pdf.e10.camp"; - icon = "di:bentopdf"; - basicAuth = true; - }) - (mkSite { - title = "Bichon"; - url = "https://bichon.e10.camp"; - icon = "sh:bichon"; - }) - (mkSite { - title = "Change Detection"; - url = "https://change-detection.e10.camp"; - icon = "di:changedetection"; - basicAuth = true; - }) - (mkSite { - title = "e10.land"; - url = "https://e10.land"; - icon = "https://e10.land/favicon.ico"; - }) - (mkSite { - title = "Fileflows"; - url = "https://fileflows.e10.camp"; - icon = "di:fileflows"; - basicAuth = true; - }) - (mkSite { - title = "Frigate"; - url = "https://frigate.e10.camp"; - icon = "di:frigate"; - }) - (mkSite { - title = "Gatus"; - url = "https://status.e10.camp"; - icon = "di:gatus"; - }) - (mkSite { - title = "Grafana"; - url = "https://grafana.e10.camp"; - icon = "di:grafana"; - }) - (mkSite { - title = "Home Assistant"; - url = "https://hass.e10.camp"; - icon = "di:home-assistant"; - }) - (mkSite { - title = "Immich"; - url = "https://immich.e10.camp"; - icon = "di:immich"; - }) - (mkSite { - title = "Seerr"; - url = "https://requests.e10.video"; - icon = "di:jellyseerr"; - }) - (mkSite { - title = "Karakeep"; - url = "https://karakeep.e10.camp"; - icon = "di:karakeep"; - }) - (mkSite { - title = "LLDAP"; - url = "https://ldap.e10.camp"; - icon = "di:lldap"; - }) - (mkSite { - title = "Mazanoke"; - url = "https://mazanoke.e10.camp"; - icon = - "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/mazanoke.png"; - basicAuth = true; - }) - (mkSite { - title = "Miniflux"; - url = "https://feeds.e10.camp"; - icon = "di:miniflux"; - }) - (mkSite { - title = "Netbox"; - url = "https://netbox.e10.camp"; - icon = "di:netbox"; - }) - (mkSite { - title = "Paperless"; - url = "https://paperless.e10.camp"; - icon = "di:paperless"; - }) - (mkSite { - title = "Plex"; - url = "https://e10.video"; - check-url = "https://e10.video/identity"; - icon = "di:plex"; - }) - (mkSite { - title = "Profilarr"; - url = "https://profilarr.e10.camp"; - icon = "di:profilarr"; - }) - (mkSite { - title = "Prowlarr"; - url = "https://prowlarr.e10.camp"; - icon = "di:prowlarr"; - }) - (mkSite { - title = "Radarr"; - url = "https://radarr.e10.camp"; - icon = "di:radarr"; - }) - (mkSite { - title = "SABnzbd"; - url = "https://sabnzbd.e10.camp"; - icon = "di:sabnzbd"; - }) - (mkSite { - title = "Sonarr"; - url = "https://sonarr.e10.camp"; - icon = "di:sonarr"; - }) - (mkSite { - title = "Tautulli"; - url = "https://tautulli.e10.camp"; - icon = "di:tautulli"; - }) - (mkSite { - title = "Termix"; - url = "https://termix.e10.camp"; - icon = "di:termix"; - }) - (mkSite { - title = "Tracearr"; - url = "https://tracearr.e10.camp"; - icon = "di:tracearr"; - }) - (mkSite { - title = "UniFi"; - url = "https://unifi.satan.network"; - icon = "di:unifi"; - }) - (mkSite { - title = "Wizarr"; - url = "https://join.e10.video"; - icon = "di:wizarr"; - }) - ]; - } - { type = "lobsters"; } - ]; - } - { - size = "small"; - widgets = [ - { - type = "clock"; - hour-format = "24h"; - timezones = [ - { - timezone = "UTC"; - label = "UTC"; - } - { - timezone = "Europe/London"; - label = "London"; - } - { - timezone = "America/Los_Angeles"; - label = "Los Angeles"; - } - { - timezone = "America/Phoenix"; - label = "Phoenix"; - } - ]; - } - { - type = "weather"; - units = "imperial"; - hour-format = "24h"; - location = "Brooklyn, New York, United States"; - } - ]; - } - ]; - }]; + pages = [ + { + name = "Home"; + columns = [ + { + size = "full"; + widgets = [ + { + type = "monitor"; + cache = "1m"; + title = "Services"; + sites = + let + mkSite = + { + title, + url, + check-url ? null, + icon, + basicAuth ? false, + }: + { + inherit + title + url + check-url + icon + ; + basic-auth = lib.mkIf basicAuth { + username = "\${AUTHELIA_BASIC_AUTH_USERNAME}"; + password = "\${AUTHELIA_BASIC_AUTH_PASSWORD}"; + }; + }; + in + [ + (mkSite { + title = "Authelia"; + url = "https://auth.e10.camp"; + icon = "di:authelia"; + }) + (mkSite { + title = "Authelia (Monitor)"; + url = "https://auth.monitor.e10.camp"; + icon = "di:authelia"; + }) + (mkSite { + title = "Bazarr"; + url = "https://bazarr.e10.camp"; + icon = "di:bazarr"; + }) + (mkSite { + title = "BentoPDF"; + url = "https://pdf.e10.camp"; + icon = "di:bentopdf"; + basicAuth = true; + }) + (mkSite { + title = "Bichon"; + url = "https://bichon.e10.camp"; + icon = "sh:bichon"; + }) + (mkSite { + title = "Change Detection"; + url = "https://change-detection.e10.camp"; + icon = "di:changedetection"; + basicAuth = true; + }) + (mkSite { + title = "e10.land"; + url = "https://e10.land"; + icon = "https://e10.land/favicon.ico"; + }) + (mkSite { + title = "Fileflows"; + url = "https://fileflows.e10.camp"; + icon = "di:fileflows"; + basicAuth = true; + }) + (mkSite { + title = "Frigate"; + url = "https://frigate.e10.camp"; + icon = "di:frigate"; + }) + (mkSite { + title = "Gatus"; + url = "https://status.e10.camp"; + icon = "di:gatus"; + }) + (mkSite { + title = "Grafana"; + url = "https://grafana.e10.camp"; + icon = "di:grafana"; + }) + (mkSite { + title = "Home Assistant"; + url = "https://hass.e10.camp"; + icon = "di:home-assistant"; + }) + (mkSite { + title = "Immich"; + url = "https://immich.e10.camp"; + icon = "di:immich"; + }) + (mkSite { + title = "Seerr"; + url = "https://requests.e10.video"; + icon = "di:jellyseerr"; + }) + (mkSite { + title = "Karakeep"; + url = "https://karakeep.e10.camp"; + icon = "di:karakeep"; + }) + (mkSite { + title = "LLDAP"; + url = "https://ldap.e10.camp"; + icon = "di:lldap"; + }) + (mkSite { + title = "Mazanoke"; + url = "https://mazanoke.e10.camp"; + icon = "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/mazanoke.png"; + basicAuth = true; + }) + (mkSite { + title = "Miniflux"; + url = "https://feeds.e10.camp"; + icon = "di:miniflux"; + }) + (mkSite { + title = "Netbox"; + url = "https://netbox.e10.camp"; + icon = "di:netbox"; + }) + (mkSite { + title = "Paperless"; + url = "https://paperless.e10.camp"; + icon = "di:paperless"; + }) + (mkSite { + title = "Plex"; + url = "https://e10.video"; + check-url = "https://e10.video/identity"; + icon = "di:plex"; + }) + (mkSite { + title = "Profilarr"; + url = "https://profilarr.e10.camp"; + icon = "di:profilarr"; + }) + (mkSite { + title = "Prowlarr"; + url = "https://prowlarr.e10.camp"; + icon = "di:prowlarr"; + }) + (mkSite { + title = "Radarr"; + url = "https://radarr.e10.camp"; + icon = "di:radarr"; + }) + (mkSite { + title = "SABnzbd"; + url = "https://sabnzbd.e10.camp"; + icon = "di:sabnzbd"; + }) + (mkSite { + title = "Sonarr"; + url = "https://sonarr.e10.camp"; + icon = "di:sonarr"; + }) + (mkSite { + title = "Tautulli"; + url = "https://tautulli.e10.camp"; + icon = "di:tautulli"; + }) + (mkSite { + title = "Termix"; + url = "https://termix.e10.camp"; + icon = "di:termix"; + }) + (mkSite { + title = "Tracearr"; + url = "https://tracearr.e10.camp"; + icon = "di:tracearr"; + }) + (mkSite { + title = "UniFi"; + url = "https://unifi.satan.network"; + icon = "di:unifi"; + }) + (mkSite { + title = "Wizarr"; + url = "https://join.e10.video"; + icon = "di:wizarr"; + }) + ]; + } + { type = "lobsters"; } + ]; + } + { + size = "small"; + widgets = [ + { + type = "clock"; + hour-format = "24h"; + timezones = [ + { + timezone = "UTC"; + label = "UTC"; + } + { + timezone = "Europe/London"; + label = "London"; + } + { + timezone = "America/Los_Angeles"; + label = "Los Angeles"; + } + { + timezone = "America/Phoenix"; + label = "Phoenix"; + } + ]; + } + { + type = "weather"; + units = "imperial"; + hour-format = "24h"; + location = "Brooklyn, New York, United States"; + } + ]; + } + ]; + } + ]; }; openFirewall = true; }; diff --git a/modules/profiles/services/karakeep/default.nix b/modules/profiles/services/karakeep/default.nix index 46206cb..4497718 100644 --- a/modules/profiles/services/karakeep/default.nix +++ b/modules/profiles/services/karakeep/default.nix @@ -37,10 +37,8 @@ NEXTAUTH_URL = "https://karakeep.e10.camp"; - OAUTH_WELLKNOWN_URL = - "https://auth.e10.camp/.well-known/openid-configuration"; - OAUTH_CLIENT_ID = - "4_PUhlKbm03-XaIAR-tBOzaCkf6dQfhgBY-xnrewL5jsOCp0UXPsbSvnaxgLXEp6kKsqjqND"; + OAUTH_WELLKNOWN_URL = "https://auth.e10.camp/.well-known/openid-configuration"; + OAUTH_CLIENT_ID = "4_PUhlKbm03-XaIAR-tBOzaCkf6dQfhgBY-xnrewL5jsOCp0UXPsbSvnaxgLXEp6kKsqjqND"; OAUTH_PROVIDER_NAME = "Authelia"; OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING = "true"; }; diff --git a/modules/profiles/services/miniflux/default.nix b/modules/profiles/services/miniflux/default.nix index bd01a8c..cbbd676 100644 --- a/modules/profiles/services/miniflux/default.nix +++ b/modules/profiles/services/miniflux/default.nix @@ -8,11 +8,15 @@ services.miniflux = { enable = true; - config = { PORT = "8070"; }; + config = { + PORT = "8070"; + }; adminCredentialsFile = config.sops.secrets.miniflux_admin_credentials.path; }; services.postgresqlBackup.databases = [ "miniflux" ]; - networking.firewall = { allowedTCPPorts = [ 8070 ]; }; + networking.firewall = { + allowedTCPPorts = [ 8070 ]; + }; } diff --git a/modules/profiles/services/netbox/default.nix b/modules/profiles/services/netbox/default.nix index e8aab0f..c6a7a9d 100644 --- a/modules/profiles/services/netbox/default.nix +++ b/modules/profiles/services/netbox/default.nix @@ -25,17 +25,13 @@ settings = { CSRF_TRUSTED_ORIGINS = [ "https://netbox.e10.camp" - "http://${config.networking.hostName}:${ - toString config.services.netbox.port - }" + "http://${config.networking.hostName}:${toString config.services.netbox.port}" "http://${config.networking.hostName}:8002" ]; REMOTE_AUTH_ENABLED = true; - REMOTE_AUTH_BACKEND = - "social_core.backends.open_id_connect.OpenIdConnectAuth"; + REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth"; SOCIAL_AUTH_OIDC_OIDC_ENDPOINT = "https://auth.e10.camp"; - SOCIAL_AUTH_OIDC_KEY = - "gY0aO8QGJT.~UbRntqa72YTm54DSUHr3HeBu4zMBlWwMwlJwLtbhXflUCAczeC-snr9I_5tZ"; + SOCIAL_AUTH_OIDC_KEY = "gY0aO8QGJT.~UbRntqa72YTm54DSUHr3HeBu4zMBlWwMwlJwLtbhXflUCAczeC-snr9I_5tZ"; }; extraConfig = '' import os @@ -59,9 +55,7 @@ not path /static/* } - reverse_proxy @proxied http://localhost:${ - toString config.services.netbox.port - } + reverse_proxy @proxied http://localhost:${toString config.services.netbox.port} file_server ''; @@ -72,5 +66,8 @@ services.postgresqlBackup.databases = [ "netbox" ]; - networking.firewall.allowedTCPPorts = [ config.services.netbox.port 8002 ]; + networking.firewall.allowedTCPPorts = [ + config.services.netbox.port + 8002 + ]; } diff --git a/modules/profiles/services/paperless/default.nix b/modules/profiles/services/paperless/default.nix index a05faa2..76003c9 100644 --- a/modules/profiles/services/paperless/default.nix +++ b/modules/profiles/services/paperless/default.nix @@ -1,5 +1,8 @@ { config, ... }: { - imports = [ ./postgresql.nix ./redis.nix ]; + imports = [ + ./postgresql.nix + ./redis.nix + ]; sops = { secrets = { diff --git a/modules/profiles/services/paperless/postgresql.nix b/modules/profiles/services/paperless/postgresql.nix index 0817ffc..e198b12 100644 --- a/modules/profiles/services/paperless/postgresql.nix +++ b/modules/profiles/services/paperless/postgresql.nix @@ -3,10 +3,12 @@ services.postgresql = { ensureDatabases = [ "paperless" ]; - ensureUsers = [{ - name = config.services.paperless.user; - ensureDBOwnership = true; - }]; + ensureUsers = [ + { + name = config.services.paperless.user; + ensureDBOwnership = true; + } + ]; }; services.paperless.settings = { @@ -16,15 +18,17 @@ PAPERLESS_DBUSER = "paperless"; }; - systemd.services = let - additionalServiceConfig = { - requires = [ "postgresql.service" ]; - after = [ "postgresql.service" ]; + systemd.services = + let + additionalServiceConfig = { + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + }; + in + { + paperless-scheduler = additionalServiceConfig; + paperless-task = additionalServiceConfig; + paperless-consumer = additionalServiceConfig; + paperless-web = additionalServiceConfig; }; - in { - paperless-scheduler = additionalServiceConfig; - paperless-task = additionalServiceConfig; - paperless-consumer = additionalServiceConfig; - paperless-web = additionalServiceConfig; - }; } diff --git a/modules/profiles/services/paperless/redis.nix b/modules/profiles/services/paperless/redis.nix index 115437e..040fbe4 100644 --- a/modules/profiles/services/paperless/redis.nix +++ b/modules/profiles/services/paperless/redis.nix @@ -1,19 +1,19 @@ { config, ... }: { services.redis.servers.paperless.enable = true; - services.paperless.settings.PAPERLESS_REDIS = - "unix://${config.services.redis.servers.paperless.unixSocket}"; + services.paperless.settings.PAPERLESS_REDIS = "unix://${config.services.redis.servers.paperless.unixSocket}"; - systemd.services = let - additionalServiceConfig = { - serviceConfig.SupplementaryGroups = - config.services.redis.servers.paperless.user; - after = [ "redis-paperless.service" ]; + systemd.services = + let + additionalServiceConfig = { + serviceConfig.SupplementaryGroups = config.services.redis.servers.paperless.user; + after = [ "redis-paperless.service" ]; + }; + in + { + paperless-scheduler = additionalServiceConfig; + paperless-task-queue = additionalServiceConfig; + paperless-consumer = additionalServiceConfig; + paperless-web = additionalServiceConfig; }; - in { - paperless-scheduler = additionalServiceConfig; - paperless-task-queue = additionalServiceConfig; - paperless-consumer = additionalServiceConfig; - paperless-web = additionalServiceConfig; - }; } diff --git a/modules/profiles/sharing/nfs-server.nix b/modules/profiles/sharing/nfs-server.nix index 825c01c..5c4c557 100644 --- a/modules/profiles/sharing/nfs-server.nix +++ b/modules/profiles/sharing/nfs-server.nix @@ -9,17 +9,19 @@ }; }; - networking.firewall = let - ports = [ - 204 - 111 - 20048 - config.services.nfs.server.statdPort - config.services.nfs.server.lockdPort - 2049 - ]; - in { - allowedUDPPorts = ports; - allowedTCPPorts = ports; - }; + networking.firewall = + let + ports = [ + 204 + 111 + 20048 + config.services.nfs.server.statdPort + config.services.nfs.server.lockdPort + 2049 + ]; + in + { + allowedUDPPorts = ports; + allowedTCPPorts = ports; + }; } diff --git a/modules/profiles/sharing/samba.nix b/modules/profiles/sharing/samba.nix index 8668365..3dcf8fa 100644 --- a/modules/profiles/sharing/samba.nix +++ b/modules/profiles/sharing/samba.nix @@ -43,8 +43,17 @@ }; networking.firewall = { - allowedTCPPorts = [ 445 139 5357 ]; - allowedUDPPorts = [ 137 138 3702 5353 ]; + allowedTCPPorts = [ + 445 + 139 + 5357 + ]; + allowedUDPPorts = [ + 137 + 138 + 3702 + 5353 + ]; }; environment.systemPackages = with pkgs; [ cifs-utils ]; diff --git a/modules/profiles/telemetry/prometheus-plex-exporter/default.nix b/modules/profiles/telemetry/prometheus-plex-exporter/default.nix index 7d460e8..0209578 100644 --- a/modules/profiles/telemetry/prometheus-plex-exporter/default.nix +++ b/modules/profiles/telemetry/prometheus-plex-exporter/default.nix @@ -1,4 +1,10 @@ -{ inputs, config, pkgs, ... }: { +{ + inputs, + config, + pkgs, + ... +}: +{ sops.secrets.plex_token = { sopsFile = ./secrets.json; mode = "0777"; @@ -6,8 +12,7 @@ services.plex-exporter = { enable = true; - package = - inputs.plex-exporter.packages.${pkgs.stdenv.hostPlatform.system}.default; + package = inputs.plex-exporter.packages.${pkgs.stdenv.hostPlatform.system}.default; url = "https://e10.video"; tokenFile = config.sops.secrets.plex_token.path; openFirewall = true; diff --git a/modules/profiles/telemetry/prometheus-unpoller-exporter/common.nix b/modules/profiles/telemetry/prometheus-unpoller-exporter/common.nix index b7952fa..8893460 100644 --- a/modules/profiles/telemetry/prometheus-unpoller-exporter/common.nix +++ b/modules/profiles/telemetry/prometheus-unpoller-exporter/common.nix @@ -12,10 +12,7 @@ enable = true; loki = { - url = "http://${hosts.monitor.config.networking.hostName}:${ - toString - hosts.monitor.config.services.loki.configuration.server.http_listen_port - }"; + url = "http://${hosts.monitor.config.networking.hostName}:${toString hosts.monitor.config.services.loki.configuration.server.http_listen_port}"; }; }; } diff --git a/modules/profiles/telemetry/prometheus-unpoller-exporter/satan.nix b/modules/profiles/telemetry/prometheus-unpoller-exporter/satan.nix index 0f813f4..54a7058 100644 --- a/modules/profiles/telemetry/prometheus-unpoller-exporter/satan.nix +++ b/modules/profiles/telemetry/prometheus-unpoller-exporter/satan.nix @@ -1,14 +1,16 @@ { config, hosts, ... }: { imports = [ ./common.nix ]; - services.prometheus.exporters.unpoller.controllers = [{ - url = "https://${hosts.controller.config.networking.hostName}:8443"; - user = "ethnt-unpoller"; - pass = config.sops.secrets.satan_unifi_password.path; - verify_ssl = false; - save_ids = true; - save_events = true; - save_anomalies = true; - save_alarms = true; - }]; + services.prometheus.exporters.unpoller.controllers = [ + { + url = "https://${hosts.controller.config.networking.hostName}:8443"; + user = "ethnt-unpoller"; + pass = config.sops.secrets.satan_unifi_password.path; + verify_ssl = false; + save_ids = true; + save_events = true; + save_anomalies = true; + save_alarms = true; + } + ]; } diff --git a/modules/profiles/telemetry/vector/common.nix b/modules/profiles/telemetry/vector/common.nix index 9a9247b..87da8b1 100644 --- a/modules/profiles/telemetry/vector/common.nix +++ b/modules/profiles/telemetry/vector/common.nix @@ -8,10 +8,7 @@ sinks.loki = { type = "loki"; inputs = [ ]; - endpoint = "http://${hosts.monitor.config.networking.hostName}:${ - toString - hosts.monitor.config.services.loki.configuration.server.http_listen_port - }"; + endpoint = "http://${hosts.monitor.config.networking.hostName}:${toString hosts.monitor.config.services.loki.configuration.server.http_listen_port}"; encoding = { codec = "json"; except_fields = [ "labels" ]; diff --git a/modules/profiles/users/ethan.nix b/modules/profiles/users/ethan.nix index 62cd494..758b7f6 100644 --- a/modules/profiles/users/ethan.nix +++ b/modules/profiles/users/ethan.nix @@ -1,7 +1,6 @@ { pkgs, ... }: { users.users.ethan = { - hashedPassword = - "$6$uWdBBHFmu2RqXQYG$if2AOX1aSpykA4uzSB//vr0GHt.Kw00tJOHazAnZUEU5LNcIOF6UyMPDSfH97Fis4DJF6kBmUMmqqxXmMn9hp."; + hashedPassword = "$6$uWdBBHFmu2RqXQYG$if2AOX1aSpykA4uzSB//vr0GHt.Kw00tJOHazAnZUEU5LNcIOF6UyMPDSfH97Fis4DJF6kBmUMmqqxXmMn9hp."; openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDjP4zPNw1dHe8a8KTOp/fxaLw9LxkX13dXPMnqHHmJzfpkHSYnrslwPME1ej/K6dxa11xfW8uBfQnWAXyCcJXdbsyBrpxmvKt+a7+wMolUIBWueVAenfc9EeEXkhr5sHNTjE6WMzhkCm7vVWj0QARAmKuT0ugQ6fWoFbP7kb/0+VEXJq82GAEjdut697VM6YSf+2rIFTpRyiGEImAi8Lt9Qyqm3cze1lQu0mdrIyyKDIJV/D+pJqZQL73nqI7OhWgPKiF4exZj7kas3sykr62Fmlr7RgfDSFrJQhBIiy1EK3dsO1ehFhtwpqtjyPMhKPOgii1q2JMvL5eHnw/x7oX1" ]; diff --git a/modules/profiles/users/nicole.nix b/modules/profiles/users/nicole.nix index 7ff3b92..3f278a6 100644 --- a/modules/profiles/users/nicole.nix +++ b/modules/profiles/users/nicole.nix @@ -1,7 +1,6 @@ { pkgs, lib, ... }: { users.users.nicole = { - hashedPassword = - "$y$j9T$6mx45DR3tlbVi8S6mtON3/$LxCAD21muEs91l2SD3mizEyOwkA6/PAn6cUuvAsmLMC"; + hashedPassword = "$y$j9T$6mx45DR3tlbVi8S6mtON3/$LxCAD21muEs91l2SD3mizEyOwkA6/PAn6cUuvAsmLMC"; isNormalUser = true; shell = lib.getExe' pkgs.shadow "nologin"; }; diff --git a/modules/profiles/users/proxmox.nix b/modules/profiles/users/proxmox.nix index 1ed71f4..889eee5 100644 --- a/modules/profiles/users/proxmox.nix +++ b/modules/profiles/users/proxmox.nix @@ -8,8 +8,7 @@ name = "proxmox"; uid = 1002; group = config.users.groups.proxmox.name; - hashedPassword = - "$6$uWdBBHFmu2RqXQYG$if2AOX1aSpykA4uzSB//vr0GHt.Kw00tJOHazAnZUEU5LNcIOF6UyMPDSfH97Fis4DJF6kBmUMmqqxXmMn9hp."; + hashedPassword = "$6$uWdBBHFmu2RqXQYG$if2AOX1aSpykA4uzSB//vr0GHt.Kw00tJOHazAnZUEU5LNcIOF6UyMPDSfH97Fis4DJF6kBmUMmqqxXmMn9hp."; isNormalUser = true; }; } diff --git a/modules/profiles/users/root.nix b/modules/profiles/users/root.nix index b20e41c..9cd40e8 100644 --- a/modules/profiles/users/root.nix +++ b/modules/profiles/users/root.nix @@ -1,8 +1,7 @@ { pkgs, ... }: { users.users.root = { initialHashedPassword = null; - hashedPassword = - "$6$uWdBBHFmu2RqXQYG$if2AOX1aSpykA4uzSB//vr0GHt.Kw00tJOHazAnZUEU5LNcIOF6UyMPDSfH97Fis4DJF6kBmUMmqqxXmMn9hp."; + hashedPassword = "$6$uWdBBHFmu2RqXQYG$if2AOX1aSpykA4uzSB//vr0GHt.Kw00tJOHazAnZUEU5LNcIOF6UyMPDSfH97Fis4DJF6kBmUMmqqxXmMn9hp."; openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDjP4zPNw1dHe8a8KTOp/fxaLw9LxkX13dXPMnqHHmJzfpkHSYnrslwPME1ej/K6dxa11xfW8uBfQnWAXyCcJXdbsyBrpxmvKt+a7+wMolUIBWueVAenfc9EeEXkhr5sHNTjE6WMzhkCm7vVWj0QARAmKuT0ugQ6fWoFbP7kb/0+VEXJq82GAEjdut697VM6YSf+2rIFTpRyiGEImAi8Lt9Qyqm3cze1lQu0mdrIyyKDIJV/D+pJqZQL73nqI7OhWgPKiF4exZj7kas3sykr62Fmlr7RgfDSFrJQhBIiy1EK3dsO1ehFhtwpqtjyPMhKPOgii1q2JMvL5eHnw/x7oX1" ]; diff --git a/modules/profiles/virtualisation/docker.nix b/modules/profiles/virtualisation/docker.nix index f79f5fd..ad198b2 100644 --- a/modules/profiles/virtualisation/docker.nix +++ b/modules/profiles/virtualisation/docker.nix @@ -20,14 +20,19 @@ systemd.services.docker-update-containers = { serviceConfig = { Type = "oneshot"; - ExecStart = let docker = lib.getExe pkgs.docker; - in lib.getExe (pkgs.writeShellScriptBin "docker-update-containers" '' - images=$(${docker} ps -a --format="{{.Image}}" | sort -u) + ExecStart = + let + docker = lib.getExe pkgs.docker; + in + lib.getExe ( + pkgs.writeShellScriptBin "docker-update-containers" '' + images=$(${docker} ps -a --format="{{.Image}}" | sort -u) - for image in $images; do - ${docker} pull "$image" - done - ''); + for image in $images; do + ${docker} pull "$image" + done + '' + ); }; }; } diff --git a/modules/profiles/web-servers/caddy.nix b/modules/profiles/web-servers/caddy.nix index 0d62365..6cb20b5 100644 --- a/modules/profiles/web-servers/caddy.nix +++ b/modules/profiles/web-servers/caddy.nix @@ -20,7 +20,14 @@ }; networking.firewall = { - allowedTCPPorts = [ 80 443 2019 ]; - allowedUDPPorts = [ 80 443 ]; + allowedTCPPorts = [ + 80 + 443 + 2019 + ]; + allowedUDPPorts = [ + 80 + 443 + ]; }; } diff --git a/modules/suites.nix b/modules/suites.nix index 27c36d5..eab3774 100644 --- a/modules/suites.nix +++ b/modules/suites.nix @@ -46,7 +46,10 @@ profiles.hardware.ssd ]; - aws = [ profiles.virtualisation.aws profiles.networking.quad9 ]; + aws = [ + profiles.virtualisation.aws + profiles.networking.quad9 + ]; proxmox-vm = [ profiles.virtualisation.qemu From f716142d2d312eca524cb62cdca58946fc2702bf Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Fri, 10 Jul 2026 18:37:31 -0400 Subject: [PATCH 03/10] Add update script for `unifi-os-server-image` --- modules/development/treefmt.nix | 1 + modules/overlays/default.nix | 88 ++++++++++--------- .../unifi-os-server-image/default.nix | 10 ++- .../packages/unifi-os-server-image/update.sh | 61 +++++++++++++ 4 files changed, 115 insertions(+), 45 deletions(-) create mode 100755 modules/packages/unifi-os-server-image/update.sh diff --git a/modules/development/treefmt.nix b/modules/development/treefmt.nix index c8979cb..a26937b 100644 --- a/modules/development/treefmt.nix +++ b/modules/development/treefmt.nix @@ -8,6 +8,7 @@ projectRootFile = "flake.nix"; programs = { actionlint.enable = true; + beautysh.enable = true; deadnix.enable = true; terraform.enable = true; nixfmt.enable = true; diff --git a/modules/overlays/default.nix b/modules/overlays/default.nix index 357cbb4..60f5ad6 100644 --- a/modules/overlays/default.nix +++ b/modules/overlays/default.nix @@ -1,50 +1,56 @@ { inputs, ... }: { imports = [ inputs.flake-parts.flakeModules.easyOverlay ]; - perSystem = { system, self', ... }: { - overlayAttrs = - let - nixpkgs-master = import inputs.nixpkgs-master { - inherit system; + perSystem = + { + system, + self', + ... + }: + { + overlayAttrs = + let + nixpkgs-master = import inputs.nixpkgs-master { + inherit system; - config = { - allowUnfree = true; - permittedInsecurePackages = [ - "dotnet-sdk-6.0.428" - "aspnetcore-runtime-6.0.36" - ]; + config = { + allowUnfree = true; + permittedInsecurePackages = [ + "dotnet-sdk-6.0.428" + "aspnetcore-runtime-6.0.36" + ]; + }; }; - }; - in - { - inherit (nixpkgs-master) - gatus - prowlarr - radarr - sabnzbd - sonarr - netbox - plex - immich - ; + in + { + inherit (nixpkgs-master) + gatus + prowlarr + radarr + sabnzbd + sonarr + netbox + plex + immich + ; - # inherit (nixpkgs-master.python312Packages) pymdown-extensions onnx; + # inherit (nixpkgs-master.python312Packages) pymdown-extensions onnx; - # This is to pick up bugfix here: https://github.com/thanos-io/thanos/issues/7923 - inherit (nixpkgs-master) thanos; + # This is to pick up bugfix here: https://github.com/thanos-io/thanos/issues/7923 + inherit (nixpkgs-master) thanos; - inherit (self'.packages) - bichon - declutarr - fileflows - mazanoke - profilarr - profilarr-parser - prometheus-plex-exporter - tracearr - unifi-os-server-image - incus-apply - ; - }; - }; + inherit (self'.packages) + bichon + declutarr + fileflows + mazanoke + profilarr + profilarr-parser + prometheus-plex-exporter + tracearr + unifi-os-server-image + incus-apply + ; + }; + }; } diff --git a/modules/packages/unifi-os-server-image/default.nix b/modules/packages/unifi-os-server-image/default.nix index 6029f2f..6fddd48 100644 --- a/modules/packages/unifi-os-server-image/default.nix +++ b/modules/packages/unifi-os-server-image/default.nix @@ -1,9 +1,9 @@ { lib, pkgs }: let - imageVersion = "f77bca81ecbf"; - installerVersion = "5.1.15"; - url = "https://fw-download.ubnt.com/data/unifi-os-server/24e0-linux-x64-5.1.15-926621de-c9d7-48cd-8921-a0ff3eebd3f4.15-x64"; - sha256 = "sha256-BMjkAes0Mw/pnZTzWqNR4ODpeJXw2aS0Wf80+1DK0rs="; + imageVersion = "ab51f5e215ae"; + installerVersion = "5.1.21"; + url = "https://fw-download.ubnt.com/data/unifi-os-server/f5e2-linux-x64-5.1.21-a400c9c6-8328-4634-b223-ebfcf742720a.21-x64"; + sha256 = "sha256-d+P+rBWVd5QC3Yf/jSDWb6o5yHtXJkb4b/AAZxEmJEU="; # TODO: Can remove when this fix is merged # https://github.com/nixos/nixpkgs/pull/530407 @@ -36,8 +36,10 @@ pkgs.stdenvNoCC.mkDerivation { work="$PWD/work" mkdir -p "$work" + cp "$src" "$work/unifi-os-installer" chmod u+w "$work/unifi-os-installer" + cd "$work" binwalk --threads 1 -e ./unifi-os-installer >/dev/null diff --git a/modules/packages/unifi-os-server-image/update.sh b/modules/packages/unifi-os-server-image/update.sh new file mode 100755 index 0000000..0101017 --- /dev/null +++ b/modules/packages/unifi-os-server-image/update.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env nix-shell +#! nix-shell -i bash -p curl jq nix binwalk coreutils findutils gnused + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +DEFAULT_NIX="$SCRIPT_DIR/default.nix" + +echo "==> Fetching latest UniFi OS Server x86_64-linux installer..." >&2 + +API_JSON="$(curl -fsSL https://download.svc.ui.com/v1/downloads/products/slugs/unifi-os-server)" + +download_json="$(jq -c '[.downloads[] | select(.name | test("UniFi OS Server .* for Linux \\(x64\\)$"))] | max_by(.date_published) // empty' <<<"$API_JSON")" + +if [ -z "$download_json" ] || [ "$download_json" = "null" ]; then + echo "Could not find x86_64-linux installer in API response" >&2 + exit 1 +fi + +installer_version="$(jq -r '.version' <<<"$download_json")" +url="$(jq -r '.file_url' <<<"$download_json")" + +echo " Version: ${installer_version}" >&2 +echo " URL: ${url}" >&2 +echo "==> Downloading installer and computing hash..." >&2 + +work="$(mktemp -d)" +trap 'rm -rf "$work"' EXIT + +curl -fsSL "$url" -o "$work/installer" + +sha256="sha256-$(nix hash file --type sha256 --base64 "$work/installer")" + +echo " SHA256: ${sha256}" >&2 +echo "==> Extracting image version..." >&2 + +chmod u+w "$work/installer" +(cd "$work" && binwalk --threads 1 -e ./installer >/dev/null) + +image_tar="$(find "$work" -type f -name image.tar | head -n1)" +if [ -z "$image_tar" ]; then + echo "Could not find embedded image.tar in installer" >&2 + exit 1 +fi + +mkdir -p "$work/extracted" +tar -xf "$image_tar" -C "$work/extracted" + +image_version="$(jq -r '.[0].RepoTags[0]' "$work/extracted/manifest.json" | cut -d: -f2)" + +echo " Image version: ${image_version}" >&2 +echo "==> Updating default.nix..." >&2 + +sed -i \ + -e "s|imageVersion = \"[^\"]*\"|imageVersion = \"${image_version}\"|" \ + -e "s|installerVersion = \"[^\"]*\"|installerVersion = \"${installer_version}\"|" \ + -e "s|url = \"[^\"]*\"|url = \"${url}\"|" \ + -e "s|sha256 = \"[^\"]*\"|sha256 = \"${sha256}\"|" \ + "$DEFAULT_NIX" + +echo "Done." >&2 From 620d9d54fd5646f94edeffc4ba3e41c6e323d866 Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Sat, 11 Jul 2026 12:26:43 -0400 Subject: [PATCH 04/10] Update `profilarr`, format packages with `nixpkgs-fmt` --- modules/development/treefmt.nix | 10 +++++- modules/packages/bichon/default.nix | 26 +++++++------- modules/packages/declutarr/default.nix | 10 +++--- modules/packages/fileflows/default.nix | 16 ++++----- modules/packages/profilarr-parser/default.nix | 14 ++++---- modules/packages/profilarr/default.nix | 36 +++++++++---------- modules/packages/tracearr/default.nix | 20 +++++------ 7 files changed, 69 insertions(+), 63 deletions(-) diff --git a/modules/development/treefmt.nix b/modules/development/treefmt.nix index a26937b..3a7bd8d 100644 --- a/modules/development/treefmt.nix +++ b/modules/development/treefmt.nix @@ -2,7 +2,12 @@ imports = [ inputs.treefmt.flakeModule ]; perSystem = - { config, pkgs, ... }: + { + config, + pkgs, + lib, + ... + }: let settings = { projectRootFile = "flake.nix"; @@ -12,6 +17,7 @@ deadnix.enable = true; terraform.enable = true; nixfmt.enable = true; + nixpkgs-fmt.enable = true; statix.enable = true; prettier.enable = true; }; @@ -22,6 +28,8 @@ "**/secrets.json" "**/secrets.yml" ]; + nixfmt.excludes = [ "modules/packages/**/*.nix" ]; + nixpkgs-fmt.includes = lib.mkOverride 10 [ "modules/packages/**/*.nix" ]; }; }; in diff --git a/modules/packages/bichon/default.nix b/modules/packages/bichon/default.nix index db97744..da081af 100644 --- a/modules/packages/bichon/default.nix +++ b/modules/packages/bichon/default.nix @@ -1,16 +1,16 @@ -{ - stdenv, - lib, - rustPlatform, - fetchFromGitHub, - fetchPnpmDeps, - nodejs_22, - pnpm, - pnpmConfigHook, - typescript, - pkg-config, - git, - openssl, +{ stdenv +, lib +, rustPlatform +, fetchFromGitHub +, fetchPnpmDeps +, nodejs_22 +, pnpm +, pnpmConfigHook +, typescript +, pkg-config +, git +, openssl +, }: rustPlatform.buildRustPackage ( diff --git a/modules/packages/declutarr/default.nix b/modules/packages/declutarr/default.nix index c9135ff..abf4892 100644 --- a/modules/packages/declutarr/default.nix +++ b/modules/packages/declutarr/default.nix @@ -1,8 +1,8 @@ -{ - lib, - fetchFromGitHub, - makeWrapper, - python3Packages, +{ lib +, fetchFromGitHub +, makeWrapper +, python3Packages +, }: python3Packages.buildPythonApplication rec { diff --git a/modules/packages/fileflows/default.nix b/modules/packages/fileflows/default.nix index 58c73bc..7cd9b50 100644 --- a/modules/packages/fileflows/default.nix +++ b/modules/packages/fileflows/default.nix @@ -1,11 +1,11 @@ -{ - lib, - stdenvNoCC, - fetchzip, - dotnetCorePackages, - sqlite, - libz, - writeShellScript, +{ lib +, stdenvNoCC +, fetchzip +, dotnetCorePackages +, sqlite +, libz +, writeShellScript +, }: let dotnet = dotnetCorePackages.aspnetcore_8_0; diff --git a/modules/packages/profilarr-parser/default.nix b/modules/packages/profilarr-parser/default.nix index ed44e15..33e4ce6 100644 --- a/modules/packages/profilarr-parser/default.nix +++ b/modules/packages/profilarr-parser/default.nix @@ -1,19 +1,19 @@ -{ - lib, - buildDotnetModule, - dotnetCorePackages, - fetchFromGitHub, +{ lib +, buildDotnetModule +, dotnetCorePackages +, fetchFromGitHub +, }: buildDotnetModule rec { pname = "profilarr-parser"; - version = "2.0.8"; + version = "2.0.9"; src = fetchFromGitHub { owner = "Dictionarry-Hub"; repo = "Profilarr"; tag = "v${version}"; - hash = "sha256-tpgTeKJCeEfhoARpq5u9W8iFZNocTNOhihAJNsyfTLY="; + hash = "sha256-FfMBu58cfaZlgxlqyO0qBz702NVcdQDarkh6JiSncCs="; }; sourceRoot = "${src.name}/src/services/parser"; diff --git a/modules/packages/profilarr/default.nix b/modules/packages/profilarr/default.nix index 3dc8217..e71a6c3 100644 --- a/modules/packages/profilarr/default.nix +++ b/modules/packages/profilarr/default.nix @@ -1,25 +1,25 @@ -{ - lib, - stdenv, - fetchFromGitHub, - deno, - cacert, - makeWrapper, - autoPatchelfHook, - sqlite, - git, - gnutar, - gzip, +{ lib +, stdenv +, fetchFromGitHub +, deno +, cacert +, makeWrapper +, autoPatchelfHook +, sqlite +, git +, gnutar +, gzip +, }: let - version = "2.0.8"; + version = "2.0.9"; src = fetchFromGitHub { owner = "Dictionarry-Hub"; repo = "Profilarr"; tag = "v${version}"; - hash = "sha256-tpgTeKJCeEfhoARpq5u9W8iFZNocTNOhihAJNsyfTLY="; + hash = "sha256-FfMBu58cfaZlgxlqyO0qBz702NVcdQDarkh6JiSncCs="; }; denoDeps = stdenv.mkDerivation { @@ -66,13 +66,11 @@ let outputHashMode = "recursive"; outputHash = { - x86_64-linux = "sha256-a+80eXiDgWzLKefqqF9hnquBr4RLhUucTUOJc6inCMs="; - aarch64-linux = "sha256-z4zIEEekyQRSLTkXLmIM5JA8vZBKUMGGtUuvtD0Xq0g="; - } - .${stdenv.hostPlatform.system} + x86_64-linux = "sha256-grOB5TLldkZ6O9x0MRR9+2jJoZFcjbkMM+e/vM4gnPw="; + aarch64-linux = "sha256-XIPWLAo1XmmKrCOSGPXsCD3uhljurV6TTKB5LJiitqk="; + }.${stdenv.hostPlatform.system} or (throw "profilarr: unsupported system ${stdenv.hostPlatform.system}"); }; - in stdenv.mkDerivation { pname = "profilarr"; diff --git a/modules/packages/tracearr/default.nix b/modules/packages/tracearr/default.nix index 3f5d920..541dcb2 100644 --- a/modules/packages/tracearr/default.nix +++ b/modules/packages/tracearr/default.nix @@ -1,13 +1,13 @@ -{ - lib, - stdenv, - pnpm_10, - fetchPnpmDeps, - pnpmConfigHook, - makeWrapper, - nodejs, - fetchFromGitHub, - turbo, +{ lib +, stdenv +, pnpm_10 +, fetchPnpmDeps +, pnpmConfigHook +, makeWrapper +, nodejs +, fetchFromGitHub +, turbo +, }: stdenv.mkDerivation (finalAttrs: { pname = "tracearr"; From c34e9239a0b6239ebb8f1e835bcd8d9cdf2efc07 Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Sat, 11 Jul 2026 12:48:34 -0400 Subject: [PATCH 05/10] Update `bichon` --- modules/packages/bichon/default.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/packages/bichon/default.nix b/modules/packages/bichon/default.nix index da081af..c388002 100644 --- a/modules/packages/bichon/default.nix +++ b/modules/packages/bichon/default.nix @@ -16,12 +16,12 @@ rustPlatform.buildRustPackage ( let pname = "bichon"; - version = "1.5.2"; + version = "1.6.2"; source = fetchFromGitHub { owner = "rustmailer"; repo = "bichon"; rev = version; - hash = "sha256-QvAUM1fncnbmXGJ4fhq7c4ZvE4rquMQqdqq6RlOIBxI="; + hash = "sha256-a8BAO93eI2eiFwmvMqUsgL1KZ11X3qg/r/Iw6ckMSTs="; }; frontend = stdenv.mkDerivation (finalAttrs: { pname = "${pname}-frontend"; @@ -40,8 +40,8 @@ rustPlatform.buildRustPackage ( pnpmDeps = fetchPnpmDeps { inherit (finalAttrs) pname version src; - fetcherVersion = 3; - hash = "sha256-7EkSYTUXOtYewvOoKJiOSNmpowJj27/Ea8PAcebJCzA="; + fetcherVersion = 4; + hash = "sha256-Ax8z1sjt8v6XOenhw7eRuEEo0huPv9fbcfzqc8RxJEc="; sourceRoot = "${finalAttrs.src.name}/web"; }; @@ -72,7 +72,7 @@ rustPlatform.buildRustPackage ( src = source; - cargoHash = "sha256-keEOzDf2DSOC2g8mLMuZhi1FwCaBXzo1yk0WmIcTFuI="; + cargoHash = "sha256-GC/2bswme76bAFRCsBHFi3lWnYx5x5H58emCmkiyKfE="; nativeBuildInputs = [ pkg-config From 8f4b9e07ecb037c502cfcd32997ba1e9a764d4d8 Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Sat, 11 Jul 2026 13:45:47 -0400 Subject: [PATCH 06/10] [build] Allow some insecure packages, pull in non-broken packages --- flake.lock | 17 +++++++++++++++++ flake.nix | 3 +++ hosts/matrix/configuration.nix | 3 +-- modules/overlays/default.nix | 19 +++++++++++++++++-- modules/profiles/core/nix-config.nix | 1 + 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/flake.lock b/flake.lock index ed87177..63956b8 100644 --- a/flake.lock +++ b/flake.lock @@ -1308,6 +1308,22 @@ "type": "github" } }, + "nixpkgs-stable_3": { + "locked": { + "lastModified": 1783703440, + "narHash": "sha256-O3/YajjWo001VUIgD8BwaRdSNLUFe7nZ1qV5TwhRBcw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "8f0500b9660505dc3cb647775fe9a978a74b5283", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-26.05", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs_2": { "locked": { "lastModified": 1767892417, @@ -1373,6 +1389,7 @@ "nixos-hardware": "nixos-hardware_2", "nixpkgs": "nixpkgs_3", "nixpkgs-master": "nixpkgs-master_2", + "nixpkgs-stable": "nixpkgs-stable_3", "plex-exporter": "plex-exporter", "sops-nix": "sops-nix_2", "treefmt": "treefmt_3" diff --git a/flake.nix b/flake.nix index 839c107..957a714 100644 --- a/flake.nix +++ b/flake.nix @@ -20,6 +20,8 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-26.05"; + nixpkgs-master.url = "github:NixOS/nixpkgs"; flake-parts.url = "github:hercules-ci/flake-parts"; @@ -100,6 +102,7 @@ permittedInsecurePackages = [ "dotnet-sdk-6.0.428" "aspnetcore-runtime-6.0.36" + "pnpm-9.15.9" ]; }; diff --git a/hosts/matrix/configuration.nix b/hosts/matrix/configuration.nix index 7b3737b..53dfe92 100644 --- a/hosts/matrix/configuration.nix +++ b/hosts/matrix/configuration.nix @@ -44,10 +44,9 @@ satan.address = "10.10.3.101"; deployment = { - buildOnTarget = true; + buildOnTarget = false; tags = [ "@vm" - "@build-on-target" ]; }; diff --git a/modules/overlays/default.nix b/modules/overlays/default.nix index 60f5ad6..822d297 100644 --- a/modules/overlays/default.nix +++ b/modules/overlays/default.nix @@ -18,6 +18,20 @@ permittedInsecurePackages = [ "dotnet-sdk-6.0.428" "aspnetcore-runtime-6.0.36" + "pnpm-9.15.9" + ]; + }; + }; + + nixpkgs-stable = import inputs.nixpkgs-stable { + inherit system; + + config = { + allowUnfree = true; + permittedInsecurePackages = [ + "dotnet-sdk-6.0.428" + "aspnetcore-runtime-6.0.36" + "pnpm-9.15.9" ]; }; }; @@ -34,11 +48,12 @@ immich ; - # inherit (nixpkgs-master.python312Packages) pymdown-extensions onnx; - # This is to pick up bugfix here: https://github.com/thanos-io/thanos/issues/7923 inherit (nixpkgs-master) thanos; + # Avoiding build failure on unstable: https://github.com/NixOS/nixpkgs/issues/540609 + inherit (nixpkgs-stable) gdalMinimal; + inherit (self'.packages) bichon declutarr diff --git a/modules/profiles/core/nix-config.nix b/modules/profiles/core/nix-config.nix index 45b1b4f..a414715 100644 --- a/modules/profiles/core/nix-config.nix +++ b/modules/profiles/core/nix-config.nix @@ -11,6 +11,7 @@ permittedInsecurePackages = [ "dotnet-sdk-6.0.428" "aspnetcore-runtime-6.0.36" + "pnpm-9.15.9" ]; }; overlays = [ From bd1b2baf6ccedfd1e68a5245dcf4c586da416698 Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Sat, 11 Jul 2026 13:59:56 -0400 Subject: [PATCH 07/10] [build] Fix `profilarr` deps hash, fix `decluttarr` naming --- .github/workflows/packages.yml | 2 +- hosts/htpc/configuration.nix | 2 +- modules/nixos/services/declutarr/default.nix | 22 +++++++++---------- modules/overlays/default.nix | 2 +- .../{declutarr => decluttarr}/default.nix | 2 +- modules/packages/default.nix | 2 +- modules/packages/profilarr/default.nix | 2 +- .../media-management/declutarr/default.nix | 10 ++++----- 8 files changed, 22 insertions(+), 22 deletions(-) rename modules/packages/{declutarr => decluttarr}/default.nix (98%) diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml index 6bfc034..d5cb512 100644 --- a/.github/workflows/packages.yml +++ b/.github/workflows/packages.yml @@ -47,7 +47,7 @@ jobs: os: ubuntu-24.04-arm package: - bichon - - declutarr + - decluttarr - fileflows - incus-apply - mazanoke diff --git a/hosts/htpc/configuration.nix b/hosts/htpc/configuration.nix index 86c1dae..eb62f8e 100644 --- a/hosts/htpc/configuration.nix +++ b/hosts/htpc/configuration.nix @@ -16,7 +16,7 @@ profiles.hardware.nvidia profiles.home-automation.frigate.default profiles.media-management.bazarr.default - profiles.media-management.declutarr.default + profiles.media-management.decluttarr.default profiles.media-management.fileflows.server profiles.media-management.jellyfin profiles.media-management.plex diff --git a/modules/nixos/services/declutarr/default.nix b/modules/nixos/services/declutarr/default.nix index 4502172..168a9bf 100644 --- a/modules/nixos/services/declutarr/default.nix +++ b/modules/nixos/services/declutarr/default.nix @@ -8,33 +8,33 @@ with lib; let - cfg = config.services.declutarr; + cfg = config.services.decluttarr; format = pkgs.formats.yaml { }; configFile = if cfg.config != null then format.generate "configuration.yaml" cfg.config else cfg.configFile; in { - options.services.declutarr = { - enable = mkEnableOption "Enable Declutarr"; + options.services.decluttarr = { + enable = mkEnableOption "Enable Decluttarr"; package = mkOption { type = types.package; - default = pkgs.declutarr; + default = pkgs.decluttarr; }; dataDir = mkOption { type = types.path; - default = "/var/lib/declutarr"; + default = "/var/lib/decluttarr"; }; user = mkOption { type = types.str; - default = "declutarr"; + default = "decluttarr"; }; group = mkOption { type = types.str; - default = "declutarr"; + default = "decluttarr"; }; config = mkOption { @@ -61,7 +61,7 @@ in } ]; - systemd.tmpfiles.settings."10-declutarr" = { + systemd.tmpfiles.settings."10-decluttarr" = { ${cfg.dataDir} = { "d" = { inherit (cfg) user group; @@ -85,15 +85,15 @@ in }; users = { - users.declutarr = mkIf (cfg.user == "declutarr") { + users.decluttarr = mkIf (cfg.user == "decluttarr") { inherit (cfg) group; isSystemUser = true; }; - groups = mkIf (cfg.group == "declutarr") { declutarr = { }; }; + groups = mkIf (cfg.group == "decluttarr") { decluttarr = { }; }; }; - systemd.services.declutarr = { + systemd.services.decluttarr = { enable = true; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; diff --git a/modules/overlays/default.nix b/modules/overlays/default.nix index 822d297..ab5950f 100644 --- a/modules/overlays/default.nix +++ b/modules/overlays/default.nix @@ -56,7 +56,7 @@ inherit (self'.packages) bichon - declutarr + decluttarr fileflows mazanoke profilarr diff --git a/modules/packages/declutarr/default.nix b/modules/packages/decluttarr/default.nix similarity index 98% rename from modules/packages/declutarr/default.nix rename to modules/packages/decluttarr/default.nix index abf4892..bae3694 100644 --- a/modules/packages/declutarr/default.nix +++ b/modules/packages/decluttarr/default.nix @@ -6,7 +6,7 @@ }: python3Packages.buildPythonApplication rec { - name = "declutarr"; + name = "decluttarr"; version = "2.1.0"; src = fetchFromGitHub { diff --git a/modules/packages/default.nix b/modules/packages/default.nix index 38ece78..906dff3 100644 --- a/modules/packages/default.nix +++ b/modules/packages/default.nix @@ -2,7 +2,7 @@ _: { perSystem = { pkgs, ... }: { packages = { bichon = pkgs.callPackage ./bichon { }; - declutarr = pkgs.callPackage ./declutarr { }; + decluttarr = pkgs.callPackage ./decluttarr { }; fileflows = pkgs.callPackage ./fileflows { }; incus-apply = pkgs.callPackage ./incus-apply { }; mazanoke = pkgs.callPackage ./mazanoke { }; diff --git a/modules/packages/profilarr/default.nix b/modules/packages/profilarr/default.nix index e71a6c3..4493adf 100644 --- a/modules/packages/profilarr/default.nix +++ b/modules/packages/profilarr/default.nix @@ -66,7 +66,7 @@ let outputHashMode = "recursive"; outputHash = { - x86_64-linux = "sha256-grOB5TLldkZ6O9x0MRR9+2jJoZFcjbkMM+e/vM4gnPw="; + x86_64-linux = "sha256-eyrIsA8KTajDvMNR0kjOHhPVPd30KgMuv+qeV7zaO/Q="; aarch64-linux = "sha256-XIPWLAo1XmmKrCOSGPXsCD3uhljurV6TTKB5LJiitqk="; }.${stdenv.hostPlatform.system} or (throw "profilarr: unsupported system ${stdenv.hostPlatform.system}"); diff --git a/modules/profiles/media-management/declutarr/default.nix b/modules/profiles/media-management/declutarr/default.nix index 9950ae4..f34656f 100644 --- a/modules/profiles/media-management/declutarr/default.nix +++ b/modules/profiles/media-management/declutarr/default.nix @@ -1,5 +1,5 @@ { config, lib, ... }: { - sops.templates."declutarr/config.yml" = { + sops.templates."decluttarr/config.yml" = { content = lib.generators.toYAML { } { general = { log_level = "INFO"; @@ -57,13 +57,13 @@ ]; }; }; - owner = config.services.declutarr.user; - inherit (config.services.declutarr) group; + owner = config.services.decluttarr.user; + inherit (config.services.decluttarr) group; mode = "0700"; }; - services.declutarr = { + services.decluttarr = { enable = true; - configFile = config.sops.templates."declutarr/config.yml".path; + configFile = config.sops.templates."decluttarr/config.yml".path; }; } From 1035be8a3afdd4de4285d68d286cc2c4bfca1e16 Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Sat, 11 Jul 2026 15:35:49 -0400 Subject: [PATCH 08/10] [build] Fix `decluttarr` profile naming --- modules/nixos/services/{declutarr => decluttarr}/default.nix | 0 .../media-management/{declutarr => decluttarr}/default.nix | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename modules/nixos/services/{declutarr => decluttarr}/default.nix (100%) rename modules/profiles/media-management/{declutarr => decluttarr}/default.nix (100%) diff --git a/modules/nixos/services/declutarr/default.nix b/modules/nixos/services/decluttarr/default.nix similarity index 100% rename from modules/nixos/services/declutarr/default.nix rename to modules/nixos/services/decluttarr/default.nix diff --git a/modules/profiles/media-management/declutarr/default.nix b/modules/profiles/media-management/decluttarr/default.nix similarity index 100% rename from modules/profiles/media-management/declutarr/default.nix rename to modules/profiles/media-management/decluttarr/default.nix From f3033c0235f03bfbe0c07ab2be64b4ca20301864 Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Sat, 11 Jul 2026 22:59:58 -0400 Subject: [PATCH 09/10] Fix Zed formatting --- .zed/settings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.zed/settings.json b/.zed/settings.json index 67592e1..d2cf8f5 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -1,8 +1,8 @@ { "formatter": { "external": { - "command": "treefmt", - "arguments": ["--stdin", "{buffer_path}"] + "command": "direnv", + "arguments": ["exec", ".", "treefmt", "--stdin", "{buffer_path}"] } } } From cfcb528368ece3cb6d9bb3e29331d2c1d0180d6c Mon Sep 17 00:00:00 2001 From: Ethan Turkeltaub Date: Sat, 11 Jul 2026 23:00:19 -0400 Subject: [PATCH 10/10] Don't use deprecated `routeConfig` --- hosts/controller/configuration.nix | 1 - hosts/dill/configuration.nix | 8 +++----- hosts/fennel/configuration.nix | 8 +++----- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/hosts/controller/configuration.nix b/hosts/controller/configuration.nix index 5ba8d94..ed9db12 100644 --- a/hosts/controller/configuration.nix +++ b/hosts/controller/configuration.nix @@ -26,7 +26,6 @@ buildOnTarget = false; tags = [ "@vm" - "@build-on-target" ]; }; diff --git a/hosts/dill/configuration.nix b/hosts/dill/configuration.nix index e494004..346bd95 100644 --- a/hosts/dill/configuration.nix +++ b/hosts/dill/configuration.nix @@ -101,11 +101,9 @@ address = [ "10.10.4.0/24" ]; routes = [ { - routeConfig = { - Destination = "0.0.0.0/0"; - Gateway = "10.10.0.1"; - GatewayOnLink = true; - }; + Destination = "0.0.0.0/0"; + Gateway = "10.10.0.1"; + GatewayOnLink = true; } ]; networkConfig.LinkLocalAddressing = "no"; diff --git a/hosts/fennel/configuration.nix b/hosts/fennel/configuration.nix index eebcfeb..7022b3b 100644 --- a/hosts/fennel/configuration.nix +++ b/hosts/fennel/configuration.nix @@ -18,11 +18,9 @@ address = [ "10.10.4.101/24" ]; routes = [ { - routeConfig = { - Destination = "0.0.0.0/0"; - Gateway = "10.10.0.1"; - GatewayOnLink = true; - }; + Destination = "0.0.0.0/0"; + Gateway = "10.10.0.1"; + GatewayOnLink = true; } ]; networkConfig.DHCP = "no";