commit 3a3a8afe306d10dc91a133eacb9102100a9d574f Author: Chinmay D. Pai Date: Mon Sep 2 18:31:19 2024 +0530 feat: add nixos configuration based on snowfall-lib Signed-off-by: Chinmay D. Pai diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..750baeb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +result +result-* diff --git a/checks/deploy-rs/default.nix b/checks/deploy-rs/default.nix new file mode 100644 index 0000000..84b64a8 --- /dev/null +++ b/checks/deploy-rs/default.nix @@ -0,0 +1,2 @@ +{ inputs, ... }: +builtins.mapAttrs (_: deployLib: deployLib.deployChecks inputs.self.deploy) inputs.deploy-rs.lib diff --git a/data.nix b/data.nix new file mode 100644 index 0000000..5afc873 --- /dev/null +++ b/data.nix @@ -0,0 +1,28 @@ +{ + secrets = { + machines = { + thonkpad = { + password.file = ./secrets/machines/thonkpad/password.age; + root-password.file = ./secrets/machines/thonkpad/root-password.age; + }; + bicboye = { + password.file = ./secrets/machines/bicboye/password.age; + root-password.file = ./secrets/machines/bicboye/root-password.age; + }; + }; + services = { + gitea = { + password.file = ./secrets/services/gitea/password.age; + }; + miniflux = { + password.file = ./secrets/services/miniflux/password.age; + }; + paperless = { + password.file = ./secrets/services/paperless/password.age; + }; + vaultwarden = { + password.file = ./secrets/services/vaultwarden/password.age; + }; + }; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..c9d172b --- /dev/null +++ b/flake.lock @@ -0,0 +1,938 @@ +{ + "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": [ + "nixpkgs" + ], + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1723293904, + "narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=", + "owner": "ryantm", + "repo": "agenix", + "rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, + "cachix": { + "locked": { + "lastModified": 1635350005, + "narHash": "sha256-tAMJnUwfaDEB2aa31jGcu7R7bzGELM9noc91L2PbVjg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "1c1f5649bb9c1b0d98637c8c365228f57126f361", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-20.09", + "repo": "nixpkgs", + "type": "github" + } + }, + "crane": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1721842668, + "narHash": "sha256-k3oiD2z2AAwBFLa4+xfU+7G5fisRXfkvrMTCJrjZzXo=", + "owner": "ipetkov", + "repo": "crane", + "rev": "529c1a0b1f29f0d78fa3086b8f6a134c71ef3aaf", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1700795494, + "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "deploy-rs": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1718194053, + "narHash": "sha256-FaGrf7qwZ99ehPJCAwgvNY5sLCqQ3GDiE/6uLhxxwSY=", + "owner": "serokell", + "repo": "deploy-rs", + "rev": "3867348fa92bc892eba5d9ddb2d7a97b9e127a8a", + "type": "github" + }, + "original": { + "owner": "serokell", + "repo": "deploy-rs", + "type": "github" + } + }, + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1724349583, + "narHash": "sha256-zgB1Cfk46irIsto8666yLdKjqKdBrjR48Dd3lhQ0CnQ=", + "owner": "nix-community", + "repo": "disko", + "rev": "435737144be0259559ca3b43f7d72252b1fdcc1b", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "firefox": { + "inputs": { + "cachix": "cachix", + "flake-compat": "flake-compat_2", + "lib-aggregate": "lib-aggregate", + "mozilla": "mozilla", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1724347032, + "narHash": "sha256-/MsJjSKmdgoPj0LCt8FE+VjeDcQtTtw90cy7hca0PrI=", + "owner": "nix-community", + "repo": "flake-firefox-nightly", + "rev": "376edecefc793dee239bb7c363647358fa53347a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "flake-firefox-nightly", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "locked": { + "lastModified": 1717312683, + "narHash": "sha256-FrlieJH50AuvagamEvWMIE6D2OAnERuDboFDYAED/dE=", + "owner": "nix-community", + "repo": "flake-compat", + "rev": "38fd3954cf65ce6faf3d0d45cd26059e059f07ea", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_3": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_4": { + "flake": false, + "locked": { + "lastModified": 1650374568, + "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "b4a34015c698c7793d592d66adbab377907a2be8", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719994518, + "narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils-plus": { + "inputs": { + "flake-utils": "flake-utils_4" + }, + "locked": { + "lastModified": 1715533576, + "narHash": "sha256-fT4ppWeCJ0uR300EH3i7kmgRZnAVxrH+XtK09jQWihk=", + "owner": "gytis-ivaskevicius", + "repo": "flake-utils-plus", + "rev": "3542fe9126dc492e53ddd252bb0260fe035f2c0f", + "type": "github" + }, + "original": { + "owner": "gytis-ivaskevicius", + "repo": "flake-utils-plus", + "rev": "3542fe9126dc492e53ddd252bb0260fe035f2c0f", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_5" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "inputs": { + "systems": "systems_6" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_7" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "freetype2": { + "flake": false, + "locked": { + "lastModified": 1687587065, + "narHash": "sha256-+Fh+/k+NWL5Ow9sDLtp8Cv/8rLNA1oByQQCIQS/bysY=", + "owner": "wez", + "repo": "freetype2", + "rev": "e4586d960f339cf75e2e0b34aee30a0ed8353c0d", + "type": "github" + }, + "original": { + "owner": "wez", + "repo": "freetype2", + "rev": "e4586d960f339cf75e2e0b34aee30a0ed8353c0d", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "pre-commit-hooks-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "harfbuzz": { + "flake": false, + "locked": { + "lastModified": 1711722720, + "narHash": "sha256-GdxcAPx5QyniSHPAN1ih28AD9JLUPR0ItqW9JEsl3pU=", + "owner": "harfbuzz", + "repo": "harfbuzz", + "rev": "63973005bc07aba599b47fdd4cf788647b601ccd", + "type": "github" + }, + "original": { + "owner": "harfbuzz", + "ref": "8.4.0", + "repo": "harfbuzz", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1723986931, + "narHash": "sha256-Fy+KEvDQ+Hc8lJAV3t6leXhZJ2ncU5/esxkgt3b8DEY=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "2598861031b78aadb4da7269df7ca9ddfc3e1671", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "lanzaboote": { + "inputs": { + "crane": "crane", + "flake-compat": "flake-compat_3", + "flake-parts": "flake-parts", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks-nix": "pre-commit-hooks-nix", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1722329086, + "narHash": "sha256-e/fSi0WER06N8WCvpht62fkGtWfe5ckDxr6zNYkwkFw=", + "owner": "nix-community", + "repo": "lanzaboote", + "rev": "f5a3a7dff44d131807fc1a89fbd8576cd870334a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "lanzaboote", + "type": "github" + } + }, + "lib-aggregate": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1723983147, + "narHash": "sha256-SMCz4/S1/r+5ONMbxWrLiasPNd1J5FBM6HbNe00OBnw=", + "owner": "nix-community", + "repo": "lib-aggregate", + "rev": "abccaf0cb3f013739df2a89f19a33f912195384c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "lib-aggregate", + "type": "github" + } + }, + "libpng": { + "flake": false, + "locked": { + "lastModified": 1549245649, + "narHash": "sha256-1+cRp0Ungme/OGfc9kGJbklYIWAFxk8Il1M+NV4KSgw=", + "owner": "glennrp", + "repo": "libpng", + "rev": "8439534daa1d3a5705ba92e653eda9251246dd61", + "type": "github" + }, + "original": { + "owner": "glennrp", + "repo": "libpng", + "rev": "8439534daa1d3a5705ba92e653eda9251246dd61", + "type": "github" + } + }, + "maych-in": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1723472993, + "narHash": "sha256-0oD7G/z5D6iEnXq9saTRNnPJZVb9TGapbxFiwgUvC64=", + "rev": "7c4c0bcd15fdf0056bc0556ab8fa90ccb66c39e9", + "type": "tarball", + "url": "https://git.deku.moe/api/v1/repos/thunderbottom/website/archive/7c4c0bcd15fdf0056bc0556ab8fa90ccb66c39e9.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://git.deku.moe/thunderbottom/website/archive/main.tar.gz" + } + }, + "mozilla": { + "flake": false, + "locked": { + "lastModified": 1704373101, + "narHash": "sha256-+gi59LRWRQmwROrmE1E2b3mtocwueCQqZ60CwLG+gbg=", + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "rev": "9b11a87c0cc54e308fa83aac5b4ee1816d5418a2", + "type": "github" + }, + "original": { + "owner": "mozilla", + "repo": "nixpkgs-mozilla", + "type": "github" + } + }, + "nil": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": "rust-overlay_2" + }, + "locked": { + "lastModified": 1723948777, + "narHash": "sha256-rX14joTzvRUiCfmCT0LUMV3Mxi79VJANcKB/kkh7Qys=", + "owner": "oxalica", + "repo": "nil", + "rev": "4f3081d1f10bb61f197b780e67f426e53f818691", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "nil", + "type": "github" + } + }, + "nixos-hardware": { + "locked": { + "lastModified": 1724067415, + "narHash": "sha256-WJBAEFXAtA41RMpK8mvw0cQ62CJkNMBtzcEeNIJV7b0=", + "owner": "nixos", + "repo": "nixos-hardware", + "rev": "b09c46430ffcf18d575acf5c339b38ac4e1db5d2", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixos-hardware", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1724224976, + "narHash": "sha256-Z/ELQhrSd7bMzTO8r7NZgi9g5emh+aRKoCdaAv5fiO0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "c374d94f1536013ca8e92341b540eba4c22f9c62", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1723942470, + "narHash": "sha256-QdSArN0xKESEOTcv+3kE6yu4B4WX9lupZ4+Htx3RXGg=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "531a2e8416a6d8200a53eddfbdb8f2c8dc4a1251", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1720386169, + "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nur": { + "locked": { + "lastModified": 1724348704, + "narHash": "sha256-h8HB+4AiVZAe3ie6zYOmJco7QkKRPC7iHfChsoSOHm4=", + "owner": "nix-community", + "repo": "nur", + "rev": "bf3ebc298e0a5091f4f41cb45f38b31cac050e62", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nur", + "type": "github" + } + }, + "pre-commit-hooks-nix": { + "inputs": { + "flake-compat": [ + "lanzaboote", + "flake-compat" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1721042469, + "narHash": "sha256-6FPUl7HVtvRHCCBQne7Ylp4p+dpP3P/OYuzjztZ4s70=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "f451c19376071a90d8c58ab1a953c6e9840527fd", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "agenix": "agenix", + "deploy-rs": "deploy-rs", + "disko": "disko", + "firefox": "firefox", + "home-manager": "home-manager", + "lanzaboote": "lanzaboote", + "maych-in": "maych-in", + "nil": "nil", + "nixos-hardware": "nixos-hardware", + "nixpkgs": "nixpkgs", + "nur": "nur", + "snowfall-lib": "snowfall-lib", + "srvos": "srvos", + "wezterm": "wezterm" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1722219664, + "narHash": "sha256-xMOJ+HW4yj6e69PvieohUJ3dBSdgCfvI0nnCEe6/yVc=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "a6fbda5d9a14fb5f7c69b8489d24afeb349c7bb4", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_2": { + "inputs": { + "nixpkgs": [ + "nil", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1722824458, + "narHash": "sha256-2k3/geD5Yh8JT1nrGaRycje5kB0DkvQA/OUZoel1bIU=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "a8a937c304e62a5098c6276c9cdf65c19a43b1a5", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_3": { + "inputs": { + "nixpkgs": [ + "wezterm", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1721441897, + "narHash": "sha256-gYGX9/22tPNeF7dR6bWN5rsrpU4d06GnQNNgZ6ZiXz0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "b7996075da11a2d441cfbf4e77c2939ce51506fd", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "snowfall-lib": { + "inputs": { + "flake-compat": "flake-compat_4", + "flake-utils-plus": "flake-utils-plus", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719005984, + "narHash": "sha256-mpFl3Jv4fKnn+5znYXG6SsBjfXHJdRG5FEqNSPx0GLA=", + "owner": "snowfallorg", + "repo": "lib", + "rev": "c6238c83de101729c5de3a29586ba166a9a65622", + "type": "github" + }, + "original": { + "owner": "snowfallorg", + "repo": "lib", + "type": "github" + } + }, + "srvos": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1724287640, + "narHash": "sha256-MAjp8fUU6/WambitI/jOVxgjuH3YEfE6A8l4EtonktY=", + "owner": "nix-community", + "repo": "srvos", + "rev": "9810f43ff22a10b6f70c38d6085ac6c201b26640", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "srvos", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_7": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "wezterm": { + "inputs": { + "flake-utils": "flake-utils_5", + "freetype2": "freetype2", + "harfbuzz": "harfbuzz", + "libpng": "libpng", + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": "rust-overlay_3", + "zlib": "zlib" + }, + "locked": { + "dir": "nix", + "lastModified": 1723525023, + "narHash": "sha256-ZsDJQSUokodwFMP4FIZm2dYojf5iC4F/EeKC5VuQlqY=", + "owner": "wez", + "repo": "wezterm", + "rev": "30345b36d8a00fed347e4df5dadd83915a7693fb", + "type": "github" + }, + "original": { + "dir": "nix", + "owner": "wez", + "repo": "wezterm", + "type": "github" + } + }, + "zlib": { + "flake": false, + "locked": { + "lastModified": 1484501380, + "narHash": "sha256-j5b6aki1ztrzfCqu8y729sPar8GpyQWIrajdzpJC+ww=", + "owner": "madler", + "repo": "zlib", + "rev": "cacf7f1d4e3d44d871b605da3b647f07d718623f", + "type": "github" + }, + "original": { + "owner": "madler", + "ref": "v1.2.11", + "repo": "zlib", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..5d2db72 --- /dev/null +++ b/flake.nix @@ -0,0 +1,108 @@ +{ + outputs = inputs: let + lib = inputs.snowfall-lib.mkLib { + inherit inputs; + src = ./.; + snowfall = { + namespace = "snowflake"; + meta = { + name = "nix-snowflake"; + title = "NixOS Flake configuration for snowflakes"; + }; + }; + }; + userdata = import ./data.nix; + in + lib.mkFlake { + inherit inputs; + src = ./.; + + systems.modules.nixos = with inputs; [ + agenix.nixosModules.age + disko.nixosModules.disko + nur.nixosModules.nur + srvos.nixosModules.common + srvos.nixosModules.mixins-systemd-boot + ]; + + systems.hosts.thonkpad.modules = [ + inputs.nixos-hardware.nixosModules.lenovo-thinkpad-x1-9th-gen + inputs.lanzaboote.nixosModules.lanzaboote + ]; + systems.hosts.thonkpad.specialArgs = { + inherit userdata; + }; + # TODO: setup atticd + systems.hosts.bicboye.modules = [inputs.srvos.nixosModules.server]; + systems.hosts.bicboye.specialArgs = { + inherit userdata; + }; + systems.hosts.smolboye.modules = [inputs.srvos.nixosModules.server]; + + overlays = [(_: prev: {inherit (inputs.maych-in.packages.${prev.system}) maych-in;})]; + + channels-config.allowUnfree = true; + + outputs-builder = channels: { + formatter = channels.nixpkgs.writeShellApplication { + name = "format"; + runtimeInputs = with channels.nixpkgs; [ + nixfmt-rfc-style + deadnix + shfmt + statix + ]; + text = '' + set -euo pipefail + shfmt --write --simplify --language-dialect bash --indent 2 --case-indent --space-redirects .; + deadnix --edit + statix check . || statix fix . + nixfmt . + ''; + }; + }; + + deploy = lib.mkDeploy {inherit (inputs) self;}; + }; + + inputs = { + agenix.url = "github:ryantm/agenix"; + agenix.inputs.nixpkgs.follows = "nixpkgs"; + agenix.inputs.home-manager.follows = "nixpkgs"; + + deploy-rs.url = "github:serokell/deploy-rs"; + deploy-rs.inputs.nixpkgs.follows = "nixpkgs"; + + disko.url = "github:nix-community/disko"; + disko.inputs.nixpkgs.follows = "nixpkgs"; + + firefox.url = "github:nix-community/flake-firefox-nightly"; + firefox.inputs.nixpkgs.follows = "nixpkgs"; + + home-manager.url = "github:nix-community/home-manager"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + + lanzaboote.url = "github:nix-community/lanzaboote"; + lanzaboote.inputs.nixpkgs.follows = "nixpkgs"; + + maych-in.url = "https://git.deku.moe/thunderbottom/website/archive/main.tar.gz"; + maych-in.inputs.nixpkgs.follows = "nixpkgs"; + + nil.url = "github:oxalica/nil"; + nil.inputs.nixpkgs.follows = "nixpkgs"; + + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixos-hardware.url = "github:nixos/nixos-hardware"; + + nur.url = "github:nix-community/nur"; + + snowfall-lib.url = "github:snowfallorg/lib"; + snowfall-lib.inputs.nixpkgs.follows = "nixpkgs"; + + srvos.url = "github:nix-community/srvos"; + srvos.inputs.nixpkgs.follows = "nixpkgs"; + + wezterm.url = "github:wez/wezterm?dir=nix"; + wezterm.inputs.nixpkgs.follows = "nixpkgs"; + }; +} diff --git a/homes/x86_64-linux/chnmy@thonkpad/default.nix b/homes/x86_64-linux/chnmy@thonkpad/default.nix new file mode 100644 index 0000000..c97b486 --- /dev/null +++ b/homes/x86_64-linux/chnmy@thonkpad/default.nix @@ -0,0 +1,135 @@ +{ + config, + inputs, + pkgs, + ... +}: { + snowfallorg.user.enable = true; + snowfallorg.user.name = "chnmy"; + + snowflake.desktop.wezterm.enable = true; + + snowflake.development.git.enable = true; + snowflake.development.git.user = { + name = "Chinmay D. Pai"; + email = "chinmaydpai@gmail.com"; + signingKey = "75507BE256F40CED"; + }; + snowflake.development.git.work = { + enable = true; + email = "chinmay.pai@zerodha.com"; + path = "/home/${config.snowfallorg.user.name}/workspace/gitlab.zerodha.tech"; + extraConfig = { + url."ssh://git@gitlab.zerodha.tech:2280".insteadOf = "https://gitlab.zerodha.tech"; + url."ssh://git@gitlab.zerodha.tech:2280/".insteadOf = "git@gitlab.zerodha.tech:"; + }; + }; + + snowflake.development.helix.enable = true; + snowflake.development.tmux.enable = true; + snowflake.shell.fish.enable = true; + + programs.firefox = { + enable = true; + package = inputs.firefox.packages.${pkgs.system}.firefox-nightly-bin.override { + cfg = { + pipewireSupport = true; + }; + }; + # extensions = with config.nur.repos.rycee.firefox-addons; [ + # bitwarden + # clearurls + # duckduckgo-privacy-essentials + # reddit-enhancement-suite + # sponsorblock + # ublock-origin + # ]; + # policies = { + # DisableFirefoxStudies = true; + # EnableTrackingProtection = { + # Value = true; + # Locked = true; + # Cryptomining = true; + # Fingerprinting = true; + # }; + # OfferToSaveLoginsDefault = false; + + # DisableTelemetry = true; + # DisablePocket = true; + # DisableFirefoxAccounts = true; + # OverrideFirstRunPage = ""; + # OverridePostUpdatePage = ""; + # DontCheckDefaultBrowser = true; + # DisplayMenuBar = "default-off"; + # SearchBar = "unified"; + # NoDefaultBookmarks = true; + # DisplayBookmarksToolbar = "never"; + # Preferences = let + # lock-false = { + # Value = false; + # Status = "locked"; + # }; + # lock-true = { + # Value = false; + # Status = "locked"; + # }; + # lock-empty-string = { + # Value = false; + # Status = "locked"; + # }; + # in { + # "toolkit.legacyUserProfileCustomizations.stylesheets" = lock-true; + + # # Remove poluting defaults + # "extensions.pocket.enabled" = lock-false; + + # # Remove default top sites + # "browser.topsites.contile.enabled" = lock-false; + # "browser.urlbar.suggest.topsites" = lock-false; + + # # Remove sponsored sites + # "browser.newtabpage.pinned" = lock-empty-string; + # "browser.newtabpage.activity-stream.showSponsored" = lock-false; + # "browser.newtabpage.activity-stream.system.showSponsored" = lock-false; + # "browser.newtabpage.activity-stream.showSponsoredTopSites" = lock-false; + + # # Remove firefox shiny buttons + # "browser.tabs.firefox-view" = false; + # "browser.tabs.firefox-view-next" = false; + # # Style + # "browser.compactmode.show" = lock-true; + # "browser.uidensity" = { + # Value = 1; + # Status = "locked"; + # }; + # # Fonts - make web pages follow system font + # "browser.display.use_document_fonts" = { + # Value = 0; + # Status = "locked"; + # }; + + # "browser.tabs.loadInBackground" = true; + # "gfx.canvas.accelerated" = true; + # "gfx.webrender.enabled" = true; + # "gfx.x11-egl.force-enabled" = true; + # "layers.acceleration.force-enabled" = true; + # "media.av1.enabled" = false; + # "media.ffmpeg.vaapi.enabled" = true; + # "media.hardware-video-decoding.force-enabled" = true; + # "media.rdd-ffmpeg.enabled" = true; + # "widget.dmabuf.force-enabled" = true; + # "svg.context-properties.content.enabled" = true; + # "gnomeTheme.hideSingleTab" = true; + # "gnomeTheme.bookmarksToolbarUnderTabs" = true; + # "gnomeTheme.normalWidthTabs" = false; + # "gnomeTheme.tabsAsHeaderbar" = false; + # }; + # }; + }; + + home.packages = [ + pkgs.mpv + ]; + + home.stateVersion = "24.05"; +} diff --git a/homes/x86_64-linux/server@bicboye/default.nix b/homes/x86_64-linux/server@bicboye/default.nix new file mode 100644 index 0000000..efdd644 --- /dev/null +++ b/homes/x86_64-linux/server@bicboye/default.nix @@ -0,0 +1,11 @@ +_: { + snowfallorg.user.enable = true; + snowfallorg.user.name = "server"; + + # snowflake.development.git.enable = true; + snowflake.development.helix.enable = true; + snowflake.development.tmux.enable = true; + snowflake.shell.fish.enable = true; + + home.stateVersion = "24.05"; +} diff --git a/lib/deploy-rs/default.nix b/lib/deploy-rs/default.nix new file mode 100644 index 0000000..9b447b6 --- /dev/null +++ b/lib/deploy-rs/default.nix @@ -0,0 +1,26 @@ +{ inputs }: +let + inherit (inputs) deploy-rs; +in +{ + mkDeploy = + { self }: + let + hosts = self.nixosConfigurations or { }; + nodes = builtins.mapAttrs (_: machine: { + hostname = machine.config.networking.hostName; + fastConnection = true; + remoteBuild = false; + autoRollback = false; + magicRollback = false; + profiles.system = { + user = "root"; + sshUser = "root"; + path = deploy-rs.lib.${machine.pkgs.system}.activate.nixos machine; + }; + }) hosts; + in + { + inherit nodes; + }; +} diff --git a/lib/nixos/default.nix.bak b/lib/nixos/default.nix.bak new file mode 100644 index 0000000..c08b2f7 --- /dev/null +++ b/lib/nixos/default.nix.bak @@ -0,0 +1,12 @@ +{ + inputs, + nixosModules, + overlays, + userdata, + ... +}: let + helpers = import ./helpers.nix {inherit inputs nixosModules overlays userdata;}; +in { + inherit (helpers) mkHost; + inherit (helpers) forAllSystems; +} diff --git a/lib/nixos/helpers.nix.bak b/lib/nixos/helpers.nix.bak new file mode 100644 index 0000000..581d14f --- /dev/null +++ b/lib/nixos/helpers.nix.bak @@ -0,0 +1,45 @@ +{ + inputs, + nixosModules, + overlays, + userdata, + ... +}: { + # Helper function for generating host configurations. + mkHost = { + hostname, + system ? "x86_64-linux", + extraArgs ? {}, + extraModules ? [], + }: let + inherit (inputs.nixpkgs) lib; + in + inputs.nixpkgs.lib.nixosSystem { + inherit system; + specialArgs = + {inherit inputs userdata;} + // extraArgs; + + modules = + [ + { + networking.hostName = lib.mkDefault hostname; + nixpkgs.overlays = overlays; + } + ../machines/${hostname} + nixosModules.default + inputs.agenix.nixosModules.default + inputs.disko.nixosModules.disko + inputs.home-manager.nixosModules.home-manager + ] + ++ extraModules; + }; + + forAllSystems = inputs.nixpkgs.lib.genAttrs [ + "aarch64-linux" + "i686-linux" + "x86_64-linux" + "aarch64-darwin" + "x86_64-darwin" + ]; +} diff --git a/modules/home/desktop/wezterm/default.nix b/modules/home/desktop/wezterm/default.nix new file mode 100644 index 0000000..f951881 --- /dev/null +++ b/modules/home/desktop/wezterm/default.nix @@ -0,0 +1,44 @@ +{ + config, + inputs, + lib, + pkgs, + ... +}: +{ + options.snowflake.desktop.wezterm.enable = lib.mkEnableOption "Enable wezterm home configuration"; + + config = lib.mkIf config.snowflake.desktop.wezterm.enable { + programs.wezterm = { + enable = true; + package = inputs.wezterm.packages.${pkgs.system}.default; + + extraConfig = '' + local wezterm = require 'wezterm' + + local function BaseName(s) + return string.gsub(s, '(.*[/\\])(.*)', '%2') + end + + wezterm.on('format-tab-title', function(tab) + local title = BaseName(tab.active_pane.foreground_process_name) + if title and #title > 0 then + return ' ' .. BaseName(tab.active_pane.foreground_process_name) .. ' ' + end + return ' ' .. tab.active_pane.title .. ' ' + end) + + return { + font = wezterm.font 'IBM Plex Mono', + font_size = 12.0, + + cursor_blink_rate = 800, + + color_scheme = "ayu", + use_fancy_tab_bar = false, + window_decorations = "NONE", + } + ''; + }; + }; +} diff --git a/modules/home/development/git/default.nix b/modules/home/development/git/default.nix new file mode 100644 index 0000000..231be9d --- /dev/null +++ b/modules/home/development/git/default.nix @@ -0,0 +1,108 @@ +{ config, lib, ... }: +let + # Redefine gitIniTyp. + # ref: https://github.com/nix-community/home-manager/blob/master/modules/programs/git.nix + gitIniType = + with lib.types; + let + primitiveType = either str (either bool int); + multipleType = either primitiveType (listOf primitiveType); + sectionType = attrsOf multipleType; + supersectionType = attrsOf (either multipleType sectionType); + in + attrsOf supersectionType; +in +{ + options.snowflake.development.git = { + enable = lib.mkEnableOption "Enable development git configuration"; + + user.name = lib.mkOption { + type = lib.types.str; + description = "Real name for the work git profile"; + }; + user.email = lib.mkOption { + type = lib.types.str; + description = "Email for the work git profile"; + }; + user.signingKey = lib.mkOption { + type = lib.types.str; + description = "Public GPG Key for the work git profile"; + }; + + work.enable = lib.mkEnableOption "Enable work git configuration"; + work.path = lib.mkOption { + type = lib.types.str; + description = "Absolute path to apply the work git configuration."; + }; + work.extraConfig = lib.mkOption { + type = lib.types.either lib.types.lines gitIniType; + default = { }; + description = "Additional configuration for work git."; + }; + work.email = lib.mkOption { + type = lib.types.str; + description = "Email for the work git profile"; + }; + }; + + config = lib.mkIf config.snowflake.development.git.enable { + programs.git = { + enable = true; + + delta = { + enable = true; + options = { + diff-so-fancy = true; + line-numbers = true; + true-color = "always"; + }; + }; + + extraConfig = { + init.defaultBranch = "main"; + commit.gpgSign = true; + diff.algorithm = "histogram"; + gc.writeCommitGraph = true; + + # Do not `git fetch && git merge` or `git fetch && git rebase` + # on default `git pull behavior`. + pull.ff = "only"; + pull.rebase = false; + + # Enable REuse REcorded REsolution for git merge conflicts. + rerere.enabled = true; + + user.name = config.snowflake.development.git.user.name; + user.email = config.snowflake.development.git.user.email; + user.signingKey = config.snowflake.development.git.user.signingKey; + } // config.snowflake.development.git.work.extraConfig; + + # Global gitignore configuration. + ignores = [ + "*~" + ".#*" + ]; + includes = lib.mkIf config.snowflake.development.git.work.enable [ + # Enable work git configuration in specific directories. + # This allows existence of two different gitconfigs based on directories. + # For this, structuring the git repositories into directories based on + # origin is an ideal workflow. + # Example: + # ~/workspace/github.com: personal git workflow. + # ~/workspace/git.work.example: $WORK git workflow. + # Setting config.snowflake.work.git.workpath = "~/workspace/git.work.example" + # would apply the following configuration to only + # the ~/workspace.git.work.example folder. + { + condition = "gitdir:${config.snowflake.development.git.work.path}"; + contents = { + commit.gpgSign = true; + user.email = config.snowflake.development.git.work.email; + user.name = config.snowflake.development.git.user.name; + user.signingKey = config.snowflake.development.git.user.signingKey; + }; + } + ]; + }; + }; +} diff --git a/modules/home/development/helix/default.nix b/modules/home/development/helix/default.nix new file mode 100644 index 0000000..340a348 --- /dev/null +++ b/modules/home/development/helix/default.nix @@ -0,0 +1,126 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.development.helix.enable = lib.mkEnableOption "Enable helix development configuration"; + + config = lib.mkIf config.snowflake.development.helix.enable { + programs.helix = { + enable = true; + package = pkgs.helix.overrideAttrs (old: { + makeWrapperArgs = + with pkgs; + old.makeWrapperArgs or [ ] + ++ [ + "--suffix" + "PATH" + ":" + (lib.makeBinPath [ + alejandra + nil + gopls + gotools + marksman + shellcheck + ]) + ]; + }); + + defaultEditor = true; + + settings = { + theme = "ayu_dark"; + editor = { + line-number = "relative"; + cursorline = true; + cursor-shape.insert = "bar"; + scrolloff = 5; + color-modes = true; + idle-timeout = 1; + true-color = true; + bufferline = "always"; + soft-wrap.enable = true; + completion-replace = true; + lsp = { + display-messages = true; + display-inlay-hints = true; + }; + + whitespace.render = "all"; + whitespace.characters = { + space = "·"; + nbsp = "⍽"; + tab = "→"; + newline = "⤶"; + }; + + gutters = [ + "diagnostics" + "line-numbers" + "spacer" + "diff" + ]; + statusline = { + separator = "of"; + left = [ + "mode" + "selections" + "file-type" + "register" + "spinner" + "diagnostics" + ]; + center = [ "file-name" ]; + right = [ + "file-encoding" + "file-line-ending" + "position-percentage" + "spacer" + "separator" + "total-line-numbers" + ]; + mode = { + normal = "NORMAL"; + insert = "INSERT"; + select = "SELECT"; + }; + }; + indent-guides = { + render = true; + rainbow-option = "normal"; + }; + }; + }; + + languages = { + language = [ + { + name = "go"; + auto-format = true; + } + { + name = "nix"; + formatter.command = "alejandra"; + auto-format = true; + } + ]; + language-server = { + nil = { + command = lib.getExe pkgs.nil; + config.nil.formatting.command = [ + "${lib.getExe pkgs.alejandra}" + "-q" + ]; + }; + gopls = { + command = lib.getExe pkgs.gopls; + config.gopls.formatting.command = [ "${pkgs.go}/bin/gofmt" ]; + }; + }; + }; + }; + }; +} diff --git a/modules/home/development/tmux/default.nix b/modules/home/development/tmux/default.nix new file mode 100644 index 0000000..137d710 --- /dev/null +++ b/modules/home/development/tmux/default.nix @@ -0,0 +1,57 @@ +{ config, lib, ... }: +{ + options.snowflake.development.tmux.enable = lib.mkEnableOption "Enable tmux core configuration"; + + config = lib.mkIf config.snowflake.development.tmux.enable { + programs.tmux = { + enable = true; + shortcut = "a"; + aggressiveResize = true; + baseIndex = 1; + newSession = true; + escapeTime = 0; + secureSocket = false; + + extraConfig = '' + # Set terminal emulator window title + set -g set-titles on + set -g set-titles-string "#S:#I.#P #W" + + # Status Bar styles + set -g status-bg black + set -g status-fg white + set -g status-interval 1 + + # Show hostname on left side + set -g status-left-length 30 + set -g status-left '#[fg=colour2][ #[fg=colour10]#h#[fg=colour2] ][#[default] ' + + # Set mouse to work + set-option -g mouse on + + # Show load and date/time on right side + set -g status-right-length 60 + set -g status-right '#[fg=colour2]][ #[fg=colour11]#(cut -d " " -f 1-4 /proc/loadavg)#[fg=colour2] ][ #[fg=colour14]%Y-%m-%d %H:%M:%S#[fg=colour2] ]#[default]' + + # Center the window list + set -g status-justify centre + + # Format of window items + set -g window-status-format ' #I-$ #W ' + set -g window-status-current-format '#[bg=black]#[fg=red,bold](#[fg=white,bold]#I*$ #W#[fg=red,bold])#[default]' + + # Notifying if other windows has activities + setw -g monitor-activity on + set -g visual-activity off + + # Easy to remember split pane commands + bind | split-window -h -c "#{pane_current_path}" + bind - split-window -v -c "#{pane_current_path}" + bind c new-window -c "#{pane_current_path}" + + # 256 Color terminals + set -g default-terminal "screen-256color" + ''; + }; + }; +} diff --git a/modules/home/shell/fish/default.nix b/modules/home/shell/fish/default.nix new file mode 100644 index 0000000..1465899 --- /dev/null +++ b/modules/home/shell/fish/default.nix @@ -0,0 +1,105 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.shell.fish.enable = lib.mkEnableOption "Enable fish shell home configuration"; + + config = lib.mkIf config.snowflake.shell.fish.enable { + programs.fish.enable = true; + programs.fish.interactiveShellInit = '' + set fish_greeting + ${pkgs.nix-index}/etc/profile.d/command-not-found.sh | source + ${pkgs.starship}/bin/starship init fish | source + ''; + + programs.fish.plugins = [ + { + inherit (pkgs.fishPlugins.autopair) src; + name = "autopair"; + } + ]; + + programs.starship = + let + elemsConcatted = lib.strings.concatStrings ( + map (s: "\$${s}") [ + "hostname" + "username" + "directory" + "shell" + "nix_shell" + "git_branch" + "git_commit" + "git_state" + "git_status" + "jobs" + "cmd_duration" + ] + ); + in + { + enable = true; + + settings = { + scan_timeout = 2; + command_timeout = 2000; # nixpkgs makes starship implode with lower values + # add_newline = false; + line_break.disabled = false; + + format = "${elemsConcatted}\n$character"; + + hostname = { + ssh_only = true; + disabled = false; + format = "@[$hostname](bold blue) "; # the whitespace at the end is actually important + }; + + # configure specific elements + character = { + error_symbol = "[❯](bold red)"; + success_symbol = "[❯](bold green)"; + vicmd_symbol = "[](bold yellow)"; + format = "$symbol [|](bold bright-black) "; + }; + + username = { + format = "[$user]($style) in "; + }; + + directory = { + # removes the read_only symbol from the format, it doesn't play nicely with my folder icon + format = "[ ](bold green) [$path]($style) "; + }; + + # git + git_commit.commit_hash_length = 7; + git_branch.style = "bold purple"; + git_status = { + style = "red"; + ahead = "⇡ "; + behind = "⇣ "; + conflicted = " "; + renamed = "»"; + deleted = "✘ "; + diverged = "⇆ "; + modified = "!"; + stashed = "≡"; + staged = "+"; + untracked = "?"; + }; + + # language configurations + # the whitespaces at the end *are* necessary for proper formatting + python.symbol = "[ ](blue) "; + rust.symbol = "[ ](red) "; + nix_shell.symbol = "[󱄅 ](blue) "; + golang.symbol = "[󰟓 ](blue)"; + + package.disabled = true; + }; + }; + }; +} diff --git a/modules/home/user/default.nix b/modules/home/user/default.nix new file mode 100644 index 0000000..1ced91e --- /dev/null +++ b/modules/home/user/default.nix @@ -0,0 +1,51 @@ +{ + config, + inputs, + lib, + pkgs, + ... +}: +{ + config = lib.mkIf config.snowfallorg.user.enable { + programs.eza = { + enable = true; + extraOptions = [ + "--group-directories-first" + "--header" + ]; + git = config.snowflake.development.git.enable; + icons = true; + }; + + # Enable faster, indexed search for nixpkgs. + programs.nix-index = { + enable = true; + enableFishIntegration = true; + }; + + # Allow home-manager to manage itself. + programs.home-manager.enable = true; + + # Enable fuzzy finder. + programs.fzf.enable = true; + + # Enable faster, smarter `cd`. + programs.zoxide.enable = true; + + home.file = { + # Set allow unfree in user home nix config. + ".config/nixpkgs/config.nix".text = "{ allowUnfree = true; }"; + + # Set sane nano defaults. + ".nanorc".text = "set constantshow # Show linenumbers -c as default"; + }; + + # Set the EDITOR environment variable. + home.sessionVariables.EDITOR = if config.snowflake.development.helix.enable then "hx" else "nano"; + + # Show activation change diff for new builds. + home.activation.report-changes = inputs.home-manager.lib.hm.dag.entryAnywhere '' + ${pkgs.nvd}/bin/nvd diff $oldGenPath $newGenPath + ''; + }; +} diff --git a/modules/nixos/core/default.nix b/modules/nixos/core/default.nix new file mode 100644 index 0000000..21e5f07 --- /dev/null +++ b/modules/nixos/core/default.nix @@ -0,0 +1,160 @@ +{ + config, + lib, + pkgs, + ... +}: { + options.snowflake = { + stateVersion = lib.mkOption { + type = lib.types.str; + example = "24.05"; + description = "NixOS state version to use for this system"; + }; + extraPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = []; + description = "Extra packages to be installed system-wide"; + }; + timeZone = lib.mkOption { + type = lib.types.str; + description = "Timezone to use for the system"; + default = "Asia/Kolkata"; + }; + }; + + config = { + console = { + keyMap = lib.mkDefault "us"; + useXkbConfig = true; + font = lib.mkDefault "${pkgs.terminus_font}/share/consolefonts/ter-u28n.psf.gz"; + }; + + # Enable all snowflake core modules. + snowflake.core.fish.enable = lib.mkDefault true; + snowflake.core.gnupg.enable = lib.mkDefault true; + snowflake.core.nix.enable = lib.mkDefault true; + snowflake.core.security.enable = lib.mkDefault true; + snowflake.core.security.sysctl.enable = lib.mkDefault true; + snowflake.core.sshd.enable = lib.mkDefault true; + + boot = { + initrd.systemd.enable = true; + initrd.verbose = false; + # Default to the latest kernel package. + kernelPackages = lib.mkDefault pkgs.linuxPackages_latest; + # Force performance policy for Active State Performance Management. + kernelParams = [ + "pcie_aspm.policy=performance" + "nmi_watchdog=0" + "udev.log_level=3" + ]; + + loader = { + efi.canTouchEfiVariables = true; + # Use systemd-boot for all systems. + systemd-boot = { + enable = true; + # Show only last 10 configurations in the boot menu. + configurationLimit = lib.mkDefault 10; + }; + }; + }; + + # NixOS documentation. + documentation = { + enable = true; + doc.enable = false; + info.enable = false; + man.enable = true; + nixos.enable = false; + }; + + environment = { + defaultPackages = with pkgs; + lib.mkForce [ + gitMinimal + home-manager + rsync + ]; + shells = with pkgs; [ + bash + fish + ]; + systemPackages = with pkgs; + [ + bat + btop + curl + duf + fd + file + fzf + git + gnumake + jc + jq + ncdu + ripgrep + tree + unzip + wget + + # Networking tools. + dnsutils + ethtool + host + prettyping + whois + ] + ++ config.snowflake.extraPackages; + }; + + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; + supportedLocales = ["en_US.UTF-8/UTF-8"]; + }; + + # Can be configured further or is started in user sessions. + programs.mtr.enable = true; + # Run unpatched dynamic binaries on NixOS. + programs.nix-ld.enable = true; + + # Enable firmware updates for the system. + services.fwupd.enable = true; + + # Enable irqbalance. + services.irqbalance.enable = true; + + # Use a high-performance implementation for DBus + services.dbus.implementation = "broker"; + + # Workaround for irqbalance read-only filesystem issue. + # ref: https://github.com/Irqbalance/irqbalance/issues/308 + systemd.services.irqbalance.serviceConfig.ProtectKernelTunables = "no"; + + system.stateVersion = config.snowflake.stateVersion; + system.activationScripts.diff = { + supportsDryActivation = true; + text = '' + ${pkgs.nvd}/bin/nvd --nix-bin-dir=${pkgs.nix}/bin diff /run/current-system "$systemConfig" + ''; + }; + + time.timeZone = config.snowflake.timeZone; + + # Enable zram swap. + # ref: https://wiki.archlinux.org/title/Zram + zramSwap.enable = true; + }; +} diff --git a/modules/nixos/core/docker/default.nix b/modules/nixos/core/docker/default.nix new file mode 100644 index 0000000..1cd1972 --- /dev/null +++ b/modules/nixos/core/docker/default.nix @@ -0,0 +1,30 @@ +{ + config, + lib, + ... +}: { + options.snowflake.core.docker = { + enable = lib.mkEnableOption "Enable core docker configuration"; + storageDriver = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Storage driver backend to use for docker"; + }; + }; + + config = lib.mkIf config.snowflake.core.docker.enable { + virtualisation.docker = { + enable = true; + # Required for containers with `--restart=always`. + enableOnBoot = true; + autoPrune = { + enable = true; + }; + extraOptions = "--iptables=False"; + inherit (config.snowflake.core.docker) storageDriver; + }; + + # Add the system user to the docker group + snowflake.user.extraGroups = ["docker"]; + }; +} diff --git a/modules/nixos/core/fish/default.nix b/modules/nixos/core/fish/default.nix new file mode 100644 index 0000000..7d5b9a1 --- /dev/null +++ b/modules/nixos/core/fish/default.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.core.fish.enable = lib.mkEnableOption "Enable core fish configuration"; + + config = lib.mkIf config.snowflake.core.fish.enable { + environment.systemPackages = [ pkgs.starship ]; + programs.fish.enable = true; + + users.users.${config.snowflake.user.username} = lib.mkIf config.snowflake.user.enable { + shell = pkgs.fish; + }; + + users.users.root.shell = pkgs.fish; + }; +} diff --git a/modules/nixos/core/gnupg/default.nix b/modules/nixos/core/gnupg/default.nix new file mode 100644 index 0000000..23290d5 --- /dev/null +++ b/modules/nixos/core/gnupg/default.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.core.gnupg.enable = lib.mkEnableOption "Enable core gnupg configuration"; + + config = lib.mkIf config.snowflake.core.gnupg.enable { + services.pcscd.enable = true; + + programs.gnupg.agent = { + enable = true; + enableSSHSupport = !config.snowflake.core.sshd.enable; + }; + + environment.systemPackages = [ pkgs.gnupg ]; + }; +} diff --git a/modules/nixos/core/lanzaboote/default.nix b/modules/nixos/core/lanzaboote/default.nix new file mode 100644 index 0000000..6a5a786 --- /dev/null +++ b/modules/nixos/core/lanzaboote/default.nix @@ -0,0 +1,18 @@ +{ + config, + lib, + pkgs, + ... +}: { + options.snowflake.core.lanzaboote.enable = lib.mkEnableOption "Enable secure boot configuration"; + + config = lib.mkIf config.snowflake.core.lanzaboote.enable { + environment.systemPackages = [pkgs.sbctl]; + + boot.loader.systemd-boot.enable = lib.mkForce false; + boot.lanzaboote = { + enable = true; + pkiBundle = "/etc/secureboot"; + }; + }; +} diff --git a/modules/nixos/core/nix/default.nix b/modules/nixos/core/nix/default.nix new file mode 100644 index 0000000..457f3ed --- /dev/null +++ b/modules/nixos/core/nix/default.nix @@ -0,0 +1,73 @@ +{ + config, + inputs, + lib, + pkgs, + ... +}: +{ + options.snowflake.core.nix = { + enable = lib.mkEnableOption "Enable core nix configuration"; + }; + + config = lib.mkIf config.snowflake.core.nix.enable { + nix = { + # Run garbage collector daily, and remove anything + # older than 7 days. + gc = { + automatic = true; + dates = "daily"; + options = "--delete-older-than 7d"; + }; + + # Add each flake input as a registry to make nix3 commands + # consistent with nix flakes. + registry = lib.mapAttrs (_: value: { flake = value; }) inputs; + + # Add inputs to system's legacy channels. + nixPath = lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry; + + # Use the latest, unstable version of nix. + package = pkgs.nixVersions.git; + + settings = { + # Accept flake configuration without prompting. + accept-flake-config = true; + # Replace identical nix store files with hard links. + auto-optimise-store = true; + # Use cache from remote build machines if available. + builders-use-substitutes = true; + experimental-features = [ + "auto-allocate-uids" + "ca-derivations" + "cgroups" + "flakes" + "nix-command" + "recursive-nix" + ]; + # Set local flake registry. + flake-registry = "/etc/nix/registry.json"; + # Increase http connections (from 25 to 50) for binary cache. + http-connections = 50; + # Avoid unwanted garbage collection while using nix-direnv. + keep-outputs = true; + keep-derivations = true; + max-jobs = "auto"; + # Use sandboxed build environments for builds on all systems. + # Defaults to true on linux. + sandbox = true; + # Add `wheel` group to trusted users. + trusted-users = [ + "root" + "@wheel" + ]; + # Disable warning for dirty git tree. + warn-dirty = false; + + # Add cache substituters to allow fetching cached builds. + trusted-substituters = [ "https://nix-community.cachix.org" ]; + trusted-public-keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; + }; + }; + }; +} diff --git a/modules/nixos/core/security/default.nix b/modules/nixos/core/security/default.nix new file mode 100644 index 0000000..b96dc51 --- /dev/null +++ b/modules/nixos/core/security/default.nix @@ -0,0 +1,82 @@ +{ + config, + lib, + ... +}: { + options.snowflake.core.security = { + enable = lib.mkEnableOption "Enable core security configuration"; + sysctl.enable = lib.mkEnableOption "Enable sysctl security configuration"; + }; + + config = lib.mkIf config.snowflake.core.security.enable { + boot = lib.mkMerge [ + { + # Disable console logging. + consoleLogLevel = 0; + + # Disable verbose message on initrd to prevent log flooding. + initrd.verbose = false; + + # Use tmpfs for /tmp, and clean only when not using tmpfs. + tmp.useTmpfs = lib.mkDefault true; + tmp.tmpfsSize = "95%"; + + # Disable kernel param editing on boot. + loader.systemd-boot.editor = false; + kernelModules = ["tcp_bbr"]; + } + + (lib.mkIf config.snowflake.core.security.sysctl.enable { + kernel.sysctl = { + # The Magic SysRq key is a key combo that allows users connected to the + # system console of a Linux kernel to perform some low-level commands. + # Disable it, since we don't need it, and is a potential security concern. + "kernel.sysrq" = 0; + + ## TCP hardening + # Prevent bogus ICMP errors from filling up logs. + "net.ipv4.icmp_ignore_bogus_error_responses" = 1; + # Reverse path filtering causes the kernel to do source validation of + # packets received from all interfaces. This can mitigate IP spoofing. + "net.ipv4.conf.default.rp_filter" = 1; + "net.ipv4.conf.all.rp_filter" = 1; + # Do not accept IP source route packets (we're not a router). + "net.ipv4.conf.all.accept_source_route" = 0; + "net.ipv6.conf.all.accept_source_route" = 0; + # Don't send ICMP redirects (again, we're on a router). + "net.ipv4.conf.all.send_redirects" = 0; + "net.ipv4.conf.default.send_redirects" = 0; + # Refuse ICMP redirects (MITM mitigations). + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + "net.ipv4.conf.default.secure_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + "net.ipv6.conf.default.accept_redirects" = 0; + # Protects against SYN flood attacks. + "net.ipv4.tcp_syncookies" = 1; + # Incomplete protection again TIME-WAIT assassination. + "net.ipv4.tcp_rfc1337" = 1; + + # TCP optimization + # Enable TCP Fast Open for incoming and outgoing connections. + "net.ipv4.tcp_fastopen" = 3; + # Bufferbloat mitigations + slight improvement in throughput & latency. + "net.ipv4.tcp_congestion_control" = "bbr"; + "net.core.default_qdisc" = "cake"; + }; + }) + ]; + + security = { + # Prevent replacing the kernel without reboot. + # protectKernelImage = true; + # Accept ACME terms, so we don't have to do this later. + acme.acceptTerms = true; + # Allows unauthorized applications to send unauthorization request. + polkit.enable = true; + # Enable sudo. + sudo.enable = true; + }; + }; +} diff --git a/modules/nixos/core/sshd/default.nix b/modules/nixos/core/sshd/default.nix new file mode 100644 index 0000000..420abca --- /dev/null +++ b/modules/nixos/core/sshd/default.nix @@ -0,0 +1,22 @@ +{ config, lib, ... }: +{ + options.snowflake.core.sshd = { + enable = lib.mkEnableOption "Enable core sshd configuration"; + }; + + config = lib.mkIf config.snowflake.core.sshd.enable { + services.openssh = { + enable = true; + settings = { + # Disable password auth and root login. + PasswordAuthentication = false; + PermitRootLogin = "no"; + }; + openFirewall = true; + }; + + # Enable mosh for access over spotty networks. + programs.mosh.enable = true; + programs.ssh.startAgent = true; + }; +} diff --git a/modules/nixos/desktop/default.nix b/modules/nixos/desktop/default.nix new file mode 100644 index 0000000..10dd811 --- /dev/null +++ b/modules/nixos/desktop/default.nix @@ -0,0 +1,82 @@ +{ + config, + lib, + pkgs, + ... +}: { + options.snowflake.desktop.enable = lib.mkEnableOption "Enable core Desktop Environment configuration"; + + config = lib.mkIf config.snowflake.desktop.enable { + snowflake = { + # Enable the fonts module. + desktop.fonts.enable = true; + # Enable the pipewire module. + desktop.pipewire.enable = true; + + # Add user to networkmanager and adbusers group. + # Works only when snowflake.user.enable is true. + user.extraGroups = ["adbusers"]; + }; + + # Enable ADB for Android devices. + programs.adb.enable = true; + programs.dconf.enable = true; + # Start the ssh agent if enabled. + programs.ssh.startAgent = config.snowflake.core.sshd.enable; + + # Add opengl hardware support. + hardware.graphics = { + enable = true; + enable32Bit = true; + extraPackages = with pkgs; [ + vaapiIntel + libvdpau-va-gl + vaapiVdpau + intel-ocl + intel-media-driver + ]; + }; + + environment.sessionVariables = { + LIBVA_DRIVER_NAME = "iHD"; + }; + + # Prevents xterm from being installed. + # Prefer installing a custom terminal emulator instead. + services.xserver.excludePackages = [pkgs.xterm]; + services.xserver.desktopManager.xterm.enable = false; + + # Enable profile-sync-daemon for browsers. + # ref: https://wiki.archlinux.org/title/profile-sync-daemon + services.psd.enable = true; + + # Add udev rules for ADB. + services.udev.packages = [pkgs.android-udev-rules]; + + # Enable XDG Portal. + # Additional configuration will be done through individual + # desktop environment configurations. + xdg.portal.enable = true; + + # Set environment variables for the system. + environment.variables = { + # Make Electron applications run in wayland. + NIXOS_OZONE_WL = "1"; + # Disable G-Sync and VRR. + __GL_GSYNC_ALLOWED = "0"; + __GL_VRR_ALLOWED = "0"; + GDK_BACKEND = "wayland"; + DIRENV_LOG_FORMAT = ""; + WLR_DRM_NO_ATOMIC = "1"; + QT_AUTO_SCREEN_SCALE_FACTOR = "1"; + QT_QPA_PLATFORM = "wayland;xcb"; + # Run firefox in wayland. + MOZ_ENABLE_WAYLAND = "1"; + WLR_BACKEND = "vulkan"; + WLR_RENDERER = "vulkan"; + XDG_SESSION_TYPE = "wayland"; + SDL_VIDEODRIVER = "wayland"; + CLUTTER_BACKEND = "wayland"; + }; + }; +} diff --git a/modules/nixos/desktop/fonts/default.nix b/modules/nixos/desktop/fonts/default.nix new file mode 100644 index 0000000..218140e --- /dev/null +++ b/modules/nixos/desktop/fonts/default.nix @@ -0,0 +1,85 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.desktop.fonts.enable = lib.mkEnableOption "Enable desktop font configuration"; + + config = lib.mkIf config.snowflake.desktop.fonts.enable { + fonts = { + fontDir.enable = true; + packages = with pkgs; [ + cantarell-fonts + corefonts + dejavu_fonts + fira + fira-code + fira-code-symbols + fira-go + google-fonts + hack-font + ibm-plex + inconsolata + inter + iosevka + liberation_ttf + libertine + libre-baskerville + material-design-icons + mplus-outline-fonts.githubRelease + (nerdfonts.override { + fonts = [ + "FiraCode" + "JetBrainsMono" + "NerdFontsSymbolsOnly" + "SourceCodePro" + "UbuntuMono" + ]; + }) + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + noto-fonts-extra + powerline-fonts + proggyfonts + source-serif + roboto + ubuntu_font_family + vistafonts + work-sans + ]; + + fontconfig = { + enable = true; + + antialias = true; + defaultFonts = { + serif = [ + "Noto Serif" + "Noto Color Emoji" + ]; + sansSerif = [ + "Noto Sans" + "Noto Color Emoji" + ]; + monospace = [ + "JetBrainsMono Nerd Font" + "Noto Color Emoji" + ]; + emoji = [ "Noto Color Emoji" ]; + }; + hinting = { + autohint = false; + enable = true; + style = "slight"; + }; + subpixel = { + rgba = "rgb"; + lcdfilter = "light"; + }; + }; + }; + }; +} diff --git a/modules/nixos/desktop/kde/default.nix b/modules/nixos/desktop/kde/default.nix new file mode 100644 index 0000000..1dd1e74 --- /dev/null +++ b/modules/nixos/desktop/kde/default.nix @@ -0,0 +1,57 @@ +{ + config, + lib, + pkgs, + ... +}: { + options.snowflake.desktop.kde = { + enable = lib.mkEnableOption "Enable the KDE Plasma Desktop Environment"; + }; + + config = lib.mkIf config.snowflake.desktop.kde.enable { + services = { + libinput.enable = true; + + xserver = { + enable = true; + videoDrivers = ["intel"]; + }; + displayManager.sddm = { + enable = true; + wayland.enable = true; + wayland.compositor = "kwin"; + }; + desktopManager.plasma6.enable = true; + + # Enable fingerprint authentication. + # Requires fingerprint registered using `fprint-enroll` to work. + fprintd.enable = true; + }; + + # Remove bloatware that we do not require. + environment.plasma6.excludePackages = with pkgs.kdePackages; [ + konsole + khelpcenter + kate + elisa + ]; + + # Disable fprint authentication for login. + # SDDM does not work well with fingerprint authentication. + security.pam.services.login.fprintAuth = false; + + # Additional configuration for XDG Portal. + xdg.portal.wlr.enable = true; + xdg.portal.xdgOpenUsePortal = true; + xdg.portal.extraPortals = with pkgs; [ + xdg-desktop-portal-gtk + xdg-desktop-portal-kde + ]; + + snowflake.user.extraGroups = [ + "audio" + "input" + "video" + ]; + }; +} diff --git a/modules/nixos/desktop/pipewire/default.nix b/modules/nixos/desktop/pipewire/default.nix new file mode 100644 index 0000000..d8b21bc --- /dev/null +++ b/modules/nixos/desktop/pipewire/default.nix @@ -0,0 +1,31 @@ +{ + config, + lib, + pkgs, + ... +}: { + options.snowflake.desktop.pipewire.enable = lib.mkEnableOption "Enable pipewire configuration"; + + config = lib.mkIf config.snowflake.desktop.pipewire.enable { + # Enable sound. + # sound.enable = true; + + # Use pipewire for sound and disable pulseaudio. + hardware.pulseaudio.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + wireplumber.enable = true; + }; + + # Add sof-firmware for system mic and speaker mute keys. + # Specifically for thinkpad, might work for a few other systems (untested). + environment.systemPackages = [ + pkgs.sof-firmware + pkgs.ffmpeg + ]; + }; +} diff --git a/modules/nixos/gaming/steam/default.nix b/modules/nixos/gaming/steam/default.nix new file mode 100644 index 0000000..676fbeb --- /dev/null +++ b/modules/nixos/gaming/steam/default.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.gaming.steam.enable = lib.mkEnableOption "Enable steam"; + + config = lib.mkIf config.snowflake.gaming.steam.enable { + programs.steam = { + enable = true; + remotePlay.openFirewall = true; + dedicatedServer.openFirewall = true; + + package = pkgs.steam.override { + extraPkgs = + pkgs: with pkgs; [ + pango + libthai + harfbuzz + glxinfo + ]; + }; + }; + }; +} diff --git a/modules/nixos/hardware/bluetooth/default.nix b/modules/nixos/hardware/bluetooth/default.nix new file mode 100644 index 0000000..d70b0fc --- /dev/null +++ b/modules/nixos/hardware/bluetooth/default.nix @@ -0,0 +1,18 @@ +{ config, lib, ... }: +{ + options.snowflake.hardware.bluetooth.enable = lib.mkEnableOption "Enable bluetooth hardware support"; + + config = lib.mkIf config.snowflake.hardware.bluetooth.enable { + # Enable bluetooth hardware. + hardware.bluetooth = { + enable = true; + settings = { + General = { + # Enable battery charge levels for bluetooth devices. + Experimental = true; + KernelExperimental = true; + }; + }; + }; + }; +} diff --git a/modules/nixos/hardware/initrd-luks/default.nix b/modules/nixos/hardware/initrd-luks/default.nix new file mode 100644 index 0000000..a1894f6 --- /dev/null +++ b/modules/nixos/hardware/initrd-luks/default.nix @@ -0,0 +1,61 @@ +{ + config, + lib, + ... +}: { + options.snowflake.hardware.initrd-luks = { + enable = lib.mkEnableOption "Enable initrd-luks hardware configuration"; + + sshPort = lib.mkOption { + type = lib.types.int; + default = 22; + description = "SSH Port to use for initrd-luks decryption"; + }; + shell = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = "Shell to use for initrd-luks decryption"; + }; + hostKeys = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = ["/etc/ssh/ssh_host_ed25519_key"]; + description = "Path to the host keys to use for initrd-luks decryption"; + }; + authorizedKeys = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + description = "List of authorized keys for initrd-luks decyption"; + }; + availableKernelModules = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = []; + description = "List of available kernel modules for initrd-luks decryption"; + }; + }; + + config = lib.mkIf config.snowflake.hardware.initrd-luks.enable { + # Enable remote LUKS unlocking. + # This allows remote SSH to unlock LUKS encrypted root. + # $ ssh root@ + # While in the shell, run `systemctl default` or `systemd-ask-password` + # to trigger the unlock prompt. + boot = { + initrd.network = { + flushBeforeStage2 = true; + enable = true; + ssh = { + enable = true; + port = config.snowflake.hardware.initrd-luks.sshPort; + inherit (config.snowflake.hardware.initrd-luks) hostKeys; + inherit (config.snowflake.hardware.initrd-luks) authorizedKeys; + }; + }; + # initrd.systemd.users.root.shell = config.snowflake.hardware.initrd-luks.shell; + # Required for the network card that + # requires a kernel module to work. + initrd.availableKernelModules = config.snowflake.hardware.initrd-luks.availableKernelModules; + # Use DHCP to figure out the IP address. + kernelParams = ["ip=dhcp"]; + }; + }; +} diff --git a/modules/nixos/hardware/yubico/default.nix b/modules/nixos/hardware/yubico/default.nix new file mode 100644 index 0000000..d400d4b --- /dev/null +++ b/modules/nixos/hardware/yubico/default.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.hardware.yubico.enable = lib.mkEnableOption "Enable yubico hardware support"; + + config = lib.mkIf config.snowflake.hardware.yubico.enable { + # Enable FIDO authentication support. + # ref: https://nixos.wiki/wiki/Yubikey + security.pam = { + u2f.enable = true; + services = { + login.u2fAuth = true; + sudo.u2fAuth = true; + }; + }; + services.udev.packages = [ pkgs.yubikey-personalization ]; + }; +} diff --git a/modules/nixos/networking/default.nix b/modules/nixos/networking/default.nix new file mode 100644 index 0000000..629329d --- /dev/null +++ b/modules/nixos/networking/default.nix @@ -0,0 +1,81 @@ +{ + config, + lib, + ... +}: { + options.snowflake.networking = { + iwd.enable = lib.mkEnableOption "Enable iwd backend for network manager"; + networkd.enable = lib.mkEnableOption "Enable systemd network management daemon"; + networkManager.enable = lib.mkEnableOption "Enable network-manager"; + resolved.enable = lib.mkEnableOption "Enable systemd-resolved"; + firewall.enable = lib.mkEnableOption "Enable system firewall"; + }; + + config = lib.mkMerge [ + { + # Enable the network firewall by default. + networking.firewall.enable = config.snowflake.networking.firewall.enable; + # use nftables for firewall + networking.nftables.enable = true; + } + + (lib.mkIf config.snowflake.networking.iwd.enable { + networking.wireless.iwd = { + enable = true; + settings = { + General = { + AddressRandomization = "network"; + AddressRandomizationRange = "full"; + EnableNetworkConfiguration = true; + RoamRetryInterval = 15; + }; + Network = { + EnableIPv6 = true; + RoutePriorityOffset = 300; + }; + Settings = { + AutoConnect = true; + }; + # Prioritize connection to 5GHz. + Rank.BandModifier5Ghz = 2.0; + Scan.DisablePeriodicScan = true; + }; + }; + }) + + (lib.mkIf config.snowflake.networking.networkManager.enable { + systemd.services.NetworkManager-wait-online.enable = false; + + networking.networkmanager = { + enable = lib.mkDefault true; + # Disable Wifi powersaving + wifi.powersave = false; + wifi.backend = + if config.snowflake.networking.iwd.enable + then "iwd" + else "wpa_supplicant"; + }; + + snowflake.user.extraGroups = ["networkmanager"]; + + services.resolved = { + enable = config.snowflake.networking.resolved.enable; + }; + }) + + (lib.mkIf config.snowflake.networking.networkd.enable { + systemd.network.enable = true; + + systemd.services = { + systemd-networkd-wait-online.enable = false; + systemd-networkd.restartIfChanged = false; + firewall.restartIfChanged = false; + }; + + networking.interfaces = { + enp1s0.useDHCP = true; + wlan0.useDHCP = true; + }; + }) + ]; +} diff --git a/modules/nixos/networking/mullvad/default.nix b/modules/nixos/networking/mullvad/default.nix new file mode 100644 index 0000000..8a1d847 --- /dev/null +++ b/modules/nixos/networking/mullvad/default.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.networking.mullvad.enable = lib.mkEnableOption "Enable Mullvad VPN client"; + + config = lib.mkIf config.snowflake.networking.mullvad.enable { + networking = { + # ref: https://github.com/NixOS/nixpkgs/issues/113589 + firewall.checkReversePath = "loose"; + wireguard.enable = true; + + # mullvad-daemon requires iproute2 route tables. + iproute2.enable = true; + }; + + services.mullvad-vpn = { + enable = true; + package = pkgs.mullvad-vpn; + }; + }; +} diff --git a/modules/nixos/networking/netbird/default.nix b/modules/nixos/networking/netbird/default.nix new file mode 100644 index 0000000..0b83740 --- /dev/null +++ b/modules/nixos/networking/netbird/default.nix @@ -0,0 +1,30 @@ +{ + config, + lib, + pkgs, + ... +}: { + options.snowflake.networking.netbird.enable = lib.mkEnableOption "Enable Netbird VPN client"; + + config = lib.mkIf config.snowflake.networking.netbird.enable { + networking = { + firewall = { + checkReversePath = "loose"; + trustedInterfaces = ["wt0"]; + allowedUDPPorts = [config.services.netbird.tunnels.wt0.port]; + }; + # networkmanager.unmanaged = ["wt0"]; + + # ref: https://github.com/NixOS/nixpkgs/issues/113589 + wireguard.enable = true; + + # netbird requires iproute2 route tables. + # iproute2.enable = true; + }; + + services.netbird.enable = true; + # Unmanage the `wt0` interface rules to allow reconnection after suspend. + systemd.network.config.networkConfig.ManageForeignRoutingPolicyRules = lib.mkDefault false; + snowflake.extraPackages = [pkgs.netbird-ui]; + }; +} diff --git a/modules/nixos/services/arr/default.nix b/modules/nixos/services/arr/default.nix new file mode 100644 index 0000000..0b6c0de --- /dev/null +++ b/modules/nixos/services/arr/default.nix @@ -0,0 +1,51 @@ +{ + config, + lib, + pkgs, + ... +}: { + options.snowflake.services.arr = { + enable = lib.mkEnableOption "Enable arr suite configuration"; + jellyfin.enable = lib.mkEnableOption "Enable jellyfin configuration for NixOS"; + # mediaDir = lib.mkOption { + # type = lib.types.path; + # description = "Path to media storage directory, accessible by all *arr suite applications"; + # }; + }; + + config = let + cfg = config.snowflake.services.arr; + in + lib.mkIf cfg.enable { + services.jellyfin = { + enable = cfg.jellyfin.enable; + openFirewall = true; + }; + + users.groups.media = { + members = ["@wheel" "jellyfin"]; + }; + + nixpkgs.config.packageOverrides = pkgs: { + jellyfin-ffmpeg = pkgs.jellyfin-ffmpeg.override { + ffmpeg_6-full = pkgs.ffmpeg_6-full.override { + withMfx = false; + withVpl = true; + }; + }; + }; + + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + intel-media-driver + intel-compute-runtime + onevpl-intel-gpu + libvdpau-va-gl + ]; + }; + + services.jellyseerr.enable = true; + services.jellyseerr.openFirewall = true; + }; +} diff --git a/modules/nixos/services/backup/default.nix b/modules/nixos/services/backup/default.nix new file mode 100644 index 0000000..c43f800 --- /dev/null +++ b/modules/nixos/services/backup/default.nix @@ -0,0 +1,116 @@ +{ + config, + lib, + ... +}: +with lib; let + inherit (utils.systemdUtils.unitOptions) unitOption; +in { + options.snowflake.services.backups = { + enable = mkEnableOption "Enable restic backup service"; + + resticEnvironmentFile = mkOption { + description = "Age module containing the restic environment details"; + }; + + resticPasswordFile = mkOption { + description = "Age module containing the restic password"; + }; + + repository = mkOption { + description = "Repository to use as the restic endpoint. Must be in the form of :"; + type = types.str; + example = "b2:nix-backup-repository"; + }; + + config = mkOption { + default = {}; + type = types.attrsOf ( + types.submodule ( + {_}: { + options = { + dynamicFilesFrom = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + A script that produces a list of files to back up. + The result of this command are given to the `--files-from` option. + ''; + example = "find /home/user/repository -type d -name .git"; + }; + + paths = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + description = '' + List of paths to bck up. If null or an empty array, + no backup command will be run. This can be used to + create a prune-only job. + ''; + example = [ + "/etc/nixos" + "/var/lib/postgresql" + ]; + }; + + user = mkOption { + type = types.str; + default = "root"; + description = '' + The user under which the backup should run. + ''; + example = "postgresql"; + }; + + timerConfig = mkOption { + type = types.attrsOf unitOption; + default = { + OnCalendar = "daily"; + }; + description = '' + When to run the backup process. See man systemd.timer for details. + ''; + example = { + OnCalendar = "00:05"; + RandomizedDelaySec = "5h"; + }; + }; + }; + } + ) + ); + }; + }; + + config = let + cfg = config.snowflake.services.backups; + in + mkIf cfg.enable { + age.secrets = { + restic-environment.file = cfg.resticEnvironment.file; + restic-password.file = cfg.resticPassword.file; + }; + + services.restic.backups = + mapAttrs' ( + name: value: + nameValuePair name ( + { + initialize = true; + + repository = "${cfg.repository}:/${config.system.name}/${name}"; + environmentFile = config.age.secrets.restic-environment.path; + passwordFile = config.age.secrets.restic-password.path; + + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + ]; + } + // value + ) + ) + cfg.config; + }; +} diff --git a/modules/nixos/services/gitea/default.nix b/modules/nixos/services/gitea/default.nix new file mode 100644 index 0000000..0895ad1 --- /dev/null +++ b/modules/nixos/services/gitea/default.nix @@ -0,0 +1,109 @@ +{ config, lib, ... }: +{ + options.snowflake.services.gitea = { + enable = lib.mkEnableOption "Enable gitea service"; + + domain = lib.mkOption { + type = lib.types.str; + description = "Configuration domain to use for the gitea service"; + }; + + sshDomain = lib.mkOption { + type = lib.types.str; + description = "SSH domain to use for the gitea service"; + }; + + dbPasswordFile = lib.mkOption { + description = "Age module containing the postgresql password to use for gitea"; + }; + + httpPort = lib.mkOption { + type = lib.types.int; + description = "Configuration port for the gitea service to listen on"; + default = 3001; + }; + + sshPort = lib.mkOption { + type = lib.types.int; + description = "SSH port for the gitea service to listen on"; + default = 22022; + }; + }; + + config = lib.mkIf config.snowflake.services.gitea.enable { + age.secrets.gitea = { + inherit (config.snowflake.services.gitea.dbPasswordFile) file; + owner = config.services.gitea.user; + group = config.services.gitea.user; + }; + services.gitea = { + enable = true; + lfs.enable = true; + user = "git"; + + database = { + type = "postgres"; + passwordFile = config.age.secrets.gitea.path; + name = config.services.gitea.user; + inherit (config.services.gitea) user; + }; + + settings = { + actions = { + ENABLED = true; + }; + picture = { + DISABLE_GRAVATAR = true; + }; + server = { + DOMAIN = config.snowflake.services.gitea.domain; + HTTP_ADDR = "127.0.0.1"; + HTTP_PORT = config.snowflake.services.gitea.httpPort; + ROOT_URL = "https://${config.snowflake.services.gitea.domain}"; + SSH_DOMAIN = "https://${config.snowflake.services.gitea.sshDomain}"; + SSH_PORT = config.snowflake.services.gitea.sshPort; + }; + service = { + DISABLE_REGISTRATION = true; + SHOW_REGISTRATION_BUTTON = false; + }; + security = { + LOGIN_REMEMBER_DAYS = 14; + MIN_PASSWORD_LENGTH = 12; + PASSWORD_COMPLEXITY = "lower,upper,digit,spec"; + PASSWORD_CHECK_PWN = true; + }; + other = { + SHOW_FOOTER_VERSION = false; + SHOW_FOOTER_TEMPLATE_LOAD_TIME = false; + }; + }; + }; + + networking.firewall = lib.mkIf config.networking.firewall.enable { + allowedTCPPorts = [ config.snowflake.services.gitea.sshPort ]; + }; + + users.users.git = { + description = "Gitea service user"; + home = config.services.gitea.stateDir; + useDefaultShell = true; + group = "git"; + isSystemUser = true; + }; + users.groups.git = { }; + + services.nginx = { + virtualHosts = { + "${config.snowflake.services.gitea.domain}" = { + serverName = config.snowflake.services.gitea.domain; + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://localhost:${toString config.snowflake.services.gitea.httpPort}/"; + }; + }; + }; + }; + }; +} diff --git a/modules/nixos/services/homebridge/default.nix b/modules/nixos/services/homebridge/default.nix new file mode 100644 index 0000000..b49b26a --- /dev/null +++ b/modules/nixos/services/homebridge/default.nix @@ -0,0 +1,46 @@ +{ config, lib, ... }: +{ + options.snowflake.services.homebridge.enable = lib.mkEnableOption "Enable homebridge service for Apple HomeKit"; + + config = lib.mkIf config.snowflake.services.homebridge.enable { + networking.firewall = lib.mkIf config.networking.firewall.enable { + allowedTCPPorts = [ + 5353 + 8581 + 51241 + ]; + allowedTCPPortRanges = [ + { + from = 52100; + to = 52150; + } + ]; + allowedUDPPorts = [ + 5353 + 8581 + 51241 + ]; + allowedUDPPortRanges = [ + { + from = 52100; + to = 52150; + } + ]; + }; + + virtualisation.oci-containers.containers.homebridge = { + image = "docker.io/homebridge/homebridge:latest"; + volumes = [ "/var/lib/homebridge:/homebridge" ]; + environment = { + TZ = config.time.timeZone; + }; + ports = [ "8581:8581" ]; + extraOptions = [ + "--privileged" + "--net=host" + # For podman + "label=io.containers.autoupdate=registry" + ]; + }; + }; +} diff --git a/modules/nixos/services/maych-in/default.nix b/modules/nixos/services/maych-in/default.nix new file mode 100644 index 0000000..8645fc4 --- /dev/null +++ b/modules/nixos/services/maych-in/default.nix @@ -0,0 +1,27 @@ +{ config, lib, ... }: +{ + options.snowflake.services.static-site = { + enable = lib.mkEnableOption "Enable static site using nginx"; + package = lib.mkOption { + type = lib.types.package; + description = "Package to use as a root directory for the static site"; + }; + domain = lib.mkOption { + type = lib.types.str; + description = "Domain to use for the static site"; + }; + }; + + config = lib.mkIf config.snowflake.services.static-site.enable { + services.nginx = { + virtualHosts = { + "${config.snowflake.services.static-site.domain}" = { + serverName = config.snowflake.services.static-site.domain; + enableACME = true; + forceSSL = true; + root = config.snowflake.services.static-site.package; + }; + }; + }; + }; +} diff --git a/modules/nixos/services/miniflux/default.nix b/modules/nixos/services/miniflux/default.nix new file mode 100644 index 0000000..01c9cdf --- /dev/null +++ b/modules/nixos/services/miniflux/default.nix @@ -0,0 +1,61 @@ +{ config, lib, ... }: +{ + options.snowflake.services.miniflux = { + enable = lib.mkEnableOption "Enable miniflux service"; + + domain = lib.mkOption { + type = lib.types.str; + default = ""; + description = "Configuration domain to use for the miniflux service"; + }; + + adminTokenFile = lib.mkOption { + description = "Age module containing the ADMIN_USERNAME and ADMIN_PASSWORD to use for miniflux"; + }; + + listenPort = lib.mkOption { + type = lib.types.int; + description = "Configuration port for the miniflux service to listen on"; + default = 8816; + }; + }; + + config = + let + cfg = config.snowflake.services.miniflux; + in + lib.mkIf cfg.enable { + age.secrets.miniflux = { + inherit (cfg.adminTokenFile) file; + owner = "miniflux"; + group = "miniflux"; + }; + + services.miniflux.enable = true; + services.miniflux.adminCredentialsFile = config.age.secrets.miniflux.path; + + services.miniflux.config = { + LISTEN_ADDR = "localhost:${toString cfg.listenPort}"; + BASE_URL = "https://${cfg.domain}"; + }; + + services.nginx = { + virtualHosts = { + "${cfg.domain}" = { + serverName = "${cfg.domain}"; + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://localhost:${toString cfg.listenPort}"; + extraConfig = '' + proxy_redirect off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + ''; + }; + }; + }; + }; + }; +} diff --git a/modules/nixos/services/paperless/default.nix b/modules/nixos/services/paperless/default.nix new file mode 100644 index 0000000..9fc0001 --- /dev/null +++ b/modules/nixos/services/paperless/default.nix @@ -0,0 +1,67 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.services.paperless = { + enable = lib.mkEnableOption "Enable paperless service"; + + domain = lib.mkOption { + type = lib.types.str; + default = ""; + description = "Configuration domain to use for the paperless service"; + }; + + passwordFile = lib.mkOption { + description = "Age module containing the password to use for paperless"; + }; + + adminUser = lib.mkOption { + type = lib.types.str; + description = "Administrator username for the paperless service"; + }; + }; + + config = + let + cfg = config.snowflake.services.paperless; + in + lib.mkIf cfg.enable { + age.secrets.paperless = { + inherit (cfg.passwordFile) file; + owner = "paperless"; + group = "paperless"; + }; + + services.paperless = { + enable = true; + package = pkgs.paperless-ngx; + + passwordFile = config.age.secrets.paperless.path; + + settings = { + PAPERLESS_URL = "https://${cfg.domain}"; + PAPERLESS_OCR_LANGUAGE = "eng"; + PAPEERLESS_TASK_WORKERS = 4; + PAPERLESS_THREADS_PER_WORKER = 4; + PAPERLESS_ADMIN_USER = cfg.adminUser; + }; + }; + + # Requires services.nginx.enable. + services.nginx = { + virtualHosts = { + "${cfg.domain}" = { + serverName = "${cfg.domain}"; + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString config.services.paperless.port}/"; + }; + }; + }; + }; + }; +} diff --git a/modules/nixos/services/unifi-controller/default.nix b/modules/nixos/services/unifi-controller/default.nix new file mode 100644 index 0000000..3b6a34b --- /dev/null +++ b/modules/nixos/services/unifi-controller/default.nix @@ -0,0 +1,21 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.services.unifi-controller.enable = lib.mkEnableOption "Enable Unifi controller service for Unifi devices"; + + config = lib.mkIf config.snowflake.services.unifi-controller.enable { + networking.firewall.allowedTCPPorts = [ 8443 ]; + services.unifi = { + enable = true; + unifiPackage = pkgs.unifi8; + # Limit memory to 256MB. Works well enough + # for small, home-based controller deployments. + maximumJavaHeapSize = 256; + openFirewall = true; + }; + }; +} diff --git a/modules/nixos/services/vaultwarden/default.nix b/modules/nixos/services/vaultwarden/default.nix new file mode 100644 index 0000000..891146f --- /dev/null +++ b/modules/nixos/services/vaultwarden/default.nix @@ -0,0 +1,79 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.snowflake.services.vaultwarden = { + enable = lib.mkEnableOption "Enable vaultwarden service with postgres and nginx"; + + domain = lib.mkOption { + type = lib.types.str; + default = ""; + description = "Configuration domain to use for the vaultwarden service"; + }; + + adminTokenFile = lib.mkOption { + description = "Age module containing the ADMIN_TOKEN to use for vaultwarden"; + }; + }; + + config = + let + cfg = config.snowflake.services.vaultwarden; + in + lib.mkIf cfg.enable { + age.secrets.vaultwarden = { + inherit (cfg.adminTokenFile) file; + owner = "vaultwarden"; + group = "vaultwarden"; + }; + + services.vaultwarden = { + enable = true; + package = pkgs.vaultwarden; + + environmentFile = config.age.secrets.vaultwarden.path; + + dbBackend = "postgresql"; + + config = { + domain = "https://${cfg.domain}"; + signupsAllowed = false; + + rocketAddress = "127.0.0.1"; + rocketPort = 33003; + + databaseUrl = "postgres:///vaultwarden?host=/var/run/postgresql"; + }; + }; + + services.postgresql = { + # NOTE: To upgrade postgresql to a newer version, refer: + # https://nixos.org/manual/nixos/stable/#module-services-postgres-upgrading + package = pkgs.postgresql_14; + ensureDatabases = [ "vaultwarden" ]; + ensureUsers = [ + { + name = "vaultwarden"; + ensureDBOwnership = true; + } + ]; + }; + + # Requires services.nginx.enable. + services.nginx = { + virtualHosts = { + "${cfg.domain}" = { + serverName = "${cfg.domain}"; + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://${config.services.vaultwarden.config.rocketAddress}:${toString config.services.vaultwarden.config.rocketPort}/"; + }; + }; + }; + }; + }; +} diff --git a/modules/nixos/user/default.nix b/modules/nixos/user/default.nix new file mode 100644 index 0000000..94f9c22 --- /dev/null +++ b/modules/nixos/user/default.nix @@ -0,0 +1,89 @@ +{ config, lib, ... }: +{ + options.snowflake.user = { + enable = lib.mkEnableOption "Enable user configuration"; + + uid = lib.mkOption { + type = lib.types.nullOr lib.types.int; + default = 1000; + description = "User ID for the system user"; + }; + username = lib.mkOption { + type = lib.types.str; + description = "Username for the system user"; + }; + description = lib.mkOption { + type = lib.types.str; + description = "Real name for the system user"; + }; + extraGroups = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + }; + extraAuthorizedKeys = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "Additional authorized keys for the system user"; + }; + extraRootAuthorizedKeys = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "Additional authorized keys for root user"; + }; + userPasswordAgeModule = lib.mkOption { + description = "Age file to include to use as user password"; + }; + rootPasswordAgeModule = lib.mkOption { + description = "Age file to include to use as root password"; + }; + setEmptyPassword = lib.mkEnableOption "Enable to set empty password for the system user"; + setEmptyRootPassword = lib.mkEnableOption "Enable to set empty password for the root user"; + }; + + config = { + # Make users immutable. + users.mutableUsers = false; + + # Add ~/bin to $PATH. + environment.homeBinInPath = config.snowflake.user.enable; + + # Load password files. + age.secrets.hashed-user-password = lib.mkIf ( + !config.snowflake.user.setEmptyPassword && config.snowflake.user.enable + ) config.snowflake.user.userPasswordAgeModule; + age.secrets.hashed-root-password = lib.mkIf ( + !config.snowflake.user.setEmptyRootPassword + ) config.snowflake.user.rootPasswordAgeModule; + + # Configure the user account. + # NOTE: hashedPasswordFile has an issue. If the auth method is changed from `hashedPassword` + # to `hashedPasswordFile`, /etc/shadow gets messed up and login does not work. To fix this + # we need to remove all the users' entries from /etc/shadow and run nixos-rebuild. Seems to be + # a one-time thing. + # ref: https://github.com/NixOS/nixpkgs/issues/99433 + users.users.${config.snowflake.user.username} = lib.mkIf config.snowflake.user.enable { + inherit (config.snowflake.user) description; + extraGroups = [ + "wheel" + "users" + ] ++ config.snowflake.user.extraGroups; + hashedPasswordFile = lib.mkIf ( + !config.snowflake.user.setEmptyPassword + ) config.age.secrets.hashed-user-password.path; + isNormalUser = true; + openssh.authorizedKeys.keys = config.snowflake.user.extraAuthorizedKeys; + inherit (config.snowflake.user) uid; + }; + + # Define password, authorized keys and shell for root user. + users.users.root = { + hashedPasswordFile = lib.mkIf ( + !config.snowflake.user.setEmptyRootPassword + ) config.age.secrets.hashed-root-password.path; + openssh.authorizedKeys.keys = config.snowflake.user.extraRootAuthorizedKeys; + }; + + # Configure some miscellaneous dotfiles for my user. + # home-manager.users.${config.snowflake.user.username} = lib.mkIf config.snowflake.user.enable { + }; +} diff --git a/overlays/netbird/default.nix b/overlays/netbird/default.nix new file mode 100644 index 0000000..74a8578 --- /dev/null +++ b/overlays/netbird/default.nix @@ -0,0 +1,26 @@ +_: _self: super: let + version = "0.28.8"; +in { + netbird = super.netbird.override { + buildGoModule = args: + super.buildGoModule ( + args + // { + inherit version; + src = super.fetchFromGitHub { + owner = "netbirdio"; + repo = "netbird"; + rev = "v${version}"; + hash = "sha256-DfY8CVBHgE/kLALKNzSgmUxM0flWLesU0XAgVsHHLKc="; + }; + vendorHash = "sha256-CqknRMijAkWRLXCcIjRBX2wB64+RivD/mXq28TqzNjg="; + ldflags = [ + "-s" + "-w" + "-X github.com/netbirdio/netbird/version.version=${version}" + "-X main.builtBy=nix" + ]; + } + ); + }; +} diff --git a/secrets/machines/bicboye/password.age b/secrets/machines/bicboye/password.age new file mode 100644 index 0000000..c7ab03f --- /dev/null +++ b/secrets/machines/bicboye/password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA KqFc6Ej8L8yNVX3EoEqlJZlpdmsBTAn3GDPlH0CsmWc +6cEtER5dcQNzWfPUGeN0tMyPEwOUMkSTiqnCQrsNhp8 +-> ssh-ed25519 9JjquQ sFTTVGk5VDcfw/K4yKbwGX73O2LFXp5eHWkzHhAeDVY +usZ/giJLoWxXJ0pA8HZZSHMybxuxf8HxjDkeD5Kpuz4 +--- CjABvoWY5QYTJ2OmUnqxOxyehm3r/YQmYyx00auShxY +t0]ifE!i+ԬA(ңTڔR,M9׺?s~=Ox}7!{"'FC$@ƞo%JݮbxEW:x<3(U \ No newline at end of file diff --git a/secrets/machines/bicboye/root-password.age b/secrets/machines/bicboye/root-password.age new file mode 100644 index 0000000..6f7e710 --- /dev/null +++ b/secrets/machines/bicboye/root-password.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA 3+hMUFIxtx9E/zDlfBO+hGXrH9DczMw+7iD0X1XKU3k +TOkvyYCoTcDa2hNlKEzlgsw5igOhFbUMDRuW2HAUNw8 +-> ssh-ed25519 9JjquQ dPcsKuRuy8x1eDFfECiSfBYZqb6OUXAAdmbURYvaW0E +UmpPB5oPTX24i9lthZmG5Ec13LDiwWO3rDyU4VParcE +--- L03TAuKNx+q1xZSKLIPaeC70arrtZYKr5S3y8B2kPJI +'~^c tv_%# Tde[pBܵa{߯ddr +C.s]-6bJk;g#Etg @iQP|>̝ \ No newline at end of file diff --git a/secrets/machines/thonkpad/password.age b/secrets/machines/thonkpad/password.age new file mode 100644 index 0000000..f84b040 --- /dev/null +++ b/secrets/machines/thonkpad/password.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA tlbrFSUIpErZri6A7aRu9mrzDG7QcIy/18lEvX25hkA +Fj6JcwB4uJs+aM3AbV6Svrj6VJezt7cpZC1dId5/hSs +-> ssh-ed25519 XbzZEw uKNtnEb70dMwdqQ30o9AQZHu5YlCNibttAXpcNgzxG0 +yCkEOaU2ioYdOJxCCbijkKJZREiV02M9gxLyXmOvdTE +-> ssh-ed25519 wWcc7w OSUGAGAa++2z9JudGKv9pdZnP0ZbxuapbAuyjycanz4 +i9mArrFaC+zUIJWQms7F57mEnAYKLJzKyu1r9R16j4Q +--- 1unXr5UfhyzTZqri4fExZh0dLtvnQZM6zfWLLlXIBgI +Xl4K.$ZnA4M}RAeO6pJE!B ^-~",ql@GpM!*IRȧ) l]q/NheR*vЄ *k؋B163k \ No newline at end of file diff --git a/secrets/machines/thonkpad/root-password.age b/secrets/machines/thonkpad/root-password.age new file mode 100644 index 0000000..4fb1e5f Binary files /dev/null and b/secrets/machines/thonkpad/root-password.age differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix new file mode 100644 index 0000000..3e3a78a --- /dev/null +++ b/secrets/secrets.nix @@ -0,0 +1,33 @@ +let + codingcoffee = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJQWA+bAwpm9ca5IhC6q2BsxeQH4WAiKyaht48b7/xkN cc@predator" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKJnFvU6nBXEuZF08zRLFfPpxYjV3o0UayX0zTPbDb7C cc@eden" + ]; + thunderbottom = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG3PeMbehJBkmv8Ee7xJimTzXoSdmAnxhBatHSdS+saM" + ]; + + thonkpad = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOyY8ZkhwWiqJCiTqXvHnLpXQb1qWwSZAoqoSWJI1ogP" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMrNdHskpknCow+nuCTEBRrKb0b2BKzwTQY60eEAWztS" + ]; + + smolboye = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQFm91hLes24sYbq96zD52mDrrr1l2F2xstcfAEg+qI"]; + bicboye = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBsciEMPwLAYtbHNkdedjhSrb66fFQ46lgnVGssCuiLH"]; + + servers = bicboye ++ smolboye; + users = thunderbottom ++ codingcoffee; +in { + "machines/thonkpad/password.age".publicKeys = thunderbottom ++ thonkpad; + "machines/thonkpad/root-password.age".publicKeys = thunderbottom ++ thonkpad; + "machines/bicboye/password.age".publicKeys = thunderbottom ++ bicboye; + "machines/bicboye/root-password.age".publicKeys = thunderbottom ++ bicboye; + "services/backup/environment.age".publicKeys = thunderbottom ++ bicboye; + "services/backup/password.age".publicKeys = thunderbottom ++ bicboye; + "services/gitea/password.age".publicKeys = thunderbottom ++ bicboye; + "services/maddy/password.age".publicKeys = thunderbottom ++ bicboye; + "services/maddy/user-watashi.age".publicKeys = thunderbottom ++ servers; + "services/miniflux/password.age".publicKeys = thunderbottom ++ bicboye; + "services/paperless/password.age".publicKeys = users ++ bicboye; + "services/vaultwarden/password.age".publicKeys = users ++ bicboye; +} diff --git a/secrets/services/backup/environment.age b/secrets/services/backup/environment.age new file mode 100644 index 0000000..53354cf Binary files /dev/null and b/secrets/services/backup/environment.age differ diff --git a/secrets/services/backup/password.age b/secrets/services/backup/password.age new file mode 100644 index 0000000..0b22c40 --- /dev/null +++ b/secrets/services/backup/password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA cu04OlowGfn91ape/TGXYToi4kFU9JIS4iY09qlMPmo +Yv2vSFELyNl93DaNQc+E3b9MuwGr0k79TISXF2fUxTY +-> ssh-ed25519 9JjquQ FJ0QtlUi+VKZ7S6BtqCj21x5Q2QG/8s2bay4j+JFFlQ +K1ijqw6pz7F0CZedLxNdXWuPrKMm/y4cnVaVlMuQ4CM +--- WJz/j8eixXYAzN4VxyHrdMaXCSFsVzlVAhXU8cgq6cU +[ Uu fL8̶ǭQRrV4'_&Żzϐ,Q6g䃡Nقq \ No newline at end of file diff --git a/secrets/services/gitea/password.age b/secrets/services/gitea/password.age new file mode 100644 index 0000000..ea57572 --- /dev/null +++ b/secrets/services/gitea/password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA PIaYFOuYTsAufLY3jySjdLfKzfcQ6hAetR8sG9k4KTM +Wg1kb+WgD8MW81bJfwejeTiiEVJCH9WWQ7O7J5zeYj8 +-> ssh-ed25519 9JjquQ nN0gqdhhk+tcsXgb2YdlNr9TCM8ZzJ8jgwFQK+o3Cw0 +uklN8haFY8XCUMIlAPqIheganGtCyLSg2w/4LM9dcdM +--- uNsDhT+Z43s4wRMaKiuVS0CIib7Geh+zBtSHIPLdHmY +7V%)},1ýr㊔_ ;ݷͭNbl \ No newline at end of file diff --git a/secrets/services/maddy/password.age b/secrets/services/maddy/password.age new file mode 100644 index 0000000..67bd1ba --- /dev/null +++ b/secrets/services/maddy/password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA 6fvS/eRe0S7zxzr85BqpsPzsrcgnpnVvHh8qI7CEyig +9QpSqlaAfRJ3zS3tnwna6WnZLfQdvoGqFETjVHbZVJ4 +-> ssh-ed25519 9JjquQ l8kHf5rPgVU/ls1nHp9c1pLhCOfxgodbcKhxP1CTwi0 +kU/FeaKvBfEtTAT3F6jBMesZDtenUA4lza7+lYsaJlc +--- 7pUn3sY/IBJkMQWYzjY99NJURtov6Aiyz5djQCgpgPo +RX2)Rcb q1q!>w#W((yJDz#)D("yQ~YPaOV(Э#lm싆+/H#+Zy3@ {p \ No newline at end of file diff --git a/secrets/services/maddy/user-watashi.age b/secrets/services/maddy/user-watashi.age new file mode 100644 index 0000000..b76954a --- /dev/null +++ b/secrets/services/maddy/user-watashi.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA OsckddKmgFuwo64IFPysoEWhUWdaNz0fQOpgup0dKQY +o1/BcRP/NND8YHZYuQnclfa1GxlczSdc57nOw9Zm2io +-> ssh-ed25519 9JjquQ pLjLs2p363cKXPmz8iYAOJUYSlmK4N9GCXlizaE5fj4 +kIdPVG/i3WdRGYxLefEnCA8cTytHCZEcpqbp5Y8aG2o +-> ssh-ed25519 H9OGOA BowCiYKCWxWbiapKpdshcRzdZR1UEscscAAOe/kEig8 +Lexjp0LuPZs5bV8CQ63Scb+xh8lPDM7x17KD9r0/1qU +--- e+NBlts82HBx3gbjznmUKufAYF1w2fzEO+LNx9yvq18 +# ssh-ed25519 XInHQA inhxQU5+jlt6A2Ahn7xif+Ncv2SGSRusySaiGSRC/Cg +mUIduBibBHSQKf+3gyFxU4HRA1Hrb4dVA5grE/vO2Mc +-> ssh-ed25519 9JjquQ qnjvC1aSVNonnVKwEgSPwpbWmalSI2rL99XnGCFMr0I +lbLq+anGxBDIZ5JLxv0AuW33wRqzgU/TQ8yT5m5rHJg +--- 28LhE362umkY5DWiBzAiT32Zm6AvBQRiVLjJ9EALRkA +p~RtR $}J@X$Mc> <<[&d3ޑ8cm~l \ No newline at end of file diff --git a/secrets/services/paperless/password.age b/secrets/services/paperless/password.age new file mode 100644 index 0000000..0cad219 --- /dev/null +++ b/secrets/services/paperless/password.age @@ -0,0 +1,12 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA uCUIywKJrUQhqYI8uhhxNIsXoTcRBbZSRVfUJPCp2wM +2p1OvwRBUMJTXvhp2PdGBCwxKU/rFPBHKZaKJ38HvAo +-> ssh-ed25519 K8TEKA d4DDO/774I+lhafaKbrERWsl6NqeqpdkbmZy0FA6Dws +ObQGhn0BmzqE5pSg+vPSVdx3rLng9h3wPfoFx2umVAI +-> ssh-ed25519 7+Zv5Q M1P+teBvn1p4zbFNIVvGremZC5hViNswi9q24mCxCEg +zR1sV/5t8nI3jky5Ou9Ud7IYC8E8nkQnvRIW9lG7nbA +-> ssh-ed25519 9JjquQ P5F2UqVRXkySbbI4OHM6rChELU0wpx6Stpvz78Ie1yY +uWOhkO0vx0anNHA5EWuLmDmTQvoY/c1iSzlVl2xldC4 +--- BARoI30iwdy5g5hWJoHpVlA6Hlhu4SBpGhxrTPvG8ok +;&_xIXRϣĴ螞ܾ]9'La1Q )@ +WMe%3K \ No newline at end of file diff --git a/secrets/services/vaultwarden/password.age b/secrets/services/vaultwarden/password.age new file mode 100644 index 0000000..8c3f6f4 --- /dev/null +++ b/secrets/services/vaultwarden/password.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 XInHQA aQ/88prWa3Tx1JdSIgSGZPhF+DAMtQllm4KRhUlDDg8 +31xawF9XFf83zxx7SdHYLul12Pb8wk+5DBjbT236FD4 +-> ssh-ed25519 K8TEKA 75kXFnNq76OsX+aRQp5BN0q4mw1cdGIeBVdYUcly2wg +9LFm33M8FTRYRJtAwGrwspSFJmcpMGIrq36wYs3Zz8g +-> ssh-ed25519 7+Zv5Q yTsGVm9Q1IWiuEd57JzOjqkLpVwfnFdkz5RnwCsLxB0 +TfiDbFF/yI8ZQBCaz8QmL5dWkQlDSPHLXvPnaeNMAQs +-> ssh-ed25519 9JjquQ 4ksLVKkaDvsg7c5tK/PUELN+NOJUmC0ajD3aliuvkhY +8Swc8sjfpjP+yvIuZkucC121ei7cvHV9CRsi5Kdm98E +--- 4K9ZIqe95VA4ewxLh8OELKCywAs2NKhPdVzaYzmzAjI +-F،(3C\L /]v.C#U nruMG2*>6`~H E]ὴ`>;ԶH8\Q4Y!iitgW >儣P<0c˼|MP_)᳗%YE2؃ov \ No newline at end of file diff --git a/systems/x86_64-linux/bicboye/default.nix b/systems/x86_64-linux/bicboye/default.nix new file mode 100644 index 0000000..179fa33 --- /dev/null +++ b/systems/x86_64-linux/bicboye/default.nix @@ -0,0 +1,111 @@ +{ + lib, + pkgs, + userdata, + ... +}: { + imports = [./hardware.nix]; + + hardware.cpu.intel.updateMicrocode = true; + hardware.enableRedistributableFirmware = true; + + networking = { + hostName = "bicboye"; + useDHCP = lib.mkDefault false; + interfaces.enp6s0 = { + useDHCP = lib.mkDefault true; + wakeOnLan.enable = true; + }; + firewall.allowedTCPPorts = [ + 80 + 443 + ]; + }; + + # Enable weekly btrfs auto-scrub. + services.btrfs.autoScrub = { + enable = true; + interval = "weekly"; + fileSystems = ["/"]; + }; + + # Power management, enable powertop and thermald. + powerManagement.powertop.enable = true; + services.thermald.enable = true; + + # TODO: move to module + security.acme.defaults.email = "chinmaydpai@gmail.com"; + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedTlsSettings = true; + }; + + snowflake = { + stateVersion = "24.05"; + + core.docker.enable = true; + core.docker.storageDriver = "btrfs"; + core.security.sysctl.enable = lib.mkForce false; + + networking.networkManager.enable = true; + + hardware.initrd-luks = { + enable = true; + authorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG3PeMbehJBkmv8Ee7xJimTzXoSdmAnxhBatHSdS+saM" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOyY8ZkhwWiqJCiTqXvHnLpXQb1qWwSZAoqoSWJI1ogP" + ]; + availableKernelModules = ["r8169"]; + }; + + services = { + gitea = { + enable = true; + domain = "git.deku.moe"; + sshDomain = "git-ssh.deku.moe"; + dbPasswordFile = userdata.secrets.services.gitea.password; + }; + + miniflux = { + enable = true; + domain = "flux.deku.moe"; + adminTokenFile = userdata.secrets.services.miniflux.password; + }; + + paperless = { + enable = true; + domain = "docs.deku.moe"; + passwordFile = userdata.secrets.services.paperless.password; + adminUser = "chinmay"; + }; + + vaultwarden = { + enable = true; + domain = "bw.deku.moe"; + adminTokenFile = userdata.secrets.services.vaultwarden.password; + }; + + static-site = { + enable = true; + package = pkgs.maych-in; + domain = "maych.in"; + }; + unifi-controller.enable = true; + }; + + user = { + enable = true; + username = "server"; + description = "Bicboye Server"; + userPasswordAgeModule = userdata.secrets.machines.bicboye.password; + rootPasswordAgeModule = userdata.secrets.machines.bicboye.root-password; + extraAuthorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG3PeMbehJBkmv8Ee7xJimTzXoSdmAnxhBatHSdS+saM" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOyY8ZkhwWiqJCiTqXvHnLpXQb1qWwSZAoqoSWJI1ogP" + ]; + }; + }; +} diff --git a/systems/x86_64-linux/bicboye/hardware-intel.nix b/systems/x86_64-linux/bicboye/hardware-intel.nix new file mode 100644 index 0000000..35058b8 --- /dev/null +++ b/systems/x86_64-linux/bicboye/hardware-intel.nix @@ -0,0 +1,122 @@ +_: { + boot = { + initrd = { + availableKernelModules = [ + "xhci_pci" + "ahci" + "ehci_pci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + luks.devices."cryptroot".device = "/dev/disk/by-uuid/e570c2be-65df-4208-9cac-a03de08a6209"; + }; + kernelModules = ["kvm-intel"]; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@" + ]; + neededForBoot = true; # required + }; + + "/home" = { + device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@home" + ]; + }; + + "/.snapshots" = { + device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@snapshots" + ]; + }; + + "/var/log" = { + device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@log" + ]; + }; + + "/etc/nixos" = { + device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@nixos-config" + ]; + }; + + "/var/cache" = { + device = "/dev/disk/by-uuid/a1b57a56-16d4-45ea-bac3-daeacd3dbcb2"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@cache" + ]; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/B731-09A3"; + fsType = "vfat"; + options = ["fmask=0022" "dmask=0022"]; + }; + + # "/storage/immich" = { + # device = "/dev/disk/by-uuid/bae65b7a-4f08-4b0d-963c-72e71bfcff46"; + # fsType = "btrfs"; + # options = [ + # "defaults" + # "compress-force=zstd" + # "noatime" + # "user" + # ]; + # }; + + # TODO: delete btrfs subvolume + # "/storage/syncthing" = { + # device = "/dev/disk/by-uuid/e3a4c251-a3e2-4b5e-a63b-70f53b51836a"; + # fsType = "btrfs"; + # options = [ + # "defaults" + # "compress-force=zstd" + # "noatime" + # "user" + # ]; + # }; + }; + swapDevices = []; +} diff --git a/systems/x86_64-linux/bicboye/hardware.nix b/systems/x86_64-linux/bicboye/hardware.nix new file mode 100644 index 0000000..3720266 --- /dev/null +++ b/systems/x86_64-linux/bicboye/hardware.nix @@ -0,0 +1,121 @@ +_: { + boot = { + initrd = { + availableKernelModules = [ + "xhci_pci" + "ahci" + "ehci_pci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + luks.devices."root".device = "/dev/disk/by-uuid/e70bfc3c-1147-4af7-9bae-69f70146953f"; + }; + kernelModules = ["kvm-intel"]; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@" + ]; + neededForBoot = true; # required + }; + + "/home" = { + device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@home" + ]; + }; + + "/.snapshots" = { + device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@snapshots" + ]; + }; + + "/var/log" = { + device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@log" + ]; + }; + + "/etc/nixos" = { + device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@nixos-config" + ]; + }; + + "/var/cache" = { + device = "/dev/disk/by-uuid/5cabc339-898c-4604-9bfc-0a2cf17e44ca"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@cache" + ]; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/1C6C-122C"; + fsType = "vfat"; + }; + + "/storage/immich" = { + device = "/dev/disk/by-uuid/bae65b7a-4f08-4b0d-963c-72e71bfcff46"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "user" + ]; + }; + + # TODO: delete btrfs subvolume + "/storage/syncthing" = { + device = "/dev/disk/by-uuid/e3a4c251-a3e2-4b5e-a63b-70f53b51836a"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "user" + ]; + }; + }; + swapDevices = []; +} diff --git a/systems/x86_64-linux/thonkpad/default.nix b/systems/x86_64-linux/thonkpad/default.nix new file mode 100644 index 0000000..ae4ccfc --- /dev/null +++ b/systems/x86_64-linux/thonkpad/default.nix @@ -0,0 +1,73 @@ +{ + lib, + pkgs, + userdata, + ... +}: { + imports = [./hardware.nix]; + + hardware.cpu.intel.updateMicrocode = true; + hardware.enableRedistributableFirmware = true; + + networking.hostName = "thonkpad"; + networking.interfaces.wlan0.useDHCP = lib.mkDefault false; + networking.useNetworkd = true; + + # Enable weekly btrfs auto-scrub. + services.btrfs.autoScrub = { + enable = true; + interval = "weekly"; + fileSystems = ["/"]; + }; + + services.system76-scheduler.enable = true; + services.system76-scheduler.settings.cfsProfiles.enable = true; + # Power management, enable powertop and thermald. + powerManagement.powertop.enable = true; + powerManagement.cpuFreqGovernor = lib.mkDefault "schedutil"; + services.thermald.enable = true; + + # TODO: remove, temporary for mongoDB build + systemd.services.nix-daemon.environment.TMPDIR = "/var/tmp/nix-daemon"; + + services.ratbagd.enable = true; + + snowflake = { + stateVersion = "24.05"; + extraPackages = with pkgs; [ + easyeffects + glibc + logseq + obsidian + piper + # terraform + terraform-ls + ]; + + core.lanzaboote.enable = true; + + core.docker.enable = true; + core.docker.storageDriver = "btrfs"; + + desktop.enable = true; + desktop.kde.enable = true; + + gaming.steam.enable = true; + + hardware.bluetooth.enable = true; + hardware.yubico.enable = true; + + networking.firewall.enable = true; + networking.networkManager.enable = true; + networking.iwd.enable = true; + networking.resolved.enable = true; + networking.netbird.enable = true; + + user.enable = true; + user.username = "chnmy"; + user.description = "Chinmay D. Pai"; + user.extraGroups = ["video"]; + user.userPasswordAgeModule = userdata.secrets.machines.thonkpad.password; + user.rootPasswordAgeModule = userdata.secrets.machines.thonkpad.root-password; + }; +} diff --git a/systems/x86_64-linux/thonkpad/disk-config.nix b/systems/x86_64-linux/thonkpad/disk-config.nix new file mode 100644 index 0000000..ffcd441 --- /dev/null +++ b/systems/x86_64-linux/thonkpad/disk-config.nix @@ -0,0 +1 @@ +{ } diff --git a/systems/x86_64-linux/thonkpad/hardware.nix b/systems/x86_64-linux/thonkpad/hardware.nix new file mode 100644 index 0000000..ce95327 --- /dev/null +++ b/systems/x86_64-linux/thonkpad/hardware.nix @@ -0,0 +1,141 @@ +_: { + boot = { + initrd = { + availableKernelModules = [ + "xhci_pci" + "xhci_hcd" + "nvme" + "usb_storage" + "sd_mod" + ]; + luks.devices."cryptroot".device = "/dev/disk/by-uuid/312b4d84-64dc-4721-9be3-bb0148199b16"; + luks.devices."cryptroot".preLVM = true; + }; + kernelModules = [ + "kvm-intel" + "thinkpad_acpi" + "iwlwifi" + "i915" + ]; + blacklistedKernelModules = [ + "iTCO_wdt" + ]; + kernelParams = ["resume_offset=2465529" "intel_pstate=active" "i915.enable_gvt=1" "i915.enable_guc=3" "thinkpad_acpi.fan_control=1"]; + resumeDevice = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + supportedFilesystems = ["btrfs"]; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + fsType = "btrfs"; + options = [ + "defaults" + # "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@" + "discard=async" + ]; + neededForBoot = true; + }; + + "/home" = { + device = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + fsType = "btrfs"; + options = [ + "defaults" + # "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@home" + "discard=async" + ]; + }; + + "/.snapshots" = { + device = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@snapshots" + "discard=async" + ]; + }; + + "/var/log" = { + device = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + fsType = "btrfs"; + options = [ + "defaults" + # "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@log" + "discard=async" + ]; + }; + + "/var/cache" = { + device = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + fsType = "btrfs"; + options = [ + "defaults" + # "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@cache" + "discard=async" + ]; + }; + + "/etc/nixos" = { + device = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@nix-config" + ]; + }; + + "/nix" = { + device = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + fsType = "btrfs"; + options = [ + "defaults" + # "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@nix-store" + "discard=async" + ]; + }; + + # ref: https://sawyershepherd.org/post/hibernating-to-an-encrypted-swapfile-on-btrfs-with-nixos/ + "/swap" = { + device = "/dev/disk/by-uuid/d5c21883-f0e6-4e7a-b9a5-ee0bf4780ec5"; + fsType = "btrfs"; + options = [ + "subvol=@swap" + "noatime" + ]; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/90A5-35FF"; + fsType = "vfat"; + }; + }; + swapDevices = [{device = "/swap/swapfile";}]; +} diff --git a/systems/x86_64-linux/thonkpad/thonkpad-12.nix b/systems/x86_64-linux/thonkpad/thonkpad-12.nix new file mode 100644 index 0000000..49ebb2f --- /dev/null +++ b/systems/x86_64-linux/thonkpad/thonkpad-12.nix @@ -0,0 +1,136 @@ +_: { + boot = { + initrd = { + availableKernelModules = [ + "xhci_pci" + "thunderbolt" + "nvme" + "usb_storage" + "sd_mod" + ]; + luks.devices."cryptroot".device = "/dev/disk/by-uuid/9de352ea-128f-4d56-a720-36d81dfd9b92"; + }; + kernelModules = [ + "kvm-intel" + # "thinkpad_acpi" + "iwlwifi" + "xe" + ]; + kernelParams = [ + "xe.force_probe=7d45" + # "resume_offset=2465529" + # "intel_pstate=active" + # "thinkpad_acpi.fan_control=1" + ]; + # resumeDevice = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + fsType = "btrfs"; + options = [ + "defaults" + "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@" + ]; + neededForBoot = true; + }; + + "/home" = { + device = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + fsType = "btrfs"; + options = [ + "defaults" + "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@home" + ]; + }; + + "/.snapshots" = { + device = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@snapshots" + ]; + }; + + "/var/log" = { + device = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + fsType = "btrfs"; + options = [ + "defaults" + "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@log" + ]; + }; + + "/var/cache" = { + device = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + fsType = "btrfs"; + options = [ + "defaults" + "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@cache" + ]; + }; + + "/etc/nixos" = { + device = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + fsType = "btrfs"; + options = [ + "defaults" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@nix-config" + ]; + }; + + "/nix" = { + device = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + fsType = "btrfs"; + options = [ + "defaults" + "autodefrag" + "compress-force=zstd" + "noatime" + "ssd" + "subvol=@nix-store" + ]; + }; + + # ref: https://sawyershepherd.org/post/hibernating-to-an-encrypted-swapfile-on-btrfs-with-nixos/ + # "/swap" = { + # device = "/dev/disk/by-uuid/870fde90-a91a-4554-8b1c-d5702c789f4d"; + # fsType = "btrfs"; + # options = [ + # "subvol=@swap" + # "noatime" + # ]; + # }; + + "/boot" = { + device = "/dev/disk/by-uuid/B9A2-7AA6"; + fsType = "vfat"; + options = ["fmask=0022" "dmask=0022"]; + }; + }; + swapDevices = []; +}