From b9db20d45cc8b52082e7eba30c0d22c1e5dab432 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 15 Oct 2026 19:22:18 +0200 Subject: [PATCH] Nixos updates 11-10-2026 --- flake.lock | 250 ++++++++++++++----------- flake.nix | 40 ++-- iso/iso/default.nix | 2 +- iso/proxmox/default.nix | 2 +- machines/amaterasu/main/default.nix | 2 +- machines/amaterasu/minimal/default.nix | 2 +- machines/builder/default.nix | 2 +- machines/izanagi/main/default.nix | 2 +- machines/izanagi/minimal/default.nix | 2 +- machines/minimal.nix | 2 +- machines/susano/main/default.nix | 2 +- machines/susano/minimal/default.nix | 2 +- modules/development/emacs/default.nix | 2 +- modules/scripts/pve-build.sh | 162 ++++++++++------ 14 files changed, 284 insertions(+), 190 deletions(-) diff --git a/flake.lock b/flake.lock index 9c4296b..76d6ef3 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ ] }, "locked": { - "lastModified": 1788016784, - "narHash": "sha256-RO90Fk+Rn2Yy+I8oL4ePTLLKLgOAr8hrTx7tlpwdLaA=", + "lastModified": 1791041429, + "narHash": "sha256-Y/Q4JtMo6nHB6XS1LPSfK7Y4AnuNl9jci/5sCps1MRc=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "783bfd9ae441d1d0519b979ac68b73ddd6e81df0", + "rev": "52ea11f06dd492f34b3cc0b39a9c805beecafcff", "type": "github" }, "original": { @@ -127,11 +127,11 @@ "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1787524125, - "narHash": "sha256-P48TOQdIbB0PKMn4FTk6X0utbf0LemNlJ+bFcSbveGA=", + "lastModified": 1791505570, + "narHash": "sha256-2yRQ87dNTVr1kauBR6PTlfw7hnm90MAL0ObpA05xOTU=", "owner": "9001", "repo": "copyparty", - "rev": "9de090265f8d063056320f41d984830839017a2f", + "rev": "0dc1cb329120743ca85599ba3fba24849f137677", "type": "github" }, "original": { @@ -147,11 +147,11 @@ ] }, "locked": { - "lastModified": 1781152676, - "narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=", + "lastModified": 1789770686, + "narHash": "sha256-uZkBR7yHdIKUFB5SZdfgh1qkGfI3XmYmI/lTiquxbck=", "owner": "nix-community", "repo": "disko", - "rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1", + "rev": "725ea35e410ad83be4931d1bff7e090eacaf3563", "type": "github" }, "original": { @@ -166,11 +166,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1788150896, - "narHash": "sha256-suPEqotkAM4UyRxFk6VjWg1E/yBRrpom2E9lr0vnT+8=", + "lastModified": 1791694748, + "narHash": "sha256-EuKPk2ArrYaFRw5zfSOtuR3qJDONkU+tKSUIQHpK0nA=", "owner": "nix-community", "repo": "emacs-overlay", - "rev": "f6229276417aa356ae16dfd3b21b51525f55083f", + "rev": "383b1adaf66e95ef5976068ebc3d55ec13009b7b", "type": "github" }, "original": { @@ -401,11 +401,11 @@ ] }, "locked": { - "lastModified": 1786719456, - "narHash": "sha256-B74DLQs/VjlqyhnnX3tguWwghqJHWSJX30TKZuAljIg=", + "lastModified": 1790819692, + "narHash": "sha256-rvubAPbh3QCliic3sAK+CXTrPCGgJstY52OTs/5H1J4=", "owner": "nix-community", "repo": "home-manager", - "rev": "83b7606dcf44abe3a94b86e8bb2b3355d22e8797", + "rev": "c8ecc29e5175452bee4a2aa1ba2383856d795338", "type": "github" }, "original": { @@ -458,6 +458,38 @@ "systems" ] }, + "locked": { + "lastModified": 1791066858, + "narHash": "sha256-hLh6ALHrGpgYm8viWCo1pO+ErC22YDGdAvVPcfYsXA8=", + "owner": "hyprwm", + "repo": "hyprgraphics", + "rev": "80c7d00f2236732853e390019ff8d79d17fa3612", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprgraphics", + "type": "github" + } + }, + "hyprgraphics_2": { + "inputs": { + "hyprutils": [ + "hyprland", + "xdph", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "xdph", + "nixpkgs" + ], + "systems": [ + "hyprland", + "xdph", + "systems" + ] + }, "locked": { "lastModified": 1786464367, "narHash": "sha256-k58p4wbzIXWyRWrW84pP8tD+iaZSSYiiM+fr0Auk4oU=", @@ -480,6 +512,7 @@ "hyprland-guiutils": "hyprland-guiutils", "hyprland-protocols": "hyprland-protocols", "hyprlang": "hyprlang", + "hyprtoolkit": "hyprtoolkit", "hyprutils": "hyprutils", "hyprwayland-scanner": "hyprwayland-scanner", "hyprwire": "hyprwire", @@ -489,11 +522,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1788100302, - "narHash": "sha256-21MFGYEl3m5SjN9kZGKb+gELVLlMCF1DkbwHqHzSK1w=", + "lastModified": 1791545463, + "narHash": "sha256-EuTde/DbLBZ0nm8Ctj4Il3M5SKsWAKeDITvUuatu5+g=", "ref": "refs/heads/main", - "rev": "86c24e2e079aa62214421c76f01b603fc8178125", - "revCount": 7779, + "rev": "663b29b846e4bad17cfa29941f6d2fbb6b61f139", + "revCount": 7901, "type": "git", "url": "https://github.com/hyprwm/Hyprland" }, @@ -516,7 +549,10 @@ "hyprland", "hyprlang" ], - "hyprtoolkit": "hyprtoolkit", + "hyprtoolkit": [ + "hyprland", + "hyprtoolkit" + ], "hyprutils": [ "hyprland", "hyprutils" @@ -565,11 +601,11 @@ ] }, "locked": { - "lastModified": 1788037253, - "narHash": "sha256-QSGOM0IFpp45DwmtIwcih8+kKuSgAoQal9QkVVSRNew=", + "lastModified": 1791378645, + "narHash": "sha256-9Eix+ZUcI9IUklrtJAD9l/nTcS/Byz7fi94Y3InxS2Y=", "owner": "hyprwm", "repo": "hyprland-plugins", - "rev": "67c3a4c019f223c27b5bdc6bb656ce891a60861a", + "rev": "428bfcd1c9ee34965400bb359349f518140c9920", "type": "github" }, "original": { @@ -590,11 +626,11 @@ ] }, "locked": { - "lastModified": 1772460177, - "narHash": "sha256-/6G/MsPvtn7bc4Y32pserBT/Z4SUUdBd4XYJpOEKVR4=", + "lastModified": 1789475883, + "narHash": "sha256-YRFLrPESYitsDYqQKquOFg8OWNI7tHKwPnTrTZWXxWY=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "1cb6db5fd6bb8aee419f4457402fa18293ace917", + "rev": "cc9a8fd253bdc00f48a967ecf4828211ef08751f", "type": "github" }, "original": { @@ -636,46 +672,39 @@ "inputs": { "aquamarine": [ "hyprland", - "hyprland-guiutils", "aquamarine" ], "hyprgraphics": [ "hyprland", - "hyprland-guiutils", "hyprgraphics" ], "hyprlang": [ "hyprland", - "hyprland-guiutils", "hyprlang" ], "hyprutils": [ "hyprland", - "hyprland-guiutils", "hyprutils" ], "hyprwayland-scanner": [ "hyprland", - "hyprland-guiutils", "hyprwayland-scanner" ], "nixpkgs": [ "hyprland", - "hyprland-guiutils", "nixpkgs" ], "systems": [ "hyprland", - "hyprland-guiutils", "systems" ] }, "locked": { - "lastModified": 1785930473, - "narHash": "sha256-DitTu625BhEYpZjtjxtGpjrEJwPwW+X/+jJvhSZNSJM=", + "lastModified": 1789562890, + "narHash": "sha256-LFzeVJkDMQLjCpi55S9oc3N/wMrW2RCS1ShPL+1HB78=", "owner": "hyprwm", "repo": "hyprtoolkit", - "rev": "af515b69dfbe366dc7873aa1475cb2f4db3ebad7", + "rev": "b3f2d0e725e4eaf804af7e529cb69bbed43d1a04", "type": "github" }, "original": { @@ -696,11 +725,11 @@ ] }, "locked": { - "lastModified": 1786903207, - "narHash": "sha256-QTwMqLLONRhv9iz6CVeuX6BqQNQCIqI8hL/cPYlR/24=", + "lastModified": 1789968180, + "narHash": "sha256-YGRfhw+fJW7oKW3IspoceD34jeokN1KXNxKU6APlFH4=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "6cf50415e06dc6bd9f1252f1b745eac6b4a1cc39", + "rev": "95983ee836ff205e615bba67d1f67098e1231941", "type": "github" }, "original": { @@ -768,11 +797,11 @@ "nixpkgs": "nixpkgs_6" }, "locked": { - "lastModified": 1787822983, - "narHash": "sha256-wusELfq9vxbkbZy8cPprcOldqoqSbKltxt++EW9gQ9g=", + "lastModified": 1791490285, + "narHash": "sha256-JPu+WSXX4TaQnue+UKGMmv2YYCbM5t9Bwwm0fp6lJXc=", "owner": "Lxtharia", "repo": "minegrub-theme", - "rev": "89f9e24f44cbe06b11d69068e39f534666e4d3d3", + "rev": "cdd067ebc31ac59e24ae3c99e5b0f05a18eb8a1d", "type": "github" }, "original": { @@ -803,11 +832,11 @@ ] }, "locked": { - "lastModified": 1788166029, - "narHash": "sha256-+hgpdq6rXpbBHhB5Pbu80kq7UTZhVpbZZtJXePs9ufE=", + "lastModified": 1791190188, + "narHash": "sha256-d+5+d7r62PZcHc4UFA5HkjxnzBDfVIixsdJX+dwQsyI=", "owner": "Mic92", "repo": "nix-ld", - "rev": "2cced31ac171b55dd6ab8cc04502cb1ad012d7cf", + "rev": "2ba7201c2db8a49b9bd745d240430282f67bbe39", "type": "github" }, "original": { @@ -857,11 +886,11 @@ "nixpkgs": "nixpkgs_7" }, "locked": { - "lastModified": 1788044418, - "narHash": "sha256-cmOd3iGoE140M2GidgQMQbyxHZ4dT7C0QZq2+CrXQyA=", + "lastModified": 1791373788, + "narHash": "sha256-c3oMt0QoE+4yiRk6u1m2L9ogjaUw0uTGn9yk808KkgE=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "dc3f0cfde2050172abf6c3cdb684f735c15a57c5", + "rev": "4bc63156b109ee7b4103e3ec30565c8c92bde435", "type": "github" }, "original": { @@ -919,11 +948,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1787962033, - "narHash": "sha256-u6z9VTZA4Kf3RkHQo9sQI7NI4Ei/uiU9vrMqOiwWP1Y=", + "lastModified": 1791426274, + "narHash": "sha256-MWhktfFtFE8Jl7bf9Pkp7TR5MSdYCjCswSo0Gkb4ywc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c5c4a43b0e8056328ec4529f735cabdb8f1942bb", + "rev": "7c8764b7c7b09b34f632464276218ef9090eaa11", "type": "github" }, "original": { @@ -935,11 +964,11 @@ }, "nixpkgs_10": { "locked": { - "lastModified": 1786599213, - "narHash": "sha256-yNJd40f11EzXBjSByCB7IPpeFFAdeoSKKM67dGkfFoU=", + "lastModified": 1790689126, + "narHash": "sha256-ilerN1WLSvF+HMjziC/Wv99J5y02maDH+6hZPwsORKg=", "owner": "nixos", "repo": "nixpkgs", - "rev": "0e251e24a4f24e036a084b6b4b2d2491af4167f4", + "rev": "b4fd65b198c599cbe814fcb9f42d25d021595ec9", "type": "github" }, "original": { @@ -981,11 +1010,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1788039129, - "narHash": "sha256-pa4Q0qErvCvzCaaUph7Sm37RhR4xvPrYI8Lgz6k85+A=", + "lastModified": 1791594108, + "narHash": "sha256-XK4KceonkwD8LuMAt/vNrz982mXJM5jeHAxMwsUXXAQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d2f67949798825fe853f7c5d0492b8bf016d3f88", + "rev": "6510408d147d8c5e6d76043e899e9251756f6a75", "type": "github" }, "original": { @@ -997,11 +1026,11 @@ }, "nixpkgs_5": { "locked": { - "lastModified": 1787736819, - "narHash": "sha256-cV5xEJJK3BvhU8rEd4mC9UsmDi5qscv/kzGPhBRC5WA=", + "lastModified": 1791048980, + "narHash": "sha256-KgItSKML8Xvte0B7/uGnBDsYzSnnKHcOaiUbgWBXLXw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9fbb54b33e91ee4ca368e35a78e0613c720600b3", + "rev": "a7868a727837f3c09cee2ce0ca671c76b1589fed", "type": "github" }, "original": { @@ -1029,11 +1058,11 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1767892417, - "narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=", - "rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba", + "lastModified": 1789546076, + "narHash": "sha256-vWkSk5bbfTqdtMoSgD9FshACO8JCvXTFi+3cqEp0mH0=", + "rev": "b1b875982b17dabde9b4a37f3e229e74913e6db3", "type": "tarball", - "url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz" + "url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1074753.b1b875982b17/nixexprs.tar.xz" }, "original": { "type": "tarball", @@ -1058,11 +1087,11 @@ }, "nixpkgs_9": { "locked": { - "lastModified": 1775036866, - "narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=", + "lastModified": 1789149629, + "narHash": "sha256-H6GwaZzZf+4npqv0tph94w9tZddSjFjmQrVsW0z78uk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6201e203d09599479a3b3450ed24fa81537ebc4e", + "rev": "eaad089433ca2bb662274377d33df3d0e51ef28b", "type": "github" }, "original": { @@ -1079,11 +1108,11 @@ ] }, "locked": { - "lastModified": 1788154427, - "narHash": "sha256-nCzmnj3rk60iznPMoDBg09b3wsDzEoGAjQj81QlsUTo=", + "lastModified": 1791701131, + "narHash": "sha256-mBCtcZPGgBLfEYxFvBRsc0KeDz0JtN2BMhcIWGoMk94=", "owner": "noctalia-dev", "repo": "noctalia", - "rev": "bee126157205f9e686e4f3f98d2cc3be1c1bf252", + "rev": "45084cf764f08c1f00e0c7e7432732f225105b7e", "type": "github" }, "original": { @@ -1126,11 +1155,11 @@ ] }, "locked": { - "lastModified": 1787424939, - "narHash": "sha256-O2tBn84NNuHrnqNVxx/XqsXwfYvS1YwBh+7CBnbCYsk=", + "lastModified": 1790500375, + "narHash": "sha256-XN3sDtn8TU9hAc9xqZ+SqRB/HHm2wjxM6aSWYLJU+oo=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "809414f0cdadf82cf11b06c2b29ba9b3168b3297", + "rev": "a0e4241b51206fbcbf52fd322eb5f0cd80f153c4", "type": "github" }, "original": { @@ -1155,11 +1184,11 @@ ] }, "locked": { - "lastModified": 1773870109, - "narHash": "sha256-ZoTdqZP03DcdoyxvpFHCAek4bkPUTUPUF3oCCgc3dP4=", + "lastModified": 1788149501, + "narHash": "sha256-XKJP4KvhawV3pyVfraX3sflz05Rp7KP74gRt6QqKjNE=", "owner": "pyproject-nix", "repo": "build-system-pkgs", - "rev": "b6e74f433b02fa4b8a7965ee24680f4867e2926f", + "rev": "150839ac67b5a34db56a55e8f6b7099a4e7878ab", "type": "github" }, "original": { @@ -1176,11 +1205,11 @@ ] }, "locked": { - "lastModified": 1775439158, - "narHash": "sha256-NHY9SJNU019n+8NCabBDtmuzRFeE2gZlYKHowp9bV24=", + "lastModified": 1788394333, + "narHash": "sha256-xYOP0Xym1eVGUaHFx+eJEaycFGoiCbst3fZf0xFHP78=", "owner": "pyproject-nix", "repo": "pyproject.nix", - "rev": "fb6b728260f3f32761367e9fd1e1a25b4245bcd0", + "rev": "6a8a7881d75b6f98967e7b8069f4ead331384301", "type": "github" }, "original": { @@ -1221,11 +1250,11 @@ ] }, "locked": { - "lastModified": 1786629091, - "narHash": "sha256-gkig4nPi1CWc4Z50GBsjE4ygSE7hMpl/TwID2an2Cck=", + "lastModified": 1791710405, + "narHash": "sha256-mVD4XIc5JkqMW2K04IkFUzHgHmyJZlzw5ktfgMDCbKU=", "owner": "Mic92", "repo": "sops-nix", - "rev": "a8627b21b9107c5711c96b84f32a9a4b3d45295f", + "rev": "ee48786c6f9160d2c1a084aac841f68195b8420c", "type": "github" }, "original": { @@ -1242,11 +1271,11 @@ "nix-filter": "nix-filter" }, "locked": { - "lastModified": 1787489216, - "narHash": "sha256-VE1o0B6GPHrwmYANfGIEm/hDz2u4IhG0Gdj+ZkEV2uY=", + "lastModified": 1790431438, + "narHash": "sha256-D0pKfzVlRz8VnLIZVaPtr2d+LHYspICllgIz+oQlw98=", "owner": "zjeffer", "repo": "split-monitor-workspaces", - "rev": "47b22971e3a21d228882ca1e2509fdac26f2d5b2", + "rev": "f26d624c2638d0661f3e0352a634650bfd08296d", "type": "github" }, "original": { @@ -1275,11 +1304,11 @@ "tinted-zed": "tinted-zed" }, "locked": { - "lastModified": 1787771653, - "narHash": "sha256-DkkJSBOXWV/mja5Vy8az5g1KpZlsbUwlmH0BsQhowaQ=", + "lastModified": 1791574276, + "narHash": "sha256-UMnLnZ3JlA7UTBNNNx1rNsXYoPP/cirXLCKGiQ/yDx8=", "owner": "nix-community", "repo": "stylix", - "rev": "5e3809851f486e7fc7e84b40f174c74b60ecc784", + "rev": "2856c4c6a845b9bec98828ef197abe176e4806bb", "type": "github" }, "original": { @@ -1343,11 +1372,11 @@ "uv2nix": "uv2nix" }, "locked": { - "lastModified": 1776248910, - "narHash": "sha256-MrwY8D48uZMTI/D6TEBmG1osklyAlqdtYeH+1cBeRNU=", + "lastModified": 1791196392, + "narHash": "sha256-BQ2f4gEtc2An1t9xac66C+ZIPEopJotoH2OhNcm5eLg=", "owner": "LichHunter", "repo": "thefuck", - "rev": "7cac5ac8709dade676264af51afbe7a4d3c84582", + "rev": "7a102bb398407e57aaf64f4e5123f47256b11c04", "type": "github" }, "original": { @@ -1422,11 +1451,11 @@ }, "unstable": { "locked": { - "lastModified": 1788039129, - "narHash": "sha256-pa4Q0qErvCvzCaaUph7Sm37RhR4xvPrYI8Lgz6k85+A=", + "lastModified": 1791594108, + "narHash": "sha256-XK4KceonkwD8LuMAt/vNrz982mXJM5jeHAxMwsUXXAQ=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d2f67949798825fe853f7c5d0492b8bf016d3f88", + "rev": "6510408d147d8c5e6d76043e899e9251756f6a75", "type": "github" }, "original": { @@ -1443,11 +1472,11 @@ ] }, "locked": { - "lastModified": 1788146656, - "narHash": "sha256-XmJmvk9rytTb7dCotO/aqR+YysB8HOqnprlOdv+LAF4=", + "lastModified": 1791642191, + "narHash": "sha256-0bK0A59rVUn1SRZzo4cNi4VSqAe7vR1gL2/MZl53Frw=", "owner": "nix-community", "repo": "home-manager", - "rev": "82c265faf4e3161d6015db07c9b0f1ee36a9029b", + "rev": "c58f54c733a7894d84fa2fdff26cc12088c4b78c", "type": "github" }, "original": { @@ -1469,11 +1498,11 @@ ] }, "locked": { - "lastModified": 1775386139, - "narHash": "sha256-n82p7WF+dYxf5r01pXlqbk8CAF7xX0Tk7wAcmMjkuhc=", + "lastModified": 1788001239, + "narHash": "sha256-AELmsXPI546MhbC/ZXC7WRUkCz7d4rqKTHUmliIgPpI=", "owner": "pyproject-nix", "repo": "uv2nix", - "rev": "3cffcee173635d553e213d11418690b5290ff1c9", + "rev": "7f9c6b613d2e749e54854b1d60ab6a2192db889e", "type": "github" }, "original": { @@ -1502,6 +1531,11 @@ }, "xdph": { "inputs": { + "aquamarine": [ + "hyprland", + "aquamarine" + ], + "hyprgraphics": "hyprgraphics_2", "hyprland-protocols": [ "hyprland", "hyprland-protocols" @@ -1510,6 +1544,10 @@ "hyprland", "hyprlang" ], + "hyprtoolkit": [ + "hyprland", + "hyprtoolkit" + ], "hyprutils": [ "hyprland", "hyprutils" @@ -1528,11 +1566,11 @@ ] }, "locked": { - "lastModified": 1786988229, - "narHash": "sha256-frEFLVRj8xXvBBDs44IRiqHo6R2PxsRpluygL7abjjI=", + "lastModified": 1790080407, + "narHash": "sha256-uKM+FAvcllYFcHoh4LEmyB0CGLaT3dMOjK4dxXyIIgc=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "59d429bf45aed4e2209043c0c36565ad8e2859a5", + "rev": "e87ae7823e7bf0601385220c69b5a3b245123fc5", "type": "github" }, "original": { @@ -1547,11 +1585,11 @@ "nixpkgs": "nixpkgs_10" }, "locked": { - "lastModified": 1788149125, - "narHash": "sha256-GueAv4789rOV70hixnL9+uN4tiDKJm7s92DnTejdpuE=", + "lastModified": 1791629930, + "narHash": "sha256-djG2tdpl/U+8eUmlozsRTRoU2yIvh8r1z8qj8gB/qWM=", "owner": "0xc000022070", "repo": "zen-browser-flake", - "rev": "5fe00f38d41ced9a5c0ba1cbf2127d7e8b3e3d56", + "rev": "1fd1ee43a0fd0bff17a8ba07e2a281406a92991f", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 6801bb0..6df702f 100644 --- a/flake.nix +++ b/flake.nix @@ -213,19 +213,35 @@ "fujin"; }; - packages.x86_64-linux = { - nixos-lxc = (nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - modules = [ - ./machines/builder - ({ modulesPath, ... }: { - imports = [ (modulesPath + "/virtualisation/proxmox-lxc.nix") ]; - }) - ]; - specialArgs = { - inherit inputs; + packages.x86_64-linux = + let + builderSystem = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./machines/builder + ({ modulesPath, ... }: { + imports = [ (modulesPath + "/virtualisation/proxmox-lxc.nix") ]; + }) + ]; + specialArgs = { + inherit inputs; + }; }; - }).config.system.build.image; + in { + # pve-build keys template identity on this output's outPath: the + # store-path hash (covers nixpkgs pin + builder config) becomes the + # template filename on PVE. overrideAttrs only names the derivation + # so the filename reads -nixos-lxc-builder.tar.xz instead of + # -tarball.tar.xz. + nixos-lxc = builderSystem.config.system.build.image.overrideAttrs (_: { + name = "nixos-lxc-builder"; + }); + + # Toplevel the builder image boots. pve-build compares it against + # /run/current-system inside a running disposable to detect clones + # of stale templates (pct config drops the ostemplate field after + # creation, so it cannot be used for this). + nixos-lxc-toplevel = builderSystem.config.system.build.toplevel; izanami-proxmox = nixos-generators.nixosGenerate { system = "x86_64-linux"; diff --git a/iso/iso/default.nix b/iso/iso/default.nix index 811fd72..e4ccf21 100644 --- a/iso/iso/default.nix +++ b/iso/iso/default.nix @@ -19,7 +19,7 @@ in { nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; # Workaround for https://github.com/NixOS/nix/issues/9574 diff --git a/iso/proxmox/default.nix b/iso/proxmox/default.nix index b950a2f..22e4fbb 100644 --- a/iso/proxmox/default.nix +++ b/iso/proxmox/default.nix @@ -19,7 +19,7 @@ in { nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; # Workaround for https://github.com/NixOS/nix/issues/9574 diff --git a/machines/amaterasu/main/default.nix b/machines/amaterasu/main/default.nix index 61192db..9696212 100644 --- a/machines/amaterasu/main/default.nix +++ b/machines/amaterasu/main/default.nix @@ -26,7 +26,7 @@ in { nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; # Workaround for https://github.com/NixOS/nix/issues/9574 diff --git a/machines/amaterasu/minimal/default.nix b/machines/amaterasu/minimal/default.nix index 98d14c7..13b1586 100644 --- a/machines/amaterasu/minimal/default.nix +++ b/machines/amaterasu/minimal/default.nix @@ -33,7 +33,7 @@ in nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; # Workaround for https://github.com/NixOS/nix/issues/9574 diff --git a/machines/builder/default.nix b/machines/builder/default.nix index b591bdc..6044fc5 100644 --- a/machines/builder/default.nix +++ b/machines/builder/default.nix @@ -41,7 +41,7 @@ in { nix = { settings = { - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; flake-registry = ""; nix-path = config.nix.nixPath; diff --git a/machines/izanagi/main/default.nix b/machines/izanagi/main/default.nix index d0c37ff..c488d9f 100644 --- a/machines/izanagi/main/default.nix +++ b/machines/izanagi/main/default.nix @@ -26,7 +26,7 @@ in { nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; # Workaround for https://github.com/NixOS/nix/issues/9574 diff --git a/machines/izanagi/minimal/default.nix b/machines/izanagi/minimal/default.nix index 9084d84..e0499ad 100644 --- a/machines/izanagi/minimal/default.nix +++ b/machines/izanagi/minimal/default.nix @@ -33,7 +33,7 @@ in { nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; # Workaround for https://github.com/NixOS/nix/issues/9574 diff --git a/machines/minimal.nix b/machines/minimal.nix index 3798742..f85370e 100644 --- a/machines/minimal.nix +++ b/machines/minimal.nix @@ -51,7 +51,7 @@ in { nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; diff --git a/machines/susano/main/default.nix b/machines/susano/main/default.nix index de7afff..0540fd1 100644 --- a/machines/susano/main/default.nix +++ b/machines/susano/main/default.nix @@ -43,7 +43,7 @@ in nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; # Workaround for https://github.com/NixOS/nix/issues/9574 diff --git a/machines/susano/minimal/default.nix b/machines/susano/minimal/default.nix index 4d6b60b..2a8b8fd 100644 --- a/machines/susano/minimal/default.nix +++ b/machines/susano/minimal/default.nix @@ -42,7 +42,7 @@ in nix = { settings = { # Enable flakes and new 'nix' command - experimental-features = "nix-command flakes"; + experimental-features = [ "nix-command" "flakes" ]; # Opinionated: disable global registry flake-registry = ""; # Workaround for https://github.com/NixOS/nix/issues/9574 diff --git a/modules/development/emacs/default.nix b/modules/development/emacs/default.nix index 46d0259..e4d6e1e 100644 --- a/modules/development/emacs/default.nix +++ b/modules/development/emacs/default.nix @@ -39,7 +39,7 @@ in { ## Module dependencies # :checkers spell - (aspellWithDicts (ds: with ds; [ en en-computers en-science ])) + (aspellWithDicts (ds: with ds; [ en ])) # :tools editorconfig editorconfig-core-c # per-project style config # :tools lookup & :lang org +roam diff --git a/modules/scripts/pve-build.sh b/modules/scripts/pve-build.sh index 064512a..1d36cad 100755 --- a/modules/scripts/pve-build.sh +++ b/modules/scripts/pve-build.sh @@ -8,8 +8,8 @@ # # Stage Step command Effect # ------ ------------------------- -------------------------------------- -# 1 check-image Read-only: is a NixOS LXC ostemplate on PVE? -# deploy-image Idempotent: build+upload if missing, no-op if present. +# 1 check-image Read-only: is the ostemplate matching the current flake on PVE? +# deploy-image Idempotent: build+upload if missing/stale, no-op if current. # update-image Force: rebuild locally + replace on PVE. # 2 start-builder deploy-image + clone a fresh CT under a free # VMID + start it + wait for DHCP. @@ -90,6 +90,7 @@ PVE_BRIDGE="${PVE_BRIDGE:-vmbr0}" # network bridge VMID_START="${VMID_START:-9999}" # scan downward from here for a free VMID VMID_FLOOR="${VMID_FLOOR:-100}" # lowest VMID to consider (PVE minimum) TEMPLATE_OUTPUT="${TEMPLATE_OUTPUT:-nixos-lxc}" # flake output to build +TEMPLATE_TOPLEVEL_OUTPUT="${TEMPLATE_TOPLEVEL_OUTPUT:-nixos-lxc-toplevel}" # flake output a disposable must be running CT_HOSTNAME_PREFIX="${CT_HOSTNAME_PREFIX:-nixos-builder}" # disposables' hostname prefix BUILD_SSH_USER="${BUILD_SSH_USER:-builder}" # user nixos-rebuild SSHes as on the CT CT_BOOT_TIMEOUT="${CT_BOOT_TIMEOUT:-120}" # seconds to wait for DHCP lease @@ -244,9 +245,9 @@ Composite commands (chain all stages): + destroy-builder. Disposable destroyed on success. Step commands (run one stage — VMID auto-discovered from PVE if omitted): - check-image Read-only: exit 0 if a NixOS LXC ostemplate is on PVE, 1 if not. - deploy-image Idempotent: build+upload if missing, no-op if present. - update-image Force: rebuild .$TEMPLATE_OUTPUT locally + replace on PVE. + check-image Read-only: exit 0 if the ostemplate matching the current flake is on PVE. + deploy-image Idempotent: build+upload if missing/stale, no-op if current. + update-image Force: rebuild .$TEMPLATE_OUTPUT + upload. Old templates are kept. start-builder deploy-image + clone a fresh CT + start. build-on [VMID] Build closure on an existing disposable. activate @@ -279,7 +280,8 @@ Options: Environment: PVE_HOST, PVE_STORAGE, PVE_ROOTFS_STORAGE, PVE_BRIDGE, VMID_START, VMID_FLOOR, BUILD_SSH_USER, - CT_BOOT_TIMEOUT, CT_ROOTFS_GIB, TEMPLATE_OUTPUT, CT_HOSTNAME_PREFIX + CT_BOOT_TIMEOUT, CT_ROOTFS_GIB, TEMPLATE_OUTPUT, TEMPLATE_TOPLEVEL_OUTPUT, + CT_HOSTNAME_PREFIX Examples: # Full happy path — build + activate susano permanently, auto-destroy CT. @@ -481,17 +483,33 @@ resolve_vmid() { ## --------------------------------------------------------------------------- # Stage 1: image management (check / deploy / update). # All three operate on the NixOS LXC ostemplate stored in PVE's -# /var/lib/vz/template/cache/. The "latest" template is whichever -# nixos-lxc-*.tar.xz sorts last alphabetically (matches the helpers below). +# /var/lib/vz/template/cache/. +# +# Template identity: .$TEMPLATE_OUTPUT's store path is evaluated (no build); +# its basename embeds the full derivation hash — nixpkgs pin AND NixOS +# config — and becomes the uploaded filename. Matching against PVE is exact: +# a template matches the current flake iff its name equals the evaluated +# one. This catches both "missing" and "stale" images. (The previous +# "alphabetically last nixos*lxc*.tar.xz" pick was wrong: unstable version +# strings like 26.05pre-git sort above dated stable ones like 25.05.2026…, +# so a stale image could win over the current one.) # --------------------------------------------------------------------------- -# Echo the storage-relative path of the newest nixos-lxc template on PVE, or -# empty if none. Read-only. -find_template_on_pve() { - debug "find_template_on_pve: pveam list $PVE_STORAGE" - pve pveam list "$PVE_STORAGE" 2>/dev/null \ - | awk '/nixos.*lxc.*\.tar\.xz/ {print $1}' \ - | sort | tail -n1 || true +# Evaluate the image derivation's store path WITHOUT building it, and derive +# the canonical template filename from it. Sets TEMPLATE_FILENAME and +# OSTEMPLATE. Because the store-path hash covers the flake lock and the +# whole NixOS config, any edit to machines/builder/ or nixpkgs pin bump +# changes the filename — "same name, older build" becomes impossible. +resolve_template_identity() { + step "Evaluating .$TEMPLATE_OUTPUT image identity (nix eval, no build) ..." + local out_path + out_path=$(cd "$FLAKE_ROOT" && nix eval --raw ".#$TEMPLATE_OUTPUT.outPath") \ + || die "Failed to eval .$TEMPLATE_OUTPUT.outPath — is the flake evaluable?" + TEMPLATE_FILENAME="$(basename "$out_path").tar.xz" + OSTEMPLATE="$PVE_STORAGE:vztmpl/$TEMPLATE_FILENAME" + debug "image outPath: $out_path" + debug "template on PVE: $OSTEMPLATE" + ok "Current flake image: $TEMPLATE_FILENAME" } # Build .$TEMPLATE_OUTPUT locally and scp the tarball to PVE's template cache. @@ -505,80 +523,60 @@ build_and_upload_image() { || die "nix build .$TEMPLATE_OUTPUT produced no output path." log " nix output: $result_dir" - # nixos-generators proxmox-lxc format lays the file under result/tarball/*.tar.xz + # Identity first, so the upload target is the canonical hash-embedded + # filename even when called without a prior check_image (update-image). + resolve_template_identity + + # nixos-generators / proxmox-lxc image lays the file under result/tarball/*.tar.xz local tarball tarball=$(find "$result_dir/tarball" -maxdepth 1 -type f -name '*.tar.xz' -print -quit | head -n1) [[ -n "$tarball" ]] \ - || die "No .tar.xz found under $result_dir/tarball/. Did nixos-generators output layout change?" - local tname; tname=$(basename "$tarball") + || die "No .tar.xz found under $result_dir/tarball/. Did the image output layout change?" debug "tarball path: $tarball" - debug "tarball name: $tname" - ok "Built image: $tname" + ok "Built image: $(basename "$tarball")" step "Uploading to $PVE_HOST:/var/lib/vz/template/cache/ ..." local size_human size_human=$(du -h "$tarball" | cut -f1) - log " scp $tarball ($size_human) -> $PVE_HOST:/var/lib/vz/template/cache/$tname" - pve_scp "$tarball" "$PVE_HOST:/var/lib/vz/template/cache/$tname" - - OSTEMPLATE="$PVE_STORAGE:vztmpl/$tname" + log " scp $tarball ($size_human) -> $PVE_HOST:/var/lib/vz/template/cache/$TEMPLATE_FILENAME" + pve_scp "$tarball" "$PVE_HOST:/var/lib/vz/template/cache/$TEMPLATE_FILENAME" } -# Remove old nixos-lxc templates from PVE, keeping $1. Must be called after -# the new image is uploaded so a build/upload failure leaves the previous -# template intact. -purge_old_templates_on_pve() { - local keep="${1:-}" - step "Purging old nixos-lxc templates from $PVE_HOST (keeping ${keep:-none}) ..." - local all - all=$(pve pveam list "$PVE_STORAGE" 2>/dev/null \ - | awk '/nixos.*lxc.*\.tar\.xz/ {print $1}' || true) - local removed=0 - while IFS= read -r t; do - [[ -n "$t" ]] || continue - if [[ -n "$keep" && "$t" == "$keep" ]]; then - debug "keeping: $t" - continue - fi - local filename="${t##*/}" - log " removing: $t" - pve rm -f "/var/lib/vz/template/cache/$filename" 2>/dev/null || true - removed=$((removed + 1)) - done <<<"$all" - ok "Purged $removed old template(s)" -} - -# Read-only check. Sets OSTEMPLATE and returns 0 if a template exists; -# clears OSTEMPLATE and returns 1 if missing. +# Read-only check. Sets OSTEMPLATE and returns 0 if the template matching +# the CURRENT flake build is on PVE; clears OSTEMPLATE and returns 1 if it +# is missing or stale (a differently-named nixos-lxc template may exist). check_image() { - step "Checking for nixos-lxc ostemplate on $PVE_HOST (storage: $PVE_STORAGE) ..." + resolve_template_identity + step "Checking for $OSTEMPLATE on $PVE_HOST (storage: $PVE_STORAGE) ..." local existing - existing=$(find_template_on_pve) + existing=$(pve pveam list "$PVE_STORAGE" 2>/dev/null | awk -v t="$OSTEMPLATE" '$1 == t {print $1}') if [[ -n "$existing" ]]; then - OSTEMPLATE="$existing" - ok "Image present: $OSTEMPLATE" + ok "Image present (matches current flake build): $OSTEMPLATE" return 0 fi OSTEMPLATE="" - warn "No nixos-lxc ostemplate found." + warn "No template matching the current flake build on $PVE_HOST." return 1 } -# Idempotent deploy: build + upload only if no template exists. +# Idempotent deploy: ensure PVE holds the template matching the CURRENT +# flake build. No-op when it matches; build + upload otherwise. Historical +# templates are deliberately left in place — other tooling (e.g. the +# terraform handler) may pin containers to them. deploy_image() { if check_image; then - log "Nothing to do — image already on PVE." + log "Nothing to do — image on PVE matches current flake build." return fi build_and_upload_image ok "Image deployed: $OSTEMPLATE" } -# Force update: build + upload first, then purge old. If the build or upload -# fails, the previous template remains on PVE. +# Force update: rebuild + upload even if the current template is present. +# Old templates are never deleted (terraform may pin them); prune manually +# with `pveam remove` if really desired. update_image() { build_and_upload_image - purge_old_templates_on_pve "$OSTEMPLATE" ok "Image updated: $OSTEMPLATE" } @@ -640,11 +638,27 @@ create_and_start_ct() { # Echo the current IPv4 of a running container's eth0, or empty if unavailable. get_ct_ip() { local vmid="$1" - pve pct exec "$vmid" -- ip -j -4 addr show eth0 2>/dev/null \ + # NixOS containers have no standard /bin|/sbin — lxc-attach needs the + # full path or exec fails with "No such file or directory". + pve pct exec "$vmid" -- /run/current-system/sw/bin/ip -j -4 addr show eth0 2>/dev/null \ | jq -r '.[0].addr_info[]? | select(.scope=="global") | .local' 2>/dev/null \ | head -n1 || true } +# Echo the NixOS toplevel a running disposable actually booted, or empty. +# pct config drops the ostemplate field after creation, so the container's +# own /run/current-system is the only reliable record of what it runs. +ct_toplevel() { + local vmid="$1" + pve pct exec "$vmid" -- /run/current-system/sw/bin/readlink /run/current-system 2>/dev/null || true +} + +# Echo the toplevel the current flake's builder image boots, or empty on +# eval failure (callers treat empty as "cannot tell, skip the check"). +expected_toplevel() { + (cd "$FLAKE_ROOT" && nix eval --raw ".#$TEMPLATE_TOPLEVEL_OUTPUT.outPath" 2>/dev/null) || true +} + # Wait for a disposable to become SSH-reachable via its hostname. Echos the # hostname on success (so the caller can pass it to do_build / probe_ssh). # We deliberately do NOT use the IP here — the script's contract is that @@ -832,6 +846,21 @@ cmd_composite() { step "Container $vmid is stopped — starting ..." pve pct start "$vmid" fi + + local running_top want_top + running_top=$(ct_toplevel "$vmid") + want_top=$(expected_toplevel) + if [[ -n "$running_top" && -n "$want_top" && "$running_top" != "$want_top" ]]; then + warn "Disposable $vmid runs a stale image:" + warn " running: $running_top" + warn " current: $want_top" + step "Destroying $vmid and recreating from current image ..." + pve pct destroy "$vmid" --purge --force + vmid=$(find_free_vmid) + hostname="$CT_HOSTNAME_PREFIX-$vmid" + log "Created fresh disposable: $hostname" + create_and_start_ct "$vmid" + fi fi hostname=$(wait_for_ready "$vmid") @@ -867,6 +896,7 @@ cmd_composite() { # --------------------------------------------------------------------------- cmd_check_image() { require ssh "drive PVE" + require nix "evaluate the image identity" require_pve phase "check-image — read-only probe of ostemplate on PVE" if check_image; then @@ -970,6 +1000,16 @@ cmd_build_on() { die "Start it on PVE first ('pct start $vmid') or pick another VMID." fi + # Guard: a disposable cloned from a stale template boots without + # sshd/networkd config and hangs the build — refuse instead of hanging. + local running_top want_top + running_top=$(ct_toplevel "$vmid") + want_top=$(expected_toplevel) + if [[ -n "$running_top" && -n "$want_top" && "$running_top" != "$want_top" ]]; then + fail "Disposable $vmid runs a stale image: $running_top" + die "Current flake boots: $want_top — recreate with: $0 destroy-builder $vmid && $0 start-builder" + fi + probe_ssh "$hostname" || { print_debug_info "$vmid" "$hostname"; die "Aborting build-on."; } do_build "$vmid" "$hostname" && rc=0 || rc=$?