diff --git a/.helix/languages.toml b/.helix/languages.toml index 5dd999ea..29fc7109 100644 --- a/.helix/languages.toml +++ b/.helix/languages.toml @@ -1,6 +1,11 @@ -[language-server.nil] -command = "nil" +[language-server.nixd] +command = "nixd" +# args = ["--log=debug"] +[language-server.nixd.config.nixd] +nixpkgs = { expr = "import (builtins.getFlake (builtins.toString ./.)).inputs.nixpkgs { }" } +options = { nixos = { expr = "(builtins.getFlake (builtins.toString ./.)).colmenaHive.nodes.theseus.options" }}#, home-manager = { expr = "(builtins.getFlake (builtins.toString ./.)).colmenaHive.nodes.theseus.options.home-manager.users.type.getSubOptions []" } } + [[language]] name = "nix" formatter = {command = "nixfmt"} -language-servers = [ "nil" ] +language-servers = [ "nixd" ] diff --git a/flake.lock b/flake.lock index 7a14a408..cb75e271 100644 --- a/flake.lock +++ b/flake.lock @@ -1,55 +1,76 @@ { "nodes": { - "authentik": { - "inputs": { - "authentik-src": "authentik-src", - "flake-compat": "flake-compat", - "flake-parts": "flake-parts", - "flake-utils": "flake-utils", - "napalm": "napalm", - "nixpkgs": [ - "nixpkgs" - ], - "pyproject-build-systems": "pyproject-build-systems", - "pyproject-nix": "pyproject-nix", - "systems": "systems", - "uv2nix": "uv2nix" - }, + "adw-colors": { + "flake": false, "locked": { - "lastModified": 1759322529, - "narHash": "sha256-yiv/g/tiJI3PI95F7vhTnaf1TDsIkFLrmmFTjWfb6pQ=", - "owner": "nix-community", - "repo": "authentik-nix", - "rev": "69fac057b2e553ee17c9a09b822d735823d65a6c", + "lastModified": 1759892823, + "narHash": "sha256-ocrVOebwU2AN4MAQywTOHEA8Lwbx7iOMbuI85V5jk4I=", + "owner": "lassekongo83", + "repo": "adw-colors", + "rev": "4f32945ffe95e871b46191d96dc5f61b153d699f", "type": "github" }, "original": { - "owner": "nix-community", - "repo": "authentik-nix", + "owner": "lassekongo83", + "repo": "adw-colors", "type": "github" } }, - "authentik-src": { - "flake": false, + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager_2", + "nixpkgs": [ + "oldConf", + "nixpkgs" + ], + "systems": "systems" + }, "locked": { - "lastModified": 1759190535, - "narHash": "sha256-pIzDaoDWc58cY/XhsyweCwc4dfRvkaT/zqsV1gDSnCI=", - "owner": "goauthentik", - "repo": "authentik", - "rev": "8d3a289d12c7de2f244c76493af7880f70d08af2", + "lastModified": 1754433428, + "narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=", + "owner": "ryantm", + "repo": "agenix", + "rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d", "type": "github" }, "original": { - "owner": "goauthentik", - "ref": "version/2025.8.4", - "repo": "authentik", + "owner": "ryantm", + "ref": "main", + "repo": "agenix", + "type": "github" + } + }, + "attic": { + "inputs": { + "crane": "crane_2", + "flake-compat": "flake-compat_3", + "flake-parts": "flake-parts_2", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "oldConf", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1758711588, + "narHash": "sha256-0nZlCCDC5PfndsQJXXtcyrtrfW49I3KadGMDlutzaGU=", + "owner": "zhaofengli", + "repo": "attic", + "rev": "12cbeca141f46e1ade76728bce8adc447f2166c6", + "type": "github" + }, + "original": { + "owner": "zhaofengli", + "repo": "attic", "type": "github" } }, "colmena": { "inputs": { - "flake-compat": "flake-compat_2", - "flake-utils": "flake-utils_2", + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", "nixpkgs": [ "nixpkgs" ], @@ -85,23 +106,67 @@ "type": "github" } }, - "flake-compat": { - "flake": false, + "crane_2": { "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "lastModified": 1751562746, + "narHash": "sha256-smpugNIkmDeicNz301Ll1bD7nFOty97T79m4GUMUczA=", + "owner": "ipetkov", + "repo": "crane", + "rev": "aed2020fd3dc26e1e857d4107a5a67a33ab6c1fd", "type": "github" }, "original": { - "owner": "edolstra", - "repo": "flake-compat", + "owner": "ipetkov", + "repo": "crane", "type": "github" } }, - "flake-compat_2": { + "darwin": { + "inputs": { + "nixpkgs": [ + "oldConf", + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744478979, + "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "43975d782b418ebf4969e9ccba82466728c2851b", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "darwin_2": { + "inputs": { + "nixpkgs": [ + "oldConf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1758805352, + "narHash": "sha256-BHdc43Lkayd+72W/NXRKHzX5AZ+28F3xaUs3a88/Uew=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "c48e963a5558eb1c3827d59d21c5193622a1477c", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "flake-compat": { "flake": false, "locked": { "lastModified": 1650374568, @@ -117,7 +182,7 @@ "type": "github" } }, - "flake-compat_3": { + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1696426674, @@ -133,25 +198,23 @@ "type": "github" } }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, + "flake-compat_3": { + "flake": false, "locked": { - "lastModified": 1756770412, - "narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "4524271976b625a4a605beefd893f270620fd751", + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", "type": "github" }, "original": { - "owner": "hercules-ci", - "repo": "flake-parts", + "owner": "edolstra", + "repo": "flake-compat", "type": "github" } }, - "flake-parts_2": { + "flake-parts": { "inputs": { "nixpkgs-lib": [ "lanzaboote", @@ -172,19 +235,38 @@ "type": "github" } }, - "flake-parts_3": { + "flake-parts_2": { "inputs": { "nixpkgs-lib": [ - "terranix", + "oldConf", + "attic", "nixpkgs" ] }, "locked": { - "lastModified": 1736143030, - "narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=", + "lastModified": 1751413152, + "narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de", + "rev": "77826244401ea9de6e3bac47c2db46005e1f30b5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1738453229, + "narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", "type": "github" }, "original": { @@ -194,27 +276,6 @@ } }, "flake-utils": { - "inputs": { - "systems": [ - "authentik", - "systems" - ] - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_2": { "locked": { "lastModified": 1659877975, "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", @@ -229,9 +290,9 @@ "type": "github" } }, - "flake-utils_3": { + "flake-utils_2": { "inputs": { - "systems": "systems_3" + "systems": "systems_2" }, "locked": { "lastModified": 1731533236, @@ -247,6 +308,39 @@ "type": "github" } }, + "flake-utils_3": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flakey-profile": { + "locked": { + "lastModified": 1712898590, + "narHash": "sha256-FhGIEU93VHAChKEXx905TSiPZKga69bWl1VB37FK//I=", + "owner": "lf-", + "repo": "flakey-profile", + "rev": "243c903fd8eadc0f63d205665a92d4df91d42d9d", + "type": "github" + }, + "original": { + "owner": "lf-", + "repo": "flakey-profile", + "type": "github" + } + }, "gitignore": { "inputs": { "nixpkgs": [ @@ -277,11 +371,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1761141169, - "narHash": "sha256-5IZjbTvP5dNTD8CbEYlNbicdGcbCN9SC9ksMm2ZEXH0=", + "lastModified": 1764123663, + "narHash": "sha256-Q3WxbsjPJV8QHF1fU+B4kz9hDfHkdMarW1CCM0x44Ks=", "owner": "helix-editor", "repo": "helix", - "rev": "d79cce4e4bfc24dd204f1b294c899ed73f7e9453", + "rev": "24f45746cc68e7c90cd4c43334a756f68986a1be", "type": "github" }, "original": { @@ -297,11 +391,11 @@ ] }, "locked": { - "lastModified": 1761191301, - "narHash": "sha256-xsRL2Oyb4YRZZ1Tu4WzR2uFg1n931bH+PfLdFcqtLg8=", + "lastModified": 1764304195, + "narHash": "sha256-bO7FN/bF6gG7TlZpKAZjO3VvfsLaPFkefeUfJJ7F/7w=", "owner": "nix-community", "repo": "home-manager", - "rev": "4958aafe7b237dc1e857fb0c916efff72075048f", + "rev": "86ff0ef506c209bb397849706e85cc3a913cb577", "type": "github" }, "original": { @@ -313,6 +407,51 @@ "home-manager_2": { "inputs": { "nixpkgs": [ + "oldConf", + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1745494811, + "narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_3": { + "inputs": { + "nixpkgs": [ + "oldConf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1758463745, + "narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-25.05", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_4": { + "inputs": { + "nixpkgs": [ + "oldConf", "zen-browser", "nixpkgs" ] @@ -331,6 +470,27 @@ "type": "github" } }, + "home-manager_5": { + "inputs": { + "nixpkgs": [ + "zen-browser", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1762964643, + "narHash": "sha256-RYHN8O/Aja59XDji6WSJZPkJpYVUfpSkyH+PEupBJqM=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "827f2a23373a774a8805f84ca5344654c31f354b", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, "impermanence": { "locked": { "lastModified": 1737831083, @@ -346,6 +506,21 @@ "type": "github" } }, + "impermanence_2": { + "locked": { + "lastModified": 1737831083, + "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, "kmonad": { "inputs": { "nixpkgs": [ @@ -369,16 +544,42 @@ "url": "https://github.com/jokesper/kmonad" } }, + "kmonad_2": { + "inputs": { + "nixpkgs": [ + "oldConf", + "nixpkgs" + ] + }, + "locked": { + "dir": "nix", + "lastModified": 1751398458, + "narHash": "sha256-EHg2Z0EbsFN5zU1WrLc1sFszbUsLLpqZgFim7Zi8dRc=", + "ref": "feat-tap-overlap", + "rev": "fb0334cbd16ec64c5ebcc10f7982a9857bd97d27", + "revCount": 986, + "type": "git", + "url": "https://github.com/jokesper/kmonad" + }, + "original": { + "dir": "nix", + "ref": "feat-tap-overlap", + "type": "git", + "url": "https://github.com/jokesper/kmonad" + } + }, "lanzaboote": { "inputs": { "crane": "crane", - "flake-compat": "flake-compat_3", - "flake-parts": "flake-parts_2", + "flake-compat": "flake-compat_2", + "flake-parts": "flake-parts", "nixpkgs": [ "nixpkgs" ], "pre-commit-hooks-nix": "pre-commit-hooks-nix", - "rust-overlay": "rust-overlay_2" + "rust-overlay": [ + "rust-overlay" + ] }, "locked": { "lastModified": 1737639419, @@ -395,14 +596,66 @@ "type": "github" } }, + "lix": { + "flake": false, + "locked": { + "lastModified": 1753223229, + "narHash": "sha256-tkT4aCZZE6IEmjYotOzKKa2rV3pGpH3ZREeQn7ACgdU=", + "rev": "7ac20fc47cf2f1b7469c7a2f379e5a3a51a6789a", + "type": "tarball", + "url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/7ac20fc47cf2f1b7469c7a2f379e5a3a51a6789a.tar.gz?rev=7ac20fc47cf2f1b7469c7a2f379e5a3a51a6789a" + }, + "original": { + "type": "tarball", + "url": "https://git.lix.systems/lix-project/lix/archive/release-2.93.tar.gz" + } + }, + "lix-module": { + "inputs": { + "flake-utils": "flake-utils_2", + "flakey-profile": "flakey-profile", + "lix": "lix", + "nixpkgs": [ + "oldConf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1753282722, + "narHash": "sha256-KYMUrTV7H/RR5/HRnjV5R3rRIuBXMemyJzTLi50NFTs=", + "rev": "46a9e8fcfe4be72b4c7c8082ee11d2c42da1e873", + "type": "tarball", + "url": "https://git.lix.systems/api/v1/repos/lix-project/nixos-module/archive/46a9e8fcfe4be72b4c7c8082ee11d2c42da1e873.tar.gz?rev=46a9e8fcfe4be72b4c7c8082ee11d2c42da1e873" + }, + "original": { + "type": "tarball", + "url": "https://git.lix.systems/lix-project/nixos-module/archive/2.93.3-1.tar.gz" + } + }, + "miro": { + "flake": false, + "locked": { + "lastModified": 1644177791, + "narHash": "sha256-t8L6UboaOcg6JkGjX1NTd13Yw7ATySGxmnkJ7wUyZAE=", + "owner": "miromannino", + "repo": "miro-windows-manager", + "rev": "faa6f5f0bc025cc2465f3198609d2123d86101c2", + "type": "github" + }, + "original": { + "owner": "miromannino", + "repo": "miro-windows-manager", + "type": "github" + } + }, "mobile-nixos": { "flake": false, "locked": { - "lastModified": 1759261417, - "narHash": "sha256-TjuoBb8+isL3KTdGgtYh90XPyeUMFbgNAOG9l23CB3A=", + "lastModified": 1763065138, + "narHash": "sha256-46lJeUYH8YrfTccAoKQbO9lprq4dlo9VVLk+StPBSWM=", "owner": "mobile-nixos", "repo": "mobile-nixos", - "rev": "e6f6d527bf6abf94dd52fbba3143a720cef96431", + "rev": "1943b7b06fcd1a2c87f4b89df58231915cc2ca44", "type": "github" }, "original": { @@ -427,40 +680,14 @@ "type": "github" } }, - "napalm": { - "inputs": { - "flake-utils": [ - "authentik", - "flake-utils" - ], - "nixpkgs": [ - "authentik", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1725806412, - "narHash": "sha256-lGZjkjds0p924QEhm/r0BhAxbHBJE1xMOldB/HmQH04=", - "owner": "willibutz", - "repo": "napalm", - "rev": "b492440d9e64ae20736d3bec5c7715ffcbde83f5", - "type": "github" - }, - "original": { - "owner": "willibutz", - "ref": "avoid-foldl-stack-overflow", - "repo": "napalm", - "type": "github" - } - }, "nheko": { "flake": false, "locked": { - "lastModified": 1757886200, - "narHash": "sha256-FU73Pb47e6Q0qEAJcxDVhVLmL+hJ4gXvssRD9NcUNkM=", + "lastModified": 1762138523, + "narHash": "sha256-93M4T6peRRMq0uL0X955+N0KnU1t/0AAyVQ/TV2zpQs=", "owner": "Nheko-Reborn", "repo": "nheko", - "rev": "2769642d3c7bd3c0d830b2f18ef6b3bf6a710bf4", + "rev": "1bd2970c4dd69daa87d906f63d869d56cf5d4915", "type": "github" }, "original": { @@ -474,14 +701,14 @@ "nixpkgs": [ "nixpkgs-master" ], - "rust-overlay": "rust-overlay_3" + "rust-overlay": "rust-overlay_2" }, "locked": { - "lastModified": 1760940149, - "narHash": "sha256-KbM47vD6E0cx+v4jYQZ8mD5N186AKm2CQlyh34TW58U=", + "lastModified": 1764306526, + "narHash": "sha256-Lwz8CwV4ryaqbKNZ4ftnNrhwZI29aoHQ5MRJponTDTY=", "owner": "YaLTeR", "repo": "niri", - "rev": "b3245b81a6ed8edfaf5388a74d2e0a23c24941e5", + "rev": "0652342df8fffa93abcc5e567be1afb3eab002f6", "type": "github" }, "original": { @@ -495,7 +722,7 @@ "nixpkgs": [ "nixpkgs" ], - "rust-overlay": "rust-overlay_4" + "rust-overlay": "rust-overlay_3" }, "locked": { "lastModified": 1760113386, @@ -511,6 +738,28 @@ "url": "https://git.xyno.systems/xyno/nix-ci" } }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "oldConf", + "attic", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1737420293, + "narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, "nix-index-database": { "inputs": { "nixpkgs": [ @@ -518,11 +767,11 @@ ] }, "locked": { - "lastModified": 1760846226, - "narHash": "sha256-xmU8kAsRprJiTGBTaGrwmjBP3AMA9ltlrxHKFuy5JWc=", + "lastModified": 1763870992, + "narHash": "sha256-NPyc76Wxmv/vAsXJ8F+/8fXECHYcv2YGSqdiSHp/F/A=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "5024e1901239a76b7bf94a4cd27f3507e639d49e", + "rev": "d7423982c7a26586aa237d130b14c8b302c7a367", "type": "github" }, "original": { @@ -533,11 +782,27 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1760958188, - "narHash": "sha256-2m1S4jl+GEDtlt2QqeHil8Ny456dcGSKJAM7q3j/BFU=", + "lastModified": 1764328224, + "narHash": "sha256-hFyF1XQd+XrRx7WZCrGJp544dykexD8Q5SrJJZpEQYg=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "d6645c340ef7d821602fd2cd199e8d1eed10afbc", + "rev": "d62603a997438e19182af69d3ce7be07565ecad4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "master", + "repo": "nixos-hardware", + "type": "github" + } + }, + "nixos-hardware_2": { + "locked": { + "lastModified": 1758663926, + "narHash": "sha256-6CFdj7Xs616t1W4jLDH7IohAAvl5Dyib3qEv/Uqw1rk=", + "owner": "NixOS", + "repo": "nixos-hardware", + "rev": "170ff93c860b2a9868ed1e1102d4e52cb3d934e1", "type": "github" }, "original": { @@ -549,11 +814,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1761114652, - "narHash": "sha256-f/QCJM/YhrV/lavyCVz8iU3rlZun6d+dAiC3H+CDle4=", + "lastModified": 1764242076, + "narHash": "sha256-sKoIWfnijJ0+9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "01f116e4df6a15f4ccdffb1bcd41096869fb385c", + "rev": "2fad6eac6077f03fe109c4d4eb171cf96791faa4", "type": "github" }, "original": { @@ -563,28 +828,41 @@ "type": "github" } }, - "nixpkgs-lib": { + "nixpkgs-darwin": { "locked": { - "lastModified": 1754788789, - "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", + "lastModified": 1735564410, + "narHash": "sha256-HB/FA0+1gpSs8+/boEavrGJH+Eq08/R2wWNph1sM1Dg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1e7a8f391f1a490460760065fa0630b5520f9cf8", "type": "github" }, "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", + "owner": "NixOS", + "ref": "nixpkgs-24.05-darwin", + "repo": "nixpkgs", "type": "github" } }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1738452942, + "narHash": "sha256-vJzFZGaCpnmo7I6i416HaBLpC+hvcURh/BQwROcGIp8=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" + } + }, "nixpkgs-master": { "locked": { - "lastModified": 1761228883, - "narHash": "sha256-8jKkT4Yc8I/PnDczaD9diDcJkckwP7WAstQcYbMSo4s=", + "lastModified": 1764330598, + "narHash": "sha256-tIMoFVAMzjGq3iLiA0hQ+C6CtLkmJEBXuEm0XtwlgtU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "0cfbb4d10f6e813e6e9750fbf5396747cf3b6212", + "rev": "b8ee623e26961c7f34e78248d553fa35e1f8032b", "type": "github" }, "original": { @@ -594,6 +872,22 @@ "type": "github" } }, + "nixpkgs-master_2": { + "locked": { + "lastModified": 1759258560, + "narHash": "sha256-ykJfEwNYol4x+gQdbePWc5tfxwky7aXpM4ZJDyCpK5Y=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "66063074cf41f08c39738b1436f4bdae7fb97265", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "master", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-stable": { "locked": { "lastModified": 1730741070, @@ -610,6 +904,124 @@ "type": "github" } }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1751741127, + "narHash": "sha256-t75Shs76NgxjZSgvvZZ9qOmz5zuBE8buUaYD28BMTxg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "29e290002bfff26af1db6f64d070698019460302", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1759143472, + "narHash": "sha256-TvODmeR2W7yX/JmOCmP+lAFNkTT7hAxYcF3Kz8SZV3w=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5ed4e25ab58fd4c028b59d5611e14ea64de51d23", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1736320768, + "narHash": "sha256-nIYdTAiKIGnFNugbomgBJR+Xv5F1ZQU+HfaBqJKroC0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bc9c909d9ac828a039f288cf872d16d38185db8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1755615617, + "narHash": "sha256-HMwfAJBdrr8wXAkbGhtcby1zGFvs+StOp19xNsbqdOg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "20075955deac2583bb12f07151c2df830ef346b4", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "oldConf": { + "inputs": { + "agenix": "agenix", + "attic": "attic", + "darwin": "darwin_2", + "home-manager": "home-manager_3", + "impermanence": "impermanence_2", + "kmonad": "kmonad_2", + "lix-module": "lix-module", + "miro": "miro", + "nixos-hardware": "nixos-hardware_2", + "nixpkgs": "nixpkgs_2", + "nixpkgs-darwin": "nixpkgs-darwin", + "nixpkgs-master": "nixpkgs-master_2", + "pandoc-latex-template": "pandoc-latex-template", + "quadlet-nix": "quadlet-nix", + "spoons": "spoons", + "synapse": "synapse", + "utils": "utils", + "wired": "wired", + "x": "x", + "xynoblog": "xynoblog", + "zen-browser": "zen-browser" + }, + "locked": { + "lastModified": 1763992843, + "narHash": "sha256-YNaB4sPMqpZ3vacTU2lC4aLydO1WTR13TEjDaHAL1AA=", + "owner": "thexyno", + "repo": "nixos-config", + "rev": "7e226a95925f9d2b91c15652e23bc8cfeb83cba1", + "type": "github" + }, + "original": { + "owner": "thexyno", + "repo": "nixos-config", + "type": "github" + } + }, + "pandoc-latex-template": { + "flake": false, + "locked": { + "lastModified": 1758365407, + "narHash": "sha256-gat4bW9oW5UEcB23s026vmBmxwQE7Eyejgr/qIS7CsM=", + "owner": "Wandmalfarbe", + "repo": "pandoc-latex-template", + "rev": "f99fe1dbda926be29f567196b1edfeb92f96ac10", + "type": "github" + }, + "original": { + "owner": "Wandmalfarbe", + "repo": "pandoc-latex-template", + "type": "github" + } + }, "pre-commit-hooks-nix": { "inputs": { "flake-compat": [ @@ -637,59 +1049,24 @@ "type": "github" } }, - "pyproject-build-systems": { - "inputs": { - "nixpkgs": [ - "authentik", - "nixpkgs" - ], - "pyproject-nix": [ - "authentik", - "pyproject-nix" - ], - "uv2nix": [ - "authentik", - "uv2nix" - ] - }, + "quadlet-nix": { "locked": { - "lastModified": 1757296493, - "narHash": "sha256-6nzSZl28IwH2Vx8YSmd3t6TREHpDbKlDPK+dq1LKIZQ=", - "owner": "pyproject-nix", - "repo": "build-system-pkgs", - "rev": "5b8e37fe0077db5c1df3a5ee90a651345f085d38", + "lastModified": 1758631655, + "narHash": "sha256-EGeZ963L7xsNAY7snvP1JHQe7LWLVCM6f49+PzWjhEE=", + "owner": "SEIAROTg", + "repo": "quadlet-nix", + "rev": "2ebe01b175e2e1e6de3f172d23f0c3b88713eec9", "type": "github" }, "original": { - "owner": "pyproject-nix", - "repo": "build-system-pkgs", - "type": "github" - } - }, - "pyproject-nix": { - "inputs": { - "nixpkgs": [ - "authentik", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1757246327, - "narHash": "sha256-6pNlGhwOIMfhe/RLjHdpXveKS4FyLHvlGe+KtjDild4=", - "owner": "pyproject-nix", - "repo": "pyproject.nix", - "rev": "8d77f342d66ad1601cdb9d97e9388b69f64d4c8e", - "type": "github" - }, - "original": { - "owner": "pyproject-nix", - "repo": "pyproject.nix", + "owner": "SEIAROTg", + "repo": "quadlet-nix", "type": "github" } }, "root": { "inputs": { - "authentik": "authentik", + "adw-colors": "adw-colors", "colmena": "colmena", "helix": "helix", "home-manager": "home-manager", @@ -705,10 +1082,11 @@ "nixos-hardware": "nixos-hardware", "nixpkgs": "nixpkgs", "nixpkgs-master": "nixpkgs-master", + "oldConf": "oldConf", + "rust-overlay": "rust-overlay_5", "sops-nix": "sops-nix", - "terranix": "terranix", "xwayland-satellite": "xwayland-satellite", - "zen-browser": "zen-browser" + "zen-browser": "zen-browser_2" } }, "rust-overlay": { @@ -733,27 +1111,6 @@ } }, "rust-overlay_2": { - "inputs": { - "nixpkgs": [ - "lanzaboote", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1731897198, - "narHash": "sha256-Ou7vLETSKwmE/HRQz4cImXXJBr/k9gp4J4z/PF8LzTE=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "0be641045af6d8666c11c2c40e45ffc9667839b5", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "rust-overlay_3": { "inputs": { "nixpkgs": [ "niri", @@ -774,7 +1131,7 @@ "type": "github" } }, - "rust-overlay_4": { + "rust-overlay_3": { "inputs": { "nixpkgs": [ "nix-ci", @@ -795,7 +1152,45 @@ "type": "github" } }, + "rust-overlay_4": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1740709839, + "narHash": "sha256-4dF++MXIXna/AwlZWDKr7bgUmY4xoEwvkF1GewjNrt0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "b4270835bf43c6f80285adac6f66a26d83f0f277", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "rust-overlay_5": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1764297505, + "narHash": "sha256-qrLpVu2/hA9Cu6IovMEsgh9YRyvmmWS+bSx7C1JGChA=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "9623580f8ce09ec444b9aca107566ec5db110e62", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_6": { "inputs": { "nixpkgs": [ "xwayland-satellite", @@ -823,11 +1218,11 @@ ] }, "locked": { - "lastModified": 1760998189, - "narHash": "sha256-ee2e1/AeGL5X8oy/HXsZQvZnae6XfEVdstGopKucYLY=", + "lastModified": 1764021963, + "narHash": "sha256-1m84V2ROwNEbqeS9t37/mkry23GBhfMt8qb6aHHmjuc=", "owner": "Mic92", "repo": "sops-nix", - "rev": "5a7d18b5c55642df5c432aadb757140edfeb70b3", + "rev": "c482a1c1bbe030be6688ed7dc84f7213f304f1ec", "type": "github" }, "original": { @@ -836,6 +1231,22 @@ "type": "github" } }, + "spoons": { + "flake": false, + "locked": { + "lastModified": 1747090751, + "narHash": "sha256-ZRSRb2QW8hrTkdCg5xezF09DntPocE842rc4ZKt7aHY=", + "owner": "Hammerspoon", + "repo": "Spoons", + "rev": "e5b871250346c3fe93bac0d431fc75f6f0e2f92a", + "type": "github" + }, + "original": { + "owner": "Hammerspoon", + "repo": "Spoons", + "type": "github" + } + }, "stable": { "locked": { "lastModified": 1669735802, @@ -852,18 +1263,35 @@ "type": "github" } }, + "synapse": { + "flake": false, + "locked": { + "lastModified": 1754934810, + "narHash": "sha256-4HAA9Xq4C3DHxz0BgqBitfM4wZwPSEu+IO/OPfHzLVw=", + "owner": "element-hq", + "repo": "synapse", + "rev": "4054d956f75056ace9edc729ee488edcbf00d1a2", + "type": "github" + }, + "original": { + "owner": "element-hq", + "repo": "synapse", + "rev": "4054d956f75056ace9edc729ee488edcbf00d1a2", + "type": "github" + } + }, "systems": { "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", "type": "github" }, "original": { "owner": "nix-systems", - "repo": "default-linux", + "repo": "default", "type": "github" } }, @@ -897,50 +1325,80 @@ "type": "github" } }, - "terranix": { - "inputs": { - "flake-parts": "flake-parts_3", - "nixpkgs": [ - "nixpkgs" - ], - "systems": "systems_2" - }, + "systems_4": { "locked": { - "lastModified": 1757278723, - "narHash": "sha256-hTMi6oGU+6VRnW9SZZ+muFcbfMEf2ajjOp7Z2KM5MMY=", - "owner": "terranix", - "repo": "terranix", - "rev": "924573fa6587ac57b0d15037fbd2d3f0fcdf17fb", + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", "type": "github" }, "original": { - "owner": "terranix", - "repo": "terranix", + "owner": "nix-systems", + "repo": "default", "type": "github" } }, - "uv2nix": { + "utils": { "inputs": { - "nixpkgs": [ - "authentik", - "nixpkgs" - ], - "pyproject-nix": [ - "authentik", - "pyproject-nix" - ] + "systems": "systems_3" }, "locked": { - "lastModified": 1757925761, - "narHash": "sha256-7Hwz0vfHuFqCo5v7Q07GQgLBWuPvZCuf/5/pk4NoADg=", - "owner": "pyproject-nix", - "repo": "uv2nix", - "rev": "780494c40895bb7419a73d942bee326291e80b3b", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { - "owner": "pyproject-nix", - "repo": "uv2nix", + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "wired": { + "inputs": { + "flake-parts": "flake-parts_3", + "nixpkgs": [ + "oldConf", + "nixpkgs" + ], + "rust-overlay": "rust-overlay_4" + }, + "locked": { + "lastModified": 1743305055, + "narHash": "sha256-NIsi8Dno9YsOLUUTrLU4p+hxYeJr3Vkg1gIpQKVTaDs=", + "owner": "Toqozz", + "repo": "wired-notify", + "rev": "75d43f54a02b15f2a15f5c1a0e1c7d15100067a6", + "type": "github" + }, + "original": { + "owner": "Toqozz", + "repo": "wired-notify", + "type": "github" + } + }, + "x": { + "inputs": { + "nixpkgs": [ + "oldConf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1680879729, + "narHash": "sha256-ItGaOeb0wt8ESKTJxPkFVbV8cyR/0RhSFVltelLQ9b4=", + "owner": "thexyno", + "repo": "x", + "rev": "5b15dd8e511c9cd39c7dbfa583e2c85ff30afecb", + "type": "github" + }, + "original": { + "owner": "thexyno", + "repo": "x", "type": "github" } }, @@ -950,14 +1408,14 @@ "nixpkgs": [ "nixpkgs-master" ], - "rust-overlay": "rust-overlay_5" + "rust-overlay": "rust-overlay_6" }, "locked": { - "lastModified": 1761173223, - "narHash": "sha256-FumZh+fPRaKXkl9Y1uTh5KV7Io/AyOZso+UkqLhLArs=", + "lastModified": 1764304415, + "narHash": "sha256-KBSPRgS7SC/U2t0GSuEojwAIEgl4HTK2I0M4558PQwo=", "owner": "Supreeeme", "repo": "xwayland-satellite", - "rev": "bf745144acda1343934e9a094cf9458a54d57889", + "rev": "5d23452874f6d0b8fabfcd69b84098ea6ef31352", "type": "github" }, "original": { @@ -966,19 +1424,59 @@ "type": "github" } }, + "xynoblog": { + "inputs": { + "nixpkgs": [ + "oldConf", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1732833558, + "narHash": "sha256-KpAsXBkNJTNBHQuwqJkMSCsVWhbj9K7LLY7emgU6f4Q=", + "owner": "thexyno", + "repo": "blog", + "rev": "b020543dcb823c7be01a7aca9f1748a517ece659", + "type": "github" + }, + "original": { + "owner": "thexyno", + "repo": "blog", + "type": "github" + } + }, "zen-browser": { "inputs": { - "home-manager": "home-manager_2", + "home-manager": "home-manager_4", + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1759203282, + "narHash": "sha256-lsKz9cA0VpHsSbOXZcg8V2fGmUSvC183Fmmn++WAG5o=", + "owner": "0xc000022070", + "repo": "zen-browser-flake", + "rev": "7c14e901ac9d2d5b994bad90a11dfbf25500c6cb", + "type": "github" + }, + "original": { + "owner": "0xc000022070", + "repo": "zen-browser-flake", + "type": "github" + } + }, + "zen-browser_2": { + "inputs": { + "home-manager": "home-manager_5", "nixpkgs": [ "nixpkgs-master" ] }, "locked": { - "lastModified": 1761180075, - "narHash": "sha256-V4WLeUQ4gCGZiVihlXWBOZ/1FNcL0jM4zgTY1haJLvY=", + "lastModified": 1764217570, + "narHash": "sha256-vgqUC6lI/gW70uekA0bpNFU6yR0tcZRfLIZcxGfN76g=", "owner": "0xc000022070", "repo": "zen-browser-flake", - "rev": "771a2604606905d8c0ffe3b818dc2cc5bd1405d8", + "rev": "3dc281d86044322f9182b20abbc21db8824c130a", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 3f8f6c0a..2e074840 100644 --- a/flake.nix +++ b/flake.nix @@ -15,12 +15,19 @@ colmena.url = "github:zhaofengli/colmena/release-0.4.x"; colmena.inputs.nixpkgs.follows = "nixpkgs"; + + oldConf.url = "github:thexyno/nixos-config"; # software + rust-overlay = { # https://github.com/nix-community/lanzaboote/issues/485#issuecomment-3466684727 + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; lanzaboote = { url = "github:nix-community/lanzaboote/v0.4.2"; # Optional but recommended to limit the size of your system closure. inputs.nixpkgs.follows = "nixpkgs"; + inputs.rust-overlay.follows = "rust-overlay"; }; zen-browser.url = "github:0xc000022070/zen-browser-flake"; @@ -33,10 +40,6 @@ niri.inputs.nixpkgs.follows = "nixpkgs-master"; xwayland-satellite.url = "github:Supreeeme/xwayland-satellite"; xwayland-satellite.inputs.nixpkgs.follows = "nixpkgs-master"; - nheko.url = "github:Nheko-Reborn/nheko"; - nheko.flake = false; - mtxclient.url = "github:Nheko-Reborn/mtxclient"; - mtxclient.flake = false; nix-ci.url = "git+https://git.xyno.systems/xyno/nix-ci"; nix-ci.inputs.nixpkgs.follows = "nixpkgs"; @@ -49,13 +52,23 @@ helix.inputs.nixpkgs.follows = "nixpkgs-master"; # csharp-language-server.url = "github:sofusa/csharp-language-server"; # csharp-language-server.inputs.nixpkgs.follows = "nixpkgs-master"; + - # authentik + # # authentik + + # authentik.url = "github:nix-community/authentik-nix"; + # authentik.inputs.nixpkgs.follows = "nixpkgs"; + # terranix.url = "github:terranix/terranix"; + # terranix.inputs.nixpkgs.follows = "nixpkgs"; + + # non flake inputs, maybe use npins in the future? + adw-colors.url = "github:lassekongo83/adw-colors"; + adw-colors.flake = false; + nheko.url = "github:Nheko-Reborn/nheko"; + nheko.flake = false; + mtxclient.url = "github:Nheko-Reborn/mtxclient"; + mtxclient.flake = false; - authentik.url = "github:nix-community/authentik-nix"; - authentik.inputs.nixpkgs.follows = "nixpkgs"; - terranix.url = "github:terranix/terranix"; - terranix.inputs.nixpkgs.follows = "nixpkgs"; }; @@ -101,7 +114,7 @@ inputs.lanzaboote.nixosModules.lanzaboote inputs.sops-nix.nixosModules.sops inputs.impermanence.nixosModules.impermanence - inputs.authentik.nixosModules.default + # inputs.authentik.nixosModules.default inputs.nix-index-database.nixosModules.nix-index ] ++ (import ./modules/module-list.nix); @@ -113,11 +126,19 @@ importConfigs = n: map (x: { - ${x} = {nodes, ...}: { - networking.hostName = x; - imports = modules ++ [ (./instances/${x}) ]; - _module.args.otherNodes = lib.filterAttrs (n: v: n != x) nodes; - }; + ${x} = + { nodes, pkgs, ... }: + { + nixpkgs.overlays = overlays; + nix.package = pkgs.unstable.lixPackageSets.latest.lix; + networking.hostName = x; + imports = modules ++ [ (./instances/${x}) ]; + _module.args.otherNodes = lib.filterAttrs (n: v: n != x) nodes; + deployment.privilegeEscalationCommand = [ + "run0" + "--unit=colmena-apply" + ]; + }; }) n; in lib.foldl' lib.recursiveUpdate { } ( @@ -130,13 +151,9 @@ specialArgs = { inherit inputs; }; nixpkgs = genPkgs "x86_64-linux"; }; - deployment.privilegeEscalationCommand = [ - "run0" - "--unit=colmena-apply" - ]; } (importConfigs [ - "ds9" + "nemesis" "picard" "theseus" ]) @@ -178,6 +195,7 @@ devShells.${system}.default = pkgs.mkShell { packages = [ pkgs.nixfmt-rfc-style + pkgs.nixd pkgs.nil pkgs.sops (pkgs.runCommand "nix-config-bin" { } '' @@ -187,7 +205,7 @@ pkgs.colmena ] ++ (lib.attrValues self.packages.${system}); - SOPS_CONFIG = (pkgs.callPackage ./sops.nix { instanceConfigs = lib.xyno.getDirs ./instances; }); + SOPS_CONFIG = (pkgs.callPackage ./sops.nix { instanceConfigs = self.colmenaHive.nodes; }); }; diff --git a/hm-modules/dark-theme.nix b/hm-modules/dark-theme.nix index de020bd2..880bdf86 100644 --- a/hm-modules/dark-theme.nix +++ b/hm-modules/dark-theme.nix @@ -23,10 +23,10 @@ in gtk4.extraConfig.gtk-application-prefer-dark-theme = 1; gtk3.extraConfig.gtk-application-prefer-dark-theme = 1; }; - qt = { - enable = true; - style.name = "breeze"; - }; + # qt = { + # enable = true; + # style.name = "breeze"; + # }; }; } diff --git a/hm-modules/firefox.nix b/hm-modules/firefox.nix index a930af34..6fc04d5b 100644 --- a/hm-modules/firefox.nix +++ b/hm-modules/firefox.nix @@ -362,7 +362,7 @@ in "user-filters" = ''marketplace.visualstudio.com##+js(rpnt, script, /"(DisableVSCodeDownloadButtonEnabled|Microsoft\\.VisualStudio\\.Services\\.Gallery\\.DisableVSCodeDownloadButton)":true/, "$1":false)''; "hostnameSwitchesString" = - "no-large-media: behind-the-scene false\nno-remote-fonts: * true\nno-csp-reports: * true"; + "no-large-media: behind-the-scene false\nno-remote-fonts: * false\nno-csp-reports: * true"; }; }; diff --git a/hm-modules/git.nix b/hm-modules/git.nix index bf999b94..41076a40 100644 --- a/hm-modules/git.nix +++ b/hm-modules/git.nix @@ -9,13 +9,14 @@ in { options.xyno.git.enable = lib.mkEnableOption "xynos git config"; config = lib.mkIf cfg.enable { + programs.difftastic.git.enable = true; + programs.difftastic.enable = true; programs.git = { enable = true; - difftastic.enable = true; lfs.enable = true; # Default configs - extraConfig = { + settings = { commit.gpgSign = true; gpg.format = "ssh"; diff --git a/hm-modules/helix.nix b/hm-modules/helix.nix index a123f96a..13a3ca50 100644 --- a/hm-modules/helix.nix +++ b/hm-modules/helix.nix @@ -22,20 +22,21 @@ in # nodePackages_latest.prettier dprint markdown-oxide - codebook + # codebook ## python # ruff-lsp # nodePackages_latest.pyright # inputs.csharp-language-server.packages.${pkgs.system}.csharp-language-server ] ++ (optionals cfg.withLargeLSPs [ - netcoredbg nodePackages_latest.typescript-language-server nodePackages_latest.vscode-langservers-extracted typescript # jsonnet-language-server # jsonnet lazygit + ltex-ls-plus # languagetool + tinymist # typst lsp ]); programs.helix = { @@ -107,8 +108,7 @@ in keys = { normal = { space."=" = ":fmt"; - "C-g" = - ":sh tmux popup -d \"#{pane_current_path}\" -xC -yC -w80%% -h80%% -E lazygit"; + "C-g" = ":sh tmux popup -d \"#{pane_current_path}\" -xC -yC -w80%% -h80%% -E lazygit"; "C-t" = ":sh tmux split-window -v -l '35%%'"; "C-h" = ":sh tmux select-pane -t '{left-of}'"; "C-l" = ":sh tmux select-pane -t '{right-of}'"; @@ -143,55 +143,143 @@ in language-server.csharp = { command = "csharp-language-server"; }; - language-server.codebook = { - command = "codebook-lsp"; - args = ["serve"]; - }; - language = flatten [ - (map - (x: { - name = x; - language-servers = [ - "typescript-language-server" - "eslint" - ]; - #formatter = { command = "dprint"; args = [ "fmt" "--stdin" x ]; }; - # formatter = { command = "prettier"; args = [ "--parser" "typescript" ]; }; - }) - [ - "typescript" - "javascript" - "jsx" - "tsx" - ] - ) - { - name = "nix"; - formatter = { - command = "nixpkgs-fmt"; - }; - } - { - name = "python"; - language-servers = [ - "pyright" - "ruff" + language-server.ltex = { + command = "ltex-ls-plus"; + config = { + additionalRules.motherTongue = "de-DE"; + additionalRules.enablePickyRules = true; + language = [ + "en-US" + "de-DE" ]; - } - { - name = "markdown"; - language-servers = ["codebook"]; - } - { - name = "c-sharp"; - language-servers = [ "csharp" ]; - formatter = { - command = "dotnet"; - args = [ "csharpier" ]; - }; + }; + }; + language-server.tinymist = { + command = "tinymist"; + }; + # language-server.nil = { + # command = "nil"; + # config.nil.nix = { + # maxMemoryMB = 5120; + # flake = { + # autoEvalInputs = true; + # autoArchive = true; + # }; + # }; + # }; + language = + let + applySingleConfig = + languages: config: + let + applied = + foldl' + ( + acc: l: + if (any (x: l.name == x) config.languages) then + { + done = acc.done ++ [ + (mkMerge [ + l + config.conf + ]) + ]; + notFound = filter (x: x != l.name) acc.notFound; + } + else + { + done = acc.done ++ [ l ]; + notFound = acc.notFound; + } + ) + { + done = [ ]; + notFound = config.languages; + } + languages; + in + applied.done ++ (map (x: { name = x; } // config.conf) applied.notFound); + applyConfs = lspConfs: languages: foldl' applySingleConfig languages lspConfs; + in + applyConfs + [ + { + languages = [ + "typescript" + "javascript" + "jsx" + "tsx" + ]; + conf = { + language-servers = [ + "typescript-language-server" + "eslint" + ]; + }; + } + { + languages = [ + "markdown" + "typst" + "bibtex" + "comment" + "latex" + "html" + ]; + conf = { + language-servers = [ + "ltex" + ]; + }; + } + ] + [ + { + name = "__common__"; + scope = "source.__common__"; + file-types = [ ]; + language-servers = [ + "ltex" + ]; + } + # { + # name = "nix"; + # language-servers = [ + # "nixd" + # ]; + # formatter = { + # command = "nixpkgs-fmt"; + # }; + # } + { + name = "python"; + language-servers = [ + "pyright" + "ruff" + ]; + } + { + name = "markdown"; + language-servers = [ + "markdown-oxide" + ]; + } + { + name = "typst"; + language-servers = [ + "tinymist" + ]; + } + { + name = "c-sharp"; + language-servers = [ "csharp" ]; + formatter = { + command = "dotnet"; + args = [ "csharpier" ]; + }; - } - ]; + } + ]; }; }; }; diff --git a/hm-modules/mpv.nix b/hm-modules/mpv.nix index 852657d7..7f37504b 100644 --- a/hm-modules/mpv.nix +++ b/hm-modules/mpv.nix @@ -14,6 +14,11 @@ in programs.mpv = { enable = true; scripts = with pkgs.mpvScripts; [ mpv-webm sponsorblock ]; + config = { + profile = "gpu-hq"; + ytdl-format = "bestvideo[width<=1920]+bestaudio"; + cache-secs = 1200; + }; }; }; diff --git a/instances/ds9/configuration.nix b/instances/ds9/configuration.nix deleted file mode 100644 index 8f640680..00000000 --- a/instances/ds9/configuration.nix +++ /dev/null @@ -1,36 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: -{ - nixpkgs.system = "x86_64-linux"; - imports = [ - ./hardware-configuration.nix - ./services/attic.nix - ./services/immich.nix - ./services/jellyfin.nix - ./services/paperless.nix - ./services/ytdl-sub.nix - - ]; - time.timeZone = "Europe/Berlin"; - - networking.hostId = "7b4c2932"; - - xyno.presets.cli.enable = true; - xyno.presets.server.enable = true; - xyno.services.wireguard.enable = true; - xyno.services.caddy.enable = true; - xyno.services.monitoring.enable = true; - xyno.services.authentik.enable = true; - xyno.presets.home-manager.enable = true; - xyno.system.user.enable = true; - xyno.networking.networkd = { - enable = true; - }; - - - system.stateVersion = "24.11"; -} diff --git a/instances/ds9/default.nix b/instances/ds9/default.nix deleted file mode 100644 index a324215e..00000000 --- a/instances/ds9/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - imports = [ ./configuration.nix ]; - xyno.services.monitoring.prometheusServer = true; - xyno.meta = { - sopsKey = "fada7e7be28e186e463ad745a38d17f36849d8a7"; - }; - xyno.services.wireguard.pubKey = "aZvSeAhKG3B5I2My5IqQoSlntMzbCHM6OU92WEScohc="; - deployment = { - targetHost = "ds9.hailsatan.eu"; - }; -} diff --git a/instances/ds9/hardware-configuration.nix b/instances/ds9/hardware-configuration.nix deleted file mode 100644 index 338b716d..00000000 --- a/instances/ds9/hardware-configuration.nix +++ /dev/null @@ -1,59 +0,0 @@ -# Do not modify this file! It was generated by ‘nixos-generate-config’ -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. -{ config, lib, pkgs, modulesPath, ... }: - -{ - imports = [ "${modulesPath}/installer/scan/not-detected.nix" ]; - - boot.lanzaboote = { - enable = true; - pkiBundle = "/var/lib/sbctl"; - }; - boot.loader.systemd-boot.enable = lib.mkForce false; - - - - boot.initrd.availableKernelModules = [ "r8169" "ahci" "vfio-pci" "xhci_pci" "ehci_pci" "nvme" "usbhid" "sd_mod" "sr_mod" ]; - boot.kernelModules = [ "kvm-amd" ]; - nix.settings.max-jobs = lib.mkDefault 12; - powerManagement.powertop.enable = true; - powerManagement.cpuFreqGovernor = "powersave"; - powerManagement.scsiLinkPolicy = "min_power"; - - services.zfs.autoScrub.enable = true; - - services.sanoid.datasets."rpool/content/safe/data/media" = { }; - services.sanoid.enable = true; - services.sanoid.interval = "0/8:00:00"; - - swapDevices = [{ device = "/dev/disk/by-id/nvme-eui.000000000000000100a075202c247839-part1"; randomEncryption = true; }]; - fileSystems."/boot".device = "/dev/disk/by-uuid/149F-23AA"; - - - fileSystems."/" = { - device = "spool/safe/persist"; - fsType = "zfs"; - }; - fileSystems."/nix" = { - device = "spool/local/nix"; - fsType = "zfs"; - }; - fileSystems."/var/log" = { - device = "spool/local/journal"; - fsType = "zfs"; - }; - fileSystems."/data" = { - device = "rpool/content/safe/data"; - fsType = "zfs"; - }; - fileSystems."/data/media" = { - device = "rpool/content/safe/data/media"; - fsType = "zfs"; - }; - fileSystems."/backups" = { - device = "rpool/content/local/backups"; - fsType = "zfs"; - }; - -} diff --git a/instances/nemesis/configuration.nix b/instances/nemesis/configuration.nix new file mode 100644 index 00000000..72217765 --- /dev/null +++ b/instances/nemesis/configuration.nix @@ -0,0 +1,131 @@ +{ + config, + pkgs, + lib, + inputs, + ... +}: +{ + nixpkgs.system = "x86_64-linux"; + imports = [ + ./hardware-configuration.nix + ./services/traccar.nix + ./services/navidrome.nix + # ./services/attic.nix + # ./services/immich.nix + # ./services/jellyfin.nix + # ./services/paperless.nix + # ./services/ytdl-sub.nix + + ]; + time.timeZone = "Europe/Berlin"; + networking.hostId = "7b4c2932"; + + containers.ds9 = { + autoStart = true; + timeoutStartSec = "10000000min"; + privateNetwork = true; + enableTun = true; + additionalCapabilities = [ + "CAP_NET_ADMIN" + "CAP_MKNOD" + "CAP_BPF" + "CAP_DAC_READ_SEARCH" + "CAP_SYS_RESOURCE" + "CAP_SYS_ADMIN" + ]; + hostAddress = "192.168.100.10"; + localAddress = "192.168.100.11"; + # hostAddress6 = "fc00::1"; + # localAddress6 = "fc00::2"; + + path = inputs.oldConf.nixosConfigurations.ds9.config.system.build.toplevel; + + bindMounts = { + "/data" = { + hostPath = "/data"; + isReadOnly = false; + }; + "/backups" = { + hostPath = "/backups"; + isReadOnly = false; + }; + "/persistent" = { + hostPath = "/oldds9/persistent"; + isReadOnly = false; + }; + "/var/lib/containers" = { + hostPath = "/oldds9/persistent/var/lib/containers"; + isReadOnly = false; + }; + }; + }; + networking.nat.enable = true; + networking.nat.enableIPv6 = true; + networking.nat.internalInterfaces = [ "ve-+" ]; + networking.nat.externalInterface = "enp1s0f1"; # TODO: changeme + + services.traefik.staticConfigOptions.entryPoints.websecure.proxyProtocol.trustedIPs = ["10.0.0.1"]; + services.traefik.dynamicConfigOptions.http.routers.simpleproxy-oldds9-router.rule = + lib.mkForce "HostRegexp(`^.+\.hailsatan\.eu$`)"; + # services.traefik.dynamicConfigOptions.http.routers.simpleproxy-oldds9-router.tls.options = "old"; + services.traefik.dynamicConfigOptions.http.routers.simpleproxy-oldds9-router-robotstxt.rule = + lib.mkForce "HostRegexp(`^.+\.hailsatan\.eu$`) && Path(`/robots.txt`)"; + xyno.services.traefik = { + enable = true; + simpleProxy.oldds9 = { + host = "*.hailsatan.eu"; + internal = "http://192.168.100.11"; + }; + }; + + users.users.root.password = "hunter2"; + + systemd.services."dyndns-refresh" = { + script = '' + set -eu + export PATH=$PATH:${pkgs.curl}/bin:${pkgs.jq}/bin:${pkgs.iproute2}/bin + ${pkgs.bash}/bin/bash ${config.sops.secrets.dyndns.path} + ''; + serviceConfig = { + Type = "oneshot"; + User = "root"; + }; + startAt = "*:0/10"; + }; + sops.secrets.dyndns = { + sopsFile = ./secrets/dyndns.yaml; + }; + + xyno.services.kanidm = { + enable = true; + setupTraefik = true; + }; + xyno.services.oauth2Proxy.enable = true; + xyno.services.postgres.enable = true; + + xyno.presets.cli.enable = true; + xyno.presets.server.enable = true; + xyno.impermanence.enable = true; + # xyno.services.wireguard.enable = true; + # xyno.services.caddy.enable = true; + # xyno.services.monitoring.enable = true; + # xyno.services.authentik.enable = true; + xyno.presets.home-manager.enable = true; + xyno.system.user.enable = true; + xyno.networking.networkd = { + enable = true; + }; + networking.useDHCP = lib.mkForce false; + networking.interfaces."enp1s0f1" = { + useDHCP = true; + tempAddress = "enabled"; + }; + systemd.network.networks."40-enp1s0f1" = { + networkConfig = { + IPv6AcceptRA = true; + }; + }; + + system.stateVersion = "25.11"; +} diff --git a/instances/nemesis/default.nix b/instances/nemesis/default.nix new file mode 100644 index 00000000..25b8ed78 --- /dev/null +++ b/instances/nemesis/default.nix @@ -0,0 +1,11 @@ +{ + imports = [ ./configuration.nix ]; + # xyno.services.monitoring.prometheusServer = true; + xyno.meta = { + sopsKey = "fada7e7be28e186e463ad745a38d17f36849d8a7"; + }; + # xyno.services.wireguard.pubKey = "aZvSeAhKG3B5I2My5IqQoSlntMzbCHM6OU92WEScohc="; + deployment = { + targetHost = "nemesis.xyno.systems"; + }; +} diff --git a/instances/nemesis/hardware-configuration.nix b/instances/nemesis/hardware-configuration.nix new file mode 100644 index 00000000..89b00b5d --- /dev/null +++ b/instances/nemesis/hardware-configuration.nix @@ -0,0 +1,150 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: + +{ + imports = [ "${modulesPath}/installer/scan/not-detected.nix" ]; + + # boot.lanzaboote = { + # enable = true; + # pkiBundle = "/var/lib/sbctl"; + # }; + # boot.loader.systemd-boot.enable = lib.mkForce false; + boot.loader.systemd-boot.enable = true; + + boot.initrd.availableKernelModules = [ + "r8169" + "ahci" + "vfio-pci" + "xhci_pci" + "ehci_pci" + "nvme" + "usbhid" + "sd_mod" + "sr_mod" + ]; + boot.kernelModules = [ "kvm-amd" ]; + nix.settings.max-jobs = lib.mkDefault 12; + powerManagement.powertop.enable = true; + powerManagement.cpuFreqGovernor = "powersave"; + powerManagement.scsiLinkPolicy = "min_power"; + + services.zfs.autoScrub.enable = true; + + services.sanoid.datasets."rpool/content/safe/data/media" = { }; + services.sanoid.datasets."rpool/content/safe/data" = { }; + services.sanoid.datasets."spool/nemesis/persistent" = { }; + services.sanoid.enable = true; + services.sanoid.interval = "0/8:00:00"; + + # boot.initrd.systemd = { + # enable = true; + # }; + boot.initrd.network = { + enable = true; + postCommands = '' + zpool import rpool + zpool import spool + echo "zfs load-key -a; killall zfs" >> /root/.profile + ''; + ssh = { + enable = true; + port = 2222; + hostKeys = [ + "/persistent/initrd/ssh_host_rsa_key" + "/persistent/initrd/ssh_host_ed25519_key" + ]; + authorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID/oMAi5jyQsNohfhcSH2ItisTpBGB0WtYTVxJYKKqhj" # TODO + ]; + + }; + + }; + + # swapDevices = [ + # { + # device = "/dev/disk/by-id/nvme-eui.000000000000000100a075202c247839-part1"; + # randomEncryption = true; + # } + # ]; + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/149F-23AA"; + fsType = "vfat"; + options = [ + "noauto" + "x-systemd.automount" + ]; + }; + + zramSwap.enable = true; + zramSwap.writebackDevice = "/dev/zvol/spool/nemesis/zswap"; + + fileSystems."/persistent/var/lib/postgresql" = { + # has things of https://wiki.archlinux.org/title/ZFS#Databases set + device = "spool/nemesis/postgres"; + fsType = "zfs"; + neededForBoot = true; + }; + fileSystems."/persistent" = { + device = "spool/nemesis/persistent"; + fsType = "zfs"; + neededForBoot = true; + }; + fileSystems."/var/log" = lib.mkForce { + device = "spool/nemesis/varlog"; + fsType = "zfs"; + neededForBoot = true; + }; + fileSystems."/nix" = { + device = "spool/local/nix"; + fsType = "zfs"; + neededForBoot = true; + }; + + fileSystems."/data" = { + device = "rpool/content/safe/data"; + fsType = "zfs"; + neededForBoot = true; + }; + fileSystems."/data/media" = { + device = "rpool/content/safe/data/media"; + fsType = "zfs"; + neededForBoot = true; + }; + fileSystems."/backups" = { + device = "rpool/content/local/backups"; + fsType = "zfs"; + neededForBoot = true; + }; + + fileSystems."/oldds9/persistent" = { + device = "spool/safe/persist"; + fsType = "zfs"; + neededForBoot = true; + }; + fileSystems."/oldds9/persistent/var/lib/containers" = { + device = "spool/safe/containers"; + fsType = "zfs"; + neededForBoot = true; + }; + fileSystems."/oldds9/varlog" = { + device = "spool/local/journal"; + fsType = "zfs"; + neededForBoot = true; + }; + fileSystems."/" = { + device = "none"; + fsType = "tmpfs"; + options = [ "size=8G" ]; + neededForBoot = true; + }; + +} diff --git a/instances/ds9/secrets/atticd.yaml b/instances/nemesis/secrets/atticd.yaml similarity index 100% rename from instances/ds9/secrets/atticd.yaml rename to instances/nemesis/secrets/atticd.yaml diff --git a/instances/ds9/secrets/authentik.yaml b/instances/nemesis/secrets/authentik.yaml similarity index 100% rename from instances/ds9/secrets/authentik.yaml rename to instances/nemesis/secrets/authentik.yaml diff --git a/instances/nemesis/secrets/dyndns.yaml b/instances/nemesis/secrets/dyndns.yaml new file mode 100644 index 00000000..824a4121 --- /dev/null +++ b/instances/nemesis/secrets/dyndns.yaml @@ -0,0 +1,56 @@ +dyndns: ENC[AES256_GCM,data:E+yFHhfpyB3kFb59Nokjr4kIBpgRVZPLZzpHjwp9Ixd9b4rr8Fky0yz4b+/5MlXsSKsR4zfhUi/4yudeYVrSwMWeLibKHeAtoWYTlnEjhBn30wvlEA08M3zmvfMRvGB0Ur2bmax5OzCQbh2v0NKB+4mrIN9SVhBIR89Y5DLm7sd7KIJJxTruo2d+ODphAzFFNtuuyg4s3iq2+Y5H/zwrpgT4Td39h1ys+hfk4ght/OAseTZfda4qCdHhT0S4+aoCkhiyPUxr80KtuHhmt6UvpsazSDJmZyKyVJ3PpYcfS1VfBqAIdNc2enxxquNBRwppd3V8pXjIZKzPRTySFnLpgPIJBhnFkozJm44jaOttoSFrbrF1+7/iL/ssNWpHQvtr0Ke5jS1EPb6k0MZZnJxhGKUiZWzDL/Xb7FJex8pE5gTTK+24VD13mvIW2qCrtXybTydnid/76SzYpdz407mHgBsQUorA,iv:WGbR31NhtayYfdn89diNlOwWkUOulYmBVs9qqZSNieo=,tag:yvqJ6Ok2i0GC5ZSFYWySsg==,type:str] +sops: + lastmodified: "2025-12-01T18:59:41Z" + mac: ENC[AES256_GCM,data:DGjRJWTAl2q58KDAcCxk30gvsin8C7/yBvw5qt+gGcHgJr4ggdVU1afW2Hn+qkexuSK0vLZP6tPJo6reiwyEAZNREPXnU21DUm83lMybu/zRdLFenA03ffPgJ4V+a6m9Ya/CmJzz/vaUxxtyeqCgynUI24otI/+ta0Hh1LQCbC4=,iv:t7NbX7mMMh2r2b0FLrmssxlFJSd9TTGAb7kjoYeKnzc=,tag:MKvgoxYoOj5TT/EzD8hKzw==,type:str] + pgp: + - created_at: "2025-11-24T13:05:23Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hL4DAAAAAAAAAAASBAMEIEXAYYvAspPhhSKpflgdFds2UrMJYMBl1TyKwMsTxQd/ + Chj1aQqRRdrQ0tF3Mkd13EEDJwU3kgJWrrh8uB5ukU+yYuig5kS5Gl51eW5H+FlD + YFYJFsvJBIqbpNzpI7zitD4OvBZ6UCmwul+X9ibYVZRJjrZ6e4zSPmOk9D4Srecw + Pz9nn6NnUA5PXd627Kt4JFBQ1OiLon/ZMBTKhk/vHuUKdYYJNQleJFnpWCU3lNN2 + 0l4BTf26neMgV1qi34Nb86n3Jk8zqC/pMOgtoN2IrY45kR5lUDqGHTemKHw3JdmO + 9oiuqPnlGJktOxdAk+8jHxDrVwRsth+2f+U0cLkMNGTBcY8g1OPWk65ObwIpZ1rZ + =NWw0 + -----END PGP MESSAGE----- + fp: 0D98D5964AC8BB1CA034CE4EC456133700066642 + - created_at: "2025-11-24T15:13:16Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQGMAwAAAAAAAAAAAQv9EPOBFyrp+Zysk3SaNiYaQl928f0pe84uSO9Fm4VPqKtC + xjov8740j38gvQIXpI2zADMlemLGzftbJPfBarSFVlukYoQkjs0SXQD0ukXsiCw2 + eLpEyOx57BFQMRwiNeh6gSkS6WeHAJNiQj1rY11MvyAsDIup8su5XPEw5DWjr3R0 + JdY029HuF6wqpmtgZnaFn6vmPYWYdtnYsxjqOJSPx+rXbWagiDgYy3DAOc7ltyIs + bZoAsjVwQW/tl3hjWhKFeOSfsd9vdUX1TacKqqNZy4mLeEHZOYANeeLkOb+T1T4r + Cexau6H3xZqc87T4S1ZBpEyWawIJHmIalFDoj466mUMOTJth7LxW7vfAdMpwbl1K + HHbTK7vyYxLeo/e5rw646eVmbyPeFf3gF/IXRWB8qoL4g/atGbbQ+WJ86mLgMDg9 + 9AqgVhSbVLoaWooqjh40tJ53raNm5HsO8ozfrJ9hx7Dq3QmCivpA14Q7UD6Yu1nT + RxY6Ng7ykHGGIx3LacV70lgBoinGEzvbxe2Se7B+FOlEL+zFywRt8yFwqc0SXY6o + qLriyhU2p05gvV45oR3pm9336VtwKu1lsN+Z9guKDZmKSgfIxZ22NulsA7E2zV8Z + MacEdQskbB7J + =zk6P + -----END PGP MESSAGE----- + fp: b730b2bf54eb792a14bfd3e68c14c08894376c5f + - created_at: "2025-11-29T08:16:39Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQGMAwAAAAAAAAAAAQv+OaIQywQwV7AS4gi4GjVHFVyhk7Wd3/5fLlMt9UeB56gt + l5+4VVkIzslwiuu9NF5KfvuXr4OQG3cOnb7KRgU5UEUEQtaDrMLFO/TwbBzVTC40 + YNHOya0Ow3MRcEegnM3ox5vL4nHLQwevL0jY8TUxa1xfcTvSj8qOQ9zzzkxzR3L6 + XvD6+dL9pHh1gtU6vlmPIm1PLsWalp0LJAOij3FQdzaxWpDRc0U+Wwr4lt5LiYS2 + jOFc5OZFeIOqMfzul5GCy933eu+V+Ch8PXa5/6PtWxFHx5bvF2pclubguRLziux1 + koeCxBpK3coHT1NX5AEmbtCEieFY9bMy6JTiih4I8eM2nkPjWyqByGh2mFuzjf4V + OBGyHUZHK+KpDkRkwSS/6GqX3n89KMsf6aZwM35CkBvdG3PamyO8eVmE36OTGe4g + 1oj12rIjIj4dKtQ68vRgexvlH1Qq3GBHfsJRF5lRi4dKtPPLjU2P1fJWFcjszIEe + q2QEcpDbCPYelI7mhwzT0lgBND6Yxso3tpW/Il/uRKao/9H+DgIYaIIRBml/cqaq + VqDnFIYodxuW73R8n5GlfctY+gya9ZiGlK5uJwlghRE8gCVUjFrDnFS+uiVC6QI6 + SepzVJKOMUB8 + =7yY4 + -----END PGP MESSAGE----- + fp: fada7e7be28e186e463ad745a38d17f36849d8a7 + unencrypted_suffix: _unencrypted + version: 3.11.0 diff --git a/instances/nemesis/secrets/kanidm.yaml b/instances/nemesis/secrets/kanidm.yaml new file mode 100644 index 00000000..ed564412 --- /dev/null +++ b/instances/nemesis/secrets/kanidm.yaml @@ -0,0 +1,80 @@ +oauth2Proxy: + cookieSecret: ENC[AES256_GCM,data:CA6VBdPT3tuit4eWfBi1ycau4kErwAMfLwJ0maYr+/8Th8q51ZFHaWOcCA8=,iv:HSWCUEgVTkB9tKfzZWXUzH/sCoVZztzwbr1ZUwZBLBs=,tag:qOdClvQl2Cgn3lHXXA/o1Q==,type:str] +kanidm: + adminPassword: ENC[AES256_GCM,data:JQHTQHwXKMgbc0SRdkhMjKjZBznuIbHdcR4TXsmikKWX+5T4VOSqo4CwlXj0XQSV,iv:ruCMDfPlwcAUXdRypB0lNSH1UuV9ryS4vLSleVHnWwc=,tag:V4phitbR0tk6jUrdyFlZWQ==,type:str] + idmAdminPassword: ENC[AES256_GCM,data:D128I5u5pTP6xgSiP+EIZWJmbkXDfHHLh7Bw8wAiMxYPpjGG3EDsdG+8CwOUP8jZ,iv:5h/UZ7BHviKYIY0zpTo/seFHvMcGucDLeey9bc+GDlo=,tag:DSelYBlzIN94K7tOI3QtDA==,type:str] +sops: + lastmodified: "2025-12-03T21:25:56Z" + mac: ENC[AES256_GCM,data:R3cxPrzR5tT0CMNvrtBWDCE8RTvPj9tPslkGhubfOREQBR+qIw7e84uSrswo2+KJkc+AL7CPzVSgsdcSjalNxIqLlL2Gg1y/BKgE6UDB5GDT49+cfCL68hFYkZ+4Cl6bKdLpOuuhsR92NwQk171bx+KCgjE2KUBRFDjOllo+V7M=,iv:LdeRN1jnLNKL3pXVVEQ3BzI3csJSRil5gkQOnxyLi+U=,tag:Ti9Ryuc4kyeuKDwRelQI2A==,type:str] + pgp: + - created_at: "2025-11-29T10:45:57Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hL4DAAAAAAAAAAASBAMEYHWKHKXoJ9J5HDHfY9FhItdcvUdWz57Wl79xKzH94s42 + B7k57At1H6mW3BOrbnDNgNyBs6dHIG1jTA+4yITgIAcn/bl9JRbMOjmDZZzzevJi + 4yQdnm8C6mxQhbUNDpWJ4He6+m7vMZx8uq0S6dq0a5aAE/7ph7Z4gvIbBjZIA6gw + z/GwpL9SyZjSyTW8Z9XPLebonCp1lhD0tsVHk9GKoL46UWlYzq87XSyJOo4AHGAO + 0l4BWq3e7iDmzdxwtCoIC7PKHPmigUielz1qDdCGAIMQsAhaJqOa24gCUW7cklgk + A18EVlSyfeqGaqr//cuGqm8TnrG9cfLtMgnjUv3UQfBWVOh5P8ccKTbl4SUY2BfQ + =JRop + -----END PGP MESSAGE----- + fp: 0D98D5964AC8BB1CA034CE4EC456133700066642 + - created_at: "2025-11-29T10:45:57Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQGMAwAAAAAAAAAAAQv9GuE7hANGXNsAGi3e1oB4c2y9jpvi3RkEifcxBg19yf9n + L9t3Av1Ym2H/Bc5Sw5++qrF7Jy3Aujt1T8ytayxzVsuLesgkuDzjtot0JgUsRSWK + r2dXDoo9gaftX434fGViamHTX2wHBo9VEwqe/c2NjwLeIx/O6u4FwJmUAgzGy1pp + I5TSpYMky4coLbFpDX7AuUuPymI6lGNad6JoeOoTP2gb5Kt2Ycr7ZqzOp2kaPxua + yw5HuoiXLkzxywuWh+IIbqanyN8qxbjvEOS4ZJHegECZhDS27kocwiXhUlcT1NC1 + 1pFW7EJaVMzikSBy06LiPWsYjNmQIR9o8uoeP//XMcq34N0036IxVaOWs8Qnls97 + TJM6lCov4c0XcNrfop15hWNK2gxSzNwxWkmG5PUHwfRi9JGvL6Ng/EHbJS+6F3Nx + z7H2jAIdzc9StMd411SJrZSpDk1wpnecroUWYdO5OIKJu70J5FvNSaKripEECy1x + wBrqY5RLmi/qYsfyCupg0lgBPGUyJbV2XLt1Qcf4eStzy5ZYi8gnn02T0EWvCspf + 0tKMs7hbLm6FwK7vG7Cmc1LQCm73oW09cZCrLurd9JtiRftfww9pBEc85MfPUBIt + PYAWvU26TshG + =vU9m + -----END PGP MESSAGE----- + fp: fada7e7be28e186e463ad745a38d17f36849d8a7 + - created_at: "2025-11-29T10:45:57Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQGMAwAAAAAAAAAAAQwAnX5FoTN8ft2sFXRotgVGt2he9RJMiq0orduWeTXZPLK8 + mvyYOcrQ71fOIm9sIg6hJfabeR2GjBsm09XIXJ71zLl0lWgb8SvcYmbgaJJ+svfY + pPrW+ZninOUZgwkJ8L1gM3ZWOJlx+92NKtdxifIY98SMKacT+aVe7vNTrQVwmRn9 + cZZQd8B75zN7IV99bJCG2BYvSt+p8gZ1vm3GxhowctbSgCl6knHDHJlpXE7SyLHv + ReHjfCFetJQd/XqLL4vZifrlpGKyGPP5pYnEQT5bbsJr9exBeZQ7PsAB0OG+KpOB + r4IvB78XGJlbHTnqlP6GKAKek6NSldlEq5tCsKo5wl3Jg2/SgxSbOhbb5YmOqwcq + S+JJhbfjRGSJMMXLOP9QtLQU5qktwip5g+ZxgKDrcgQvUPUsbV3PEW9l/0WoCf1Q + 7e+mBJ+TRJVOjS9hC1mr/C6kkJJurdpH3PvUSncSk4s0+bkw66nLwmc3QLpI6DV7 + BLJVkOUQzUWaB6k6NVkE0lgBbVYeyaOS3JcoFHrYex6bDHjliD/SH+xjc8wyJR8s + wz5CwfFPqudE9ZYvilJ3lN2AtJrRBaxtR5dgrG2fUx9OB6FSOoRVOpmnFC3YUt6a + FNZYBn5X10t/ + =Mj7y + -----END PGP MESSAGE----- + fp: b730b2bf54eb792a14bfd3e68c14c08894376c5f + - created_at: "2025-11-29T10:45:57Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQIMAwAAAAAAAAAAAQ//a9QFgxhKeW4xcFeERaCiO5nb07wS8BxENBw57RDTp52F + 0kzEdp+HnkVujYMC5cjKlz3x6ZT+CFcVT8HZTwTjlrtCdO/R1OGeO0NcC/tRQNvV + LUgaV9mCzYAbfJG1skdz9EMZZ3W9qPBgKXbX7vGhPirwXyAUUEfQsWon8eOymrd6 + FoapcdLo9ymTnar14WH0kM7B0i4Kqv6+NKquc0OiL8eSufL4wubJrXZZkOdtnXCD + omwFtYmF+IgQAzaCBWLGY3sOW9nD27Y9F1vToOpKQvxE+IT3VGTZN02Xy2J4lhnJ + IE2SmaeY29g2QWIRePCrehpaRNCjlmTS7j7SRT2K9bOVcbiwljUidwkC58323EmC + UlacFRSY5Cfeav2VL188ywh4vihnUpWJoncHKvcUEEeLykbQcdpy2Zwl6u6UB+2g + oDmhk1pFV4ejJlRe1BpLHiBcnA5/OFsWxMGQp57mZ2vyGWYQgtsQZ71JVENq7nSt + TKi6OPhRTZX2Wk8lcZMjm+5XeNrGMSUEYwCPRza+5C0f3LzSfjmmGDLxwaQmCaYI + ZjKSuj14N9VQNJJ8Yxn9uni1acKs+q1XM1b3gJUT2gpFbOjh1BjtAGrat1f4mKk9 + 0PwxBA7cZkdmgJ0t/oNja8ElpOMLMTbI7yYOLY3hD64CtFKWWwpxbD7bK65neRTS + WAE9cEyjhq3TOKNdKaIP5N6a6Sq+98N9xE7/3/lVYncFZ1zV4+9l8Gyjr4rsSSV+ + 68gg9t6FUPIHyNHdrvmqLLQP+paA9RMb7yOMkULB8zBKJrZMXnu+wsI= + =Du56 + -----END PGP MESSAGE----- + fp: 4019fd893bba15618c2f93a38ef418ce360bc418 + unencrypted_suffix: _unencrypted + version: 3.11.0 diff --git a/instances/ds9/secrets/wg.yaml b/instances/nemesis/secrets/wg.yaml similarity index 100% rename from instances/ds9/secrets/wg.yaml rename to instances/nemesis/secrets/wg.yaml diff --git a/instances/ds9/secrets/woodpecker.yaml b/instances/nemesis/secrets/woodpecker.yaml similarity index 100% rename from instances/ds9/secrets/woodpecker.yaml rename to instances/nemesis/secrets/woodpecker.yaml diff --git a/instances/ds9/services/attic.nix b/instances/nemesis/services/attic.nix similarity index 100% rename from instances/ds9/services/attic.nix rename to instances/nemesis/services/attic.nix diff --git a/instances/ds9/services/immich.nix b/instances/nemesis/services/immich.nix similarity index 100% rename from instances/ds9/services/immich.nix rename to instances/nemesis/services/immich.nix diff --git a/instances/ds9/services/jellyfin.nix b/instances/nemesis/services/jellyfin.nix similarity index 100% rename from instances/ds9/services/jellyfin.nix rename to instances/nemesis/services/jellyfin.nix diff --git a/instances/nemesis/services/navidrome.nix b/instances/nemesis/services/navidrome.nix new file mode 100644 index 00000000..769f1db8 --- /dev/null +++ b/instances/nemesis/services/navidrome.nix @@ -0,0 +1,48 @@ +{ + config, + ... +}: +let + host = "music.xyno.systems"; + internalIp = "127.0.0.5"; +in +{ + services.kanidm.provision = { + groups = { + navidrome_users.members = [ "application_admins" ]; + }; + }; + xyno.services.oauth2Proxy.hosts."${host}" = { + allowedGroups = [ "navidrome_users" ]; + }; + xyno.services.traefik.simpleProxy = { + navidrome = { + inherit host; + inherit (config.xyno.services.oauth2Proxy.hosts.${host}) middlewares; + internal = "http://${internalIp}:4533"; + }; + navidrome-subsonic = { + inherit host; + rule = "Host(`${host}`) && PathPrefix(`/rest/`) && !Query(`c`, `NavidromeUI`)"; + internal = "http://${internalIp}:4533"; + }; + }; + + services.navidrome = { + enable = true; + settings = { + Address = internalIp; + MusicFolder = "/data/media/beets/music"; + ReverseProxyWhitelist = "127.0.0.1/32"; + BaseUrl = "https://${host}"; + Prometheus = { + Enabled = false; # TODO + }; + ReverseProxyUserHeader = "X-Auth-Request-Preferred-Username"; + Scanner = { + Schedule = "45 0 * * *"; # daily at 0:45 + }; + }; + }; + xyno.impermanence.directories = [ "/var/lib/navidrome" ]; +} diff --git a/instances/ds9/services/paperless.nix b/instances/nemesis/services/paperless.nix similarity index 100% rename from instances/ds9/services/paperless.nix rename to instances/nemesis/services/paperless.nix diff --git a/instances/nemesis/services/traccar.nix b/instances/nemesis/services/traccar.nix new file mode 100644 index 00000000..43cc14dc --- /dev/null +++ b/instances/nemesis/services/traccar.nix @@ -0,0 +1,93 @@ +{ + pkgs, + lib, + config, + ... +}: +{ + xyno.services.traefik.simpleProxy.traccar = { + host = "track.66642.bot"; + internal = "http://127.0.0.4:8082"; + }; + services.kanidm.provision = { + groups = { + traccar_users.members = [ "traccar_admins" ]; + traccar_admins.members = [ "application_admins" ]; + }; + systems.oauth2.traccar = { + displayName = "Traccar"; + originUrl = "https://track.66642.bot/api/session/openid/callback"; + originLanding = "https://track.66642.bot/login"; + imageFile = "${pkgs.traccar}/web/logo.svg"; + # public = true; + scopeMaps."traccar_users" = [ + "openid" + "profile" + "email" + "groups" + ]; + allowInsecureClientDisablePkce = true; + }; + }; + xyno.services.kanidm.templates."traccar" = { + text = p: '' + OPENID_CLIENT_ID=${p.clientId} + OPENID_CLIENT_SECRET=${p.basicSecret} + DATABASE_URL='jdbc:postgresql://localhost/traccar?socketFactory=org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg&socketFactoryArg=/run/postgresql/.s.PGSQL.5432' + ''; + wantedBy = [ "traccar.service" ]; + }; + systemd.services.traccar.serviceConfig.ExecStart = + lib.mkForce "${pkgs.openjdk}/bin/java -cp './tracker-server.jar:./lib/*:${pkgs.junixsocket-common}/share/java/junixsocket-common-${pkgs.junixsocket-common.version}.jar:${pkgs.junixsocket-native-common}/share/java/junixsocket-native-common-${pkgs.junixsocket-common.version}.jar' org.traccar.Main /var/lib/traccar/config.xml"; # forgive it for what it has done + services.traccar = { + enable = true; + environmentFile = config.xyno.services.kanidm.templates.traccar.path; + settings = { + database.driver = "org.postgresql.Driver"; + database.url = "$DATABASE_URL"; + database.user = "traccar"; + mail.debug = "true"; # log mail content instead of sending email + openid.adminGroup = "traccar_admins@idm.xyno.systems"; + openid.allowGroup = "traccar_users@idm.xyno.systems"; + openid.clientId = "$OPENID_CLIENT_ID"; + openid.clientSecret = "$OPENID_CLIENT_SECRET"; + openid.force = "true"; + openid.issuerUrl = "https://idm.xyno.systems/oauth2/openid/traccar"; + web.address = "127.0.0.4"; + web.url = "https://track.66642.bot"; + }; + }; + systemd.services.postgresql-install-timescale-in-traccar = { + after = [ + "postgresql.service" + "postgresql-setup.service" + ]; + requires = [ + "postgresql.service" + "postgresql-setup.service" + ]; + requiredBy = [ "traccar.service" ]; + + serviceConfig = { + User = "postgres"; + Group = "postgres"; + Type = "oneshot"; + RemainAfterExit = true; + }; + + path = [ config.services.postgresql.finalPackage ]; + environment.PGPORT = builtins.toString config.services.postgresql.settings.port; + script = '' + psql -d traccar -tAc "CREATE EXTENSION IF NOT EXISTS timescaledb;" + ''; + + }; + services.postgresql.settings.shared_preload_libraries = [ "timescaledb" ]; + services.postgresql.ensureDatabases = [ "traccar" ]; + services.postgresql.ensureUsers = [ + { + name = "traccar"; + ensureDBOwnership = true; + } + ]; +} diff --git a/instances/ds9/services/woodpecker.nix b/instances/nemesis/services/woodpecker.nix similarity index 100% rename from instances/ds9/services/woodpecker.nix rename to instances/nemesis/services/woodpecker.nix diff --git a/instances/ds9/services/ytdl-sub.nix b/instances/nemesis/services/ytdl-sub.nix similarity index 100% rename from instances/ds9/services/ytdl-sub.nix rename to instances/nemesis/services/ytdl-sub.nix diff --git a/instances/picard/configuration.nix b/instances/picard/configuration.nix index 384ebf17..80a49f24 100644 --- a/instances/picard/configuration.nix +++ b/instances/picard/configuration.nix @@ -20,7 +20,7 @@ xyno.presets.server.enable = true; xyno.presets.cli.enable = true; xyno.services.wireguard.enable = true; - xyno.services.caddy.enable = true; + # xyno.services.caddy.enable = true; xyno.services.monitoring.enable = true; xyno.presets.home-manager.enable = true; xyno.system.user.enable = true; diff --git a/instances/theseus/configuration.nix b/instances/theseus/configuration.nix index 96d46ee9..be23ba0d 100644 --- a/instances/theseus/configuration.nix +++ b/instances/theseus/configuration.nix @@ -12,6 +12,35 @@ let ''; in { + # containers.podmantest = { + # privateNetwork = true; + # enableTun = true; + # additionalCapabilities = [ + # "CAP_NET_ADMIN" + # "CAP_MKNOD" + # "CAP_BPF" + # "CAP_DAC_READ_SEARCH" + # "CAP_SYS_RESOURCE" + # "CAP_SYS_ADMIN" + # ]; + # hostAddress = "192.168.100.10"; + # localAddress = "192.168.100.11"; + # config = + # { ... }: + # { + # virtualisation.oci-containers.containers.test = { + # image = "docker.io/library/nginx"; + # ports = [ + # "80:80" + # "443:443" + # ]; + # }; + # }; + # }; + # networking.nat.enable = true; + # networking.nat.internalInterfaces = [ "ve-+" ]; + # networking.nat.externalInterface = "enp195s0f4u1u3"; + nixpkgs.system = "x86_64-linux"; imports = [ ./hardware-configuration.nix ]; boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; @@ -48,7 +77,7 @@ in pandoc tectonic rquickshare - supersonic-wayland + unstable.supersonic-wayland nheko anki-bin gimp3 @@ -59,19 +88,21 @@ in ptouch-print hledger + super-productivity ]; environment.variables."LEDGER_FILE" = "~/docs/hledger/main.journal"; time.timeZone = "Europe/Berlin"; - # orcaslicer networking.firewall.allowedTCPPorts = [ 1880 2021 + 4711 ]; networking.firewall.allowedUDPPorts = [ 1880 + 5353 2021 ]; diff --git a/instances/theseus/hardware-configuration.nix b/instances/theseus/hardware-configuration.nix index 8f595bdc..acfbaa6b 100644 --- a/instances/theseus/hardware-configuration.nix +++ b/instances/theseus/hardware-configuration.nix @@ -16,7 +16,7 @@ "${inputs.nixos-hardware}/framework/13-inch/7040-amd" ]; hardware.framework.laptop13.audioEnhancement.enable = true; - # hardware.framework.laptop13.audioEnhancement.hideRawDevice = false; + hardware.framework.laptop13.audioEnhancement.hideRawDevice = false; services.fwupd.enable = true; boot.initrd.availableKernelModules = [ diff --git a/modules/desktop/audio.nix b/modules/desktop/audio.nix index 76cc1351..0d4d61ba 100644 --- a/modules/desktop/audio.nix +++ b/modules/desktop/audio.nix @@ -229,9 +229,39 @@ in ]; }; }; + configPackages = [ + (pkgs.writeTextDir "share/pipewire/pipewire.conf.d/snapcast-discover.conf" '' + context.modules = [ + { + name = libpipewire-module-snapcast-discover + args = { + snapcast.discover-local = true + stream.rules = [ + { + matches = [ + { + snapcast.ip = "~.*" + } + ] + actions = { + create-stream = { + # node.name = "Snapcast" + # snapcast.stream-name = "default" + } + } + } + ] + } + } +] + + '') + + ]; wireplumber.extraConfig."98-bluetooth"."wireplumber.settings"."bluetooth.autoswitch-to-headset-profile" = false; - wireplumber.configPackages = mapAttrsToList (n: v: eqPkg v) cfg.eq; + wireplumber.configPackages = mapAttrsToList (n: v: eqPkg v) cfg.eq ++ [ + ]; }; }; diff --git a/modules/desktop/fcitx5.nix b/modules/desktop/fcitx5.nix deleted file mode 100644 index b57073f8..00000000 --- a/modules/desktop/fcitx5.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - pkgs, - config, - lib, - ... -}: -let - cfg = config.xyno.desktop.fcitx5; -in -{ - options.xyno.desktop.fcitx5.enable = lib.mkEnableOption "enable fcitx5 input daemon thing"; - config = lib.mkIf cfg.enable { - i18n.inputMethod = { - type = "fcitx5"; - enable = true; - fcitx5.addons = with pkgs; [ - fcitx5-table-other - ]; - fcitx5.waylandFrontend = true; - fcitx5.quickPhrase = { - ":pleading:" = "🥺"; - ":pointing_right:" = "👉"; - ":pointing_left:" = "👈"; - }; - }; - }; -} diff --git a/modules/desktop/ibus.nix b/modules/desktop/ibus.nix new file mode 100644 index 00000000..3ce963b3 --- /dev/null +++ b/modules/desktop/ibus.nix @@ -0,0 +1,81 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; +let + cfg = config.xyno.desktop.ibus; +in +{ + options.xyno.desktop.ibus.enable = mkEnableOption "enable ibus input daemon thing"; + options.xyno.desktop.ibus.wantedBy = mkOption { + type = types.str; + default = "niri.service"; + }; + config = mkIf cfg.enable { + services.libinput.enable = true; + + # just... enable ibus as input method and maybe now we have consistent unicode input everywhere + # fuck qt tbh + i18n.inputMethod = { + enable = true; + package = pkgs.ibus; + # ibus.engines = with pkgs.ibus-engines; [ uniemoji ]; + }; + # home-manager.sharedModules = [ + # ( + # { lib, ... }: + # { + # dconf.settings = { + # "org/gnome/desktop/input-sources" = { + # sources = [ + # (lib.hm.gvariant.mkTuple [ + # "xkb" + # "us" + # ]) + # (lib.hm.gvariant.mkTuple [ + # "ibus" + # "libpinyin" + # ]) + # (lib.hm.gvariant.mkTuple [ + # "ibus" + # "mozc-jp" + # ]) + # ]; + # }; + # }; + # } + # ) + # ]; + + systemd.user.services."org.freedesktop.IBus.session.generic".wantedBy = [ cfg.wantedBy ]; + systemd.packages = [ pkgs.ibus ]; + # systemd.user.services.ibus = + # let + # ibusPackage = config.i18n.inputMethod.package; + # in + # assert hasPrefix "ibus-with-plugins" ibusPackage.name; + # { + # # panel is weird... + # # default is ${ibusPackage}/libexec/ibus-ui-gtk3 which works but sends a notification that it's misconfigured + # # wayland support can be enabled with --enable-wayland-im but that segfaults (possible due to zwp_input_method_v1 not being available?) + # script = '' + # exec ${ibusPackage}/bin/ibus-daemon --xim --replace --panel '${ibusPackage}/libexec/ibus-ui-gtk3' + # ''; + # serviceConfig = { + # Type = "dbus"; + # BusName = "org.freedesktop.IBus"; + # Restart = "on-abnormal"; + # }; + # unitConfig = { + # CollectMode = "inactive-or-failed"; + # }; + # # yeah we hardcoding this now, fuck it + # wantedBy = [ cfg.wantedBy ]; + # partOf = [ "graphical-session.target" ]; + # }; + + }; +} diff --git a/modules/desktop/niri.nix b/modules/desktop/niri.nix index f93e1d31..4f3fbce5 100644 --- a/modules/desktop/niri.nix +++ b/modules/desktop/niri.nix @@ -14,6 +14,8 @@ let "KeePassXC" "org.gnome.NautilusPreviewer" "io.github.Qalculate.qalculate-qt" + "ibus-ui-emojier" + "ibus-ui-gtk3" ]; matchFloat = concatStringsSep "\n" ( map (x: '' @@ -52,20 +54,22 @@ in value = 1; } ]; - home-manager.users.${config.xyno.system.user.name} = mkIf config.xyno.presets.home-manager.enable ( - { ... }: - { - xyno.dark-theme.enable = true; - # home.file.".config/xdg-desktop-portal-termfilechooser/config".text = '' - # [filechooser] - # cmd=${pkgs.xdg-desktop-portal-termfilechooser}/share/xdg-desktop-portal-termfilechooser/yazi-wrapper.sh - # default_dir=$HOME - # env=TERMCMD=footclient --app-id floating-alacritty - # open_mode = suggested - # save_mode = suggested - # ''; - } - ); + home-manager.sharedModules = [ + ( + { ... }: + { + xyno.dark-theme.enable = true; + # home.file.".config/xdg-desktop-portal-termfilechooser/config".text = '' + # [filechooser] + # cmd=${pkgs.xdg-desktop-portal-termfilechooser}/share/xdg-desktop-portal-termfilechooser/yazi-wrapper.sh + # default_dir=$HOME + # env=TERMCMD=footclient --app-id floating-alacritty + # open_mode = suggested + # save_mode = suggested + # ''; + } + ) + ]; xdg.portal = { extraPortals = [ @@ -88,7 +92,16 @@ in environment.systemPackages = with pkgs; [ playerctl xwayland-satellite + nirius ]; + systemd.user.services.niriusd = { + unitConfig.PartOf = "graphical-session.target"; + unitConfig.After = "graphical-session.target"; + unitConfig.Requisite = "graphical-session.target"; + serviceConfig.Restart = "on-failure"; + wantedBy = [ "niri.service" ]; + script = "exec ${pkgs.nirius}/bin/niriusd"; + }; programs.niri.enable = true; environment.etc."niri/config.kdl".mode = "444"; # copy file so niri detects changes environment.etc."niri/config.kdl".text = '' @@ -105,11 +118,15 @@ in Mod+T { spawn "${cfg.term}" "tmux" "new-session" "-t" "main"; } Mod+Shift+T { spawn "${cfg.term}"; } Mod+Y { spawn "${cfg.term}" "--app-id" "floating-alacritty" "-W" "120x37" "yazi"; } + Mod+Shift+M { spawn "sh" "-c" "notify-send -t 3000 -a umpv umpv-paste $(wl-paste); umpv $(wl-paste)"; } Mod+P { spawn "keepassxc"; } Mod+S { spawn "qalculate-qt"; } Mod+Shift+N { spawn "makoctl" "dismiss" "-a"; } Mod+N { spawn "makoctl" "dismiss"; } Mod+E { spawn "makoctl" "menu" "fuzzel -d"; } + Mod+G { spawn "nirius" "toggle-follow-mode"; } + Mod+Shift+bracketleft { spawn "nirius" "scratchpad-show"; } + Mod+Shift+bracketright { spawn "nirius" "scratchpad-toggle"; } XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.03+"; } XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.03-"; } XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; } diff --git a/modules/desktop/waybar/cal.nix b/modules/desktop/waybar/cal.nix index 0cc35d99..8664509b 100644 --- a/modules/desktop/waybar/cal.nix +++ b/modules/desktop/waybar/cal.nix @@ -24,13 +24,14 @@ let UNTIL="1d" EVENT="$( - khal list "$SINCE" "$UNTIL" \ + (khal list "$SINCE" "$UNTIL" \ --day-format 'SKIPME' \ --format "{start-end-time-style} {title:.31}{repeat-symbol}" | grep -v SKIPME | # filter out headers grep -v -P '↦|↔ |⇥' | # filter out continuing all day events grep -v '^ ' | # exclude full-day events head -n 1 # show just the first + ) || echo "" )" if [ -z "$EVENT" ]; then diff --git a/modules/module-list.nix b/modules/module-list.nix index 65fff1c0..0aa44847 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -5,9 +5,9 @@ ./desktop/audio.nix ./desktop/common-programs.nix ./desktop/easyeffects.nix - ./desktop/fcitx5.nix ./desktop/foot.nix ./desktop/fuzzel.nix + ./desktop/ibus.nix ./desktop/mako.nix ./desktop/niri.nix ./desktop/shikane.nix @@ -21,17 +21,22 @@ ./presets/common.nix ./presets/development.nix ./presets/gui.nix - ./presets/server.nix ./presets/home-manager.nix - ./services/authentik - ./services/caddy + ./presets/server.nix + # ./services/authentik + # ./services/caddy + ./services/kanidm.nix + ./services/traefik.nix + ./services/postgres.nix + ./services/oauth2Proxy/default.nix + ./services/oauth2Proxy/integration.nix ./services/monitoring.nix ./services/wireguard.nix ./system/impermanence.nix ./system/meta.nix ./system/user.nix + ./to-upstream/fido2-hid-bridge.nix ./user-services/khal.nix ./user-services/syncthing.nix - ./to-upstream/fido2-hid-bridge.nix ] diff --git a/modules/presets/cli.nix b/modules/presets/cli.nix index 408cfc02..a1d7cafa 100644 --- a/modules/presets/cli.nix +++ b/modules/presets/cli.nix @@ -1,5 +1,6 @@ { config, + inputs, lib, pkgs, ... @@ -44,6 +45,11 @@ in LC_COLLATE = "de_DE.UTF-8"; }; + nix.channel.enable = false; + nix.nixPath = [ + "nixpkgs=${inputs.nixpkgs}" + "nixpkgs-master=${inputs.nixpkgs-master}" + ]; nix.settings = { substituters = [ # "https://cache.lix.systems" @@ -55,6 +61,7 @@ in # "cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o=" # "helix.cachix.org-1:ejp9KQpR1FBI2onstMQ34yogDm4OgU2ru6lIwPvuCVs=" ]; + trusted-users = lib.mkDefault [ "root" "@wheel" @@ -77,6 +84,8 @@ in # https://github.com/NixOS/nixpkgs/issues/361592 needed for run0 security.pam.services.systemd-run0 = { }; + # services.ssh.knownHosts = lib.mapAttrs' (n: v: lib.nameValuePair v.deployment.targetHost { publicKey = v.}) + programs.yazi = { enable = true; initLua = pkgs.writeText "yazi-init.lua" '' @@ -130,7 +139,7 @@ in imagemagick jq lm_sensors - moar + moor neofetch nix-output-monitor poppler @@ -145,7 +154,7 @@ in programs.mosh.enable = true; environment.variables.EDITOR = "hx"; environment.variables.VISUAL = "hx"; - environment.variables.PAGER = "moar"; + environment.variables.PAGER = "moor"; environment.shellAliases = { l = "ls -alh"; @@ -161,7 +170,7 @@ in p = "cd ~/proj"; ytl = ''yt-dlp -f "bv*+mergeall[vcodec=none]" --audio-multistreams''; sudo = "run0"; - less = "moar"; + less = "moor"; }; }; } diff --git a/modules/presets/gui.nix b/modules/presets/gui.nix index 81680433..156639f7 100644 --- a/modules/presets/gui.nix +++ b/modules/presets/gui.nix @@ -1,6 +1,7 @@ { pkgs, config, + inputs, lib, ... }: @@ -21,6 +22,7 @@ in pkgs.yubikey-personalization ]; xyno.desktop.niri.enable = true; + xyno.desktop.ibus.enable = true; xyno.desktop.audio.enable = mkDefault true; xyno.user-services.khal.enable = true; boot.kernelPackages = mkDefault pkgs.linuxPackages_zen; @@ -40,9 +42,60 @@ in qt = { enable = true; - style = "breeze"; - # platformTheme = "gnome"; + platformTheme = "qt5ct"; }; + home-manager.sharedModules = + let + gruvboxDarkColors = pkgs.writeText "gruvbox-dark.conf" '' + [ColorScheme] + active_colors=#ffebdbb2, #ff1d2021, #ffbdae93, #ffa89984, #ff3c3836, #ff504945, #ffebdbb2, #ffebdbb2, #ffebdbb2, #ff282828, #ff1d2021, #ff504945, #ff458588, #ff282828, #ff458588, #ffcc241d, #ff282828, #ffebdbb2, #ff1d2021, #ffebdbb2, #ffbdae93 + disabled_colors=#ffbdae93, #ff1d2021, #ffbdae93, #ffa89984, #ff3c3836, #ff504945, #ffbdae93, #ffbdae93, #ffbdae93, #ff282828, #ff1d2021, #ff504945, #ff438184, #ff3c3836, #ff458588, #ffcc241d, #ff282828, #ffebdbb2, #ff1d2021, #ffebdbb2, #ffbdae93 + inactive_colors=#ffebdbb2, #ff1d2021, #ffbdae93, #ffa89984, #ff3c3836, #ff504945, #ffebdbb2, #ffebdbb2, #ffebdbb2, #ff282828, #ff1d2021, #ff504945, #ff438184, #ffa89984, #ff458588, #ffcc241d, #ff282828, #ffebdbb2, #ff1d2021, #ffebdbb2, #ffbdae93 + ''; + qt5ctConf = pkgs.writeText "qt5ct.conf" '' + [Appearance] + color_scheme_path=${gruvboxDarkColors} + custom_palette=true + icon_theme=breeze-dark + standard_dialogs=xdgdesktopportal + style=Breeze + + [Fonts] + fixed="Source Sans 3,12,-1,5,50,0,0,0,0,0" + general="Source Sans 3,12,-1,5,50,0,0,0,0,0" + ''; + in + [ + { + home.file.".config/qt5ct/qt5ct.conf".source = qt5ctConf; + home.file.".config/qt6ct/qt6ct.conf".source = qt5ctConf; + dconf = { + settings = { + "org/gnome/desktop/interface" = { + color-scheme = "prefer-dark"; + gtk-theme = "adw-gtk3-dark"; + }; + }; + }; + gtk = { + enable = true; + iconTheme.name = "breeze-dark"; + gtk4.extraConfig.gtk-application-prefer-dark-theme = 1; + gtk3.extraConfig.gtk-application-prefer-dark-theme = 1; + gtk3.theme.package = pkgs.adw-gtk3; + gtk3.theme.name = "adw-gtk3-dark"; + + gtk3.extraCss = '' + @import url("${inputs.adw-colors}/themes/adw-gruvbox/gtk3-dark.css"); + ''; + gtk4.extraCss = '' + @import url("${inputs.adw-colors}/themes/adw-gruvbox/gtk4-dark.css"); + ''; + + }; + + } + ]; programs.yazi = { settings.keymap.mgr.prepend_keymap = [ @@ -70,11 +123,34 @@ in # enable the gnome shit services.gnome.gnome-keyring.enable = true; services.gnome.gnome-online-accounts.enable = true; - services.gnome.core-apps.enable = true; + environment.systemPackages = with pkgs; [ + gnome-calendar + gnome-clocks + gnome-font-viewer + mate.engrampa + papirus-folders + kdePackages.gwenview + kdePackages.skanlite + kdePackages.okular + kdePackages.breeze-gtk + kdePackages.breeze.qt5 + kdePackages.breeze + kdePackages.breeze-icons + nautilus # for xdg portal + ]; services.gnome.gcr-ssh-agent.enable = mkForce false; - services.gnome.sushi.enable = true; + # services.gnome.sushi.enable = true; services.gnome.gnome-settings-daemon.enable = true; - services.gvfs.enable = true; + + programs.thunar = { + enable = true; + plugins = with pkgs.xfce; [ + thunar-archive-plugin + thunar-volman + ]; + }; + services.tumbler.enable = true; # thunar image preview + services.gvfs.enable = true; # thunar network device mount xdg.terminal-exec = { enable = true; @@ -88,35 +164,28 @@ in { pkgs, ... }: { xyno.mpv.enable = true; - # xdg.mimeApps = { - # enable = true; - # defaultApplications = { - # "x-scheme-handler/mailto" = [ "aerc.desktop" ]; - # "inode/directory" = [ "org.gnome.Nautilus.desktop" ]; - # "application/x-gnome-saved-search" = [ "org.gnome.Nautilus.desktop" ]; - # "x-scheme-handler/http" = "userapp-Zen-D2P132.desktop"; - # "x-scheme-handler/https" = "userapp-Zen-D2P132.desktop"; - # "x-scheme-handler/chrome" = "userapp-Zen-D2P132.desktop"; - # "text/html" = "userapp-Zen-D2P132.desktop"; - # "application/x-extension-htm" = "userapp-Zen-D2P132.desktop"; - # "application/x-extension-html" = "userapp-Zen-D2P132.desktop"; - # "application/x-extension-shtml" = "userapp-Zen-D2P132.desktop"; - # "application/xhtml+xml" = "userapp-Zen-D2P132.desktop"; - # "application/x-extension-xhtml" = "userapp-Zen-D2P132.desktop"; - # "application/x-extension-xht" = "userapp-Zen-D2P132.desktop"; - # "application/pdf" = "org.gnome.Evince.desktop"; + # xdg.mimeApps = { + # enable = true; + # defaultApplications = { + # "x-scheme-handler/mailto" = [ "aerc.desktop" ]; + # "inode/directory" = [ "org.gnome.Nautilus.desktop" ]; + # "application/x-gnome-saved-search" = [ "org.gnome.Nautilus.desktop" ]; + # "x-scheme-handler/http" = "userapp-Zen-D2P132.desktop"; + # "x-scheme-handler/https" = "userapp-Zen-D2P132.desktop"; + # "x-scheme-handler/chrome" = "userapp-Zen-D2P132.desktop"; + # "text/html" = "userapp-Zen-D2P132.desktop"; + # "application/x-extension-htm" = "userapp-Zen-D2P132.desktop"; + # "application/x-extension-html" = "userapp-Zen-D2P132.desktop"; + # "application/x-extension-shtml" = "userapp-Zen-D2P132.desktop"; + # "application/xhtml+xml" = "userapp-Zen-D2P132.desktop"; + # "application/x-extension-xhtml" = "userapp-Zen-D2P132.desktop"; + # "application/x-extension-xht" = "userapp-Zen-D2P132.desktop"; + # "application/pdf" = "org.gnome.Evince.desktop"; - # }; - # }; + # }; + # }; }; - environment.systemPackages = with pkgs; [ - kdePackages.breeze-gtk - kdePackages.breeze.qt5 - kdePackages.breeze - kdePackages.breeze-icons - ]; - # fonts fonts.fontconfig.defaultFonts = { sansSerif = [ diff --git a/modules/services/caddy/default.nix b/modules/services/caddy/default.nix index bfdc9ea9..3986e1b0 100644 --- a/modules/services/caddy/default.nix +++ b/modules/services/caddy/default.nix @@ -7,71 +7,16 @@ with lib; let cfg = config.xyno.services.caddy; - wildcardMatcherStr = wildcard: hostName: content: '' - @${hostName} host ${hostName}.${wildcard} - handle @${hostName} { - ${content.extraConfig} - } - - ''; - genOneWildcard = wildcard: host: { - extraConfig = '' - # extra pre - ${host.extraConfigPre} - # block bots - ${optionalString host.blockBots "import blockBots"} - # hosts handler - ${concatStrings (mapAttrsToList (n: v: wildcardMatcherStr wildcard n v) host.hosts)} - # extra post - ${host.extraConfigPost} - abort - ''; + schema = import ./json-schema.nix { + inherit pkgs lib; + schema = builtins.fromJSON (builtins.readFile ./caddy_schema.json); }; - genVHostsFromWildcard = mapAttrs' ( - n: v: nameValuePair "*.${n}" (genOneWildcard n v) - ) cfg.wildcardHosts; - schema = import ./json-schema.nix { inherit pkgs lib; schema = builtins.fromJSON (builtins.readFile ./caddy_schema.json); }; in { options.xyno.services.caddy.enable = mkEnableOption "enables caddy with the desec plugin"; options.xyno.services.caddy.config = mkOption { - default = {}; - type = schema.type; - }; - options.xyno.services.caddy.wildcardHosts = mkOption { - example = { - "hailsatan.eu" = { - blockBots = true; - hosts.md.extraConfig = ''reverse_proxy ...''; - }; - }; default = { }; - type = - with types; - attrsOf (submodule { - options = { - blockBots = mkOption { - type = bool; - default = false; - }; - extraConfigPre = mkOption { - type = str; - default = ""; - }; - extraConfigPost = mkOption { - type = str; - default = ""; - }; - hosts = mkOption { - default = {}; - type = attrsOf (submodule { - options = { - extraConfig = mkOption { type = lines; }; - }; - }); - }; - }; - }); + type = schema.type; }; config = lib.mkIf cfg.enable { networking.firewall.allowedTCPPorts = [ @@ -79,34 +24,32 @@ in 443 ]; networking.firewall.allowedUDPPorts = [ 443 ]; + xyno.services.caddy.config = { + apps = { + http.metrics.per_host = true; + tls.automation.policies = [ + { + issuers = [ + { + ca = "https://acme-v02.api.letsencrypt.org/directory"; + challenges.dns.provider = { + name = "desec"; + token.path = ""; # TODO + + }; + } + ]; + module = "acme"; + } + ]; + }; + }; + services.caddy = { enable = true; package = pkgs.caddy-desec; adapter = "json"; configFile = json.generate "caddy-config.json" cfg.config; - # virtualHosts = genVHostsFromWildcard; - # email = mkDefault "ssl@xyno.systems"; - # acmeCA = mkDefault "https://acme-v02.api.letsencrypt.org/directory"; - # globalConfig = '' - # metrics { - # per_host - # } - # ''; - # extraConfig = '' - # (blockBots) { - # @botForbidden header_regexp User-Agent "(?i)AdsBot-Google|Amazonbot|anthropic-ai|Applebot|Applebot-Extended|AwarioRssBot|AwarioSmartBot|Bytespider|CCBot|ChatGPT|ChatGPT-User|Claude-Web|ClaudeBot|cohere-ai|DataForSeoBot|Diffbot|FacebookBot|Google-Extended|GPTBot|ImagesiftBot|magpie-crawler|omgili|Omgilibot|peer39_crawler|PerplexityBot|YouBot" - - # handle @botForbidden { - # redir https://hil-speed.hetzner.com/10GB.bin - # } - # handle /robots.txt { - # respond < "${v.path}" + chown "${v.user}:${v.group}" "${v.path}" + chmod "${v.chmod}" "${v.path}" + ''; + }; + }) cfg.templates) + ++ [ + (mkIf (cfg.tls.keyPem == null) { + + generate-kanidm-tls = + let + units = [ + "kanidm.service" + ] + ++ (lib.optional cfg.setupTraefik "traefik.service"); + in + { + serviceConfig = { + User = "root"; + Group = "kanidm"; + Type = "oneshot"; + }; + wantedBy = units; + before = units; + script = '' + mkdir -p ${tlsDir} + cd ${tlsDir} + ${config.services.kanidm.package}/bin/kanidmd cert-generate -c ${ + let + toml = pkgs.formats.toml { }; + filterConfig = converge (filterAttrsRecursive (_: v: v != null)); + in + toml.generate "kanidm-tls.conf" (filterConfig (config.services.kanidm.serverSettings)) + } + chmod +g ${tlsDir}/* + ''; + }; + }) + ] + ); + sops.secrets."kanidm/adminPassword" = { + sopsFile = ../../instances/${config.networking.hostName}/secrets/kanidm.yaml; + reloadUnits = [ "kanidm.service" ]; + owner = "kanidm"; + }; + sops.secrets."kanidm/idmAdminPassword" = { + sopsFile = ../../instances/${config.networking.hostName}/secrets/kanidm.yaml; + reloadUnits = [ "kanidm.service" ]; + owner = "kanidm"; + }; + + xyno.impermanence.directories = [ "/var/lib/kanidm" ]; + }) + (mkIf (cfg.enable && cfg.setupTraefik) { + + xyno.services.traefik.simpleProxy.kanidm = { + host = cfg.domain; + internal = "https://127.0.0.3:8443"; + transport = "kanidm-https"; + }; + services.traefik.dynamicConfigOptions.http = mkIf (cfg.tls.keyPem == null) { + serversTransports."kanidm-https" = { + serverName = cfg.domain; + rootcas = [ + "${tlsDir}/ca.pem" + ]; + }; + }; + + }) + ]; + +} diff --git a/modules/services/monitoring.nix b/modules/services/monitoring.nix index e8726b1d..0ad68d46 100644 --- a/modules/services/monitoring.nix +++ b/modules/services/monitoring.nix @@ -9,17 +9,21 @@ with lib; let cfg = config.xyno.services.monitoring; - firstInstanceWithPromServer = if cfg.prometheusServer then config.networking.hostName else (builtins.head ( - attrValues (filterAttrs (n: v: v.config.xyno.services.monitoring.prometheusServer) (otherNodes)) - )).config.networking.hostName; - vmBasicAuthUsername = "xyno-monitoring"; + # firstInstanceWithPromServer = + # if cfg.prometheusServer then + # config.networking.hostName + # else + # (builtins.head ( + # attrValues (filterAttrs (n: v: v.config.xyno.services.monitoring.prometheusServer) (otherNodes)) + # )).config.networking.hostName; + # vmBasicAuthUsername = "xyno-monitoring"; in { options.xyno.services.monitoring.enable = mkEnableOption "enables monitoring (prometheus exporters and stuff)"; options.xyno.services.monitoring.remoteWriteUrl = mkOption { type = types.str; - default = "http://${firstInstanceWithPromServer}.${config.xyno.services.wireguard.monHostsDomain}:8428/api/v1/write"; + default = "https://metrics.xyno.systems/api/v1/write"; description = "where prometheus metrics should be pushed to"; }; options.xyno.services.monitoring.prometheusServer = mkOption { @@ -44,8 +48,9 @@ in enabledCollectors = [ "systemd" ]; }; xyno.services.monitoring.exporters.node = config.services.prometheus.exporters.node.port; + # TODO: oauth2 with client per host -> kanidm -> oauth2-proxy -> victoriametrics server services.vmagent = { - remoteWrite.url = cfg.remoteWriteUrl; + remoteWrite.url = if cfg.prometheusServer then "http://localhost:8428/api/v1/write" else cfg.remoteWriteUrl; remoteWrite.basicAuthUsername = vmBasicAuthUsername; remoteWrite.basicAuthPasswordFile = config.sops.secrets."victoriametrics/basicAuthPassword".path; @@ -84,7 +89,9 @@ in ]; }; - services.grafana.declarativePlugins = with pkgs.grafanaPlugins; [ victoriametrics-metrics-datasource ]; + services.grafana.declarativePlugins = with pkgs.grafanaPlugins; [ + victoriametrics-metrics-datasource + ]; }) ]; diff --git a/modules/services/oauth2Proxy/default.nix b/modules/services/oauth2Proxy/default.nix new file mode 100644 index 00000000..d38615ee --- /dev/null +++ b/modules/services/oauth2Proxy/default.nix @@ -0,0 +1,85 @@ +{ + pkgs, + lib, + config, + ... +}: +let + inherit (lib) + mkEnableOption + mkIf + mkOption + getExe + ; + inherit (lib.types) + pathWith + listOf + ; + cfg = config.xyno.services.oauth2Proxy; + settingsFormat = pkgs.formats.toml { }; + configFile = settingsFormat.generate "oauth2-proxy.conf" cfg.settings; + absPath = pathWith { + inStore = false; + absolute = true; + }; +in +{ + options.xyno.services.oauth2Proxy = { + enable = mkEnableOption "oauth2-proxy"; + package = lib.mkPackageOption pkgs "oauth2-proxy" { }; + settings = mkOption { + type = settingsFormat.type; + description = "what to add to the config toml file"; + }; + environmentFiles = mkOption { + type = listOf absPath; + default = [ ]; + example = [ "/run/secrets/oauth2Proxy" ]; + }; + }; + config = mkIf cfg.enable { + systemd.services.oauth2-proxy = { + wantedBy = [ "multi-user.target" ]; + description = "OAuth2 Proxy (66642's less weird version)"; + confinement.enable = true; + after = [ "network.target" ]; + serviceConfig = { + BindReadOnlyPaths = [ + "-/etc/resolv.conf" + "-/run/systemd" + "/etc/hosts" + "${config.security.pki.caBundle}:/etc/ssl/certs/ca-certificates.crt" + ]; + ExecStart = "${getExe cfg.package} --config=${configFile}"; + EnvironmentFile = cfg.environmentFiles; + DynamicUser = true; + CapabilityBoundingSet = [ "" ]; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + ]; + + PrivateDevices = true; + UMask = "0022"; + SystemCallFilter = [ "@system-service" ]; + SystemCallErrorNumber = "EPERM"; + LockPersonality = true; + PrivateTmp = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + }; + }; + }; +} diff --git a/modules/services/oauth2Proxy/integration.nix b/modules/services/oauth2Proxy/integration.nix new file mode 100644 index 00000000..2d152637 --- /dev/null +++ b/modules/services/oauth2Proxy/integration.nix @@ -0,0 +1,208 @@ +{ + lib, + config, + ... +}: +let + inherit (lib) + mkIf + mkOption + mkMerge + attrNames + mapAttrsToList + ; + inherit (lib.types) + str + nullOr + submodule + listOf + attrsOf + ; + cfg = config.xyno.services.oauth2Proxy; + kanidmCfg = config.xyno.services.kanidm; + oauth2ProxyInternalHostPort = "127.0.0.4:4180"; + oauth2ProxyInternalHostPortMetrics = "127.0.0.4:4181"; +in +{ + options.xyno.services.oauth2Proxy = { + domain = mkOption { + default = "oauth.xyno.systems"; + type = str; + }; + hosts = mkOption { + type = attrsOf ( + submodule ( + { name, ... }: + { + options.allowedGroups = mkOption { + type = nullOr (listOf str); + default = null; + }; + options.allowed_email_domains = mkOption { + type = nullOr (listOf str); + default = null; + }; + options.allowed_emails = mkOption { + type = nullOr (listOf str); + default = null; + }; + options.middlewares = mkOption { + type = listOf str; + description = "add to your service"; + default = [ + "oauth-errors" + "oauth-host-${name}" + ]; + }; + } + ) + ); + example = { + "navidrome.xyno.systems" = { + allowedGroups = [ "navidrome_access@idm.xyno.systems" ]; + }; + }; + default = { }; + }; + }; + config = mkIf (cfg.enable && config.xyno.services.kanidm.enable) { + services.kanidm.provision = { + groups = { + proxy_users.members = [ "application_admins" ]; + }; + systems.oauth2.oauth2_proxy = { + displayName = "oauth2 proxy"; + originUrl = [ + "https://${cfg.domain}/oauth2/callback" + ] + ++ (mapAttrsToList (n: v: "https://${n}/oauth2/callback") cfg.hosts); + originLanding = "https://${cfg.domain}/oauth2/sign_in"; + preferShortUsername = true; + claimMaps = { + "proxy_group" = { + joinType = "array"; + valuesByGroup = { + "proxy_users" = [ + "proxy_users" + ]; + }; + }; + }; + scopeMaps."proxy_users" = [ + "email" + "openid" + ]; + }; + }; + xyno.services.kanidm.templates.oauth2_proxy = { + wantedBy = [ + "oauth2-proxy.service" + ]; + text = p: '' + OAUTH2_PROXY_CLIENT_ID=${p.clientId} + OAUTH2_PROXY_CLIENT_SECRET=${p.basicSecret} + OAUTH2_PROXY_COOKIE_SECRET=${p.env "COOKIE_SECRET"} + OAUTH2_PROXY_OIDC_ISSUER_URL=https://${kanidmCfg.domain}/oauth2/openid/${p.clientId} + ''; + environmentFiles = [ config.sops.templates.oauth2ProxyEnv.path ]; + }; + sops.secrets."oauth2Proxy/cookieSecret" = { + sopsFile = ../../../instances/${config.networking.hostName}/secrets/kanidm.yaml; + }; + sops.templates."oauth2ProxyEnv" = { + restartUnits = [ "generate-kanidm-template-oauth2_proxy.service" ]; + content = '' + COOKIE_SECRET=${config.sops.placeholder."oauth2Proxy/cookieSecret"} + ''; + }; + + xyno.services.monitoring.exporters.oauth2Proxy = "http://${oauth2ProxyInternalHostPortMetrics}"; + + systemd.services.oauth2Proxy.after = [ "traefik.service" ]; + xyno.services.oauth2Proxy = { + environmentFiles = [ kanidmCfg.templates.oauth2_proxy.path ]; + settings = mkMerge [ + { + provider = "oidc"; + scope = "openid email"; + oidc_groups_claim = "proxy_group"; + allowed_groups = [ "proxy_users" ]; + + http_address = "${oauth2ProxyInternalHostPort}"; + https_address = ""; + whitelist_domains = attrNames cfg.hosts; + email_domains = "*"; + skip_provider_button = true; + code_challenge_method = "S256"; + set_xauthrequest = true; + } + (mkIf config.xyno.services.monitoring.enable { + metrics_address = "http://${oauth2ProxyInternalHostPortMetrics}"; + + }) + ]; + }; + + xyno.services.traefik.simpleProxy = mkMerge ( + [ + { + oauth = { + rule = "Host(`${cfg.domain}`) && PathPrefix(`/oauth2`)"; + internal = "http://${oauth2ProxyInternalHostPort}"; + middlewares = [ "auth-headers" ]; + host = cfg.domain; + }; + } + ] + ++ (mapAttrsToList (n: v: { + "oauth-host-${n}" = { + rule = "Host(`${n}`) && PathPrefix(`/oauth2`)"; + internal = "http://${oauth2ProxyInternalHostPort}"; + middlewares = [ "auth-headers" ]; + host = n; + }; + }) cfg.hosts) + ); + services.traefik.dynamicConfigOptions.http.middlewares = mkMerge ( + (mapAttrsToList (n: v: { + "oauth-host-${n}" = + let + maybeQueryArg = + name: value: + if name == "middlewares" || value == null then + null + else + "${name}=${lib.concatStringsSep "," (builtins.map lib.escapeURL value)}"; + allArgs = lib.mapAttrsToList maybeQueryArg v; + cleanArgs = builtins.filter (x: x != null) allArgs; + cleanArgsStr = lib.concatStringsSep "&" cleanArgs; + in + { + forwardAuth = { + address = "https://${cfg.domain}/oauth2/auth?${cleanArgsStr}"; + authResponseHeaders = [ + "X-Auth-Request-User" + "X-Auth-Request-Groups" + "X-Auth-Request-Email" + "X-Auth-Request-Preferred-Username" + ]; + trustForwardHeader = true; + }; + }; + }) cfg.hosts) + ++ [ + { + auth-headers.headers = { + frameDeny = true; + contentTypeNosniff = true; + }; + oauth-errors.errors = { + status = [ "401-403" ]; + service = config.xyno.services.traefik.simpleProxy.oauth.serviceName; + query = "/oauth2/sign_in?rd={url}"; + }; + } + ] + ); + }; +} diff --git a/modules/services/postgres.nix b/modules/services/postgres.nix index a06ded97..bcdb16e4 100644 --- a/modules/services/postgres.nix +++ b/modules/services/postgres.nix @@ -12,7 +12,9 @@ in config = lib.mkIf cfg.enable { services.postgresql = { enable = true; - package = pkgs.postgresql_17_jit; + package = pkgs.postgresql_18; + enableJIT = true; + extensions = ps: with ps; [ timescaledb-apache ]; identMap = '' # ArbitraryMapName systemUser DBUser superuser_map root postgres @@ -26,7 +28,7 @@ in }; xyno.services.monitoring.exporters.postgres = config.services.prometheus.exporters.postgres.port; - xyno.impermanence.extraDirectories = [ "/var/lib/postgresql" ]; + xyno.impermanence.directories = [ "/var/lib/postgresql" ]; services.borgmatic.settings.postgresql_databases = [ { diff --git a/modules/services/traefik.nix b/modules/services/traefik.nix new file mode 100644 index 00000000..cdd65064 --- /dev/null +++ b/modules/services/traefik.nix @@ -0,0 +1,247 @@ +{ + pkgs, + lib, + config, + ... +}: +let + inherit (lib) + mapAttrsToList + mkMerge + splitString + concatStringsSep + mkIf + mkOption + mkEnableOption + ; + inherit (lib.types) + str + bool + nullOr + anything + attrsOf + submodule + listOf + ; + cfg = config.xyno.services.traefik; + simpleProxyOpts = mapAttrsToList ( + n: v: + let + router = v.routerName; + service = v.serviceName; + spl = splitString "." v.host; + certDomain = if (builtins.length spl) > 2 then concatStringsSep "." (builtins.tail spl) else spl; + in + mkMerge [ + (mkIf v.robotProtection { + routers."${router}-robotstxt" = { + service = "robotstxt"; + rule = "Host(`${v.host}`) && Path(`/robots.txt`)"; + tls.certResolver = "letsencrypt"; + tls.domains = [ + { + main = certDomain; + sans = [ "*.${certDomain}" ]; + } + ]; + }; + services.robotstxt = { + loadBalancer.servers = [ + { url = "http://127.0.0.2:8080"; } + ]; + }; + }) + { + routers.${router} = { + inherit service; + inherit (v) middlewares; + rule = if v.rule != null then v.rule else "Host(`${v.host}`)"; + tls.certResolver = "letsencrypt"; + tls.domains = [ + { + main = certDomain; + sans = [ "*.${certDomain}" ]; + } + ]; + }; + services.${service} = { + loadBalancer.servers = [ + { url = v.internal; } + ]; + loadBalancer.serversTransport = mkIf (v.transport != null) v.transport; + }; + } + ] + ) cfg.simpleProxy; +in +{ + options.xyno.services.traefik.enable = mkEnableOption "enables traefik"; + options.xyno.services.traefik.noBots = mkOption { + type = bool; + default = true; + }; + options.xyno.services.traefik.simpleProxy = mkOption { + example = { + "example" = { + host = "example.org"; + middlewares = [ "meow" ]; + internal = "http://127.0.0.1:8080"; + }; + }; + default = { }; + type = attrsOf ( + submodule ( + { config, name,... }: + { + options = { + middlewares = mkOption { + type = listOf str; + default = []; + + }; + internal = mkOption { + type = str; + description = "where to proxy to"; + }; + host = mkOption { + type = str; + description = "used for the route and tls"; + }; + routerName = mkOption { + type = str; + default = "simpleproxy-${name}-router"; + }; + serviceName = mkOption { + type = str; + default = "simpleproxy-${name}-service"; + }; + robotProtection = mkOption { + type = bool; + default = true; + description = "robots.txt and (soon) iocane"; + }; + rule = mkOption { + type = str; + default = "Host(`${config.host}`)"; + description = "overrides the Host(`\${host}`) rule with something custom if set"; + }; + transport = mkOption { + type = nullOr anything; + default = null; + }; + + }; + } + ) + ); + + }; + config = mkIf cfg.enable { + services.nginx = { + enable = mkIf cfg.noBots true; + defaultListen = mkIf cfg.noBots [ + { + addr = "127.0.0.2"; + port = 8080; + } + ]; + virtualHosts._.default = true; + virtualHosts._.locations."/".root = pkgs.writeTextFile { + name = "robots.txt"; + destination = "/robots.txt"; + text = '' + User-agent: * + Disallow: / + ''; + }; + }; + services.traefik = { + enable = true; + environmentFiles = [ + config.sops.templates."traefik.env".path + ]; + staticConfigOptions = { + accessLog = {}; + metrics = mkIf config.xyno.services.monitoring.enable { + otlp.http.endpoint = "http://localhost:8429/v1/metrics"; + }; + entryponits.web = { + address = ":80"; + redirections.entryPoint = { + to = "websecure"; + scheme = "https"; + permanent = true; + }; + }; + entrypoints.websecure = { + address = ":443"; + http.tls.certResolver = "letsencrypt"; + http3 = { }; + + }; + log.level = "INFO"; + certificatesResolvers.letsencrypt.acme = { + email = "ssl@xyno.systems"; + caServer = "https://acme-v02.api.letsencrypt.org/directory"; + dnsChallenge = { + resolvers = [ + "8.8.8.8" + "1.1.1.1" + ]; + provider = "desec"; + }; + }; + }; + dynamicConfigOptions = { + http = mkMerge simpleProxyOpts; + # tls.options.default = { + # # mozilla modern + # minVersion = "VersionTLS13"; + # curvePreferences = [ + # "X25519" + # "CurveP256" + # "CurveP384" + # ]; + # }; + # tls.options.old = { + # # mozilla intermediate + # minVersion = "VersionTLS12"; + # curvePreferences = [ + # "X25519" + # "CurveP256" + # "CurveP384" + # ]; + # cipherSuites = [ + # "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" + # "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" + # "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" + # "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" + # "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305" + # "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305" + # ]; + + # }; + }; + }; + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + networking.firewall.allowedUDPPorts = [ 443 ]; + xyno.impermanence.directories = [ config.services.traefik.dataDir ]; + sops.secrets."desec_token" = { + }; + sops.templates."traefik.env".content = '' + DESEC_TOKEN=${config.sops.placeholder.desec_token} + DESEC_PROPAGATION_TIMEOUT=1200 + LEGO_DISABLE_CNAME_SUPPORT=true + ''; + sops.templates."traefik.env".reloadUnits = [ "traefik.service" ]; + # services.borgmatic.settings.traefikql_databases = [ + # { + # name = "all"; # gets run as root anyways so can log in + # } + # ]; + + }; +} diff --git a/modules/system/impermanence.nix b/modules/system/impermanence.nix index ca725075..0e231fe4 100644 --- a/modules/system/impermanence.nix +++ b/modules/system/impermanence.nix @@ -21,24 +21,25 @@ in { options.xyno.impermanence = { enable = lib.mkEnableOption "erase all your darlings (they hate you anyways)"; - files = lib.mkOption { type = lib.types.listOf lib.types.str; }; - directories = lib.mkOption { type = lib.types.listOf lib.types.str; }; + files = lib.mkOption { type = lib.types.listOf lib.types.str; default = []; }; + directories = lib.mkOption { type = lib.types.listOf lib.types.anything; default = [];}; user = { - files = lib.mkOption { type = lib.types.listOf lib.types.str; }; - directories = lib.mkOption { type = lib.types.listOf lib.types.str; }; + files = lib.mkOption { type = lib.types.listOf lib.types.str; default = [];}; + directories = lib.mkOption { type = lib.types.listOf lib.types.anything; default = [];}; }; # have a seperate impermanence tree for "cache" files that can just be deleted if wanted cache = { - files = lib.mkOption { type = lib.types.listOf lib.types.str; }; - directories = lib.mkOption { type = lib.types.listOf lib.types.str; }; + files = lib.mkOption { type = lib.types.listOf lib.types.str; default = [];}; + directories = lib.mkOption { type = lib.types.listOf lib.types.anything; default = [];}; user = { - files = lib.mkOption { type = lib.types.listOf lib.types.str; }; - directories = lib.mkOption { type = lib.types.listOf lib.types.str; }; + files = lib.mkOption { type = lib.types.listOf lib.types.str; default = [];}; + directories = lib.mkOption { type = lib.types.listOf lib.types.anything; default = [];}; }; }; }; config = lib.mkIf cfg.enable { + users.mutableUsers = false; xyno.impermanence.files = [ "/etc/machine-id" # systemd/zfs unhappy otherwise ]; @@ -47,6 +48,7 @@ in "/var/lib/systemd/coredump" "/etc/ssh" # host keys "/var/lib/sbctl" # lanzaboote + "/var/lib/nixos" ]; xyno.impermanence.user.directories = [ diff --git a/modules/system/meta.nix b/modules/system/meta.nix index 76eabcdb..410bf60b 100644 --- a/modules/system/meta.nix +++ b/modules/system/meta.nix @@ -1,6 +1,6 @@ {lib,...}: with lib;{ options.xyno.meta = { - sopsKey = mkOption { type = types.text; }; + sopsKey = mkOption { type = types.str; }; }; config = { sops.defaultSopsFile = ../../secrets/common.yaml; diff --git a/overlays/default.nix b/overlays/default.nix index 8391833c..a5a14de5 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -28,15 +28,5 @@ inputs: self: super: { python-uhid = super.callPackage ../packages/uhid.nix {}; caddy-desec = super.callPackage ../packages/caddy-desec.nix {}; - # todo: remove on next supersonic release - supersonic-wayland = super.supersonic-wayland.overrideAttrs (old: { - patches = (if old?patches then old.patches else []) ++ [ - (self.fetchpatch2 { - url = "https://github.com/dweymouth/supersonic/commit/ee742cf34ef7225d345c16354d9c21d72a41bf4a.patch"; - hash = "sha256-kSeEbzrfJ4Pe8JC4rIWlSmADOcjrCRBNWlcO8VfVnn4="; - }) - ]; - vendorHash = "sha256-Sh3PxRwb6ElSeWzdvIQ+nD9VVGlpUDwxG7nAoGWPTRQ="; - }); } diff --git a/secrets/common.yaml b/secrets/common.yaml index 0c72d97d..b97ac868 100644 --- a/secrets/common.yaml +++ b/secrets/common.yaml @@ -1,17 +1,18 @@ victoriametrics: basicAuthPassword: ENC[AES256_GCM,data:5QuhkQ344qDYzhGZBJimaX94C6oxgYBRZw4MSlycdgs6zRAudMIu/HF1gpjythQpait81jMpFhIn57w433s7QQ==,iv:gytJ63cBaJseCis7gEPmOX6LeddNloQsTjc1SnS56jo=,tag:Jn6TevGsBEeHxYmVHy896w==,type:str] +desec_token: ENC[AES256_GCM,data:3aqlfpAEMyOSNGdLXm4lc0VZajduPkTYkYd+WA==,iv:sktNkKWaD/hjsQpSJzAZeCvwYXfvkhQ2A44BKedCZRg=,tag:XbxIr09c60V0PMDitSOD/w==,type:str] wg: psk: ENC[AES256_GCM,data:Anpe6IxtzsqZyvas+ddV3yjJozdZgZOl2KG/Z4YtWUB5gAVLtxsQKc/WA/M=,iv:j/A5k2VXbdqUDXEd1WRfJYdb3DsUZ1B9gPHCpDpRjmw=,tag:KQGi1O5iP2+nQccgBzytSQ==,type:str] msmtp: host: ENC[AES256_GCM,data:YxiLT5t2H52IZvB02Pjntvg=,iv:nuMPI6fuvQ4U0+xj3SF27ZO/b2knKUsO6jCf9aJqQa4=,tag:9DucIq+LUozuPLL3s8UjDQ==,type:str] - port: ENC[AES256_GCM,data:zbe7,iv:cwoK0oCIzwmQ6xHFX94KDfd7Fu+pC96c9+AnK/KpQp4=,tag:IfsCHk0SpBeQ4bD0WXyQcw==,type:int] + port: ENC[AES256_GCM,data:W7L1,iv:q2TQTGTxOWCWqgjTBmVKarVbe+mNd/rwAupXJOl4WYQ=,tag:xW/GUGCIfn466icpIvyvCQ==,type:str] from: ENC[AES256_GCM,data:QpUgsghc7e5OFJO8afzx6bt1,iv:ffrlbqFu2p5/uwv5MN9rf7iZSmfozYSwr3WkEvXNZhA=,tag:B3g+6WexBw6j6EgukX5LDg==,type:str] user: ENC[AES256_GCM,data:H2OxJp6q1QCxBxIXThXrj+SU,iv:Cu7KFDaiqM0cuofnqkLnE6Zb6ufLw6wQRSk1pthDAAo=,tag:oM1VefUo9kK8k7lHKnxOjA==,type:str] password: ENC[AES256_GCM,data:mAgsvDPzt8f/RB/2T8nrd+KUcuxUGIdCBDs5sFla5x0=,iv:qndiiKTuSpbf/gtNXPaZ6AnHHwzZ7IPJrDFriM7bKwE=,tag:5j+gjpaxIu03x1lBkRMLhQ==,type:str] aliases: ENC[AES256_GCM,data:fOZRYZ8rVs3IXhiS+VaP54gF4bir66oIZvb7ZfKV,iv:bsmh1ZCwERZuHrvORP68hj5Gz7j3+K6ZW8BR3/IQVQg=,tag:jWozmXpjk3JHCINSgP4KGg==,type:str] sops: - lastmodified: "2025-09-06T16:50:17Z" - mac: ENC[AES256_GCM,data:QdWLok9IBqTaO3StKRiAXcMIZSV5YJQoYY+3cZZ7xARbmvn5cDqnapv3HIJju7v5V48tNG3aXy1nJHG4kKVuDIMd7s7PPjLL1k0dEsnTs4YwE8XugZX86nXuSUZeUuQNfnR9sFOKho/o/I9W5hCp0IcEgo+Bs1dD3IvYxuv6Nzk=,iv:IHEDtI6lo76qPgBvBETg/SiT/tfFivN8r8J7tt93IbQ=,tag:ifW8UVaf5r8Y9HUUtCkAQQ==,type:str] + lastmodified: "2025-11-24T11:48:22Z" + mac: ENC[AES256_GCM,data:wA4AwEX67amH4UneZqV03PnaLUscUnj4VAmOqzjOTA9dKAV3KzFwD4NqRs2Dy8ap6kOOIS67gZ+3WV8QySyLT84zhEPSjB6M1FURV+LQjd4nc5EBP4Y67osy/QGB4U0d6shHt1sTFmHG2dJvTB7sPDSlRvgDhHE/ApcWuNFUfTY=,iv:Umacpqk+Zge9a9tlSsfjz1mcQvtequK8K4qLVJu8PCg=,tag:H09qfzM/xyn7TLkPCgtS6Q==,type:str] pgp: - created_at: "2025-09-06T16:37:33Z" enc: |- @@ -63,4 +64,4 @@ sops: -----END PGP MESSAGE----- fp: b730b2bf54eb792a14bfd3e68c14c08894376c5f unencrypted_suffix: _unencrypted - version: 3.10.2 + version: 3.11.0 diff --git a/sops.nix b/sops.nix index af34e3b3..d991b2db 100644 --- a/sops.nix +++ b/sops.nix @@ -12,7 +12,7 @@ let "0D98D5964AC8BB1CA034CE4EC456133700066642" # xyno main gpg key ]; keysPerHost = ( - mapAttrs (n: v: (toList v.sopsKey)) (filterAttrs (n: v: v ? sopsKey) instanceConfigs) + mapAttrs (n: v: (toList v.config.xyno.meta.sopsKey)) (filterAttrs (n: v: v.config.xyno.meta.sopsKey != null) instanceConfigs) ); desktopHostNames = [ "theseus" ];