diff --git a/.gitignore b/.gitignore index 87a3018..de901db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -result -*.qcow2 +# gitignore +.pre-commit-config.* \ No newline at end of file diff --git a/.sops.yaml b/.sops.yaml index e709730..835dd06 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,7 +1,7 @@ keys: - - &admin age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 + - &rafiq age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 creation_rules: - - path_regex: \.(yaml|json|env|ini)$ + - path_regex: \.(yaml)$ key_groups: - age: - - *admin + - *rafiq diff --git a/README.md b/README.md deleted file mode 100644 index b1d73f1..0000000 --- a/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# Planning - -## To-do - -- [ ] Copy over ~/.ssh/id_ed25519 and zellij status bar plugin confirmation -- [ ] Migrate immich to apollo, point to helios -- [x] Migrate LibreChat to apollo, maintain db -- [ ] Figure out wakapi -- [x] Add forgejo -- [ ] Add simple blog - -## Versions - -- 1.0.0 - - Setup desktop as hypervisor with nixos and win11 - - Spare drive as steam library - - GPU passthrough to either system - - Always running, VMs spun down except when in use - - Apollo as hypervisor - - VMs for docker host, home-assistant, bare metal or containerised services - - Automated backups for home and state directories - - Ability to build VMs of all systems and implement integration tests - - Staging VMs for ad-hoc testing - - All servers set up with following services: - - Git server - - Chat app - - Network shares - - Federation with ActivityPub - - Wakapi - - Add a way to define services per host and refer to them by hostname - - helios as file and db server, apollo as services and reverse proxy -- 0.3.0 - - Integration tests for all services - - Migrate services from helios - -# Modules - -The nixosModules and homeModules exposed by this flake are slightly out of the norm. - -Option declarations for user specific configuration are kept to: - -- homeModules for CLI -- nixosModules for desktop - -System configurations, to this end, should include the window manager, lockscreen, terminal etc. for that system. - -These desktop programs will be **configured** in home-manager for each user, but those configurations consult the osConfig variable passed in by home-manager. - -# System Setup - -The following files are **required** for system activation: - -- /persist/home/${mainUser}/.ssh/id_ed25519 - -This private key will be used by sops-nix to decrypt the secrets in [this encrypted file](secrets/secrets.yaml). The secrets inside the yaml file should also be set, or otherwise removed alongside their declarations , found [here](modules/nixos/system/secrets.nix) and references. - -```bash -# On the target machine -# Boot into the NixOS installer - -sudo passwd - -# On the host machine -deploy --user "rafiq" --ip "10.10.0.102" --hostname "apollo" -``` - -### From a Local NixOS Installer - -The installation may run out of space when installing from an install ISO. In that case, use Disko to format the drives first, then create a `/mnt/tmp` directory and set it as TMPDIR for nixos-install. - -```bash -sudo su -nix --extra-experimental-features "nix-command flakes" run github:nix-community/disko/master -- --mode destroy,format,mount --flake github:rrvsh/pantheon# -# Copy SSH key to /persist/home/rafiq/.ssh -mkdir /mnt/tmp -TMPDIR=/mnt/tmp nixos-install --flake github:rrvsh/pantheon# --no-root-password -reboot -``` - -# Impermanence - -System and user state is stored under /persist. Anything not declared under -`{environment,home}.persistence` is deleted on system boot. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..ff57ce6 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,29 @@ +# Pantheon +This flake serves as a monorepo for my systems (using IaC), dotfiles, and scripts. +It's hosted at https://git.rrv.sh/rrvsh/pantheon, and mirrored to https://github.com/rrvsh/pantheon. + +## Structure +The system configurations are defined in [`flake.manifest`](nix/manifest.nix). +`flake.manifest.owner` provides the attributes for the administrator user, including username and pubkey. +`flake.manifest.hosts` provides the specifications for the system configurations that should be exposed by the flake as nixosConfigurations. +`flake.modules.nixos.*` provide NixOS options and configurations. +The attribute `flake.modules.nixos.default` provides options that will be applied to every system of that class. +You can use it as seen [here](nix/modules/flake/home-manager.nix): + +```nix +flake.modules.nixos.default.imports = [ inputs.home-manager.nixosModules.default ]; +``` + +The other attributes under `flake.modules.nixos` should be opt-in, i.e. provide options that will be set in the profiles. +`flake.profiles.nixos` provides profiles which use the options defined in `flake.modules.nixos` to define different roles for each system, such as graphical, laptop, headless, etc. +Options should not be defined here. +`flake.contracts.nixos.*` will provide contracts, such as reverse proxies or databases, which will configure options on the provider and receiver host. + +## Acknowledgements +Thanks to the following for inspiring this configuration. I highly recommend you look through their writings and configurations. +- [ornicar](https://github.com/ornicar/dotfiles) which is where I first heard of NixOS +- [No Boilerplate](https://www.youtube.com/watch?v=CwfKlX3rA6E&pp=0gcJCfwAo7VqN5tD) for making me finally try the OS +- [ryan4yin](https://nixos-and-flakes.thiscute.world/) for being an amazing introduction to NixOS, home-manager, and flakes +- [NotAShelf](https://github.com/NotAShelf/) for their blog and for the wonderful [NVF](https://github.com/notashelf/nvf) +- [mightyiam](https://github.com/mightyiam/infra) for their infrastructure repo using flake-parts +- [drupol](https://not-a-number.io/2025/refactoring-my-infrastructure-as-code-configurations/) for this blog post which convinced me to rebase my infra to use flake-parts diff --git a/docs/cheatsheet.md b/docs/cheatsheet.md new file mode 100644 index 0000000..4f76757 --- /dev/null +++ b/docs/cheatsheet.md @@ -0,0 +1,2 @@ +# cheatsheet +`__curPos.file` will give the full evaluated path of the nix file it is called in. See [this issue](https://github.com/NixOS/nix/issues/5897#issuecomment-1012165198) for more information. \ No newline at end of file diff --git a/flake.lock b/flake.lock index 83e6f9b..fb9b627 100644 --- a/flake.lock +++ b/flake.lock @@ -67,31 +67,88 @@ "type": "github" } }, - "crane": { + "dedupe_flake-compat": { "locked": { - "lastModified": 1750266157, - "narHash": "sha256-tL42YoNg9y30u7zAqtoGDNdTyXTi8EALDeCB13FtbQA=", - "owner": "ipetkov", - "repo": "crane", - "rev": "e37c943371b73ed87faf33f7583860f81f1d5a48", + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", "type": "github" }, "original": { - "owner": "ipetkov", - "repo": "crane", + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "dedupe_flake-utils": { + "inputs": { + "systems": [ + "systems" + ] + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "dedupe_gitignore": { + "inputs": { + "nixpkgs": [ + "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" + } + }, + "dedupe_mnw": { + "locked": { + "lastModified": 1748710831, + "narHash": "sha256-eZu2yH3Y2eA9DD3naKWy/sTxYS5rPK2hO7vj8tvUCSU=", + "owner": "gerg-l", + "repo": "mnw", + "rev": "cff958a4e050f8d917a6ff3a5624bc4681c6187d", + "type": "github" + }, + "original": { + "owner": "gerg-l", + "repo": "mnw", "type": "github" } }, "disko": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { - "lastModified": 1750903843, - "narHash": "sha256-Ng9+f0H5/dW+mq/XOKvB9uwvGbsuiiO6HrPdAcVglCs=", + "lastModified": 1751854533, + "narHash": "sha256-U/OQFplExOR1jazZY4KkaQkJqOl59xlh21HP9mI79Vc=", "owner": "nix-community", "repo": "disko", - "rev": "83c4da299c1d7d300f8c6fd3a72ac46cb0d59aae", + "rev": "16b74a1e304197248a1bc663280f2548dbfcae3c", "type": "github" }, "original": { @@ -100,6 +157,21 @@ "type": "github" } }, + "files": { + "locked": { + "lastModified": 1750263550, + "narHash": "sha256-EW/QJ8i/13GgiynBb6zOMxhLU1uEkRqmzbIDEP23yVA=", + "owner": "mightyiam", + "repo": "files", + "rev": "5f4ef1fd1f9012354a9748be093e277675d10f07", + "type": "github" + }, + "original": { + "owner": "mightyiam", + "repo": "files", + "type": "github" + } + }, "firefox-gnome-theme": { "flake": false, "locked": { @@ -116,40 +188,11 @@ "type": "github" } }, - "flake-compat": { - "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-compat_2": { - "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "flake-parts": { "inputs": { - "nixpkgs-lib": "nixpkgs-lib" + "nixpkgs-lib": [ + "nixpkgs" + ] }, "locked": { "lastModified": 1751413152, @@ -165,157 +208,6 @@ "type": "github" } }, - "flake-parts_2": { - "inputs": { - "nixpkgs-lib": [ - "nur", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1733312601, - "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_3": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib_2" - }, - "locked": { - "lastModified": 1749398372, - "narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-parts_4": { - "inputs": { - "nixpkgs-lib": [ - "stylix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1743550720, - "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "c621e8422220273271f52058f618c94e405bb0f5", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils-plus": { - "inputs": { - "flake-utils": "flake-utils_2" - }, - "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_3" - }, - "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_4" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_4": { - "inputs": { - "systems": "systems_7" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "fromYaml": { "flake": false, "locked": { @@ -335,21 +227,21 @@ "git-hooks": { "inputs": { "flake-compat": [ - "stylix", - "flake-compat" + "dedupe_flake-compat" + ], + "gitignore": [ + "dedupe_gitignore" ], - "gitignore": "gitignore", "nixpkgs": [ - "stylix", "nixpkgs" ] }, "locked": { - "lastModified": 1747372754, - "narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=", + "lastModified": 1750779888, + "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46", + "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", "type": "github" }, "original": { @@ -358,28 +250,6 @@ "type": "github" } }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "stylix", - "git-hooks", - "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" - } - }, "gnome-shell": { "flake": false, "locked": { @@ -398,36 +268,17 @@ } }, "home-manager": { - "inputs": { - "nixpkgs": "nixpkgs_2" - }, - "locked": { - "lastModified": 1751462021, - "narHash": "sha256-RUKSK5JFZ15hsQK8qgthbzP0iTuBlAYfnkH8tjz6SPU=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "6c53df3b9c809e3b4b30d515e18bfa4c6f079254", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "home-manager", - "type": "github" - } - }, - "home-manager_2": { "inputs": { "nixpkgs": [ - "stylix", "nixpkgs" ] }, "locked": { - "lastModified": 1748737919, - "narHash": "sha256-5kvBbLYdp+n7Ftanjcs6Nv+UO6sBhelp6MIGJ9nWmjQ=", + "lastModified": 1751990210, + "narHash": "sha256-krWErNDl9ggMLSfK00Q2BcoSk3+IRTSON/DiDgUzzMw=", "owner": "nix-community", "repo": "home-manager", - "rev": "5675a9686851d9626560052a032c4e14e533c1fa", + "rev": "218da00bfa73f2a61682417efe74549416c16ba6", "type": "github" }, "original": { @@ -466,52 +317,38 @@ "type": "github" } }, - "mnw": { - "locked": { - "lastModified": 1748710831, - "narHash": "sha256-eZu2yH3Y2eA9DD3naKWy/sTxYS5rPK2hO7vj8tvUCSU=", - "owner": "Gerg-L", - "repo": "mnw", - "rev": "cff958a4e050f8d917a6ff3a5624bc4681c6187d", - "type": "github" - }, - "original": { - "owner": "Gerg-L", - "repo": "mnw", - "type": "github" - } - }, - "nil": { + "make-shell": { "inputs": { - "nixpkgs": [ - "nvf", - "nixpkgs" + "flake-compat": [ + "dedupe_flake-compat" ] }, "locked": { - "lastModified": 1750047244, - "narHash": "sha256-vluLARrk4485npdyHOj8XKr0yk6H22pNf+KVRNL+i/Y=", - "owner": "oxalica", - "repo": "nil", - "rev": "870a4b1b5f12004832206703ac15aa85c42c247b", + "lastModified": 1733933815, + "narHash": "sha256-9JjM7eT66W4NJAXpGUsdyAFXhBxFWR2Z9LZwUa7Hli0=", + "owner": "nicknovitski", + "repo": "make-shell", + "rev": "ffeceae9956df03571ea8e96ef77c2924f13a63c", "type": "github" }, "original": { - "owner": "oxalica", - "repo": "nil", + "owner": "nicknovitski", + "repo": "make-shell", "type": "github" } }, "nix-index-database": { "inputs": { - "nixpkgs": "nixpkgs_3" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { - "lastModified": 1751170039, - "narHash": "sha256-3EKpUmyGmHYA/RuhZjINTZPU+OFWko0eDwazUOW64nw=", + "lastModified": 1751774635, + "narHash": "sha256-DuOznGdgMxeSlPpUu6Wkq0ZD5e2Cfv9XRZeZlHWMd1s=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "9c932ae632d6b5150515e5749b198c175d8565db", + "rev": "85686025ba6d18df31cc651a91d5adef63378978", "type": "github" }, "original": { @@ -522,121 +359,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1750836778, - "narHash": "sha256-sRLyRiC7TezRbbjGJwUFOgb2xMbSr3wQ0oJKfYlQ6s0=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "d7bb1922f0bb3d0c990f56f9cdb767fdb20a5f22", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1751159883, - "narHash": "sha256-urW/Ylk9FIfvXfliA1ywh75yszAbiTEVgpPeinFyVZo=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "14a40a1d7fb9afa4739275ac642ed7301a9ba1ab", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "nixpkgs-lib_2": { - "locked": { - "lastModified": 1748740939, - "narHash": "sha256-rQaysilft1aVMwF14xIdGS3sj1yHlI6oKQNBRTF40cc=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "656a64127e9d791a334452c6b6606d17539476e2", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, - "nixpkgs_10": { - "locked": { - "lastModified": 1748460289, - "narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "96ec055edbe5ee227f28cdbc3f1ddf1df5965102", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_11": { - "locked": { - "lastModified": 1750865895, - "narHash": "sha256-p2dWAQcLVzquy9LxYCZPwyUdugw78Qv3ChvnX755qHA=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "61c0f513911459945e2cb8bf333dc849f1b976ff", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1751271578, - "narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1751011381, - "narHash": "sha256-krGXKxvkBhnrSC/kGBmg5MyupUUT5R6IBCLEzx9jhMM=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "30e2e2857ba47844aa71991daa6ed1fc678bcbb7", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1751271578, - "narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=", + "lastModified": 1751792365, + "narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=", "owner": "nixos", "repo": "nixpkgs", - "rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df", + "rev": "1fd8bada0b6117e6c7eb54aad5813023eed37ccb", "type": "github" }, "original": { @@ -646,124 +373,21 @@ "type": "github" } }, - "nixpkgs_5": { - "locked": { - "lastModified": 1751271578, - "narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_6": { - "locked": { - "lastModified": 1750215678, - "narHash": "sha256-Rc/ytpamXRf6z8UA2SGa4aaWxUXRbX2MAWIu2C8M+ok=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "5395fb3ab3f97b9b7abca147249fa2e8ed27b192", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_7": { - "locked": { - "lastModified": 1750506804, - "narHash": "sha256-VLFNc4egNjovYVxDGyBYTrvVCgDYgENp5bVi9fPTDYc=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "4206c4cb56751df534751b058295ea61357bbbaa", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_8": { - "locked": { - "lastModified": 1744868846, - "narHash": "sha256-5RJTdUHDmj12Qsv7XOhuospjAjATNiTMElplWnJE9Hs=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "ebe4301cbd8f81c4f8d3244b3632338bbeb6d49c", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_9": { - "locked": { - "lastModified": 1742889210, - "narHash": "sha256-hw63HnwnqU3ZQfsMclLhMvOezpM7RSB0dMAtD5/sOiw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "698214a32beb4f4c8e3942372c694f40848b360d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nur": { - "inputs": { - "flake-parts": "flake-parts_2", - "nixpkgs": "nixpkgs_5", - "treefmt-nix": "treefmt-nix" - }, - "locked": { - "lastModified": 1751458636, - "narHash": "sha256-hOl//m2j6DZPyoAe87qkZk4kD5dhfHw2odeZAFEBYmA=", - "owner": "nix-community", - "repo": "NUR", - "rev": "14864119daae84bbfdb639e1463b1b61580ce60c", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "NUR", - "type": "github" - } - }, - "nur_2": { "inputs": { "flake-parts": [ - "stylix", "flake-parts" ], "nixpkgs": [ - "stylix", "nixpkgs" - ], - "treefmt-nix": "treefmt-nix_2" + ] }, "locked": { - "lastModified": 1748730660, - "narHash": "sha256-5LKmRYKdPuhm8j5GFe3AfrJL8dd8o57BQ34AGjJl1R0=", + "lastModified": 1752005241, + "narHash": "sha256-+7DH6wh2BYnLRJzYXEbVlA1ZuAR4MxZI/paknbAuzk4=", "owner": "nix-community", "repo": "NUR", - "rev": "2c0bc52fe14681e9ef60e3553888c4f086e46ecb", + "rev": "a2570fb4d0699fd34ebbbd52e2a763722601f6c6", "type": "github" }, "original": { @@ -774,24 +398,32 @@ }, "nvf": { "inputs": { - "flake-parts": "flake-parts_3", - "flake-utils": "flake-utils", - "mnw": "mnw", - "nil": "nil", - "nixpkgs": "nixpkgs_6", - "systems": "systems_2" + "flake-parts": [ + "flake-parts" + ], + "flake-utils": [ + "dedupe_flake-utils" + ], + "mnw": [ + "dedupe_mnw" + ], + "nixpkgs": [ + "nixpkgs" + ], + "systems": [ + "systems" + ] }, "locked": { - "lastModified": 1751187535, - "narHash": "sha256-AMNouwcg9qSG/DI0JXoxZdjtcxfSErVaIsdQn4Q893k=", - "owner": "rrvsh", + "lastModified": 1752001027, + "narHash": "sha256-JgP8lW4QBr9v/U4ETaIOMvGCd/DAA1AjZ1lqjIwfWno=", + "owner": "notashelf", "repo": "nvf", - "rev": "871440fb7e5dc9d4abf59a8577bbbf7bba63bff7", + "rev": "c4d80273aaefeadaad96db97d077c647942b0e96", "type": "github" }, "original": { - "owner": "rrvsh", - "ref": "uv-nvim", + "owner": "notashelf", "repo": "nvf", "type": "github" } @@ -808,11 +440,11 @@ ] }, "locked": { - "lastModified": 1734836319, - "narHash": "sha256-h/Jiq852WJyyAL037sIxjPDScjeH8sUoZVZBWlciXaw=", + "lastModified": 1751898758, + "narHash": "sha256-8EmTPdfOymvvHhmHYWiyO3cwZ4gtLo5uBFm3CU5vySo=", "owner": "Janrupf", "repo": "python-flexseal", - "rev": "fdd313f7b9a5c9545c015acaf0729b01f708118a", + "rev": "af318e1fd047abbefcc68d0292a4d902179c95fe", "type": "github" }, "original": { @@ -823,28 +455,36 @@ }, "root": { "inputs": { + "dedupe_flake-compat": "dedupe_flake-compat", + "dedupe_flake-utils": "dedupe_flake-utils", + "dedupe_gitignore": "dedupe_gitignore", + "dedupe_mnw": "dedupe_mnw", "disko": "disko", + "files": "files", "flake-parts": "flake-parts", + "git-hooks": "git-hooks", "home-manager": "home-manager", "impermanence": "impermanence", "import-tree": "import-tree", + "make-shell": "make-shell", "nix-index-database": "nix-index-database", - "nixpkgs": "nixpkgs_4", + "nixpkgs": "nixpkgs", "nur": "nur", "nvf": "nvf", "rrv-sh": "rrv-sh", "rrvsh-nixpkgs": "rrvsh-nixpkgs", - "snowfall-lib": "snowfall-lib", "sops-nix": "sops-nix", "stable-diffusion-webui-nix": "stable-diffusion-webui-nix", "stylix": "stylix", - "systems": "systems_6", - "zjstatus": "zjstatus" + "systems": "systems", + "text": "text" } }, "rrv-sh": { "inputs": { - "nixpkgs": "nixpkgs_7" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { "lastModified": 1751721838, @@ -876,59 +516,18 @@ "type": "github" } }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "zjstatus", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1750905536, - "narHash": "sha256-Mo7yXM5IvMGNvJPiNkFsVT2UERmnvjsKgnY6UyDdySQ=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "2fa7c0aabd15fa0ccc1dc7e675a4fcf0272ad9a1", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "snowfall-lib": { - "inputs": { - "flake-compat": "flake-compat", - "flake-utils-plus": "flake-utils-plus", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1736130495, - "narHash": "sha256-4i9nAJEZFv7vZMmrE0YG55I3Ggrtfo5/T07JEpEZ/RM=", - "owner": "snowfallorg", - "repo": "lib", - "rev": "02d941739f98a09e81f3d2d9b3ab08918958beac", - "type": "github" - }, - "original": { - "owner": "snowfallorg", - "repo": "lib", - "type": "github" - } - }, "sops-nix": { "inputs": { - "nixpkgs": "nixpkgs_8" + "nixpkgs": [ + "nixpkgs" + ] }, "locked": { - "lastModified": 1750119275, - "narHash": "sha256-Rr7Pooz9zQbhdVxux16h7URa6mA80Pb/G07T4lHvh0M=", + "lastModified": 1751606940, + "narHash": "sha256-KrDPXobG7DFKTOteqdSVeL1bMVitDcy7otpVZWDE6MA=", "owner": "Mic92", "repo": "sops-nix", - "rev": "77c423a03b9b2b79709ea2cb63336312e78b72e2", + "rev": "3633fc4acf03f43b260244d94c71e9e14a2f6e0d", "type": "github" }, "original": { @@ -939,21 +538,24 @@ }, "stable-diffusion-webui-nix": { "inputs": { - "flake-utils": "flake-utils_3", - "nixpkgs": "nixpkgs_9", + "flake-utils": [ + "dedupe_flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], "python-flexseal": "python-flexseal" }, "locked": { - "lastModified": 1751651278, - "narHash": "sha256-RFP58g7aWQE9LW+Av0ljtOuuvwThICBikAx+l+cYL+4=", - "owner": "rrvsh", + "lastModified": 1751899247, + "narHash": "sha256-bh6xwc24Rv0YE4grKXvj+kmXmydns+OrlWn4WLnJSY4=", + "owner": "janrupf", "repo": "stable-diffusion-webui-nix", - "rev": "e7d156aef717cdeb1a98c7fe77cbd76c6e437c05", + "rev": "d5ba5dccd190b0ded17f9c4a23dc7665c6dc2eae", "type": "github" }, "original": { - "owner": "rrvsh", - "ref": "fix/comfy-ui-data-directory", + "owner": "janrupf", "repo": "stable-diffusion-webui-nix", "type": "github" } @@ -965,14 +567,19 @@ "base16-helix": "base16-helix", "base16-vim": "base16-vim", "firefox-gnome-theme": "firefox-gnome-theme", - "flake-compat": "flake-compat_2", - "flake-parts": "flake-parts_4", - "git-hooks": "git-hooks", + "flake-parts": [ + "flake-parts" + ], "gnome-shell": "gnome-shell", - "home-manager": "home-manager_2", - "nixpkgs": "nixpkgs_10", - "nur": "nur_2", - "systems": "systems_5", + "nixpkgs": [ + "nixpkgs" + ], + "nur": [ + "nur" + ], + "systems": [ + "systems" + ], "tinted-foot": "tinted-foot", "tinted-kitty": "tinted-kitty", "tinted-schemes": "tinted-schemes", @@ -980,11 +587,11 @@ "tinted-zed": "tinted-zed" }, "locked": { - "lastModified": 1751405764, - "narHash": "sha256-romzrDMOWMPZioeChZnrugwaUSpROfkWClHhWHuRnRQ=", + "lastModified": 1751995939, + "narHash": "sha256-C5CSTv+b8XSbqJwqTP8SGkZEK3YCCJnmvRbg209ql5w=", "owner": "nix-community", "repo": "stylix", - "rev": "5b257989a8337dddc22aa04a70d3665d0384abef", + "rev": "8f3259dbc57c8ee871492fde80f77468826bbd63", "type": "github" }, "original": { @@ -1008,93 +615,18 @@ "type": "github" } }, - "systems_2": { + "text": { "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "lastModified": 1751819711, + "narHash": "sha256-Emci++Hknzr2FEZRUbRDD7prI5JwwGsACO/GaU9Pmxg=", + "owner": "rrvsh", + "repo": "text.nix", + "rev": "00ba1e616ef3b761a52d5f7ac32892715cc4bcd1", "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", + "owner": "rrvsh", + "repo": "text.nix", "type": "github" } }, @@ -1178,70 +710,6 @@ "repo": "base16-zed", "type": "github" } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "nur", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1733222881, - "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "49717b5af6f80172275d47a418c9719a31a78b53", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "treefmt-nix_2": { - "inputs": { - "nixpkgs": [ - "stylix", - "nur", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1733222881, - "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "49717b5af6f80172275d47a418c9719a31a78b53", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "zjstatus": { - "inputs": { - "crane": "crane", - "flake-utils": "flake-utils_4", - "nixpkgs": "nixpkgs_11", - "rust-overlay": "rust-overlay" - }, - "locked": { - "lastModified": 1750957292, - "narHash": "sha256-2CYTG+jxP5e7GHAj1t5aMsgb0Rom4jdOb3rsdLKpVNA=", - "owner": "dj95", - "repo": "zjstatus", - "rev": "abd848f23eff00d21ec09278072111d97dfd7fe6", - "type": "github" - }, - "original": { - "owner": "dj95", - "repo": "zjstatus", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 6cd5bd1..86b2997 100644 --- a/flake.nix +++ b/flake.nix @@ -1,43 +1,124 @@ { - # TODO: use flake-parts and remove snowfall-lib outputs = inputs: - inputs.snowfall-lib.mkFlake { - inherit inputs; - src = ./.; - snowfall.namespace = "pantheon"; - }; + inputs.flake-parts.lib.mkFlake { inherit inputs; } ( + (inputs.import-tree ./nix) + // { + systems = import inputs.systems; + flake.paths.root = ./.; + } + ); inputs = { - # We use nixos-unstable as everything is cached. + ### SYSTEM ### + + # systems provides a list of supported nix systems. + systems.url = "github:nix-systems/default"; + # nixos-unstable provides a binary cache for all packages. nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; # My fork for random shit rrvsh-nixpkgs.url = "github:rrvsh/nixpkgs/librechat-module"; + # home-manager manages our user packages and dotfiles + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + # the nix user repository for mainly firefox extensions + nur = { + url = "github:nix-community/NUR"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-parts.follows = "flake-parts"; + }; + # impermanence provides a nice abstraction over linking files from /persist + impermanence.url = "github:nix-community/impermanence"; + # flake-parts lets us define flake modules. + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + # disko provides declarative drive partitioning + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + # sops-nix lets us version control secrets like passwords and api keys + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + stylix = { + url = "github:nix-community/stylix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-parts.follows = "flake-parts"; + systems.follows = "systems"; + nur.follows = "nur"; + }; + }; - # import-tree lets us use less imports = [] + ### FLAKE PARTS MODULES ### + + # import-tree imports all nix files in a given directory. import-tree.url = "github:vic/import-tree"; + # files lets us write text files and automatically add checks for them + files.url = "github:mightyiam/files"; + # text.nix lets us easily define markdown text to pass to files + text.url = "github:rrvsh/text.nix"; + # make-shells. creates devShells and checks + make-shell = { + url = "github:nicknovitski/make-shell"; + inputs.flake-compat.follows = "dedupe_flake-compat"; + }; + # git-hooks ensures nix flake check is ran before commits + git-hooks = { + url = "github:cachix/git-hooks.nix"; + inputs = { + flake-compat.follows = "dedupe_flake-compat"; + nixpkgs.follows = "nixpkgs"; + gitignore.follows = "dedupe_gitignore"; + }; + }; - # The following are used for less boilerplate. - flake-parts.url = "github:hercules-ci/flake-parts"; - #TODO: remove snowfall - snowfall-lib = { - url = "github:snowfallorg/lib"; + ### FLAKES ### + + # nix-index-database indexes the nixpkgs binaries for use with comma + nix-index-database = { + url = "github:nix-community/nix-index-database"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + # nvf provides modules to wrap neovim + nvf = { + url = "github:notashelf/nvf"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-parts.follows = "flake-parts"; + systems.follows = "systems"; + flake-utils.follows = "dedupe_flake-utils"; + mnw.follows = "dedupe_mnw"; + }; + }; + # provides comfy ui and sdwebui services + stable-diffusion-webui-nix = { + url = "github:janrupf/stable-diffusion-webui-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-utils.follows = "dedupe_flake-utils"; + }; + # my website :) + rrv-sh = { + url = "github:rrvsh/rrv.sh"; inputs.nixpkgs.follows = "nixpkgs"; }; - # Various nix things - nur.url = "github:nix-community/NUR"; - sops-nix.url = "github:Mic92/sops-nix"; - disko.url = "github:nix-community/disko"; - home-manager.url = "github:nix-community/home-manager"; - impermanence.url = "github:nix-community/impermanence"; - nix-index-database.url = "github:nix-community/nix-index-database"; - stylix.url = "github:nix-community/stylix"; - systems.url = "github:nix-systems/default"; + ### DEDUPE ### - # Packages and services that we don't use nixpkgs for. - rrv-sh.url = "github:rrvsh/rrv.sh"; - nvf.url = "github:rrvsh/nvf/uv-nvim"; - stable-diffusion-webui-nix.url = "github:rrvsh/stable-diffusion-webui-nix/fix/comfy-ui-data-directory"; - zjstatus.url = "github:dj95/zjstatus"; + dedupe_flake-compat.url = "github:edolstra/flake-compat"; + dedupe_flake-utils = { + url = "github:numtide/flake-utils"; + inputs.systems.follows = "systems"; + }; + dedupe_mnw.url = "github:gerg-l/mnw"; + dedupe_gitignore = { + url = "github:hercules-ci/gitignore.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; } diff --git a/homes/x86_64-linux/rafiq/cli/default.nix b/homes/x86_64-linux/rafiq/cli/default.nix deleted file mode 100644 index 87182ea..0000000 --- a/homes/x86_64-linux/rafiq/cli/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ pkgs, inputs, ... }: -{ - imports = [ inputs.nix-index-database.hmModules.nix-index ]; - programs = { - tealdeer.enable = true; - tealdeer.enableAutoUpdates = true; - direnv = { - enable = true; - nix-direnv.enable = true; - }; - zoxide.enable = true; - nix-index.enable = true; - nix-index-database.comma.enable = true; - }; - persistDirs = [ ".local/share/zoxide" ]; - home = { - shellAliases = { - windows = "sudo systemctl reboot --boot-loader-entry=auto-windows"; - v = "$EDITOR"; - e = "edit"; - cd = "z"; # zoxide - ai = "aichat -r %shell% -e"; - }; - packages = with pkgs; [ - ripgrep - aichat - pantheon.rebuild - pantheon.deploy - pantheon.edit - pantheon.commit - ]; - }; - xdg.configFile."aichat/config.yaml".text = '' - model: gemini:gemini-2.0-flash - clients: - - type: gemini - ''; -} diff --git a/homes/x86_64-linux/rafiq/cli/editor/default.nix b/homes/x86_64-linux/rafiq/cli/editor/default.nix deleted file mode 100644 index 6364db8..0000000 --- a/homes/x86_64-linux/rafiq/cli/editor/default.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ - pkgs, - lib, - inputs, - ... -}: -{ - imports = [ inputs.nvf.homeManagerModules.default ]; - home.sessionVariables.EDITOR = "nvim"; - programs.nvf.enable = true; - programs.nvf.settings.vim = { - syntaxHighlighting = true; - hideSearchHighlight = true; - searchCase = "ignore"; - undoFile.enable = true; - telescope.enable = true; - fzf-lua.enable = true; - git.enable = true; - autopairs.nvim-autopairs.enable = true; - autocomplete = import ./_nvf/autocomplete.nix { inherit lib; }; - binds = import ./_nvf/binds.nix; - languages = import ./_nvf/languages.nix; - lsp = import ./_nvf/lsp.nix; - navigation = import ./_nvf/navigation.nix; - notes.todo-comments.enable = true; - options = { - autoindent = true; - backspace = "indent,eol,start"; - cursorline = true; - expandtab = true; - shiftwidth = 2; - smartindent = true; - tabstop = 2; - }; - snippets = import ./_nvf/snippets.nix { inherit pkgs; }; - statusline = import ./_nvf/statusline.nix; - treesitter = { - autotagHtml = true; - fold = true; - indent.disable = [ "markdown" ]; - textobjects.enable = true; - }; - ui = import ./_nvf/ui.nix; - utility = import ./_nvf/utility.nix; - visuals = import ./_nvf/visuals.nix; - }; -} diff --git a/homes/x86_64-linux/rafiq/cli/fetch.nix b/homes/x86_64-linux/rafiq/cli/fetch.nix deleted file mode 100644 index d45f3f0..0000000 --- a/homes/x86_64-linux/rafiq/cli/fetch.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ pkgs, ... }: -{ - home = { - packages = [ pkgs.fastfetch ]; - sessionVariables.FETCH = "hyfetch"; - shellAliases.fetch = "hyfetch"; - }; - programs.hyfetch = { - enable = true; - settings = { - preset = "bisexual"; - mode = "rgb"; - light_dark = "dark"; - lightness = 0.5; - color_align = { - # Flag color alignment - mode = "horizontal"; - fore_back = null; - }; - backend = "fastfetch"; - }; - }; -} diff --git a/homes/x86_64-linux/rafiq/cli/file-browser.nix b/homes/x86_64-linux/rafiq/cli/file-browser.nix deleted file mode 100644 index 5a7d23b..0000000 --- a/homes/x86_64-linux/rafiq/cli/file-browser.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ - home.sessionVariables.FILE_BROWSER = "yazi"; - programs.yazi = { - enable = true; - shellWrapperName = "t"; - settings.mgr.sort_by = "natural"; - }; -} diff --git a/homes/x86_64-linux/rafiq/cli/finder.nix b/homes/x86_64-linux/rafiq/cli/finder.nix deleted file mode 100644 index ceb3f8d..0000000 --- a/homes/x86_64-linux/rafiq/cli/finder.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - programs.fzf.enable = true; - #TODO: fish - programs.fzf.enableZshIntegration = true; -} diff --git a/homes/x86_64-linux/rafiq/cli/multiplexer.nix b/homes/x86_64-linux/rafiq/cli/multiplexer.nix deleted file mode 100644 index e972e50..0000000 --- a/homes/x86_64-linux/rafiq/cli/multiplexer.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ - osConfig, - inputs, - pkgs, - ... -}: -let - zjstatus = inputs.zjstatus.packages.${pkgs.stdenv.hostPlatform.system}.default; -in -{ - home.sessionVariables.MULTIPLEXER = "zellij"; - # Persists sessions - persistDirs = [ "/.cache/zellij" ]; - programs.zellij = { - enable = true; - #TODO: fish - enableZshIntegration = true; - settings = { - pane_frames = false; - show_startup_tips = false; - show_release_notes = false; - }; - }; - xdg.configFile."zellij/layouts/default.kdl".text = # kdl - '' - layout { - default_tab_template { - pane size=1 borderless=true { - plugin location="file:${zjstatus}/bin/zjstatus.wasm" { - format_left "{mode} ${osConfig.hostname}" - format_center "{tabs}" - format_right "{datetime}" - format_space "" - format_hide_on_overlength "true" - format_precedence "lrc" - - border_enabled "false" - hide_frame_for_single_pane "false" - - mode_default_to_mode "normal" - mode_normal "#[bg=#89B4FA] {name} " - mode_locked "#[bg=#f55e18] {name} " - mode_session "#[bg=#00ff00] {name} " - - tab_normal "#[fg=#6C7086] {index} " - tab_active "#[fg=#9399B2,bold,italic] {index} " - tab_display_count "3" // limit to showing 3 tabs - tab_truncate_start_format "..." - tab_truncate_end_format "..." - - //TODO: disable if we are not on ssh - datetime "#[fg=#6C7086,bold] {format}" - datetime_format "%H:%M:%S" - datetime_timezone "Asia/Singapore" - } - } - children - } - } - ''; -} diff --git a/homes/x86_64-linux/rafiq/cli/shell.nix b/homes/x86_64-linux/rafiq/cli/shell.nix deleted file mode 100644 index d7b238a..0000000 --- a/homes/x86_64-linux/rafiq/cli/shell.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ lib, pkgs, ... }: -let - inherit (builtins) toString; - inherit (lib) getExe mkOrder; - inherit (lib.strings) concatStrings; - screensaverTimeout = toString 100; - screensaverCommand = "${getExe pkgs.cbonsai} -S -w 0.1 -L 40 -M 2 -b 2"; -in -{ - home.shell.enableShellIntegration = true; - home.sessionVariables.SHELL = "fish"; - programs.fish.enable = true; - programs.starship = { - enable = true; - settings = { - add_newline = false; - format = concatStrings [ - # First Line - ## Left Prompt - "$hostname$directory" - "$fill" - ## Right Prompt - "$all" - # Second Line - ## Left Prompt - "$character" - ]; - git_branch.format = "[$symbol$branch(:$remote_branch)]($style) "; - shlvl.disabled = false; - username.disabled = true; - fill.symbol = " "; - }; - }; - # figure out for fish - programs.zsh.initContent = - mkOrder 1200 - # zsh - '' - precmd() { - TMOUT=${screensaverTimeout} - } - - TRAPALRM() { - TMOUT=1 - ${screensaverCommand} - # If we exit, assume the previous command was exited out of - TMOUT=${screensaverTimeout} - zle reset-prompt - } - ''; -} diff --git a/homes/x86_64-linux/rafiq/cli/utilities/git.nix b/homes/x86_64-linux/rafiq/cli/utilities/git.nix deleted file mode 100644 index 4794310..0000000 --- a/homes/x86_64-linux/rafiq/cli/utilities/git.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ - home.sessionVariables.GIT_CONFIG_GLOBAL = "$HOME/.config/git/config"; - home.shellAliases = { - gs = "git status"; - gc = "git commit"; - gcam = "git commit -am"; - gu = "git push"; - gy = "git pull"; - gdh = "git diff HEAD"; - }; - programs.git = { - enable = true; - userName = "Mohammad Rafiq"; - userEmail = "rafiq@rrv.sh"; - signing.key = "~/.ssh/id_ed25519.pub"; - signing.signByDefault = true; - extraConfig = { - init.defaultBranch = "prime"; - push.autoSetupRemote = true; - pull.rebase = false; - core.editor = "$EDITOR"; - gpg.format = "ssh"; - }; - }; -} diff --git a/homes/x86_64-linux/rafiq/cli/utilities/zk.nix b/homes/x86_64-linux/rafiq/cli/utilities/zk.nix deleted file mode 100644 index 7ea3050..0000000 --- a/homes/x86_64-linux/rafiq/cli/utilities/zk.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ pkgs, ... }: -{ - persistDirs = [ "notebook" ]; - programs.zk = { - enable = true; - settings.notebook.dir = "~/notebook"; - }; - home.packages = [ - (pkgs.writeShellScriptBin "note" # bash - '' - zk edit -i - pushd ~/notebook > /dev/null - git add . - commit -u - popd > /dev/null - '' - ) - ]; -} diff --git a/homes/x86_64-linux/rafiq/default.nix b/homes/x86_64-linux/rafiq/default.nix deleted file mode 100644 index 192d67f..0000000 --- a/homes/x86_64-linux/rafiq/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ - inputs, - osConfig, - lib, - ... -}: -let - inherit (lib) singleton optional; - inherit (inputs) import-tree; -in -{ - imports = - (optional osConfig.desktop.enable (import-tree ./desktop)) - ++ singleton (import-tree ./cli); -} diff --git a/homes/x86_64-linux/rafiq/desktop/browser.nix b/homes/x86_64-linux/rafiq/desktop/browser.nix deleted file mode 100644 index 4fd287d..0000000 --- a/homes/x86_64-linux/rafiq/desktop/browser.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - lib, - inputs, - pkgs, - ... -}: -let - inherit (builtins) map listToAttrs; - inherit (lib.lists) findFirstIndex; - inherit (inputs.nur.legacyPackages.${pkgs.stdenv.hostPlatform.system}.repos.rycee) firefox-addons; - profiles = listToAttrs ( - map (name: { - inherit name; - # If there are duplicate profile names, findFirstIndex will cause issues. - value = profileCfg (findFirstIndex (x: x == name) null syncedProfiles); - }) syncedProfiles - ); - syncedProfiles = [ - "rafiq" - "test" - ]; - profileCfg = id: { - inherit id; - settings."extensions.autoDisableScopes" = 0; # Auto enable extensions - #TODO: add default seach unduck and add rest of extensions - extensions = { - force = true; - packages = with firefox-addons; [ - darkreader - gesturefy - sponsorblock - ublock-origin - ]; - }; - }; -in -{ - home.sessionVariables.BROWSER = "firefox"; - persistDirs = [ ".mozilla/firefox" ]; - programs.firefox = { - enable = true; - inherit profiles; - }; - stylix.targets.firefox.colorTheme.enable = true; - stylix.targets.firefox.profileNames = syncedProfiles; -} diff --git a/homes/x86_64-linux/rafiq/desktop/default.nix b/homes/x86_64-linux/rafiq/desktop/default.nix deleted file mode 100644 index d769793..0000000 --- a/homes/x86_64-linux/rafiq/desktop/default.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ pkgs, ... }: -{ - persistDirs = [ - "docs" - "repos" - "vids" - "tmp" - ".cache/Smart Code ltd/Stremio" - ".local/share/Smart Code ltd/Stremio" - ]; - programs = { - obs-studio.enable = true; - vesktop.enable = true; - thunderbird.enable = true; - thunderbird.profiles.rafiq.isDefault = true; - }; - home.packages = with pkgs; [ stremio ]; - stylix.image = ./wallpaper.png; -} diff --git a/homes/x86_64-linux/rafiq/desktop/launcher.nix b/homes/x86_64-linux/rafiq/desktop/launcher.nix deleted file mode 100644 index 5090898..0000000 --- a/homes/x86_64-linux/rafiq/desktop/launcher.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ - home.sessionVariables.LAUNCHER = "fuzzel"; -} diff --git a/homes/x86_64-linux/rafiq/desktop/lockscreen.nix b/homes/x86_64-linux/rafiq/desktop/lockscreen.nix deleted file mode 100644 index 91f243b..0000000 --- a/homes/x86_64-linux/rafiq/desktop/lockscreen.nix +++ /dev/null @@ -1,29 +0,0 @@ -let - styling = { - halign = "center"; - valign = "center"; - zindex = 1; - shadow_passes = 5; - shadow_size = 5; - }; -in -{ - home.sessionVariables.LOCKSCREEN = "hyprlock"; - programs.hyprlock.settings = { - general.hide_cursor = true; - general.ignore_empty_input = true; - background.blur_passes = 5; - background.blur_size = 5; - label = { - text = ''hi, $USER.''; - font_size = 32; - position = "0, 0"; - }// styling; - input-field = { - placeholder_text = ""; - fade_on_empty = true; - size = "200, 45"; - position = "0, -5%"; - } // styling; - }; -} diff --git a/homes/x86_64-linux/rafiq/desktop/media-player.nix b/homes/x86_64-linux/rafiq/desktop/media-player.nix deleted file mode 100644 index 482363e..0000000 --- a/homes/x86_64-linux/rafiq/desktop/media-player.nix +++ /dev/null @@ -1,200 +0,0 @@ -{ - xdg.configFile."vlc/vlcrc".text = '' - [visual] # Visualizer filter - [glspectrum] # 3D OpenGL spectrum visualization - [wall] # Wall video filter - [panoramix] # Panoramix: wall with overlap video filter - [clone] # Clone video filter - [yuv] # YUV video output - [xdg_shell] # XDG shell surface - [xcb_xv] # XVideo output (XCB) - [xcb_x11] # X11 video output (XCB) - [xcb_window] # X11 video window (XCB) - [wl_shell] # Wayland shell surface - [vmem] # Video memory output - [vdummy] # Dummy video output - [gl] # OpenGL video output - [flaschen] # Flaschen-Taschen video output - [fb] # GNU/Linux framebuffer video output - [transform] # Video transformation filter - [sharpen] # Sharpen video filter - [sepia] # Sepia video filter - [scene] # Scene video filter - [rotate] # Rotate video filter - [puzzle] # Puzzle interactive game video filter - [postproc] # Video post processing filter - [posterize] # Posterize video filter - [motionblur] # Motion blur filter - [mirror] # Mirror video filter - [hqdn3d] # High Quality 3D Denoiser filter - [grain] # Grain video filter - [gradient] # Gradient video filter - [gradfun] # Gradfun video filter - [gaussianblur] # Gaussian blur video filter - [fps] # FPS conversion video filter - [extract] # Extract RGB component video filter - [erase] # Erase video filter - [deinterlace] # Deinterlacing video filter - [croppadd] # Video cropping filter - [colorthres] # Color threshold filter - [canvas] # Canvas video filter - [bluescreen] # Bluescreen video filter - [blendbench] # Blending benchmark filter - [ball] # Ball video filter - [antiflicker] # antiflicker video filter - [anaglyph] # Convert 3D picture to anaglyph image video filter - [alphamask] # Alpha mask video filter - [adjust] # Image properties filter - [swscale] # Video scaling filter - [vaapi_filters] # Video Accelerated API filters - [svg] # svg - [freetype] # Freetype2 font renderer - [stream_out_transcode] # Transcode stream output - [stats] # Writes statistic info about stream - [stream_out_standard] # Standard stream output - [smem] # Stream output to memory buffer - [setid] # Change the id of an elementary stream - [stream_out_rtp] # RTP stream output - [record] # Record stream output - [mosaic_bridge] # Mosaic bridge stream output - [es] # Elementary stream output - [display] # Display stream output - [delay] # Delay a stream - [stream_out_chromecast] # Chromecast stream output - [bridge] # Bridge stream output - [prefetch] # Stream prefetch filter - [subsdelay] # Subtitle delay - [rss] # RSS and Atom feed display - [remoteosd] # Remote-OSD over VNC - [mosaic] # Mosaic video sub source - [marq] # Marquee display - [logo] # Logo sub source - [dynamicoverlay] # Dynamic video overlay - [audiobargraph_v] # Audio Bar Graph Video sub source - [upnp] # Universal Plug'n'Play - [sap] # Network streams (SAP) - [podcast] # Podcasts - [mpegvideo] # MPEG-I/II video packetizer - [mux_ts] # TS muxer (libdvbpsi) - [ps] # PS muxer - [mux_ogg] # Ogg/OGM muxer - [mp4] # MP4/MOV muxer - [avi] # AVI muxer - [asf] # ASF muxer - [rtsp] # Legacy RTSP VoD server - [logger] # File logging - [gnutls] # GNU TLS transport layer security - [audioscrobbler] # Submission of played songs to last.fm - [folder] # Folder meta data - [lua] # Lua interpreter - [syslog] # System logger (syslog) - [file] # File logger - [console] # Console logger - [file] # Secrets are stored on a file without any encryption - [skins2] # Skinnable Interface - [qt] # Qt interface - qt-privacy-ask=0 - [ncurses] # Ncurses interface - [vc1] # VC1 video demuxer - [ts] # MPEG Transport Stream demuxer - [subtitle] # Text subtitle parser - [rawvid] # Raw video demuxer - [rawdv] # DV (Digital Video) demuxer - [rawaud] # Raw audio demuxer - [ps] # MPEG-PS demuxer - [playlist] # Playlist - [mp4] # MP4 stream demuxer - [mod] # MOD demuxer (libmodplug) - [mkv] # Matroska stream demuxer - [mjpeg] # M-JPEG camera demuxer - [image] # Image demuxer - [h26x] # H264 video demuxer - [es] # MPEG-I/II/4 / A52 / DTS / MLP audio - [diracsys] # Dirac video demuxer - [demuxdump] # File dumper - [avi] # AVI demuxer - [avformat] # Avformat demuxer - [adaptive] # Unified adaptive streaming for DASH/HLS - [oldrc] # Remote control interface - [netsync] # Network synchronization - [motion] # motion control interface - [gestures] # Mouse gestures control interface - [vorbis] # Vorbis audio decoder - [ttml] # TTML subtitles decoder - [theora] # Theora video decoder - [telx] # Teletext subtitles decoder - [svgdec] # SVG video decoder - [svcdsub] # Philips OGT (SVCD subtitle) decoder - [subsusf] # USF subtitles decoder - [subsdec] # Text subtitle decoder - [spudec] # DVD subtitles decoder - [speex] # Speex audio decoder - [schroedinger] # Dirac video decoder using libschroedinger - [libass] # Subtitle renderers using libass - [kate] # Kate overlay decoder - [jpeg] # JPEG image decoder - [fluidsynth] # FluidSynth MIDI synthesizer - [dvbsub] # DVB subtitles decoder - [ddummy] # Dummy decoder - [cc] # Closed Captions decoder - [avcodec] # FFmpeg audio/video decoder - [a52] # ATSC A/52 (AC-3) audio decoder - [amem] # Audio memory output - [alsa] # ALSA audio output - [afile] # File audio output - [stereo_widen] # Simple stereo widening effect - [speex_resampler] # Speex resampler - [spatializer] # Audio Spatializer - [spatialaudio] # Ambisonics renderer and binauralizer - [scaletempo] # Audio tempo scaler synched with rate - [scaletempo_pitch] # Pitch Shifter - [samplerate] # Secret Rabbit Code (libsamplerate) resampler - [remap] # Audio channel remapper - [param_eq] # Parametric Equalizer - [normvol] # Volume normalizer - [mono] # Stereo to mono downmixer - [headphone] # Headphone virtual spatialization effect - [gain] # Gain control filter - [equalizer] # Equalizer with 10 bands - [compressor] # Dynamic range compressor - [chorus_flanger] # Sound Delay - [audiobargraph_a] # Audio part of the BarGraph function - [udp] # UDP stream output - [access_output_srt] # SRT stream output - [access_output_rist] # RIST stream output - [access_output_livehttp] # HTTP Live streaming output - [http] # HTTP stream output - [file] # File stream output - [xcb_screen] # Screen capture (with X11/XCB) - [vdr] # VDR recordings - [v4l2] # Video4Linux input - [udp] # UDP input - [timecode] # Time code subpicture elementary stream generator - [smb] # SMB input - [shm] # Shared memory framebuffer - [sftp] # SFTP input - [satip] # SAT>IP Receiver Plugin - [rtp] # Real-Time Protocol (RTP) input - [rist] # RIST input - [live555] # RTP/RTSP/SDP demuxer (using Live555) - [linsys_hdsdi] # HD-SDI Input - [libbluray] # Blu-ray Disc support (libbluray) - [access] # HTTPS input - [http] # HTTP input - [ftp] # FTP input - [filesystem] # File input - [dvdread] # DVDRead Input (no menu support) - [dvdnav] # DVDnav Input - [dvb] # DVB input with v4l2 support - [dtv] # Digital Television and Radio - [cdda] # Audio CD input - [avio] # libavformat AVIO access - [access_srt] # SRT input - [access_mms] # Microsoft Media Server (MMS) input - [imem] # Memory input - [concat] # Concatenated inputs - [access_alsa] # ALSA audio capture - [core] # core program - metadata-network-access=1 - ''; -} diff --git a/homes/x86_64-linux/rafiq/desktop/notification-daemon.nix b/homes/x86_64-linux/rafiq/desktop/notification-daemon.nix deleted file mode 100644 index 8f80fa6..0000000 --- a/homes/x86_64-linux/rafiq/desktop/notification-daemon.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - home.sessionVariables.NOTIFICATION_DAEMON = "mako"; - services.mako.enable = true; - services.mako.settings.default-timeout = 10000; -} diff --git a/homes/x86_64-linux/rafiq/desktop/status-bar.nix b/homes/x86_64-linux/rafiq/desktop/status-bar.nix deleted file mode 100644 index cd0d5ae..0000000 --- a/homes/x86_64-linux/rafiq/desktop/status-bar.nix +++ /dev/null @@ -1,53 +0,0 @@ -{ pkgs, ... }: -{ - home.sessionVariables.STATUS_BAR = "waybar"; - stylix.targets.waybar.addCss = false; - programs.waybar = { - enable = true; - settings = [ - { - #TODO: review the rest of the modules to see what else can be added - layer = "top"; - modules-left = [ - "pulseaudio" - ]; - modules-right = [ - "battery" - "clock" - ]; - "pulseaudio" = { - format = "{icon} {volume}%"; - format-muted = ""; - format-icons.default = [ - "" - "" - ]; - on-click = "${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle"; - }; - "clock" = { - interval = 1; - format = "{:%F %T}"; - }; - "battery" = { - interval = 1; - bat-compatibility = true; - }; - } - ]; - style = # css - '' - window#waybar { - background-color: rgba(0, 0, 0, 0); - } - - #pulseaudio, - #battery, - #clock { - padding-top: 5px; - padding-bottom: 5px; - padding-right: 5px; - color: #ffffff; - } - ''; - }; -} diff --git a/homes/x86_64-linux/rafiq/desktop/terminal.nix b/homes/x86_64-linux/rafiq/desktop/terminal.nix deleted file mode 100644 index 8d0b3a1..0000000 --- a/homes/x86_64-linux/rafiq/desktop/terminal.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ - home.sessionVariables.TERMINAL = "ghostty"; - programs.ghostty = { - enable = true; - settings = { - confirm-close-surface = false; - }; - }; -} diff --git a/homes/x86_64-linux/rafiq/desktop/window-manager/default.nix b/homes/x86_64-linux/rafiq/desktop/window-manager/default.nix deleted file mode 100644 index 56df97a..0000000 --- a/homes/x86_64-linux/rafiq/desktop/window-manager/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ lib, pkgs, ... }: -let - inherit (lib) mkMerge; -in -{ - wayland.windowManager.hyprland.settings = mkMerge [ - (import ./_hyprland/decoration.nix) - (import ./_hyprland/keybinds.nix { inherit pkgs; }) - { - ecosystem.no_update_news = true; - xwayland.force_zero_scaling = true; - monitor = [ ", preferred, auto, 1" ]; - exec-once = [ - "uwsm app -- $LOCKSCREEN" - "uwsm app -- $NOTIFICATION_DAEMON" - "uwsm app -- $STATUS_BAR" - ]; - } - ]; - # TODO: add gamescope here or in nixos desktop module -} diff --git a/hostSpec.nix b/hostSpec.nix deleted file mode 100644 index e07bcda..0000000 --- a/hostSpec.nix +++ /dev/null @@ -1,78 +0,0 @@ -{ - users.rafiq = { - primary = true; - email = "rafiq@rrv.sh"; - alternate-emails = [ - "mohammadrafiq@rrv.sh" - "mohammadrafiq567@gmail.com" - ]; - pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILdsZyY3gu8IGB8MzMnLdh+ClDxQQ2RYG9rkeetIKq8n"; - }; - - entrypoints = { - # For services that should only have one instance across the whole - # flake, define them here and they will get provisioned on those - # hosts, with whatever depends on them configured via that hostname. - nginx.host = "apollo"; - ssh.host = "apollo"; - }; - - # This will define all the hosts exposed by the flake and designate the - # modules and services, along with defining the hardware configuration - # for each host. - # of each attr set will resolve to the host's hostname. - hosts.nemesis = { - platform = "amd"; - gpu = "nvidia"; - ephemeralRoot = true; - boot-drive = "/dev/disk/by-id/nvme-CT2000P3SSD8_2325E6E77434"; - bootloader = "systemd-boot"; - # Enables dotfiles and desktop environment/services. - desktop.enable = true; - extraCfg = { }; - }; - hosts.apollo = { - platform = "intel"; - ephemeralRoot = true; - bootloader = "systemd-boot"; - boot-drive = "/dev/disk/by-id/nvme-eui.002538d221b47b01"; - # Public services will be exposed to the web server. - public-services = [ - { - name = "librechat"; - domain = "chat.bwfiq.com"; - } - { - name = "forgejo"; - domain = "git.rrv.sh"; - } - { - name = "rrv-sh"; - domain = "rrv.sh"; - } - { - name = "immich"; - domain = "photos.bwfiq.com"; - } - { - name = "aenyrathia-wiki"; - domain = "aenyrathia.wiki"; - } - ]; - # Internal services will be exposed with tailscale only. - internal-services = [ - "mongodb" - "mariadb" - "postgresql" - "redis" - ]; - extraCfg = { }; - }; - host.helios = { - platform = "intel"; - boot-drive = "nvme-eui.6479a784aad00284"; - ephemeralRoot = true; - bootloader = "systemd-boot"; - extraCfg = { }; - }; -} diff --git a/lib/default.nix b/lib/default.nix deleted file mode 100644 index 4b42d00..0000000 --- a/lib/default.nix +++ /dev/null @@ -1,57 +0,0 @@ -{ lib, ... }: -let - inherit (lib) mkOption singleton; - inherit (lib.types) - int - str - port - path - attrs - ; - inherit (lib.strings) splitString; - inherit (builtins) length concatStringsSep tail; -in -rec { - # Helpers - splitDomain = domain: splitString "." domain; - shortenList = - count: list: - let - len = length list; - in - if len <= count then list else (shortenList count (tail list)); - - # Modules - mkAttrOption = mkOption { - type = attrs; - default = { }; - }; - mkIntOption = - default: - mkOption { - type = int; - inherit default; - }; - mkStrOption = mkOption { - type = str; - default = ""; - }; - mkPortOption = - default: - mkOption { - type = port; - inherit default; - }; - mkPathOption = - default: - mkOption { - type = path; - inherit default; - }; - - # Domains - isRootDomain = domain: length (splitDomain domain) <= 2; - mkRootDomain = domain: concatStringsSep "." (shortenList 2 (splitDomain domain)); - mkWildcardDomain = rootDomain: concatStringsSep "." ((singleton "*") ++ (splitDomain rootDomain)); - mkHost = domain: if isRootDomain domain then domain else mkWildcardDomain (mkRootDomain domain); -} diff --git a/lib/modules/default.nix b/lib/modules/default.nix deleted file mode 100644 index e8c5402..0000000 --- a/lib/modules/default.nix +++ /dev/null @@ -1,66 +0,0 @@ -{ lib, ... }: -let - inherit (builtins) toString; - inherit (lib) - mkMerge - mkEnableOption - singleton - mkIf - ; - inherit (lib.pantheon) - mkAttrOption - mkRootDomain - mkPortOption - mkStrOption - ; - networkingConfig = - { - config, - cfg, - name, - }: - mkIf (cfg.domain != "") { - assertions = singleton { - assertion = config.server.web-servers.nginx.enable; - message = "You must enable a web server if you want to set server.web-apps.${name}.domain."; - }; - server.networking.ddns.domains = singleton (mkRootDomain cfg.domain); - server.web-servers.nginx.proxies = singleton { - source = cfg.domain; - target = "http://${config.hostname}:${toString cfg.port}"; - }; - }; -in -{ - modules.mkWebApp = - { - config, - name, - defaultPort, - persistDirs ? [ ], - #TODO: specify required secrets - extraOptions ? { }, - extraConfig ? { }, - }: - let - cfg = config.server.web-apps.${name}; - in - { - options.server.web-apps.${name} = { - enable = mkEnableOption ""; - port = mkPortOption defaultPort; - domain = mkStrOption; - openFirewall = mkEnableOption ""; - extraCfg = mkAttrOption; - } // extraOptions; - - config = mkIf cfg.enable (mkMerge [ - { - inherit persistDirs; - networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = singleton cfg.port; }; - } - (networkingConfig { inherit config cfg name; }) - extraConfig - ]); - }; -} diff --git a/modules/home/default.nix b/modules/home/default.nix deleted file mode 100644 index f31453d..0000000 --- a/modules/home/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - config, - lib, - inputs, - ... -}: -let - inherit (lib) mkOption; - inherit (lib.types) listOf str; -in -{ - imports = [ inputs.impermanence.homeManagerModules.impermanence ]; - options.persistDirs = mkOption { - type = listOf str; - default = [ ]; - }; - config = { - # Helper options - home.persistence."/persist/home/${config.home.username}" = { - directories = config.persistDirs; - allowOther = true; - }; - - # Global options - persistDirs = [ - # For system activation - ".ssh" - ".config/sops/age" - ]; - programs.ssh.enable = true; - # To set colors properly when on ssh - programs.ssh.extraConfig = '' - Host * - SetEnv TERM=xterm-256color - ''; - home.stateVersion = "24.11"; - }; -} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix deleted file mode 100644 index 3498a97..0000000 --- a/modules/nixos/default.nix +++ /dev/null @@ -1,112 +0,0 @@ -{ - inputs, - lib, - config, - ... -}: -let - inherit (lib) mkOption singleton; - inherit (lib.types) - listOf - str - coercedTo - submodule - shellPackage - ; - inherit (lib.pantheon) mkStrOption; - inherit (lib.snowfall.fs) get-file; - rootDir = submodule { - options = { - directory = mkOption { type = str; }; - user = mkOption { - type = str; - default = "root"; - }; - group = mkOption { - type = str; - default = "root"; - }; - mode = mkOption { - type = str; - default = "0755"; - }; - }; - }; -in -{ - imports = [ - inputs.sops-nix.nixosModules.sops - inputs.stylix.nixosModules.stylix - ]; - options = { - hostname = mkStrOption; - mainUser = { - name = mkStrOption; - publicKey = mkStrOption; - email = mkStrOption; - shell = mkOption { - type = shellPackage; - }; - }; - persistDirs = mkOption { - type = listOf (coercedTo str (d: { directory = d; }) rootDir); - default = [ ]; - }; - }; - config = { - # Helper options - environment.persistence."/persist".directories = config.persistDirs; - - # Global options - persistDirs = [ - "/var/lib/systemd" - "/var/lib/nixos" - ]; - stylix.enable = true; - nixpkgs.config.allowUnfree = true; - nix.settings.experimental-features = [ - "nix-command" - "flakes" - "pipe-operators" - ]; - nix.settings.trusted-users = [ "@wheel" ]; - system.stateVersion = "25.05"; - time.timeZone = "Asia/Singapore"; - i18n.defaultLocale = "en_US.UTF-8"; - users = { - # Don't allow imperative configuration - mutableUsers = false; - users.root.openssh.authorizedKeys.keys = [ config.mainUser.publicKey ]; - groups.users = { - gid = 100; - members = [ "${config.mainUser.name}" ]; - }; - users."${config.mainUser.name}" = { - inherit (config.mainUser) shell; - uid = 1000; - isNormalUser = true; - hashedPasswordFile = config.sops.secrets."${config.mainUser.name}/hashedPassword".path; - extraGroups = [ "wheel" ]; - openssh.authorizedKeys.keys = [ config.mainUser.publicKey ]; - }; - }; - security.sudo.wheelNeedsPassword = false; - sops = { - defaultSopsFile = get-file "secrets/secrets.yaml"; - age.sshKeyPaths = [ "/persist/home/${config.mainUser.name}/.ssh/id_ed25519" ]; - secrets = { - "keys/openrouter" = { }; - "keys/gemini" = { }; - "keys/cloudflare" = { }; - "keys/telegram_bot" = { }; - "rafiq/hashedPassword".neededForUsers = true; - "rafiq/personalEmailPassword" = { }; - "rafiq/workEmailPassword" = { }; - }; - }; - environment.shellInit = # sh - '' - export GEMINI_API_KEY=$(sudo cat ${config.sops.secrets."keys/gemini".path}) - ''; - }; -} diff --git a/modules/nixos/desktop/audio/default.nix b/modules/nixos/desktop/audio/default.nix deleted file mode 100644 index 7619ad7..0000000 --- a/modules/nixos/desktop/audio/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ - services.pipewire = { - enable = true; - pulse.enable = true; - }; -} diff --git a/modules/nixos/desktop/browser/tor-browser/default.nix b/modules/nixos/desktop/browser/tor-browser/default.nix deleted file mode 100644 index 1a26e83..0000000 --- a/modules/nixos/desktop/browser/tor-browser/default.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (lib) mkEnableOption mkIf singleton; - cfg = config.desktop.browser.tor-browser; -in -{ - options.desktop.browser.tor-browser.enable = mkEnableOption ""; - - config = mkIf cfg.enable { - home-manager.sharedModules = singleton { - persistDirs = singleton ".tor project"; - home.packages = singleton pkgs.tor-browser; - }; - }; -} diff --git a/modules/nixos/desktop/default.nix b/modules/nixos/desktop/default.nix deleted file mode 100644 index 282075d..0000000 --- a/modules/nixos/desktop/default.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: -let - inherit (lib) - mkEnableOption - mkIf - singleton - optional - ; - inherit (lib.pantheon) mkStrOption; - inherit (pkgs) font-awesome wl-clipboard-rs; - cfg = config.desktop; -in -{ - options.desktop = { - enable = mkEnableOption ""; - enableWaylandUtilities = mkEnableOption ""; - mainMonitor = { - id = mkStrOption; - scale = mkStrOption; - resolution = mkStrOption; - refresh-rate = mkStrOption; - }; - }; - - config = mkIf cfg.enable { - fonts.packages = singleton font-awesome; - services.getty.autologinUser = config.mainUser.name; - home-manager.sharedModules = optional cfg.enableWaylandUtilities { - home.packages = [ wl-clipboard-rs ]; - }; - }; -} diff --git a/modules/nixos/desktop/gaming/default.nix b/modules/nixos/desktop/gaming/default.nix deleted file mode 100644 index a6e4443..0000000 --- a/modules/nixos/desktop/gaming/default.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (lib) - mkEnableOption - mkIf - mkMerge - singleton - ; - cfg = config.desktop.gaming; -in -{ - options.desktop.gaming = { - steam.enable = mkEnableOption ""; - prism-launcher.enable = mkEnableOption ""; - }; - - config = mkMerge [ - (mkIf cfg.steam.enable { - programs.steam = { - enable = true; - gamescopeSession.enable = true; - }; - home-manager.sharedModules = singleton { persistDirs = singleton ".local/share/Steam"; }; - }) - (mkIf cfg.prism-launcher.enable { - home-manager.sharedModules = singleton { - home.packages = singleton pkgs.prismlauncher; - persistDirs = singleton ".local/share/PrismLauncher"; - }; - }) - ]; -} diff --git a/modules/nixos/desktop/launcher/default.nix b/modules/nixos/desktop/launcher/default.nix deleted file mode 100644 index 3a35133..0000000 --- a/modules/nixos/desktop/launcher/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ lib, config, ... }: -let - inherit (lib) singleton mkEnableOption; - cfg = config.desktop.launcher; -in -{ - options.desktop.launcher = { - fuzzel.enable = mkEnableOption ""; - wofi.enable = mkEnableOption ""; - }; - - config.home-manager.sharedModules = singleton { - programs.fuzzel.enable = cfg.fuzzel.enable; - programs.wofi.enable = cfg.wofi.enable; - }; -} diff --git a/modules/nixos/desktop/lockscreen/default.nix b/modules/nixos/desktop/lockscreen/default.nix deleted file mode 100644 index 1074bbd..0000000 --- a/modules/nixos/desktop/lockscreen/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) - mkEnableOption - mkIf - mkMerge - singleton - ; - cfg = config.desktop.lockscreen; -in -{ - options.desktop.lockscreen = { - hyprlock.enable = mkEnableOption ""; - }; - - config = mkMerge [ - (mkIf cfg.hyprlock.enable { - security.pam.services.hyprlock = { }; - home-manager.sharedModules = singleton { programs.hyprlock.enable = true; }; - }) - ]; -} diff --git a/modules/nixos/desktop/media-player/default.nix b/modules/nixos/desktop/media-player/default.nix deleted file mode 100644 index 2c71170..0000000 --- a/modules/nixos/desktop/media-player/default.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (lib) mkEnableOption optional singleton; - inherit (pkgs) vlc; - cfg = config.desktop.media-player; -in -{ - options.desktop.media-player = { - vlc.enable = mkEnableOption ""; - }; - - config.home-manager.sharedModules = optional cfg.vlc.enable { home.packages = singleton vlc; }; -} diff --git a/modules/nixos/desktop/services/default.nix b/modules/nixos/desktop/services/default.nix deleted file mode 100644 index e3e39db..0000000 --- a/modules/nixos/desktop/services/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) - mkMerge - singleton - mkEnableOption - mkIf - ; - cfg = config.desktop.services; -in -{ - options.desktop.services = { - spotifyd.enable = mkEnableOption ""; - }; - - config = mkMerge [ - (mkIf cfg.spotifyd.enable { - networking.firewall.allowedTCPPorts = [ 5353 ]; - networking.firewall.allowedUDPPorts = [ 5353 ]; - home-manager.sharedModules = singleton { - services.spotifyd.enable = true; - services.spotifyd.settings.global = { - device_name = "${config.hostname}"; - device_type = "computer"; - zeroconf_port = 5353; - }; - }; - }) - ]; -} diff --git a/modules/nixos/desktop/services/sunshine/default.nix b/modules/nixos/desktop/services/sunshine/default.nix deleted file mode 100644 index 9331030..0000000 --- a/modules/nixos/desktop/services/sunshine/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) singleton mkIf mkEnableOption; - cfg = config.desktop.services.sunshine; -in -{ - options.desktop.services.sunshine = { - enable = mkEnableOption ""; - }; - config = mkIf cfg.enable { - services.sunshine = { - enable = true; - capSysAdmin = true; - openFirewall = true; - settings = { - sunshine_name = config.hostname; - origin_pin_allowed = "wan"; - origin_web_ui_allowed = "wan"; - }; - applications = { }; - }; - home-manager.sharedModules = singleton { persistDirs = singleton ".config/sunshine"; }; - }; -} diff --git a/modules/nixos/desktop/window-manager/hyprland/default.nix b/modules/nixos/desktop/window-manager/hyprland/default.nix deleted file mode 100644 index 5d38de7..0000000 --- a/modules/nixos/desktop/window-manager/hyprland/default.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) mkEnableOption mkIf singleton; - inherit (config.desktop) mainMonitor; - cfg = config.desktop.window-manager.hyprland; -in -{ - options.desktop.window-manager.hyprland.enable = mkEnableOption ""; - - config = mkIf cfg.enable { - # Enable custom module for wayland utilities (clipboard etc.) - desktop.enableWaylandUtilities = true; - # Start Hyprland at boot only if not connecting through SSH - environment.loginShellInit = # sh - '' - if [[ -z "$SSH_CLIENT" && -z "$SSH_CONNECTION" ]]; then - if uwsm check may-start; then - exec uwsm start hyprland-uwsm.desktop - fi - fi - ''; - environment.variables = { - # Get Electron apps to use Wayland - ELECTRON_OZONE_PLATFORM_HINT = "auto"; - NIXOS_OZONE_WL = "1"; - }; - programs.hyprland = { - enable = true; - # Use UWSM to have each process controlled by systemd init - withUWSM = true; - }; - home-manager.sharedModules = singleton { - wayland.windowManager.hyprland = { - enable = true; - # This is needed for UWSM - systemd.enable = false; - # Null the packages since we use them system wide - package = null; - portalPackage = null; - settings.monitor = [ "${mainMonitor.id}, ${mainMonitor.resolution}@${mainMonitor.refresh-rate}, auto, ${mainMonitor.scale}" ]; - }; - xdg.configFile."uwsm/env".text = # sh - '' - # Force apps to scale right with Wayland - export GDK_SCALE=${mainMonitor.scale} - export STEAM_FORCE_DESKTOPUI_SCALING=${mainMonitor.scale} - ''; - xdg.configFile."uwsm/env-hyprland".text = # sh - '' - export GDK_SCALE=${mainMonitor.scale} - export STEAM_FORCE_DESKTOPUI_SCALING=${mainMonitor.scale} - ''; - }; - }; -} diff --git a/modules/nixos/machine/bootloader/default.nix b/modules/nixos/machine/bootloader/default.nix deleted file mode 100644 index b5cedea..0000000 --- a/modules/nixos/machine/bootloader/default.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - config, - lib, - ... -}: -let - inherit (lib.pantheon) mkIntOption mkStrOption; - cfg = config.machine.bootloader; -in -{ - options.machine.bootloader = { - type = mkStrOption; - configurationLimit = mkIntOption 5; - }; - config.boot = { - initrd.availableKernelModules = [ - "nvme" - "xhci_pci" - "ahci" - "usbhid" - "usb_storage" - "sd_mod" - ]; - loader.efi.canTouchEfiVariables = true; - loader.systemd-boot = { - enable = cfg.type == "systemd-boot"; - inherit (cfg) configurationLimit; - }; - }; -} diff --git a/modules/nixos/machine/default.nix b/modules/nixos/machine/default.nix deleted file mode 100644 index b1aeb5a..0000000 --- a/modules/nixos/machine/default.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ lib, modulesPath, ... }: -let - inherit (lib) singleton; -in -{ - imports = [ - (modulesPath + "/installer/scan/not-detected.nix") - ]; - - config = { - services.fwupd.enable = true; - persistDirs = singleton "/var/lib/bluetooth"; - hardware.bluetooth = { - enable = true; - settings.General.Experimental = true; - }; - hardware.xone.enable = true; - }; -} diff --git a/modules/nixos/machine/drives/btrfs/default.nix b/modules/nixos/machine/drives/btrfs/default.nix deleted file mode 100644 index 89923ff..0000000 --- a/modules/nixos/machine/drives/btrfs/default.nix +++ /dev/null @@ -1,116 +0,0 @@ -{ - config, - lib, - inputs, - ... -}: -let - inherit (lib) mkIf mkEnableOption; - inherit (lib.pantheon) mkStrOption; - cfg = config.machine.drives.btrfs; - ephemeralRootCfg = { - boot.initrd.postDeviceCommands = lib.mkAfter '' - mkdir /btrfs_tmp - mount /dev/root_vg/root /btrfs_tmp - if [[ -e /btrfs_tmp/root ]]; then - mkdir -p /btrfs_tmp/old_roots - timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S") - mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp" - fi - - delete_subvolume_recursively() { - IFS=$'\n' - for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do - delete_subvolume_recursively "/btrfs_tmp/$i" - done - btrfs subvolume delete "$1" - } - - for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do - delete_subvolume_recursively "$i" - done - - btrfs subvolume create /btrfs_tmp/root - umount /btrfs_tmp - ''; - programs.fuse.userAllowOther = true; - fileSystems."/persist".neededForBoot = true; - #FIXME: below should be in module or something - environment.persistence."/persist" = { - hideMounts = true; - files = [ - "/etc/ssh/ssh_host_ed25519_key" - "/etc/ssh/ssh_host_ed25519_key.pub" - "/etc/ssh/ssh_host_rsa_key" - "/etc/ssh/ssh_host_rsa_key.pub" - "/etc/machine-id" - ]; - }; - }; -in -{ - imports = [ - inputs.disko.nixosModules.disko - inputs.impermanence.nixosModules.impermanence - ]; - options.machine.drives.btrfs = { - enable = mkEnableOption ""; - drive = mkStrOption; - ephemeralRoot = mkEnableOption ""; - }; - config = mkIf cfg.enable ( - { - boot.initrd.kernelModules = [ "dm-snapshot" ]; - disko.devices.disk.main = { - device = cfg.drive; - type = "disk"; - content.type = "gpt"; - content.partitions = { - boot.name = "boot"; - boot.size = "1M"; - boot.type = "EF02"; - esp.name = "ESP"; - esp.size = "500M"; - esp.type = "EF00"; - esp.content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - }; - swap.size = "4G"; - swap.content = { - type = "swap"; - resumeDevice = true; - }; - root.name = "root"; - root.size = "100%"; - root.content = { - type = "lvm_pv"; - vg = "root_vg"; - }; - }; - }; - - disko.devices.lvm_vg.root_vg = { - type = "lvm_vg"; - lvs.root.size = "100%FREE"; - lvs.root.content.type = "btrfs"; - lvs.root.content.extraArgs = [ "-f" ]; - lvs.root.content.subvolumes = { - "/root".mountpoint = "/"; - "/persist".mountpoint = "/persist"; - "/persist".mountOptions = [ - "subvol=persist" - "noatime" - ]; - "/nix".mountpoint = "/nix"; - "/nix".mountOptions = [ - "subvol=nix" - "noatime" - ]; - }; - }; - } - // ephemeralRootCfg - ); -} diff --git a/modules/nixos/machine/gpu/default.nix b/modules/nixos/machine/gpu/default.nix deleted file mode 100644 index 1e54a51..0000000 --- a/modules/nixos/machine/gpu/default.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (lib) - mkMerge - mkIf - mkEnableOption - singleton - ; - cfg = config.machine.gpu; -in -{ - options.machine.gpu = { - nvidia.enable = mkEnableOption ""; - }; - config = mkMerge [ - (mkIf cfg.nvidia.enable { - hardware = { - graphics.enable = true; - graphics.extraPackages = singleton pkgs.nvidia-vaapi-driver; - nvidia.open = true; - nvidia.package = config.boot.kernelPackages.nvidiaPackages.latest; - }; - services.xserver.videoDrivers = [ "nvidia" ]; - nixpkgs.config.allowUnfree = true; - environment.variables = { - LIBVA_DRIVER_NAME = "nvidia"; - __GLX_VENDOR_LIBRARY_NAME = "nvidia"; - NVD_BACKEND = "direct"; - }; - nix.settings.substituters = [ "https://cuda-maintainers.cachix.org" ]; - nix.settings.trusted-public-keys = [ - "cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E=" - ]; - }) - ]; -} diff --git a/modules/nixos/machine/platform/default.nix b/modules/nixos/machine/platform/default.nix deleted file mode 100644 index a698c2b..0000000 --- a/modules/nixos/machine/platform/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) singleton mkOption; - inherit (lib.types) enum; - cfg = config.machine.platform; -in -{ - options.machine.platform = { - type = mkOption { - type = enum [ - "amd" - "intel" - ]; - }; - }; - - config = { - hardware.cpu.${cfg.type}.updateMicrocode = true; - boot.kernelModules = singleton "kvm-${cfg.type}"; - }; -} diff --git a/modules/nixos/machine/usb/default.nix b/modules/nixos/machine/usb/default.nix deleted file mode 100644 index 9177356..0000000 --- a/modules/nixos/machine/usb/default.nix +++ /dev/null @@ -1,45 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: -let - inherit (lib) - mkEnableOption - mkIf - mkMerge - singleton - ; - cfg = config.machine.usb; -in -{ - options.machine.usb = { - automount = mkEnableOption ""; - enableQmk = mkEnableOption ""; - }; - - config = mkMerge [ - (mkIf cfg.automount { - services.udisks2.enable = true; - home-manager.sharedModules = singleton { - services.udiskie = { - enable = true; - automount = true; - notify = true; - }; - }; - }) - (mkIf cfg.enableQmk { - hardware.keyboard.qmk.enable = true; - services.udev = { - packages = with pkgs; [ - vial - qmk - qmk-udev-rules - qmk_hid - ]; - }; - }) - ]; -} diff --git a/modules/nixos/machine/virtualisation/distrobox/default.nix b/modules/nixos/machine/virtualisation/distrobox/default.nix deleted file mode 100644 index b570fdb..0000000 --- a/modules/nixos/machine/virtualisation/distrobox/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (lib) mkIf mkEnableOption singleton; - cfg = config.machine.virtualisation.distrobox; -in -{ - options.machine.virtualisation.distrobox = { - enable = mkEnableOption ""; - }; - config = mkIf cfg.enable { - machine.virtualisation.podman.enable = true; - home-manager.sharedModules = singleton { - home.packages = singleton pkgs.distrobox; - # persistDirs = [ ".local/share/containers" ]; - }; - }; -} diff --git a/modules/nixos/machine/virtualisation/podman/default.nix b/modules/nixos/machine/virtualisation/podman/default.nix deleted file mode 100644 index e130e17..0000000 --- a/modules/nixos/machine/virtualisation/podman/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) mkEnableOption mkIf; - cfg = config.machine.virtualisation.podman; -in -{ - options.machine.virtualisation.podman = { - enable = mkEnableOption ""; - }; - config = mkIf cfg.enable { - virtualisation = { - containers.enable = true; - podman = { - enable = true; - dockerCompat = true; - defaultNetwork.settings.dns_enabled = true; - }; - }; - users.users."${config.mainUser.name}" = { - extraGroups = [ "podman" ]; - # https://wiki.nixos.org/wiki/Distrobox - # subGidRanges = singleton { - # count = 65536; - # startGid = 1000; - # }; - # subUidRanges = singleton { - # count = 65536; - # startUid = 1000; - # }; - }; - }; -} diff --git a/modules/nixos/networking/default.nix b/modules/nixos/networking/default.nix deleted file mode 100644 index ae9509e..0000000 --- a/modules/nixos/networking/default.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) mkDefault singleton; -in -{ - sops.secrets = { - "tailscale/client-id".sopsFile = ./tailscale.yaml; - "tailscale/client-secret".sopsFile = ./tailscale.yaml; - }; - networking = { - enableIPv6 = false; - useDHCP = mkDefault true; - hostName = config.hostname; - networkmanager.enable = true; - }; - - services.openssh = { - enable = true; - settings.PrintMotd = true; - }; - - services.tailscale = { - enable = true; - authKeyFile = config.sops.secrets."tailscale/client-secret".path; - authKeyParameters.preauthorized = true; - }; - persistDirs = singleton "/var/lib/tailscale"; -} diff --git a/modules/nixos/networking/tailscale.yaml b/modules/nixos/networking/tailscale.yaml deleted file mode 100644 index 87aa9d8..0000000 --- a/modules/nixos/networking/tailscale.yaml +++ /dev/null @@ -1,18 +0,0 @@ -tailscale: - client-id: ENC[AES256_GCM,data:kQ4H9b2h8DN+5eTvwIYHZ6s=,iv:/nC3LM0qDNj3wIm9XZd7UUn5SxmAOA1dofsDGElKjVU=,tag:AIj5F7KkORujLDe+ZOxJgw==,type:str] - client-secret: ENC[AES256_GCM,data:O0cKyuK+FfK2E1mzQpkgybPrqEs0fH1y3jCOG6usT++6x3sWuJNvT56OIHpVNu8GH/6BIBsnenC1J/sVNTYIzA==,iv:FugIzSjNpoe9Bwy+x/GHl0BpCtbogQXpY7s3ICevQc0=,tag:1kQIO4ekjKuvexQ923YE3g==,type:str] -sops: - age: - - recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGbTNsZE5lN2JOT1Jsd2hz - OWpDWTFzTW05Nzl5K1AyMmgxcVV2eHlBRlF3Cnc3VW5IN014ck8zM3BIWnBMNFFt - UnE4aGhGNERUOTlwZEJyNWF1Q1o0RXcKLS0tIFlZSFFoaDlOMnBMSFVyT3FMbFZj - ckl5RVZiMnkzV0RFQXN1aHZKM2doMnMKD6BjRdqsHiKDth4aBiZ1lvlcO1OgY36O - cGkZjuH45L4a0Y0kvptq3iZ/iPnmX8hw8n/gdplzUkpBzdsNPebvSg== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-07-01T21:11:39Z" - mac: ENC[AES256_GCM,data:YWgrMqqJgrGe+40a9CSDpAAgwPOeGXRFb58c6X6PxDHve3u5vQfHh+wkC0TFxadMsYcJTczRYf8YWuAwf7kFoO7ofYs+PfEi4ydKhl8WY9nXTsq+BFT4rDl/BaCfQw6qWD5/TKTtxm2pdtBNrG7bNeZJ8cVSOO/wsjoqrrbh3fk=,iv:8BXOX5O5apYLhZOWihagQBVldmsVoV+uEcejcO3cC0I=,tag:vansSul5Ebwooay48uYNZQ==,type:str] - unencrypted_suffix: _unencrypted - version: 3.10.2 diff --git a/modules/nixos/server/databases/default.nix b/modules/nixos/server/databases/default.nix deleted file mode 100644 index 726b449..0000000 --- a/modules/nixos/server/databases/default.nix +++ /dev/null @@ -1,84 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: -let - inherit (lib) singleton; - cfg = config.server.databases; -in -{ - options.server.databases = { - mongodb = { - enable = lib.mkEnableOption "the MongoDB server"; - port = lib.pantheon.mkPortOption 27017; - }; - mysql = { - enable = lib.mkEnableOption "the MySQL server"; - port = lib.pantheon.mkPortOption 3306; - }; - postgresql = { - enable = lib.mkEnableOption "the postgresql server"; - port = lib.pantheon.mkPortOption 5432; - }; - }; - - config = lib.mkMerge [ - (lib.mkIf cfg.postgresql.enable { - networking.firewall.allowedTCPPorts = lib.singleton cfg.postgresql.port; - persistDirs = singleton { - directory = builtins.toString config.services.postgresql.dataDir; - user = "postgres"; - group = "postgres"; - }; - services.postgresql = { - enable = true; - enableTCPIP = true; - settings = { inherit (cfg.postgresql) port; }; - authentication = lib.mkOverride 10 '' - #type database DBuser auth-method - local all all trust - - # ipv4 - host all all 0.0.0.0/0 trust - ''; - ensureDatabases = singleton "alphastory"; - ensureUsers = singleton { - name = "alphastory"; - ensureDBOwnership = true; - }; - }; - }) - (lib.mkIf cfg.mongodb.enable { - networking.firewall.allowedTCPPorts = [ cfg.mongodb.port ]; - persistDirs = singleton { - directory = builtins.toString config.services.mongodb.dbpath; - user = "mongodb"; - group = "mongodb"; - }; - services.mongodb = { - enable = true; - bind_ip = "0.0.0.0"; - extraConfig = '' - net.port: ${builtins.toString cfg.mongodb.port} - ''; - }; - }) - (lib.mkIf cfg.mysql.enable { - networking.firewall.allowedTCPPorts = [ cfg.mysql.port ]; - persistDirs = singleton { - directory = builtins.toString config.services.mysql.dataDir; - user = "mysql"; - group = "mysql"; - }; - services.mysql = { - enable = true; - package = pkgs.mariadb; - settings.mysqld = { - inherit (cfg.mysql) port; - }; - }; - }) - ]; -} diff --git a/modules/nixos/server/default.nix b/modules/nixos/server/default.nix deleted file mode 100644 index a9592c5..0000000 --- a/modules/nixos/server/default.nix +++ /dev/null @@ -1,43 +0,0 @@ -{ lib, config, ... }: -{ - options.server.mountHelios = lib.mkEnableOption ""; - - config = lib.mkIf config.server.mountHelios { - sops.secrets."rafiq/oldSMBCredentials" = { }; - sops.templates."smb-credentials".content = '' - username=rafiq - password=${config.sops.placeholder."rafiq/oldSMBCredentials"} - ''; - fileSystems = { - "/media/helios/data" = { - device = "//helios/data"; - fsType = "cifs"; - options = [ - "x-systemd.automount" - "x-systemd.requires=tailscaled.service" - "x-systemd.mount-timeout=0" - ]; - }; - "/media/helios/rafiqcloud" = { - device = "//helios/rafiqcloud"; - fsType = "cifs"; - options = [ - "x-systemd.automount" - "x-systemd.requires=tailscaled.service" - "x-systemd.mount-timeout=0" - "credentials=${config.sops.templates."smb-credentials".path}" - ]; - }; - "/media/helios/rafiqmedia" = { - device = "//helios/rafiqmedia"; - fsType = "cifs"; - options = [ - "x-systemd.automount" - "x-systemd.requires=tailscaled.service" - "x-systemd.mount-timeout=0" - "credentials=${config.sops.templates."smb-credentials".path}" - ]; - }; - }; - }; -} diff --git a/modules/nixos/server/networking/ddns/default.nix b/modules/nixos/server/networking/ddns/default.nix deleted file mode 100644 index b50dc0b..0000000 --- a/modules/nixos/server/networking/ddns/default.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) mkIf mkOption mkEnableOption; - inherit (lib.types) enum str listOf; - inherit (lib.lists) unique; - inherit (builtins) map; - cfg = config.server.networking.ddns; - mkDomain = domain_name: { - inherit domain_name; - sub_domains = [ - "@" - "*" - ]; - }; - # Sanitize the list of domains with unique so we can add to it with every service. - mkDomains = map mkDomain (unique cfg.domains); -in -{ - options.server.networking.ddns = { - enable = mkEnableOption ""; - type = mkOption { - type = enum [ "godns" ]; - default = "godns"; - }; - domains = mkOption { - type = listOf str; - default = [ ]; - }; - }; - - config = mkIf cfg.enable { - services.godns = { - enable = if (cfg.type == "godns") then true else false; - loadCredential = [ - "cf_token:${config.sops.secrets."keys/cloudflare".path}" - "telegram_bot_token:${config.sops.secrets."keys/telegram_bot".path}" - ]; - settings = { - provider = "Cloudflare"; - login_token_file = "$CREDENTIALS_DIRECTORY/cf_token"; - domains = mkDomains; - resolver = "1.1.1.1"; - ip_urls = [ - "https://wtfismyip.com/text" - "https://api.ipify.org" - "https://myip.biturl.top" - "https://api-ipv4.ip.sb/ip" - ]; - ip_type = "IPv4"; - interval = 300; - notify = { - telegram = { - enabled = true; - bot_api_key_file = "$CREDENTIALS_DIRECTORY/telegram_bot_token"; - chat_id = "384288005"; - message_template = "Domain *{{ .Domain }} has been updated to %0A{{ .CurrentIP }}"; - }; - }; - }; - }; - }; -} diff --git a/modules/nixos/server/web-apps/comfy-ui/default.nix b/modules/nixos/server/web-apps/comfy-ui/default.nix deleted file mode 100644 index 19731b9..0000000 --- a/modules/nixos/server/web-apps/comfy-ui/default.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ - config, - lib, - inputs, - ... -}: -let - inherit (lib) singleton; - inherit (lib.pantheon.modules) mkWebApp; - upstreamCfg = config.services.comfyUi; -in -mkWebApp { - inherit config; - name = "comfy-ui"; - defaultPort = 8188; - persistDirs = singleton { - directory = upstreamCfg.dataDir; - inherit (upstreamCfg) user group; - mode = "777"; - }; - extraConfig = { - assertions = singleton { - assertion = config.machine.gpu.nvidia.enable; - message = "You must run the comfy-ui service only with an nvidia gpu."; - }; - services.comfyUi = { - enable = true; - listenHost = "0.0.0.0"; - }; - }; -} -// { - imports = [ inputs.stable-diffusion-webui-nix.nixosModules.default ]; -} diff --git a/modules/nixos/server/web-apps/forgejo/default.nix b/modules/nixos/server/web-apps/forgejo/default.nix deleted file mode 100644 index 97140f8..0000000 --- a/modules/nixos/server/web-apps/forgejo/default.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) singleton optional; - inherit (lib.pantheon) mkPortOption; - inherit (lib.pantheon.modules) mkWebApp; - cfg = config.server.web-apps.forgejo; - upstreamCfg = config.services.forgejo; -in -mkWebApp { - inherit config; - name = "forgejo"; - defaultPort = 3000; - persistDirs = singleton { - directory = upstreamCfg.stateDir; - inherit (upstreamCfg) user group; - }; - extraOptions = { - sshPort = mkPortOption 2222; - }; - extraConfig = { - networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.sshPort; - services.forgejo = { - enable = true; - settings = { - server = { - DOMAIN = cfg.domain; - ROOT_URL = "https://${cfg.domain}/"; - HTTP_PORT = cfg.port; - START_SSH_SERVER = true; - SSH_PORT = cfg.sshPort; - }; - repository = { - USE_COMPAT_SSH_URI = false; - ENABLE_PUSH_CREATE_USER = true; - ENABLE_PUSH_CREATE_ORG = true; - }; - "repository.signing".FORMAT = "ssh"; - }; - }; - }; -} diff --git a/modules/nixos/server/web-apps/glance/default.nix b/modules/nixos/server/web-apps/glance/default.nix deleted file mode 100644 index 6e054db..0000000 --- a/modules/nixos/server/web-apps/glance/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ lib, config, ... }: -let - inherit (lib.pantheon.modules) mkWebApp; - cfg = config.server.web-apps.glance; -in -mkWebApp { - inherit config; - name = "glance"; - defaultPort = 8080; - extraConfig = { - services.glance = { - enable = true; - settings.server.host = "0.0.0.0"; - settings.server.port = cfg.port; - }; - }; -} diff --git a/modules/nixos/server/web-apps/librechat/default.nix b/modules/nixos/server/web-apps/librechat/default.nix deleted file mode 100644 index cf6d71d..0000000 --- a/modules/nixos/server/web-apps/librechat/default.nix +++ /dev/null @@ -1,80 +0,0 @@ -{ - config, - lib, - inputs, - ... -}: -let - inherit (lib) singleton; - inherit (lib.pantheon) mkStrOption; - inherit (lib.pantheon.modules) mkWebApp; - cfg = config.server.web-apps.librechat; - upstreamCfg = config.services.librechat; -in -mkWebApp { - inherit config; - name = "librechat"; - defaultPort = 3080; - persistDirs = singleton { - directory = upstreamCfg.dataDir; - inherit (upstreamCfg) user group; - }; - extraOptions.mongodbURI = mkStrOption // { - default = "mongodb://${config.hostname}:27017/LibreChat"; - }; - extraConfig = { - sops.secrets = { - "librechat/creds_key" = { }; - "librechat/creds_iv" = { }; - "librechat/jwt_secret" = { }; - "librechat/jwt_refresh_secret" = { }; - }; - services.librechat = { - enable = true; - openFirewall = true; - inherit (cfg) port; - env = { - HOST = "0.0.0.0"; - ALLOW_REGISTRATION = "true"; - NO_INDEX = "true"; - MONGO_URI = cfg.mongodbURI; - DOMAIN_CLIENT = cfg.domain; - DOMAIN_SERVER = cfg.domain; - ENDPOINTS = "anthropic,agents,google"; - }; - credentials = { - CREDS_KEY = config.sops.secrets."librechat/creds_key".path; - CREDS_IV = config.sops.secrets."librechat/creds_iv".path; - JWT_SECRET = config.sops.secrets."librechat/jwt_secret".path; - JWT_REFRESH_SECRET = config.sops.secrets."librechat/jwt_refresh_secret".path; - OPENROUTER_KEY = config.sops.secrets."keys/openrouter".path; - GOOGLE_KEY = config.sops.secrets."keys/gemini".path; - }; - settings = { - version = "1.1.4"; - cache = true; - endpoints.custom = [ - { - name = "OpenRouter"; - apiKey = "\${OPENROUTER_KEY}"; - baseURL = "https://openrouter.ai/api/v1"; - models.default = [ "meta-llama/llama-3-70b-instruct" ]; - models.fetch = true; - titleConvo = true; - titleModel = "current_model"; - modelDisplayLabel = "OpenRouter"; - } - ]; - interface = { - privacyPolicy = { - externalUrl = "https://librechat.ai/privacy-policy"; - openNewTab = true; - }; - }; - }; - }; - }; -} -// { - imports = singleton "${inputs.rrvsh-nixpkgs}/nixos/modules/services/web-apps/librechat.nix"; -} diff --git a/modules/nixos/server/web-apps/rrv-sh/default.nix b/modules/nixos/server/web-apps/rrv-sh/default.nix deleted file mode 100644 index 25a54bd..0000000 --- a/modules/nixos/server/web-apps/rrv-sh/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - config, - lib, - inputs, - ... -}: -let - inherit (lib.pantheon.modules) mkWebApp; - cfg = config.server.web-apps.rrv-sh; -in -mkWebApp { - inherit config; - name = "rrv-sh"; - defaultPort = 2309; - extraConfig = { - services.rrv-sh = { - enable = true; - inherit (cfg) port; - }; - }; -} -// { - imports = [ inputs.rrv-sh.nixosModules.default ]; -} diff --git a/modules/nixos/server/web-apps/sd-webui-forge/default.nix b/modules/nixos/server/web-apps/sd-webui-forge/default.nix deleted file mode 100644 index c7f4b04..0000000 --- a/modules/nixos/server/web-apps/sd-webui-forge/default.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ - config, - lib, - inputs, - ... -}: -let - inherit (lib) singleton; - inherit (lib.pantheon.modules) mkWebApp; - upstreamCfg = config.services.sd-webui-forge; -in -mkWebApp { - inherit config; - name = "sd-webui-forge"; - defaultPort = 7860; - persistDirs = singleton { - directory = upstreamCfg.dataDir; - inherit (upstreamCfg) user group; - }; - extraConfig = { - assertions = singleton { - assertion = config.machine.gpu.nvidia.enable; - message = "You must run the sd-webui-forge service only with an nvidia gpu."; - }; - services.sd-webui-forge = { - enable = true; - listen = true; - extraArgs = "--cuda-malloc"; - }; - }; -} -// { - imports = [ inputs.stable-diffusion-webui-nix.nixosModules.default ]; -} diff --git a/modules/nixos/server/web-servers/default.nix b/modules/nixos/server/web-servers/default.nix deleted file mode 100644 index 1aee593..0000000 --- a/modules/nixos/server/web-servers/default.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) - mkMerge - mkIf - mkEnableOption - singleton - ; - cfg = config.server.web-servers; -in -{ - options.server.web-servers = { - enableSSL = mkEnableOption ""; - }; - - config = mkMerge [ - (mkIf cfg.enableSSL { - security.acme = { - acceptTerms = true; - defaults = { - inherit (config.mainUser) email; - dnsProvider = "cloudflare"; - credentialFiles."CLOUDFLARE_DNS_API_TOKEN_FILE" = config.sops.secrets."keys/cloudflare".path; - }; - certs = { - "rrv.sh".extraDomainNames = singleton "*.rrv.sh"; - "bwfiq.com".extraDomainNames = singleton "*.bwfiq.com"; - "slayment.com".extraDomainNames = singleton "*.slayment.com"; - "aenyrathia.wiki".extraDomainNames = singleton "*.aenyrathia.wiki"; - }; - }; - }) - ]; -} diff --git a/modules/nixos/server/web-servers/nginx/default.nix b/modules/nixos/server/web-servers/nginx/default.nix deleted file mode 100644 index d0d6cc8..0000000 --- a/modules/nixos/server/web-servers/nginx/default.nix +++ /dev/null @@ -1,119 +0,0 @@ -{ config, lib, ... }: -let - inherit (lib) - mkMerge - mkOption - mkEnableOption - mkIf - singleton - ; - inherit (lib.types) listOf submodule attrs; - inherit (lib.pantheon) mkStrOption mkPathOption mkRootDomain; - inherit (builtins) listToAttrs map; - cfg = config.server.web-servers.nginx; - sslCheck = good: bad: if config.server.web-servers.enableSSL then good else bad; - defaultSink = mkIf cfg.enableDefaultSink { - "_" = { - default = true; - rejectSSL = sslCheck true false; - locations."/" = { - return = "444"; - }; - }; - }; - pages = listToAttrs ( - map (page: { - name = page.domain; - value = { - addSSL = sslCheck true false; - useACMEHost = sslCheck (mkRootDomain page.domain) null; - acmeRoot = null; # needed for DNS validation - locations = { - "/" = { - inherit (page) root; - } // page.extraConfig; - } // page.locations; - }; - }) cfg.pages - ); - proxyPasses = listToAttrs ( - map (proxy: { - name = proxy.source; - value = { - addSSL = sslCheck true false; - useACMEHost = sslCheck (mkRootDomain proxy.source) null; - acmeRoot = null; # needed for DNS validation - locations = { - "/" = { - proxyPass = proxy.target; - } // proxy.extraConfig; - } // proxy.locations; - }; - }) cfg.proxies - ); -in -{ - options.server.web-servers.nginx = { - enable = mkEnableOption "the Nginx server"; - openFirewall = mkEnableOption "" // { - default = true; - }; - enableDefaultSink = mkEnableOption "" // { - default = true; - }; - pages = mkOption { - default = [ ]; - type = listOf (submodule { - options = { - domain = mkStrOption; - root = mkPathOption ""; - extraConfig = lib.mkOption { - type = attrs; - default = { }; - }; - locations = lib.mkOption { - type = attrs; - default = { }; - }; - }; - }); - }; - proxies = mkOption { - default = [ ]; - type = listOf (submodule { - options = { - source = mkStrOption; - target = mkStrOption; - extraConfig = lib.mkOption { - type = attrs; - default = { }; - }; - locations = lib.mkOption { - type = attrs; - default = { }; - }; - }; - }); - }; - }; - - config = mkIf cfg.enable { - networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ - 443 - 80 - ]; - users.users.nginx.extraGroups = singleton "acme"; - services.nginx = { - enable = true; - recommendedProxySettings = true; - recommendedTlsSettings = true; - recommendedOptimisation = true; - recommendedGzipSettings = true; - virtualHosts = mkMerge [ - defaultSink - proxyPasses - pages - ]; - }; - }; -} diff --git a/nix/configurations.nix b/nix/configurations.nix new file mode 100644 index 0000000..1d27ceb --- /dev/null +++ b/nix/configurations.nix @@ -0,0 +1,45 @@ +{ + config, + lib, + inputs, + ... +}: +let + inherit (lib) nixosSystem; + inherit (lib.lists) optional; + inherit (lib.attrsets) mapAttrs; + inherit (cfg.lib.modules) forAllUsers'; + cfg = config.flake; + globalCfg = name: hostConfig: { + useGlobalPkgs = true; + useUserPackages = true; + extraSpecialArgs = { + inherit hostConfig; + hostName = name; + }; + sharedModules = [ cfg.modules.homeManager.default ]; + users = forAllUsers' (name: _: cfg.modules.homeManager.${name}); + }; + hosts = cfg.manifest.hosts or { }; + mkConfigurations = + class: hosts: + mapAttrs ( + name: value: + if class == "nixos" then + nixosSystem { + specialArgs.hostName = name; + modules = [ + cfg.modules.nixos.default + inputs.home-manager.nixosModules.home-manager + { home-manager = globalCfg name value; } + (value.extraCfg or { }) + ] ++ optional value.graphical cfg.modules.nixos.graphical; + } + else + { } + ) hosts; +in +{ + imports = [ inputs.home-manager.flakeModules.home-manager ]; + flake.nixosConfigurations = mkConfigurations "nixos" hosts.nixos; +} diff --git a/nix/files/cheatsheet.nix b/nix/files/cheatsheet.nix new file mode 100644 index 0000000..e307bbc --- /dev/null +++ b/nix/files/cheatsheet.nix @@ -0,0 +1,18 @@ +{ lib, config, ... }: +let + inherit (builtins) concatStringsSep; + inherit (lib.lists) singleton; +in +{ + text.cheatsheet = concatStringsSep "\n" [ + "`__curPos.file` will give the full evaluated path of the nix file it is called in. See [this issue](https://github.com/NixOS/nix/issues/5897#issuecomment-1012165198) for more information." + ]; + perSystem = + { pkgs, ... }: + { + files.files = singleton { + path_ = "docs/cheatsheet.md"; + drv = pkgs.writeText "cheatsheet.md" config.text.cheatsheet; + }; + }; +} diff --git a/nix/files/gitignore.nix b/nix/files/gitignore.nix new file mode 100644 index 0000000..a35e3ee --- /dev/null +++ b/nix/files/gitignore.nix @@ -0,0 +1,13 @@ +{ config, ... }: +{ + perSystem = + { pkgs, ... }: + { + files.files = [ + { + path_ = ".gitignore"; + drv = pkgs.writeText ".gitignore" config.text.gitignore; + } + ]; + }; +} diff --git a/nix/files/readme.nix b/nix/files/readme.nix new file mode 100644 index 0000000..a8eccbf --- /dev/null +++ b/nix/files/readme.nix @@ -0,0 +1,54 @@ +{ config, ... }: +{ + text.readme = { + heading = "Pantheon"; + description = # markdown + '' + This flake serves as a monorepo for my systems (using IaC), dotfiles, and scripts. + It's hosted at https://git.rrv.sh/rrvsh/pantheon, and mirrored to https://github.com/rrvsh/pantheon. + ''; + order = [ + "Structure" + "Acknowledgements" + ]; + parts."Acknowledgements" = # markdown + '' + Thanks to the following for inspiring this configuration. I highly recommend you look through their writings and configurations. + - [ornicar](https://github.com/ornicar/dotfiles) which is where I first heard of NixOS + - [No Boilerplate](https://www.youtube.com/watch?v=CwfKlX3rA6E&pp=0gcJCfwAo7VqN5tD) for making me finally try the OS + - [ryan4yin](https://nixos-and-flakes.thiscute.world/) for being an amazing introduction to NixOS, home-manager, and flakes + - [NotAShelf](https://github.com/NotAShelf/) for their blog and for the wonderful [NVF](https://github.com/notashelf/nvf) + - [mightyiam](https://github.com/mightyiam/infra) for their infrastructure repo using flake-parts + - [drupol](https://not-a-number.io/2025/refactoring-my-infrastructure-as-code-configurations/) for this blog post which convinced me to rebase my infra to use flake-parts + ''; + parts."Structure" = # markdown + '' + The system configurations are defined in [`flake.manifest`](nix/manifest.nix). + `flake.manifest.owner` provides the attributes for the administrator user, including username and pubkey. + `flake.manifest.hosts` provides the specifications for the system configurations that should be exposed by the flake as nixosConfigurations. + `flake.modules.nixos.*` provide NixOS options and configurations. + The attribute `flake.modules.nixos.default` provides options that will be applied to every system of that class. + You can use it as seen [here](nix/modules/flake/home-manager.nix): + + ```nix + flake.modules.nixos.default.imports = [ inputs.home-manager.nixosModules.default ]; + ``` + + The other attributes under `flake.modules.nixos` should be opt-in, i.e. provide options that will be set in the profiles. + `flake.profiles.nixos` provides profiles which use the options defined in `flake.modules.nixos` to define different roles for each system, such as graphical, laptop, headless, etc. + Options should not be defined here. + `flake.contracts.nixos.*` will provide contracts, such as reverse proxies or databases, which will configure options on the provider and receiver host. + ''; + }; + + perSystem = + { pkgs, ... }: + { + files.files = [ + { + path_ = "docs/README.md"; + drv = pkgs.writeText "README.md" config.text.readme; + } + ]; + }; +} diff --git a/nix/flake-parts/debug.nix b/nix/flake-parts/debug.nix new file mode 100644 index 0000000..38e2cb3 --- /dev/null +++ b/nix/flake-parts/debug.nix @@ -0,0 +1,3 @@ +{ + debug = true; +} diff --git a/nix/flake-parts/files.nix b/nix/flake-parts/files.nix new file mode 100644 index 0000000..e210c52 --- /dev/null +++ b/nix/flake-parts/files.nix @@ -0,0 +1,28 @@ +{ + inputs, + withSystem, + lib, + config, + ... +}: +let + inherit (builtins) map head; + inherit (lib.lists) concatStringsSep; + mkListEntry = x: "- [" + x.path_ + "](" + x.path_ + ")"; + listOfGeneratedFiles = withSystem (head config.systems) (psArgs: psArgs.config.files.files); +in +{ + imports = [ inputs.files.flakeModules.default ]; + perSystem = psArgs: { + make-shells.default.packages = [ psArgs.config.files.writer.drv ]; + }; + text.readme.parts."Generated Files" = concatStringsSep "\n" ( + [ + "This flake uses the [files flake-parts module](https://flake.parts/options/files.html) to generate documentation." + + "The list of generated files are:" + + ] + ++ (map mkListEntry listOfGeneratedFiles) + ); +} diff --git a/nix/flake-parts/git-hooks.nix b/nix/flake-parts/git-hooks.nix new file mode 100644 index 0000000..d17bcce --- /dev/null +++ b/nix/flake-parts/git-hooks.nix @@ -0,0 +1,24 @@ +{ inputs, ... }: +{ + imports = [ inputs.git-hooks.flakeModule ]; + text.gitignore = ".pre-commit-config.*"; + perSystem = psArgs: { + pre-commit.settings.hooks = { + # Nix Linters + deadnix.enable = true; + statix.enable = true; + nil.enable = true; + nixfmt-rfc-style.enable = true; + # Flake Health Checks + flake-checker.enable = true; + # Misc + mixed-line-endings.enable = true; + trim-trailing-whitespace.enable = true; + #TODO: figure out vale + #TODO: make nix develop work + #TODO: add nix flake check + #TODO: add write-files + }; + make-shells.default.shellHook = psArgs.config.pre-commit.installationScript; + }; +} diff --git a/nix/flake-parts/make-shell.nix b/nix/flake-parts/make-shell.nix new file mode 100644 index 0000000..66ca600 --- /dev/null +++ b/nix/flake-parts/make-shell.nix @@ -0,0 +1,5 @@ +{ inputs, ... }: +{ + #TODO: add to readme + imports = [ inputs.make-shell.flakeModules.default ]; +} diff --git a/nix/flake-parts/modules.nix b/nix/flake-parts/modules.nix new file mode 100644 index 0000000..1c75663 --- /dev/null +++ b/nix/flake-parts/modules.nix @@ -0,0 +1,4 @@ +{ inputs, ... }: +{ + imports = [ inputs.flake-parts.flakeModules.modules ]; +} diff --git a/nix/flake-parts/text.nix b/nix/flake-parts/text.nix new file mode 100644 index 0000000..81b2f51 --- /dev/null +++ b/nix/flake-parts/text.nix @@ -0,0 +1,4 @@ +{ inputs, ... }: +{ + imports = [ inputs.text.flakeModules.default ]; +} diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/autocomplete.nix b/nix/homes/rafiq/_nvf/autocomplete.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/autocomplete.nix rename to nix/homes/rafiq/_nvf/autocomplete.nix diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/binds.nix b/nix/homes/rafiq/_nvf/binds.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/binds.nix rename to nix/homes/rafiq/_nvf/binds.nix diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/languages.nix b/nix/homes/rafiq/_nvf/languages.nix similarity index 91% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/languages.nix rename to nix/homes/rafiq/_nvf/languages.nix index 1eb16fb..cc3dd8c 100644 --- a/homes/x86_64-linux/rafiq/cli/editor/_nvf/languages.nix +++ b/nix/homes/rafiq/_nvf/languages.nix @@ -23,8 +23,6 @@ enable = true; format.type = "ruff"; lsp.server = "pyright"; - uv.enable = true; - uv.setupOpts.picker_integration = true; }; rust.enable = true; rust.crates.enable = true; diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/lsp.nix b/nix/homes/rafiq/_nvf/lsp.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/lsp.nix rename to nix/homes/rafiq/_nvf/lsp.nix diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/navigation.nix b/nix/homes/rafiq/_nvf/navigation.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/navigation.nix rename to nix/homes/rafiq/_nvf/navigation.nix diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/snippets.nix b/nix/homes/rafiq/_nvf/snippets.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/snippets.nix rename to nix/homes/rafiq/_nvf/snippets.nix diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/statusline.nix b/nix/homes/rafiq/_nvf/statusline.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/statusline.nix rename to nix/homes/rafiq/_nvf/statusline.nix diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/ui.nix b/nix/homes/rafiq/_nvf/ui.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/ui.nix rename to nix/homes/rafiq/_nvf/ui.nix diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/utility.nix b/nix/homes/rafiq/_nvf/utility.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/utility.nix rename to nix/homes/rafiq/_nvf/utility.nix diff --git a/homes/x86_64-linux/rafiq/cli/editor/_nvf/visuals.nix b/nix/homes/rafiq/_nvf/visuals.nix similarity index 100% rename from homes/x86_64-linux/rafiq/cli/editor/_nvf/visuals.nix rename to nix/homes/rafiq/_nvf/visuals.nix diff --git a/packages/commit/default.nix b/nix/homes/rafiq/_scripts/commit.nix similarity index 100% rename from packages/commit/default.nix rename to nix/homes/rafiq/_scripts/commit.nix diff --git a/packages/edit/default.nix b/nix/homes/rafiq/_scripts/edit.nix similarity index 100% rename from packages/edit/default.nix rename to nix/homes/rafiq/_scripts/edit.nix diff --git a/nix/homes/rafiq/_scripts/note.nix b/nix/homes/rafiq/_scripts/note.nix new file mode 100644 index 0000000..0470fc2 --- /dev/null +++ b/nix/homes/rafiq/_scripts/note.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: +pkgs.writeShellScriptBin "note" # bash + '' + zk edit -i + pushd ~/notebook > /dev/null + git add . + commit -u + popd > /dev/null + '' diff --git a/packages/rebuild/default.nix b/nix/homes/rafiq/_scripts/rebuild.nix similarity index 95% rename from packages/rebuild/default.nix rename to nix/homes/rafiq/_scripts/rebuild.nix index cb303ac..223a4db 100644 --- a/packages/rebuild/default.nix +++ b/nix/homes/rafiq/_scripts/rebuild.nix @@ -1,6 +1,6 @@ -{ pkgs, lib, ... }: +{ pkgs }: let - inherit (lib) getExe; + inherit (pkgs.lib) getExe; in pkgs.writeShellScriptBin "rebuild" # sh '' @@ -71,7 +71,7 @@ pkgs.writeShellScriptBin "rebuild" # sh local NEW_GENERATION=$(ssh "$1" readlink /nix/var/nix/profiles/system | cut -d- -f2) info "$1 - New generation is $NEW_GENERATION. Current is $CURRENT_GENERATION." if [ ! $NEW_GENERATION -gt $CURRENT_GENERATION ]; then - warn "New config was not added to bootloader." + warn "New config was not added to bootloader." fi fi } @@ -102,10 +102,10 @@ pkgs.writeShellScriptBin "rebuild" # sh hostnames=$(nix flake show --all-systems --json | , jq -r '.nixosConfigurations | keys | .[]') for host in ''${hostnames[@]}; do info "Checking if $host is reachable..." - if ping -c 1 -W 1 "$host" > /dev/null 2>&1 ; then + if ping -c 1 -W 1 "$host" > /dev/null 2>&1 ; then info "$host is reachable." reachable_hosts+=("$host") - else + else warn "$host is unreachable." fi done diff --git a/nix/homes/rafiq/default.nix b/nix/homes/rafiq/default.nix new file mode 100644 index 0000000..ed01690 --- /dev/null +++ b/nix/homes/rafiq/default.nix @@ -0,0 +1,145 @@ +{ lib, inputs, ... }: +let + inherit (lib.strings) concatStrings; +in +{ + flake.modules.homeManager.rafiq = + { pkgs, ... }: + { + imports = [ + inputs.nvf.homeManagerModules.default + inputs.nix-index-database.hmModules.nix-index + ]; + persistDirs = [ + ".local/share/zoxide" + "notebook" + ]; + xdg.configFile."aichat/config.yaml".text = '' + model: gemini:gemini-2.0-flash + clients: + - type: gemini + ''; + home = { + sessionVariables = { + EDITOR = "nvim"; + FETCH = "hyfetch"; + FILE_BROWSER = "yazi"; + SHELL = "fish"; + }; + shellAliases = { + fetch = "hyfetch"; + windows = "sudo systemctl reboot --boot-loader-entry=auto-windows"; + v = "$EDITOR"; + e = "edit"; + cd = "z"; # zoxide + ai = "aichat -r %shell% -e"; + }; + packages = with pkgs; [ + fastfetch + ripgrep + aichat + (import ./_scripts/edit.nix { inherit pkgs; }) + (import ./_scripts/commit.nix { inherit pkgs; }) + (import ./_scripts/note.nix { inherit pkgs; }) + (import ./_scripts/rebuild.nix { inherit pkgs; }) + ]; + }; + programs = { + nvf.enable = true; + nvf.settings.vim = { + syntaxHighlighting = true; + hideSearchHighlight = true; + searchCase = "ignore"; + undoFile.enable = true; + telescope.enable = true; + fzf-lua.enable = true; + git.enable = true; + autopairs.nvim-autopairs.enable = true; + autocomplete = import ./_nvf/autocomplete.nix { inherit lib; }; + binds = import ./_nvf/binds.nix; + languages = import ./_nvf/languages.nix; + lsp = import ./_nvf/lsp.nix; + navigation = import ./_nvf/navigation.nix; + notes.todo-comments.enable = true; + options = { + autoindent = true; + backspace = "indent,eol,start"; + cursorline = true; + expandtab = true; + shiftwidth = 2; + smartindent = true; + tabstop = 2; + }; + snippets = import ./_nvf/snippets.nix { inherit pkgs; }; + statusline = import ./_nvf/statusline.nix; + treesitter = { + autotagHtml = true; + fold = true; + indent.disable = [ "markdown" ]; + textobjects.enable = true; + }; + ui = import ./_nvf/ui.nix; + utility = import ./_nvf/utility.nix; + visuals = import ./_nvf/visuals.nix; + }; + zk = { + enable = true; + settings.notebook.dir = "~/notebook"; + }; + hyfetch = { + enable = true; + settings = { + preset = "bisexual"; + mode = "rgb"; + light_dark = "dark"; + lightness = 0.5; + color_align = { + # Flag color alignment + mode = "horizontal"; + fore_back = null; + }; + backend = "fastfetch"; + }; + }; + + tealdeer.enable = true; + tealdeer.enableAutoUpdates = true; + direnv = { + enable = true; + nix-direnv.enable = true; + }; + zoxide.enable = true; + nix-index.enable = true; + nix-index-database.comma.enable = true; + fzf.enable = true; + fzf.enableZshIntegration = true; + yazi = { + enable = true; + shellWrapperName = "t"; + settings.mgr.sort_by = "natural"; + }; + fish.enable = true; + starship = { + enable = true; + settings = { + add_newline = false; + format = concatStrings [ + # First Line + ## Left Prompt + "$hostname$directory" + "$fill" + ## Right Prompt + "$all" + # Second Line + ## Left Prompt + "$character" + ]; + git_branch.format = "[$symbol$branch(:$remote_branch)]($style) "; + shlvl.disabled = false; + username.disabled = true; + fill.symbol = " "; + }; + }; + }; + }; +} diff --git a/homes/x86_64-linux/rafiq/desktop/window-manager/_hyprland/decoration.nix b/nix/homes/rafiq/desktop/_hyprland/decoration.nix similarity index 100% rename from homes/x86_64-linux/rafiq/desktop/window-manager/_hyprland/decoration.nix rename to nix/homes/rafiq/desktop/_hyprland/decoration.nix diff --git a/homes/x86_64-linux/rafiq/desktop/window-manager/_hyprland/keybinds.nix b/nix/homes/rafiq/desktop/_hyprland/keybinds.nix similarity index 100% rename from homes/x86_64-linux/rafiq/desktop/window-manager/_hyprland/keybinds.nix rename to nix/homes/rafiq/desktop/_hyprland/keybinds.nix diff --git a/nix/homes/rafiq/desktop/default.nix b/nix/homes/rafiq/desktop/default.nix new file mode 100644 index 0000000..9eb1fc4 --- /dev/null +++ b/nix/homes/rafiq/desktop/default.nix @@ -0,0 +1,288 @@ +{ + lib, + inputs, + config, + ... +}: +let + cfg = config.flake; +in +{ + allowedUnfreePackages = [ + "stremio-shell" + "stremio-server" + "steam" + "steam-unwrapped" + ]; + flake.modules.nixos.graphical = + { config, pkgs, ... }: + { + fonts.packages = [ pkgs.font-awesome ]; + services.getty.autologinUser = cfg.admin.username; + # Start Hyprland at boot only if not connecting through SSH + environment.loginShellInit = # sh + '' + if [[ -z "$SSH_CLIENT" && -z "$SSH_CONNECTION" ]]; then + if uwsm check may-start; then + exec uwsm start hyprland-uwsm.desktop + fi + fi + ''; + environment.variables = { + # Get Electron apps to use Wayland + ELECTRON_OZONE_PLATFORM_HINT = "auto"; + NIXOS_OZONE_WL = "1"; + }; + programs = { + hyprland = { + enable = true; + # Use UWSM to have each process controlled by systemd init + withUWSM = true; + }; + steam = { + enable = true; + gamescopeSession.enable = true; + }; + }; + security.pam.services.hyprlock = { }; + services.sunshine = { + enable = true; + capSysAdmin = true; + openFirewall = true; + settings = { + sunshine_name = config.networking.hostName; + origin_pin_allowed = "wan"; + origin_web_ui_allowed = "wan"; + }; + applications = { }; + }; + # spotifyd + networking.firewall.allowedTCPPorts = [ 5353 ]; + networking.firewall.allowedUDPPorts = [ 5353 ]; + }; + flake.modules.homeManager.rafiq = + { + pkgs, + config, + hostName, + hostConfig, + ... + }: + let + inherit (lib.modules) mkMerge mkIf; + inherit (builtins) map listToAttrs; + inherit (lib.lists) findFirstIndex; + inherit (inputs.nur.legacyPackages.${pkgs.stdenv.hostPlatform.system}.repos.rycee) firefox-addons; + profiles = listToAttrs ( + map (name: { + inherit name; + # If there are duplicate profile names, findFirstIndex will cause issues. + value = profileCfg (findFirstIndex (x: x == name) null syncedProfiles); + }) syncedProfiles + ); + syncedProfiles = [ + "rafiq" + "test" + ]; + profileCfg = id: { + inherit id; + settings."extensions.autoDisableScopes" = 0; # Auto enable extensions + extensions = { + force = true; + packages = with firefox-addons; [ + darkreader + gesturefy + sponsorblock + ublock-origin + ]; + }; + }; + in + mkIf config.graphical { + stylix = { + image = ./wallpaper.png; + targets = { + firefox.colorTheme.enable = true; + firefox.profileNames = syncedProfiles; + waybar.addCss = false; + }; + }; + persistDirs = [ + "docs" + "repos" + "vids" + "tmp" + ".cache/Smart Code ltd/Stremio" + ".local/share/Smart Code ltd/Stremio" + ".mozilla/firefox" + ".tor project" + ".local/share/Steam" + ".local/share/PrismLauncher" + ".config/sunshine" + ]; + home = { + packages = with pkgs; [ + prismlauncher + stremio + tor-browser + vlc + wl-clipboard-rs + ]; + sessionVariables = { + BROWSER = "firefox"; + LAUNCHER = "fuzzel"; + LOCKSCREEN = "hyprlock"; + NOTIFICATION_DAEMON = "mako"; + TERMINAL = "ghostty"; + STATUS_BAR = "waybar"; + }; + }; + programs = { + fuzzel.enable = true; + obs-studio.enable = true; + vesktop.enable = true; + thunderbird.enable = true; + thunderbird.profiles.rafiq.isDefault = true; + firefox = { + enable = true; + inherit profiles; + }; + hyprlock = { + enable = true; + settings = { + general.hide_cursor = true; + general.ignore_empty_input = true; + background.blur_passes = 5; + background.blur_size = 5; + label = { + text = ''hi, $USER.''; + font_size = 32; + position = "0, 0"; + halign = "center"; + valign = "center"; + zindex = 1; + shadow_passes = 5; + shadow_size = 5; + }; + input-field = { + placeholder_text = ""; + fade_on_empty = true; + size = "200, 45"; + position = "0, -5%"; + halign = "center"; + valign = "center"; + zindex = 1; + shadow_passes = 5; + shadow_size = 5; + }; + }; + }; + ghostty = { + enable = true; + settings = { + confirm-close-surface = false; + }; + }; + waybar = { + enable = true; + settings = [ + { + layer = "top"; + modules-left = [ + "pulseaudio" + ]; + modules-right = [ + "battery" + "clock" + ]; + "pulseaudio" = { + format = "{icon} {volume}%"; + format-muted = ""; + format-icons.default = [ + "" + "" + ]; + on-click = "${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle"; + }; + "clock" = { + interval = 1; + format = "{:%F %T}"; + }; + "battery" = { + interval = 1; + bat-compatibility = true; + }; + } + ]; + style = # css + '' + window#waybar { + background-color: rgba(0, 0, 0, 0); + } + + #pulseaudio, + #battery, + #clock { + padding-top: 5px; + padding-bottom: 5px; + padding-right: 5px; + color: #ffffff; + } + ''; + }; + + }; + services = { + spotifyd.enable = true; + spotifyd.settings.global = { + device_name = "${hostName}"; + device_type = "computer"; + zeroconf_port = 5353; + }; + + mako.enable = true; + mako.settings.default-timeout = 10000; + + }; + wayland.windowManager.hyprland = { + enable = true; + # This is needed for UWSM + systemd.enable = false; + # Null the packages since we use them system wide + package = null; + portalPackage = null; + settings = mkMerge [ + (import ./_hyprland/decoration.nix) + (import ./_hyprland/keybinds.nix { inherit pkgs; }) + { + ecosystem.no_update_news = true; + xwayland.force_zero_scaling = true; + monitor = + let + mainMonitor = hostConfig.machine.monitors.main; + in + [ + "${mainMonitor.id}, ${mainMonitor.resolution}@${mainMonitor.refresh-rate}, auto, ${mainMonitor.scale}" + ", preferred, auto, 1" + ]; + exec-once = [ + "uwsm app -- $LOCKSCREEN" + "uwsm app -- $NOTIFICATION_DAEMON" + "uwsm app -- $STATUS_BAR" + ]; + } + ]; + }; + # xdg.configFile."uwsm/env".text = # sh + # '' + # # Force apps to scale right with Wayland + # export GDK_SCALE=${mainMonitor.scale} + # export STEAM_FORCE_DESKTOPUI_SCALING=${mainMonitor.scale} + # ''; + # xdg.configFile."uwsm/env-hyprland".text = # sh + # '' + # export GDK_SCALE=${mainMonitor.scale} + # export STEAM_FORCE_DESKTOPUI_SCALING=${mainMonitor.scale} + # ''; + }; +} diff --git a/homes/x86_64-linux/rafiq/desktop/wallpaper.png b/nix/homes/rafiq/desktop/wallpaper.png similarity index 100% rename from homes/x86_64-linux/rafiq/desktop/wallpaper.png rename to nix/homes/rafiq/desktop/wallpaper.png diff --git a/nix/homes/rafiq/git.nix b/nix/homes/rafiq/git.nix new file mode 100644 index 0000000..fd6d21d --- /dev/null +++ b/nix/homes/rafiq/git.nix @@ -0,0 +1,23 @@ +{ + flake.modules.homeManager.rafiq = { + home.shellAliases = { + gs = "git status"; + gc = "git commit"; + gcam = "git commit -am"; + gu = "git push"; + gy = "git pull"; + gdh = "git diff HEAD"; + }; + programs.git = { + enable = true; + signing.signByDefault = true; + extraConfig = { + init.defaultBranch = "prime"; + push.autoSetupRemote = true; + pull.rebase = false; + core.editor = "$EDITOR"; + gpg.format = "ssh"; + }; + }; + }; +} diff --git a/nix/lib/attrsets.nix b/nix/lib/attrsets.nix new file mode 100644 index 0000000..1361c2a --- /dev/null +++ b/nix/lib/attrsets.nix @@ -0,0 +1,54 @@ +{ lib, ... }: +let + inherit (builtins) attrNames head; + inherit (lib.trivial) pipe; + inherit (lib.attrsets) filterAttrs; +in +{ + flake.lib.attrsets = { + /** + `firstAttrNameMatching pred set` filters an attribute set `set` based on a predicate `pred` + and returns the *first* attribute name that satisfies the predicate. + + # Example + + ```nix + let + mySet = { + a = { value = 1; }; + b = { value = 2; }; + c = { value = 3; }; + }; + + isGreaterThanOne = name: value: value.value > 1; + + result = firstAttrNameMatching isGreaterThanOne mySet; + + in + result + # Output: "b" + ``` + + # Type + + ``` + firstAttrNameMatching :: (String -> Any -> Bool) -> AttrSet -> String + ``` + + # Arguments + + pred + : A function that takes an attribute name and its value and returns a boolean. + + set + : The attribute set to filter. + */ + firstAttrNameMatching = + pred: set: + pipe set [ + (filterAttrs pred) + attrNames + head + ]; + }; +} diff --git a/nix/lib/lists.nix b/nix/lib/lists.nix new file mode 100644 index 0000000..370362f --- /dev/null +++ b/nix/lib/lists.nix @@ -0,0 +1,13 @@ +let + inherit (builtins) length tail; +in +{ + flake.lib.lists = rec { + shortenList = + count: list: + let + len = length list; + in + if len <= count then list else (shortenList count (tail list)); + }; +} diff --git a/nix/lib/modules.nix b/nix/lib/modules.nix new file mode 100644 index 0000000..0d5b50b --- /dev/null +++ b/nix/lib/modules.nix @@ -0,0 +1,101 @@ +{ lib, config, ... }: +let + cfg = config.flake; + inherit (builtins) foldl' attrNames; + inherit (lib.attrsets) mapAttrs; +in +{ + flake.lib.modules = { + /** + Fold over the users list and create an attribute set. + + # Inputs + + `f` + + : A function that takes the name of a user and returns an attribute set. + + # Type + + ``` + userListToAttrs :: (String -> AttrSet) -> AttrSet + ``` + + # Examples + :::{.example} + ## `userListToAttrs` usage example + + ```nix + flake.manifest.users.rafiq = { ... }; + flake.modules.homeManager.users = userListToAttrs (name: { + ${name}.home.username = name; + }); + => flake.modules.homeManager.default.users.rafiq.home.username = "rafiq"; + ``` + + ::: + */ + userListToAttrs = f: foldl' (acc: elem: acc // (f elem)) { } (attrNames cfg.manifest.users); + /** + Return an attribute set for use with a option that needs to be used for all users. + + # Inputs + + `attrset` + + : An attribute set to apply to all the users. + + # Type + + ``` + forAllUsers :: AttrSet -> AttrSet + ``` + + # Examples + :::{.example} + ## `forAllUsers` usage example + + ```nix + flake.manifest.users.rafiq = { ... }; + flake.modules.nixos.default.users = forAllUsers { + isNormalUser = true; + }; + => flake.modules.nixos.default.users.rafiq.isNormalUser = true; + ``` + + ::: + */ + forAllUsers = attrset: mapAttrs (_: _: attrset) cfg.manifest.users; + + /** + Like forAllUsers, but passes in the name and value from the manifest. + + # Inputs + + `f` + + : A function that takes an attribute name and its value, and returns the new value for the attribute. + + # Type + + ``` + forAllUsers' :: (String -> Any -> Any) -> AttrSet + ``` + + # Examples + :::{.example} + ## `forAllUsers'` usage example + + ```nix + flake.manifest.users.rafiq = { ... }; + flake.modules.homeManager.users = forAllUsers' (name: value: { + home.username = name; + }); + => flake.modules.homeManager.default.users.rafiq.home.username = "rafiq"; + ``` + + ::: + */ + forAllUsers' = f: mapAttrs f cfg.manifest.users; + }; +} diff --git a/nix/lib/options.nix b/nix/lib/options.nix new file mode 100644 index 0000000..4d0c329 --- /dev/null +++ b/nix/lib/options.nix @@ -0,0 +1,45 @@ +{ lib, ... }: +let + inherit (lib.options) mkOption; + inherit (lib.types) + str + path + int + port + attrs + ; +in +{ + flake.lib.options = { + mkStrOption = + default: + mkOption { + inherit default; + type = str; + }; + mkAttrOption = + default: + mkOption { + inherit default; + type = attrs; + }; + mkIntOption = + default: + mkOption { + inherit default; + type = int; + }; + mkPortOption = + default: + mkOption { + type = port; + inherit default; + }; + mkPathOption = + default: + mkOption { + type = path; + inherit default; + }; + }; +} diff --git a/nix/lib/services.nix b/nix/lib/services.nix new file mode 100644 index 0000000..7ec6025 --- /dev/null +++ b/nix/lib/services.nix @@ -0,0 +1,69 @@ +{ config, lib, ... }: +let + inherit (builtins) length concatStringsSep; + inherit (lib.options) mkEnableOption; + inherit (lib.strings) splitString; + inherit (lib.lists) singleton; + inherit (lib.modules) mkMerge mkIf; + inherit (cfg.lib.options) mkStrOption mkPortOption mkAttrOption; + inherit (cfg.lib.lists) shortenList; + cfg = config.flake; +in +{ + flake.lib.services = rec { + splitDomain = domain: splitString "." domain; + isRootDomain = domain: length (splitDomain domain) <= 2; + mkRootDomain = domain: concatStringsSep "." (shortenList 2 (splitDomain domain)); + mkWildcardDomain = rootDomain: concatStringsSep "." ((singleton "*") ++ (splitDomain rootDomain)); + mkHost = domain: if isRootDomain domain then domain else mkWildcardDomain (mkRootDomain domain); + mkWebApp = + { + config, + name, + defaultPort, + persistDirs ? [ ], + extraOptions ? { }, + extraConfig ? { }, + }: + let + cfg = config.server.web-apps.${name}; + networkingConfig = + { + config, + cfg, + name, + }: + mkIf (cfg.domain != "") { + assertions = singleton { + assertion = config.server.web-servers.nginx.enable; + message = "You must enable a web server if you want to set server.web-apps.${name}.domain."; + }; + server.ddns.domains = singleton (mkRootDomain cfg.domain); + server.web-servers.nginx.proxies = singleton { + source = cfg.domain; + target = "http://${config.networking.hostName}:${toString cfg.port}"; + }; + }; + + in + { + options.server.web-apps.${name} = { + enable = mkEnableOption ""; + port = mkPortOption defaultPort; + domain = mkStrOption ""; + openFirewall = mkEnableOption ""; + extraCfg = mkAttrOption { }; + } // extraOptions; + + config = mkIf cfg.enable (mkMerge [ + { + inherit persistDirs; + networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = singleton cfg.port; }; + } + (networkingConfig { inherit config cfg name; }) + extraConfig + ]); + }; + + }; +} diff --git a/nix/manifest.nix b/nix/manifest.nix new file mode 100644 index 0000000..0643eb8 --- /dev/null +++ b/nix/manifest.nix @@ -0,0 +1,92 @@ +{ + flake.manifest = { + users.rafiq = { + primary = true; + name = "Mohammad Rafiq"; + email = "rafiq@rrv.sh"; + shell = "fish"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILdsZyY3gu8IGB8MzMnLdh+ClDxQQ2RYG9rkeetIKq8n rafiq"; + }; + hosts.nixos = { + nemesis = { + graphical = true; + machine = { + platform = "amd"; + gpu = "nvidia"; + root.drive = "/dev/disk/by-id/nvme-CT2000P3SSD8_2325E6E77434"; + monitors.main = { + id = "desc:OOO AN-270W04K"; + resolution = "3840x2160"; + refresh-rate = "60"; + scale = "2"; + }; + }; + extraCfg = { + services.fwupd.enable = true; # FIXME: remove + machine = { + bluetooth.enable = true; + usb.automount = true; + virtualisation = { + podman.enable = true; + podman.distrobox.enable = true; + }; + }; + server.web-apps = { + comfy-ui.enable = true; + sd-webui-forge.enable = true; + }; + }; + }; + apollo = { + graphical = false; + machine = { + platform = "intel"; + root.drive = "/dev/disk/by-id/nvme-eui.002538d221b47b01"; + }; + extraCfg.server = { + ddns = { + enable = true; + domains = [ + "aenyrathia.wiki" + "slayment.com" + ]; + }; + web-servers = { + enableSSL = true; + nginx = { + enable = true; + proxies = [ + { + source = "aenyrathia.wiki"; + target = "http://helios:5896"; + } + { + source = "il.bwfiq.com"; + target = "http://helios:2283"; + } + ]; + }; + }; + databases = { + mongodb.enable = true; + mysql.enable = true; + postgresql.enable = true; + }; + web-apps = { + librechat = { + enable = true; + domain = "chat.bwfiq.com"; + }; + forgejo = { + enable = true; + domain = "git.rrv.sh"; + openFirewall = true; + }; + rrv-sh.enable = true; + rrv-sh.domain = "rrv.sh"; + }; + }; + }; + }; + }; +} diff --git a/nix/meta.nix b/nix/meta.nix new file mode 100644 index 0000000..0d95bd7 --- /dev/null +++ b/nix/meta.nix @@ -0,0 +1,101 @@ +{ + lib, + config, + inputs, + ... +}: +let + inherit (lib.options) mkOption mkEnableOption; + inherit (cfg.lib.options) mkStrOption; + inherit (lib.types) + path + lazyAttrsOf + raw + deferredModule + submodule + ; + inherit (inputs.flake-parts.lib) mkSubmoduleOptions; + inherit (cfg.lib.attrsets) firstAttrNameMatching; + cfg = config.flake; + monitorOpts = submodule { + options = { + id = mkStrOption ""; + resolution = mkStrOption ""; + refresh-rate = mkStrOption ""; + scale = mkStrOption ""; + }; + }; + userOpts = submodule { + options = { + username = mkStrOption ""; + primary = mkEnableOption ""; + name = mkStrOption ""; + email = mkStrOption ""; + shell = mkStrOption ""; + pubkey = mkStrOption ""; + }; + }; + hostOpts = submodule { + options = { + graphical = mkEnableOption ""; + machine = { + platform = mkStrOption ""; + gpu = mkStrOption ""; + root.drive = mkStrOption ""; + monitors = mkOption { + type = lazyAttrsOf monitorOpts; + default = { }; + }; + }; + extraCfg = mkOption { + type = deferredModule; + default = { }; + }; + }; + }; +in +{ + options.flake = mkSubmoduleOptions { + lib = mkOption { + type = lazyAttrsOf raw; + default = { }; + }; + paths = { + root = mkOption { type = path; }; + secrets = mkOption { + type = path; + readOnly = true; + }; + }; + manifest = mkOption { + type = submodule { + options = { + users = mkOption { + type = lazyAttrsOf userOpts; + default = { }; + }; + hosts = mkOption { + # hosts.nixos, hosts.darwin, etc. + type = lazyAttrsOf (lazyAttrsOf hostOpts); + default = { }; + }; + }; + }; + }; + # Helper Option + admin = mkOption { + type = userOpts; + default = { }; + }; + }; + config.flake = + let + username = firstAttrNameMatching (_: v: v.primary or false) cfg.manifest.users; + in + { + paths.secrets = cfg.paths.root + "/secrets"; + admin = cfg.manifest.users.${username} // { + inherit username; + }; + }; +} diff --git a/nix/modules/cli/git.nix b/nix/modules/cli/git.nix new file mode 100644 index 0000000..c609a1a --- /dev/null +++ b/nix/modules/cli/git.nix @@ -0,0 +1,17 @@ +{ config, ... }: +let + inherit (config.flake) manifest; +in +{ + flake.modules.homeManager.default = + { config, ... }: + { + home.sessionVariables.GIT_CONFIG_GLOBAL = "$HOME/.config/git/config"; + programs.git = { + enable = true; + userName = manifest.users.${config.home.username}.name; + userEmail = manifest.users.${config.home.username}.email; + signing.key = "~/.ssh/id_ed25519.pub"; + }; + }; +} diff --git a/nix/modules/cli/nix.nix b/nix/modules/cli/nix.nix new file mode 100644 index 0000000..ad97ee5 --- /dev/null +++ b/nix/modules/cli/nix.nix @@ -0,0 +1,6 @@ +{ + flake.modules.nixos.default.nix.settings.experimental-features = [ + "nix-command" + "flakes" + ]; +} diff --git a/nix/modules/cli/shell.nix b/nix/modules/cli/shell.nix new file mode 100644 index 0000000..c28f00b --- /dev/null +++ b/nix/modules/cli/shell.nix @@ -0,0 +1,23 @@ +{ config, lib, ... }: +let + cfg = config.flake; + inherit (cfg.lib.modules) forAllUsers'; + inherit (lib.attrsets) mapAttrs'; +in +{ + flake.modules.nixos.default = + { pkgs, ... }: + { + programs = mapAttrs' (name: value: { + name = value.shell; + value.enable = true; + }) cfg.manifest.users; + users.users = forAllUsers' (_: value: { shell = pkgs.${value.shell}; }); + }; + flake.modules.homeManager.default = + { config, ... }: + { + programs.${cfg.manifest.users.${config.home.username}.shell}.enable = true; + home.shell.enableShellIntegration = true; + }; +} diff --git a/nix/modules/graphical/default.nix b/nix/modules/graphical/default.nix new file mode 100644 index 0000000..c714a2d --- /dev/null +++ b/nix/modules/graphical/default.nix @@ -0,0 +1,14 @@ +{ lib, ... }: +let + inherit (lib.options) mkEnableOption; +in +{ + flake.modules.nixos.graphical = { + home-manager.sharedModules = [ { graphical = true; } ]; + services.pipewire = { + enable = true; + pulse.enable = true; + }; + }; + flake.modules.homeManager.default.options.graphical = mkEnableOption ""; +} diff --git a/nix/modules/graphical/stylix.nix b/nix/modules/graphical/stylix.nix new file mode 100644 index 0000000..c4b3c65 --- /dev/null +++ b/nix/modules/graphical/stylix.nix @@ -0,0 +1,12 @@ +{ inputs, ... }: +{ + # needs to be default because the options get + # evaluated even if graphical is set to false + flake.modules.nixos.default = + { pkgs, ... }: + { + imports = [ inputs.stylix.nixosModules.stylix ]; + stylix.enable = true; + stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-dark-hard.yaml"; + }; +} diff --git a/nix/modules/machine/bootloader.nix b/nix/modules/machine/bootloader.nix new file mode 100644 index 0000000..2fefe52 --- /dev/null +++ b/nix/modules/machine/bootloader.nix @@ -0,0 +1,18 @@ +{ + flake.modules.nixos.default.boot = { + initrd.availableKernelModules = [ + "nvme" + "xhci_pci" + "ahci" + "usbhid" + "usb_storage" + "sd_mod" + ]; + loader.efi.canTouchEfiVariables = true; + #TODO: disable for mbp? + loader.systemd-boot = { + enable = true; + configurationLimit = 5; + }; + }; +} diff --git a/nix/modules/machine/default.nix b/nix/modules/machine/default.nix new file mode 100644 index 0000000..8ad3f7a --- /dev/null +++ b/nix/modules/machine/default.nix @@ -0,0 +1,40 @@ +{ lib, ... }: +let + inherit (lib.options) mkEnableOption; + inherit (lib.modules) mkIf mkMerge; +in +{ + flake.modules.nixos.default = + { config, modulesPath, ... }: + let + cfg = config.machine; + in + { + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + options.machine = { + bluetooth.enable = mkEnableOption ""; + usb.automount = mkEnableOption ""; + }; + config = mkMerge [ + (mkIf cfg.usb.automount { + services.udisks2.enable = true; + home-manager.sharedModules = [ + { + services.udiskie = { + enable = true; + automount = true; + notify = true; + }; + } + ]; + }) + (mkIf cfg.bluetooth.enable { + persistDirs = [ "/var/lib/bluetooth" ]; + hardware.bluetooth = { + enable = true; + settings.General.Experimental = true; + }; + }) + ]; + }; +} diff --git a/nix/modules/machine/gpu.nix b/nix/modules/machine/gpu.nix new file mode 100644 index 0000000..00c56cd --- /dev/null +++ b/nix/modules/machine/gpu.nix @@ -0,0 +1,41 @@ +{ config, ... }: +let + cfg = config.flake; +in +{ + allowedUnfreePackages = [ + "nvidia-x11" + "nvidia-settings" + ]; + flake.modules.nixos.default = + { + config, + pkgs, + hostName, + ... + }: + let + gpu = cfg.manifest.hosts.nixos.${hostName}.machine.gpu or ""; + in + if gpu == "nvidia" then + { + hardware = { + graphics.enable = true; + graphics.extraPackages = [ pkgs.nvidia-vaapi-driver ]; + nvidia.open = true; + nvidia.package = config.boot.kernelPackages.nvidiaPackages.latest; + }; + services.xserver.videoDrivers = [ "nvidia" ]; + environment.variables = { + LIBVA_DRIVER_NAME = "nvidia"; + __GLX_VENDOR_LIBRARY_NAME = "nvidia"; + NVD_BACKEND = "direct"; + }; + nix.settings.substituters = [ "https://cuda-maintainers.cachix.org" ]; + nix.settings.trusted-public-keys = [ + "cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E=" + ]; + } + else + { }; +} diff --git a/nix/modules/machine/platform.nix b/nix/modules/machine/platform.nix new file mode 100644 index 0000000..ae8ab61 --- /dev/null +++ b/nix/modules/machine/platform.nix @@ -0,0 +1,14 @@ +{ config, ... }: +{ + flake.modules.nixos.default = + { hostName, ... }: + let + inherit (config.flake.manifest.hosts.nixos.${hostName}.machine) platform; + arch = if platform == "amd" || platform == "intel" then "x86_64" else "aarch64"; + in + { + hardware.cpu.${platform}.updateMicrocode = true; + boot.kernelModules = [ "kvm-${platform}" ]; + nixpkgs.hostPlatform = "${arch}-linux"; + }; +} diff --git a/nix/modules/machine/root.nix b/nix/modules/machine/root.nix new file mode 100644 index 0000000..98c1120 --- /dev/null +++ b/nix/modules/machine/root.nix @@ -0,0 +1,100 @@ +{ + config, + lib, + inputs, + ... +}: +let + inherit (lib.modules) mkMerge mkIf mkAfter; +in +{ + flake.modules.nixos.default = + { hostName, ... }: + let + inherit (config.flake.manifest.hosts.nixos.${hostName}.machine) root; + in + { + imports = [ inputs.disko.nixosModules.disko ]; + config = mkMerge [ + { + # BTRFS - may add more later on + boot.initrd.kernelModules = [ "dm-snapshot" ]; + disko.devices.disk.main = { + device = root.drive; + content.type = "gpt"; + content.partitions = { + boot = { + name = "boot"; + size = "1M"; + type = "EF02"; + }; + esp = { + name = "ESP"; + size = "500M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + swap = { + size = "4G"; + content = { + type = "swap"; + resumeDevice = true; + }; + }; + root = { + name = "root"; + size = "100%"; + content = { + type = "lvm_pv"; + vg = "root_vg"; + }; + }; + }; + }; + + disko.devices.lvm_vg.root_vg = { + type = "lvm_vg"; + lvs.root = { + size = "100%FREE"; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/root".mountpoint = "/"; + "/persist" = { + mountpoint = "/persist"; + mountOptions = [ + "subvol=persist" + "noatime" + ]; + }; + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ + "subvol=nix" + "noatime" + ]; + }; + }; + }; + }; + }; + } + # Ephemeral by default - assumes btrfs + (mkIf (config.flake.manifest.hosts.nixos.${hostName}.machine.root.ephemeral or true) { + boot.initrd.postDeviceCommands = mkAfter '' + mkdir /btrfs_tmp + mount /dev/root_vg/root /btrfs_tmp + + if [[ -e /btrfs_tmp/root ]]; then + btrfs subvolume delete "/btrfs_tmp/root" + fi + ''; + }) + ]; + }; +} diff --git a/nix/modules/machine/virtualisation.nix b/nix/modules/machine/virtualisation.nix new file mode 100644 index 0000000..81b586e --- /dev/null +++ b/nix/modules/machine/virtualisation.nix @@ -0,0 +1,36 @@ +{ lib, config, ... }: +let + inherit (lib.modules) mkIf; + inherit (lib.options) mkEnableOption; + inherit (lib.lists) optional; + inherit (config.flake.lib.modules) forAllUsers; +in +{ + flake.modules.nixos.default = + { pkgs, config, ... }: + let + cfg = config.machine.virtualisation; + in + { + options.machine.virtualisation = { + podman.enable = mkEnableOption ""; + podman.distrobox.enable = mkEnableOption ""; + }; + config = mkIf cfg.podman.enable { + virtualisation.containers.enable = true; + virtualisation.podman = { + enable = true; + dockerCompat = true; + defaultNetwork.settings.dns_enabled = true; + }; + users.users = forAllUsers { + extraGroups = [ "podman" ]; + autoSubUidGidRange = cfg.podman.distrobox.enable; + }; + home-manager.sharedModules = optional cfg.podman.distrobox.enable { + home.packages = [ pkgs.distrobox ]; + persistDirs = [ ".local/share/containers" ]; + }; + }; + }; +} diff --git a/nix/modules/networking/default.nix b/nix/modules/networking/default.nix new file mode 100644 index 0000000..435e501 --- /dev/null +++ b/nix/modules/networking/default.nix @@ -0,0 +1,16 @@ +{ lib, ... }: +let + inherit (lib.modules) mkDefault; +in +{ + flake.modules.nixos.default = + { hostName, ... }: + { + networking = { + inherit hostName; + enableIPv6 = false; + useDHCP = mkDefault true; + networkmanager.enable = true; + }; + }; +} diff --git a/nix/modules/networking/ssh.nix b/nix/modules/networking/ssh.nix new file mode 100644 index 0000000..d721746 --- /dev/null +++ b/nix/modules/networking/ssh.nix @@ -0,0 +1,29 @@ +{ config, lib, ... }: +let + cfg = config.flake; + inherit (lib.modules) mkMerge; + inherit (cfg.lib.modules) forAllUsers'; +in +{ + flake.modules.nixos.default = mkMerge [ + { + services.openssh.enable = true; + users.users = forAllUsers' (_: value: { openssh.authorizedKeys.keys = [ value.pubkey ]; }); + persistFiles = [ + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + ]; + } + { users.users.root.openssh.authorizedKeys.keys = [ cfg.admin.pubkey ]; } + ]; + flake.modules.homeManager.default = { + persistDirs = [ ".ssh" ]; + programs.ssh.enable = true; + programs.ssh.extraConfig = '' + Host * + SetEnv TERM=xterm-256color + ''; + }; +} diff --git a/nix/modules/networking/tailscale.nix b/nix/modules/networking/tailscale.nix new file mode 100644 index 0000000..ddf1b9a --- /dev/null +++ b/nix/modules/networking/tailscale.nix @@ -0,0 +1,17 @@ +{ config, ... }: +let + inherit (config.flake.paths) secrets; +in +{ + flake.modules.nixos.default = + { config, ... }: + { + services.tailscale = { + enable = true; + authKeyFile = config.sops.secrets."tailscale/client-secret".path; + authKeyParameters.preauthorized = true; + }; + persistDirs = [ "/var/lib/tailscale" ]; + sops.secrets."tailscale/client-secret".sopsFile = secrets + "/tailscale.yaml"; + }; +} diff --git a/nix/modules/server/databases.nix b/nix/modules/server/databases.nix new file mode 100644 index 0000000..2827b9d --- /dev/null +++ b/nix/modules/server/databases.nix @@ -0,0 +1,90 @@ +{ lib, config, ... }: +let + inherit (builtins) toString; + inherit (lib.modules) mkIf mkMerge mkOverride; + inherit (lib.lists) singleton; + inherit (lib.options) mkEnableOption; + inherit (config.flake.lib.options) mkPortOption; +in +{ + allowedUnfreePackages = [ "mongodb" ]; + flake.modules.nixos.default = + { config, pkgs, ... }: + let + cfg = config.server.databases; + in + { + options.server.databases = { + mongodb = { + enable = mkEnableOption "the MongoDB server"; + port = mkPortOption 27017; + }; + mysql = { + enable = mkEnableOption "the MySQL server"; + port = mkPortOption 3306; + }; + postgresql = { + enable = mkEnableOption "the postgresql server"; + port = mkPortOption 5432; + }; + }; + + config = mkMerge [ + (mkIf cfg.postgresql.enable { + networking.firewall.allowedTCPPorts = singleton cfg.postgresql.port; + persistDirs = singleton { + directory = toString config.services.postgresql.dataDir; + user = "postgres"; + group = "postgres"; + }; + services.postgresql = { + enable = true; + enableTCPIP = true; + settings = { inherit (cfg.postgresql) port; }; + authentication = mkOverride 10 '' + #type database DBuser auth-method + local all all trust + + # ipv4 + host all all 0.0.0.0/0 trust + ''; + ensureDatabases = singleton "alphastory"; + ensureUsers = singleton { + name = "alphastory"; + ensureDBOwnership = true; + }; + }; + }) + (mkIf cfg.mongodb.enable { + networking.firewall.allowedTCPPorts = [ cfg.mongodb.port ]; + persistDirs = singleton { + directory = toString config.services.mongodb.dbpath; + user = "mongodb"; + group = "mongodb"; + }; + services.mongodb = { + enable = true; + bind_ip = "0.0.0.0"; + extraConfig = '' + net.port: ${toString cfg.mongodb.port} + ''; + }; + }) + (mkIf cfg.mysql.enable { + networking.firewall.allowedTCPPorts = [ cfg.mysql.port ]; + persistDirs = singleton { + directory = toString config.services.mysql.dataDir; + user = "mysql"; + group = "mysql"; + }; + services.mysql = { + enable = true; + package = pkgs.mariadb; + settings.mysqld = { + inherit (cfg.mysql) port; + }; + }; + }) + ]; + }; +} diff --git a/nix/modules/server/ddns.nix b/nix/modules/server/ddns.nix new file mode 100644 index 0000000..40a03ea --- /dev/null +++ b/nix/modules/server/ddns.nix @@ -0,0 +1,59 @@ +{ lib, config, ... }: +let + inherit (lib.modules) mkIf; + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.types) enum str listOf; + inherit (lib.lists) unique; + inherit (builtins) map; + inherit (config.flake.paths) secrets; +in +{ + flake.modules.nixos.default = + { config, ... }: + let + cfg = config.server.ddns; + mkDomain = domain_name: { + inherit domain_name; + sub_domains = [ + "@" + "*" + ]; + }; + in + { + options.server.ddns = { + enable = mkEnableOption ""; + type = mkOption { + type = enum [ "godns" ]; + default = "godns"; + }; + domains = mkOption { + type = listOf str; + default = [ ]; + }; + }; + + config = mkIf cfg.enable { + sops.secrets."keys/cloudflare".sopsFile = secrets + "/keys.yaml"; + services.godns = { + enable = if (cfg.type == "godns") then true else false; + loadCredential = [ "cf_token:${config.sops.secrets."keys/cloudflare".path}" ]; + settings = { + provider = "Cloudflare"; + login_token_file = "$CREDENTIALS_DIRECTORY/cf_token"; + # Sanitize the list of domains with unique so we can add to it with every service. + domains = map mkDomain (unique cfg.domains); + resolver = "1.1.1.1"; + ip_urls = [ + "https://wtfismyip.com/text" + "https://api.ipify.org" + "https://myip.biturl.top" + "https://api-ipv4.ip.sb/ip" + ]; + ip_type = "IPv4"; + interval = 300; + }; + }; + }; + }; +} diff --git a/nix/modules/server/web-apps/comfy-ui.nix b/nix/modules/server/web-apps/comfy-ui.nix new file mode 100644 index 0000000..738e2e5 --- /dev/null +++ b/nix/modules/server/web-apps/comfy-ui.nix @@ -0,0 +1,34 @@ +{ + lib, + config, + inputs, + ... +}: +let + inherit (lib.lists) singleton; + inherit (config.flake.lib.services) mkWebApp; +in +{ + flake.modules.nixos.default = + { config, ... }: + let + upstreamCfg = config.services.comfyUi; + in + mkWebApp { + inherit config; + name = "comfy-ui"; + defaultPort = 8188; + persistDirs = singleton { + directory = upstreamCfg.dataDir; + inherit (upstreamCfg) user group; + mode = "777"; + }; + extraConfig.services.comfyUi = { + enable = true; + listenHost = "0.0.0.0"; + }; + } + // { + imports = [ inputs.stable-diffusion-webui-nix.nixosModules.default ]; + }; +} diff --git a/nix/modules/server/web-apps/forgejo.nix b/nix/modules/server/web-apps/forgejo.nix new file mode 100644 index 0000000..5beb028 --- /dev/null +++ b/nix/modules/server/web-apps/forgejo.nix @@ -0,0 +1,47 @@ +{ lib, config, ... }: +let + inherit (lib.lists) singleton optional; + inherit (config.flake.lib.options) mkPortOption; + inherit (config.flake.lib.services) mkWebApp; +in +{ + flake.modules.nixos.default = + { config, ... }: + let + cfg = config.server.web-apps.forgejo; + upstreamCfg = config.services.forgejo; + in + mkWebApp { + inherit config; + name = "forgejo"; + defaultPort = 3000; + persistDirs = singleton { + directory = upstreamCfg.stateDir; + inherit (upstreamCfg) user group; + }; + extraOptions = { + sshPort = mkPortOption 2222; + }; + extraConfig = { + networking.firewall.allowedTCPPorts = optional cfg.openFirewall cfg.sshPort; + services.forgejo = { + enable = true; + settings = { + server = { + DOMAIN = cfg.domain; + ROOT_URL = "https://${cfg.domain}/"; + HTTP_PORT = cfg.port; + START_SSH_SERVER = true; + SSH_PORT = cfg.sshPort; + }; + repository = { + USE_COMPAT_SSH_URI = false; + ENABLE_PUSH_CREATE_USER = true; + ENABLE_PUSH_CREATE_ORG = true; + }; + "repository.signing".FORMAT = "ssh"; + }; + }; + }; + }; +} diff --git a/nix/modules/server/web-apps/librechat.nix b/nix/modules/server/web-apps/librechat.nix new file mode 100644 index 0000000..63d2efa --- /dev/null +++ b/nix/modules/server/web-apps/librechat.nix @@ -0,0 +1,87 @@ +{ + lib, + inputs, + config, + ... +}: +let + inherit (lib.lists) singleton; + inherit (config.flake.lib.options) mkStrOption; + inherit (config.flake.lib.services) mkWebApp; + inherit (config.flake.paths) secrets; +in +{ + flake.modules.nixos.default = + { config, ... }: + let + cfg = config.server.web-apps.librechat; + upstreamCfg = config.services.librechat; + in + mkWebApp { + inherit config; + name = "librechat"; + defaultPort = 3080; + persistDirs = singleton { + directory = upstreamCfg.dataDir; + inherit (upstreamCfg) user group; + }; + extraOptions.mongodbURI = mkStrOption "mongodb://${config.networking.hostName}:27017/LibreChat"; + extraConfig = { + sops.secrets = { + "librechat/creds_key".sopsFile = secrets + "/librechat.yaml"; + "librechat/creds_iv".sopsFile = secrets + "/librechat.yaml"; + "librechat/jwt_secret".sopsFile = secrets + "/librechat.yaml"; + "librechat/jwt_refresh_secret".sopsFile = secrets + "/librechat.yaml"; + "keys/gemini".sopsFile = secrets + "/keys.yaml"; + "keys/openrouter".sopsFile = secrets + "/keys.yaml"; + }; + services.librechat = { + enable = true; + openFirewall = true; + inherit (cfg) port; + env = { + HOST = "0.0.0.0"; + ALLOW_REGISTRATION = "true"; + NO_INDEX = "true"; + MONGO_URI = cfg.mongodbURI; + DOMAIN_CLIENT = cfg.domain; + DOMAIN_SERVER = cfg.domain; + ENDPOINTS = "anthropic,agents,google"; + }; + credentials = { + CREDS_KEY = config.sops.secrets."librechat/creds_key".path; + CREDS_IV = config.sops.secrets."librechat/creds_iv".path; + JWT_SECRET = config.sops.secrets."librechat/jwt_secret".path; + JWT_REFRESH_SECRET = config.sops.secrets."librechat/jwt_refresh_secret".path; + OPENROUTER_KEY = config.sops.secrets."keys/openrouter".path; + GOOGLE_KEY = config.sops.secrets."keys/gemini".path; + }; + settings = { + version = "1.1.4"; + cache = true; + endpoints.custom = [ + { + name = "OpenRouter"; + apiKey = "\${OPENROUTER_KEY}"; + baseURL = "https://openrouter.ai/api/v1"; + models.default = [ "meta-llama/llama-3-70b-instruct" ]; + models.fetch = true; + titleConvo = true; + titleModel = "current_model"; + modelDisplayLabel = "OpenRouter"; + } + ]; + interface = { + privacyPolicy = { + externalUrl = "https://librechat.ai/privacy-policy"; + openNewTab = true; + }; + }; + }; + }; + }; + } + // { + imports = singleton "${inputs.rrvsh-nixpkgs}/nixos/modules/services/web-apps/librechat.nix"; + }; +} diff --git a/nix/modules/server/web-apps/rrv-sh.nix b/nix/modules/server/web-apps/rrv-sh.nix new file mode 100644 index 0000000..d4c801d --- /dev/null +++ b/nix/modules/server/web-apps/rrv-sh.nix @@ -0,0 +1,23 @@ +{ config, inputs, ... }: +let + inherit (config.flake.lib.services) mkWebApp; +in +{ + flake.modules.nixos.default = + { config, ... }: + let + cfg = config.server.web-apps.rrv-sh; + in + mkWebApp { + inherit config; + name = "rrv-sh"; + defaultPort = 2309; + extraConfig.services.rrv-sh = { + enable = true; + inherit (cfg) port; + }; + } + // { + imports = [ inputs.rrv-sh.nixosModules.default ]; + }; +} diff --git a/nix/modules/server/web-apps/sd-webui-forge.nix b/nix/modules/server/web-apps/sd-webui-forge.nix new file mode 100644 index 0000000..cf88d86 --- /dev/null +++ b/nix/modules/server/web-apps/sd-webui-forge.nix @@ -0,0 +1,34 @@ +{ + lib, + inputs, + config, + ... +}: +let + inherit (lib.lists) singleton; + inherit (config.flake.lib.services) mkWebApp; +in +{ + flake.modules.nixos.default = + { config, ... }: + let + upstreamCfg = config.services.sd-webui-forge; + in + mkWebApp { + inherit config; + name = "sd-webui-forge"; + defaultPort = 7860; + persistDirs = singleton { + directory = upstreamCfg.dataDir; + inherit (upstreamCfg) user group; + }; + extraConfig.services.sd-webui-forge = { + enable = true; + listen = true; + extraArgs = "--cuda-malloc"; + }; + } + // { + imports = [ inputs.stable-diffusion-webui-nix.nixosModules.default ]; + }; +} diff --git a/nix/modules/server/web-servers.nix b/nix/modules/server/web-servers.nix new file mode 100644 index 0000000..1967268 --- /dev/null +++ b/nix/modules/server/web-servers.nix @@ -0,0 +1,142 @@ +{ lib, config, ... }: +let + inherit (builtins) listToAttrs map; + inherit (config.flake.lib.options) mkStrOption mkPathOption; + inherit (config.flake.lib.services) mkRootDomain; + inherit (config.flake.paths) secrets; + inherit (config.flake.admin) email; + inherit (lib.types) listOf submodule attrs; + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.modules) mkMerge mkIf; + inherit (lib.lists) singleton; +in +{ + flake.modules.nixos.default = + { config, ... }: + let + cfg = config.server.web-servers; + sslCheck = good: bad: if cfg.enableSSL then good else bad; + in + { + options.server.web-servers = { + enableSSL = mkEnableOption ""; + nginx = { + enable = mkEnableOption "the Nginx server"; + openFirewall = mkEnableOption "" // { + default = true; + }; + enableDefaultSink = mkEnableOption "" // { + default = true; + }; + pages = mkOption { + default = [ ]; + type = listOf (submodule { + options = { + domain = mkStrOption ""; + root = mkPathOption ""; + extraConfig = mkOption { + type = attrs; + default = { }; + }; + locations = mkOption { + type = attrs; + default = { }; + }; + }; + }); + }; + proxies = mkOption { + default = [ ]; + type = listOf (submodule { + options = { + source = mkStrOption ""; + target = mkStrOption ""; + extraConfig = mkOption { + type = attrs; + default = { }; + }; + locations = mkOption { + type = attrs; + default = { }; + }; + }; + }); + }; + }; + }; + config = mkMerge [ + (mkIf cfg.enableSSL { + sops.secrets."keys/cloudflare".sopsFile = secrets + "/keys.yaml"; + security.acme = { + acceptTerms = true; + defaults = { + inherit email; + dnsProvider = "cloudflare"; + credentialFiles."CLOUDFLARE_DNS_API_TOKEN_FILE" = config.sops.secrets."keys/cloudflare".path; + }; + certs = { + "rrv.sh".extraDomainNames = singleton "*.rrv.sh"; + "bwfiq.com".extraDomainNames = singleton "*.bwfiq.com"; + "slayment.com".extraDomainNames = singleton "*.slayment.com"; + "aenyrathia.wiki".extraDomainNames = singleton "*.aenyrathia.wiki"; + }; + }; + }) + (mkIf cfg.nginx.enable { + networking.firewall.allowedTCPPorts = mkIf cfg.nginx.openFirewall [ + 443 + 80 + ]; + users.users.nginx.extraGroups = singleton "acme"; + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + virtualHosts = mkMerge [ + (mkIf cfg.nginx.enableDefaultSink { + "_" = { + default = true; + rejectSSL = sslCheck true false; + locations."/" = { + return = "444"; + }; + }; + }) + (listToAttrs ( + map (page: { + name = page.domain; + value = { + addSSL = sslCheck true false; + useACMEHost = sslCheck (mkRootDomain page.domain) null; + acmeRoot = null; # needed for DNS validation + locations = { + "/" = { + inherit (page) root; + } // page.extraConfig; + } // page.locations; + }; + }) cfg.nginx.pages + )) + (listToAttrs ( + map (proxy: { + name = proxy.source; + value = { + addSSL = sslCheck true false; + useACMEHost = sslCheck (mkRootDomain proxy.source) null; + acmeRoot = null; # needed for DNS validation + locations = { + "/" = { + proxyPass = proxy.target; + } // proxy.extraConfig; + } // proxy.locations; + }; + }) cfg.nginx.proxies + )) + ]; + }; + }) + ]; + }; +} diff --git a/nix/modules/system/persist.nix b/nix/modules/system/persist.nix new file mode 100644 index 0000000..4e298c0 --- /dev/null +++ b/nix/modules/system/persist.nix @@ -0,0 +1,63 @@ +{ + lib, + inputs, + config, + ... +}: +let + inherit (lib.options) mkOption; + inherit (config.flake.lib.options) mkStrOption; + inherit (lib.types) + listOf + str + coercedTo + submodule + ; + permOpts = { + user = mkStrOption "root"; + group = mkStrOption "root"; + mode = mkStrOption "0755"; + }; + mkOpts = + type: opts: + mkOption { + default = [ ]; + type = listOf ( + coercedTo str (d: { ${type} = d; }) (submodule { + options = { + ${type} = mkStrOption ""; + } // opts; + }) + ); + }; +in +{ + flake.modules.nixos.default = + { config, ... }: + { + imports = [ inputs.impermanence.nixosModules.impermanence ]; + options.persistDirs = mkOpts "directory" permOpts; + options.persistFiles = mkOpts "file" { parentDirectory = permOpts; }; + config = { + programs.fuse.userAllowOther = true; + fileSystems."/persist".neededForBoot = true; + environment.persistence."/persist" = { + hideMounts = true; + directories = config.persistDirs; + files = config.persistFiles; + }; + }; + }; + flake.modules.homeManager.default = + { config, ... }: + { + imports = [ inputs.impermanence.homeManagerModules.impermanence ]; + options.persistDirs = mkOpts "directory" { }; + options.persistFiles = mkOpts "file" { }; + config.home.persistence."/persist${config.home.homeDirectory}" = { + allowOther = true; + directories = config.persistDirs; + files = config.persistFiles; + }; + }; +} diff --git a/nix/modules/system/secrets.nix b/nix/modules/system/secrets.nix new file mode 100644 index 0000000..ff90532 --- /dev/null +++ b/nix/modules/system/secrets.nix @@ -0,0 +1,50 @@ +{ + config, + inputs, + lib, + ... +}: +let + cfg = config.flake; + inherit (builtins) readFile; + inherit (lib.meta) getExe; + inherit (lib.strings) trim; + inherit (cfg.admin) username pubkey; +in +{ + flake.modules.nixos.default = + { config, ... }: + { + imports = [ inputs.sops-nix.nixosModules.sops ]; + config.sops.age.sshKeyPaths = [ + "/persist${config.users.defaultUserHome}/${username}/.ssh/id_ed25519" + ]; + }; + flake.modules.homeManager.default.persistDirs = [ ".config/sops/age" ]; + perSystem = + { pkgs, ... }: + { + files.files = [ + { + path_ = ".sops.yaml"; + drv = + pkgs.writeText ".sops.yaml" # yaml + '' + keys: + - &${username} ${trim ( + readFile "${ + pkgs.runCommand "" { } '' + mkdir $out; echo ${pubkey} | ${getExe pkgs.ssh-to-age} > $out/agepubkey + '' + }/agepubkey" + )} + creation_rules: + - path_regex: \.(yaml)$ + key_groups: + - age: + - *${username} + ''; + } + ]; + }; +} diff --git a/nix/modules/system/sudo.nix b/nix/modules/system/sudo.nix new file mode 100644 index 0000000..1c9b560 --- /dev/null +++ b/nix/modules/system/sudo.nix @@ -0,0 +1,11 @@ +{ config, ... }: +let + cfg = config.flake; +in +{ + flake.modules.nixos.default = { + security.sudo.wheelNeedsPassword = false; + nix.settings.trusted-users = [ "@wheel" ]; + users.users.${cfg.admin.username}.extraGroups = [ "wheel" ]; + }; +} diff --git a/nix/modules/system/system.nix b/nix/modules/system/system.nix new file mode 100644 index 0000000..15342b1 --- /dev/null +++ b/nix/modules/system/system.nix @@ -0,0 +1,14 @@ +{ + flake.modules.nixos.default = { + persistFiles = [ "/etc/machine-id" ]; + persistDirs = [ "/var/lib/systemd" ]; + time.timeZone = "Asia/Singapore"; + i18n.defaultLocale = "en_US.UTF-8"; + system.stateVersion = "25.11"; + }; + flake.modules.homeManager.default = + { osConfig, ... }: + { + home.stateVersion = osConfig.system.stateVersion; + }; +} diff --git a/nix/modules/system/users.nix b/nix/modules/system/users.nix new file mode 100644 index 0000000..5815089 --- /dev/null +++ b/nix/modules/system/users.nix @@ -0,0 +1,34 @@ +{ config, ... }: +let + cfg = config.flake; + inherit (cfg.lib.modules) userListToAttrs forAllUsers'; +in +{ + flake.modules.nixos.default = + { config, ... }: + { + persistDirs = [ "/var/lib/nixos" ]; + users = { + mutableUsers = false; + groups.users.gid = 100; + users = forAllUsers' ( + name: _: { + isNormalUser = true; + hashedPasswordFile = config.sops.secrets."${name}/hashedPassword".path; + } + ); + }; + sops.secrets = userListToAttrs (name: { + "${name}/hashedPassword" = { + neededForUsers = true; + sopsFile = cfg.paths.secrets + "/users.yaml"; + }; + }); + home-manager.users = forAllUsers' ( + name: _: { + home.username = name; + home.homeDirectory = config.users.users.${name}.home; + } + ); + }; +} diff --git a/nix/modules/unfree-packages.nix b/nix/modules/unfree-packages.nix new file mode 100644 index 0000000..b74984e --- /dev/null +++ b/nix/modules/unfree-packages.nix @@ -0,0 +1,17 @@ +{ lib, config, ... }: +let + inherit (builtins) elem; + inherit (lib.options) mkOption; + inherit (lib.strings) getName; + inherit (lib.types) listOf str; + predicate = pkg: elem (getName pkg) config.allowedUnfreePackages; +in +{ + options.allowedUnfreePackages = mkOption { + type = listOf str; + default = [ ]; + }; + config.flake.modules.nixos.default = { + nixpkgs.config.allowUnfreePredicate = predicate; + }; +} diff --git a/packages/deploy/default.nix b/packages/deploy/default.nix deleted file mode 100644 index f9280e8..0000000 --- a/packages/deploy/default.nix +++ /dev/null @@ -1,123 +0,0 @@ -{ pkgs, ... }: -pkgs.writeShellScriptBin "deploy" # sh - '' - while [[ $# -gt 0 ]]; do - case "$1" in - --user) - USER="$2" - shift 2 - ;; - --ip) - IP="$2" - shift 2 - ;; - --hostname) - HOSTNAME="$2" - shift 2 - ;; - *) - echo "Error: Unknown parameter: $1" - exit 1 - ;; - esac - done - - # Check if required arguments are provided - if [[ -z "$USER" || -z "$IP" || -z "$HOSTNAME" ]]; then - echo "Usage: $0 --user --ip --hostname [--wait-timeout ]" - exit 1 - fi - - # --- Helper Functions --- - - wait_for_ping() { - local ip="$1" - - echo "Waiting for ping to $ip..." - while true; do - if ping -c 1 -W 1 "$ip"; then - echo "Ping successful." - return 0 - fi - sleep 2 - done - } - - wait_for_ssh() { - local ip="$1" - - echo "Waiting for SSH to $ip..." - while true; do - ssh-keygen -R "$ip" || true # Suppress error if key doesn't exist - if ssh -o StrictHostKeyChecking=no root@"$ip" exit; then - echo "SSH connection successful." - return 0 - fi - sleep 2 - done - } - - retry_rebuild() { - local ip="$1" - - echo "Attempting rebuild..." - while true; do - if nixos-rebuild switch --flake . --target-host root@"$ip"; then - echo "Rebuild successful." - return 0 - fi - sleep 2 - done - } - - test_connection() { - local ip="$1" - # Wait for the server to come back up after the reboot. Ping first. - if ! wait_for_ping $ip; then - echo "Error: Server did not respond to ping after reboot." - exit 1 - fi - - # Wait for SSH access after reboot - if ! wait_for_ssh $ip; then - echo "Error: SSH access not available after reboot." - exit 1 - fi - } - - # --- Deployment Steps --- - - test_connection "$IP" - - # Copy SSH key to remote server - ssh-copy-id -o StrictHostKeyChecking=no root@"$IP" || { echo "Error: Failed to copy SSH key."; exit 1; } - - # Deploy NixOS configuration using nixos-anywhere - nix run github:nix-community/nixos-anywhere -- \ - -i ~/.ssh/id_ed25519 --ssh-option StrictHostKeyChecking=no \ - --flake .#"$HOSTNAME" --target-host root@"$IP" || { echo "Error: nixos-anywhere failed."; exit 1; } - - test_connection "$IP" - - # Create SSH directory on the remote server (if not already present) - ssh root@"$IP" -o StrictHostKeyChecking=no mkdir -p "/persist/home/$USER/.ssh" || { echo "Error: Failed to create SSH directory."; exit 1; } - - # Set owner of the user's home directory - ssh root@"$IP" -o StrictHostKeyChecking=no chown -R "$USER:users" "/persist/home/$USER" || { echo "Error: Failed to set ownership."; exit 1; } - - # Copy SSH keys to the remote server - scp -r ~/.ssh root@"$IP":/persist/home/"$USER" || { echo "Error: Failed to copy SSH keys."; exit 1; } - - #TODO: remove device from tailscale - - # Build and switch the configuration - retry_rebuild "$IP" - - # Reboot the system - ssh root@"$IP" -o StrictHostKeyChecking=no systemctl reboot || { echo "Error: Failed to reboot."; exit 1; } - - test_connection "$IP" - test_connection "$HOSTNAME" - - echo "Deployment complete. System should be ready." - '' diff --git a/secrets/keys.yaml b/secrets/keys.yaml new file mode 100644 index 0000000..93a7ff8 --- /dev/null +++ b/secrets/keys.yaml @@ -0,0 +1,19 @@ +keys: + cloudflare: ENC[AES256_GCM,data:p2IISOuU/ShoifW5OFY/6Bi6PI0iIiQoBfnV512f2z84U9QS/KEhzA==,iv:5AkwtNAK8mD2DbvXCtTeNeIrpF/GIsSyOYxy8G4Jsqo=,tag:u2xJcRBR5WTMWdzupx4tbQ==,type:str] + gemini: ENC[AES256_GCM,data:GwXVBsQdLesgP6PUZJRrLO5u6jd6XYFv9vjNTsojOwaWlxkDeRos,iv:w6Uz6j/MfpgQdIRYqJCneWqTsA+JEsB/T3cySVY2k3c=,tag:JY+LDar1UzC6qLKLichKnQ==,type:str] + openrouter: ENC[AES256_GCM,data:kRr/f/qlso/SGyZa7J2zeQqbWDZnBoBsUvCEFbWuXpS8ah0qKDANfmX5NsJy3ehjXYOljbHl9WOxQcyriMTE8cyZodp9QySMEQ==,iv:NkWa/Q0AncaDQFo+SZEd3qKDddCxsLPgTi3bYb3SbhQ=,tag:HPTr27cxIV5mx432UMTfXQ==,type:str] +sops: + age: + - recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmcTdPWURrK2w1QUZubVZo + VUMrcFFQU0UxdDU3OG9PdEUxcGs2bzZNcmg0Cm03cUlPZkRMK0ZXOTllV3BtZWFp + QXBPRWtOd0xjZC9BdGdmWnVoVGpHR1UKLS0tIEpaVXlSNkhpMVZnTFZWTFVEWTgv + T3VyZXZnaGZaMVBnVko2Tlc2S3FpdDQKRiHCOtkHKugfquQfYkk4o9SMtZlo1CqZ + 3i9+9Z516KS1+ERTklBUzZDBRZISY0c2nluO+tn71wnKAMIxetKryQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-08T20:53:06Z" + mac: ENC[AES256_GCM,data:hcY1uSNp1E6LrQDpEgK8MABDijc0NQg89iEH1duq8rXFlOFG8BWrEDTasoUX3mH8RPBu5DF9YJHv216w1v2RdVz5w32e4GlcpuA8NUjNxBx38cx/GCp9bx0wEapVVf4Er+a8OmCmbp0MUhKvV3Xy5xs/ZlNJ7KppRXX9hZvzW84=,iv:7SirDOpe3ds23+XKQXe7CKnzb4yhQQWhvcARFnL0qRU=,tag:75tXPKJHfrMKYiM+XUI98Q==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/secrets/librechat.yaml b/secrets/librechat.yaml new file mode 100644 index 0000000..d6668cd --- /dev/null +++ b/secrets/librechat.yaml @@ -0,0 +1,20 @@ +librechat: + creds_key: ENC[AES256_GCM,data:sELKgqif9ec6VV0Q9OVk8IbUAI5noPtUB1b1WrPvxjDzJODd9YoJHWiH+N0vwORje5LiuzqZ/0Kn/UMdPfy3qw==,iv:SFFW+P0vxy4s6TkaAyCNLLXLIBrdi8oMkm7Q/Vec/yk=,tag:ZNC0vMdyh+S204Qr0itvnw==,type:str] + creds_iv: ENC[AES256_GCM,data:h8RHcW7zt8CnKrYDGxlN/H9Wim4KpLaiFl2E2AK+YJY=,iv:xRctbyBFprN6Y1Lvk08EpzZNXa0owYCph+wqcOAR/Gw=,tag:ZdA0ibjyH1Y6DAd23mfJRQ==,type:str] + jwt_secret: ENC[AES256_GCM,data:mXMi0EenuU1EIZWUyLE3wkVTouJk2QPXIKV38sfwbKfjdc28GgdsaWtunaSpD4uYBrWCv1rXq5qj18ohlAKs/g==,iv:ZWZWgYzVQh+kRN4+EEBFdWc4aWGq5IDtlEVde9mzS7I=,tag:BmWQN9yI92RHJMy/pt8rRg==,type:str] + jwt_refresh_secret: ENC[AES256_GCM,data:iw+/E0wb2Ih1iQOaCCXBN5tj98Z2CdpaJMYOiuoTanjW7bvJXGfVObXKTBTtRs1P4TzCc4qK7mes5Sa6oajBpg==,iv:3mr3PYAjJ3bncATgfSwEyrIM2YioSfSu38NUfDmk6zs=,tag:RIYJ1YBaQVpwAmlo3CKg2Q==,type:str] +sops: + age: + - recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArcko2MmowTkpKaDJTdjZE + NVdzbklXZngxaHhrbkhGTXlCNDkzNml4dnlZCjRWOFZCSWRKenZzN0dhYXplVzh0 + OVdaUnRkS2dIYklFS2dwUXVxaElxNkkKLS0tICtxZDV0a2hIaUM2NFBwOGwxcklz + YWJyU0VKRXFxT29TSjR1KzE0ZHJGQncKrX5Sujd617WgFDYA5r63K4ZwoJpP9m8M + xexbGVHAeSyWNjOG7x5A9gYC1/dG3NY2l5xoITn0NKi68ZEfGD/J3w== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-08T19:37:50Z" + mac: ENC[AES256_GCM,data:LBkUPMR8D8+IVUugWzK4a51d0lkGJqnG5D9EkHC4aGXcuSpxpxkbUDXWsqK3u1FxxfCnR87ZhD+UGd3OV6Wvsl9/v968eC/3jxuZALnOgUGcTyUayo8qLq1J6HEFUDoUoH2tk/SF0Cn2r34fkcUd1NtRdQX+C0Zsc8Tk0zIRA8U=,iv:aUvg409sogxRBgYzNECW5eH7GsSAsYY9AHWmL0UD6PA=,tag:0pMoXeuF6DLCyIdDVsPmGA==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml deleted file mode 100644 index 4fb2114..0000000 --- a/secrets/secrets.yaml +++ /dev/null @@ -1,30 +0,0 @@ -rafiq: - hashedPassword: ENC[AES256_GCM,data:SzzSPg5Ze4H+fVl6ZvAULO9FDfRehusmP6uldT4Ok2/9ZeOp9r4LgjKajoiw2A1DWD1zQ1GQwMCHKpeZjCC4rBUNWW5DMcBUJA==,iv:KktKuqr0JNhjeJIlIgkoAv6mP2dQlfQrXiIOASLPkbw=,tag:g9LarkT6EjDrH+dXSjMwPg==,type:str] - personalEmailPassword: ENC[AES256_GCM,data:TGJtDO++QcWqU1AbLe4=,iv:RjLRmq7fdbVRbv0M8ZQHyCK5l95JW3TRjN5w9Ci92zs=,tag:JibrH863smajCXESwhAR4g==,type:str] - workEmailPassword: ENC[AES256_GCM,data:++Gm9dIhmqEQz3+Ej9c=,iv:dAvyyLZvsHcjudU4gdU0iyWYDjjhe49UC2swHh++ldc=,tag:6o1DyJk5WOFO/Hfr0uMKSw==,type:str] - oldSMBCredentials: ENC[AES256_GCM,data:aY41trUJcvGa584H0A==,iv:3h9AZ33HXWT4D/vGMyy/o+TXyGg75Ixcj3+h2EskvIQ=,tag:dDo55h1ljOYLZBHn9bK7ew==,type:str] -keys: - openrouter: ENC[AES256_GCM,data:Uddc0leKVD2xxpvDpsTJV3qZ4oe89Uz6dJMuzF/TeI5iIrG+DNIAYPcnIQiA6LDScO9mag8XNiYpYH7lyMnUg1cvThChiVhO+A==,iv:RHSrL/L74dSvLKAvGwyMME53RzKr2+RDnI8xBpDJVng=,tag:d81mr26SeStmAa8UgEF/LA==,type:str] - gemini: ENC[AES256_GCM,data:t4XTzJLMbHBG7LNaWMwO0YyYHREYOp4Zn95Kwshunnpwq9ezVv+0,iv:ZHq1ytak7Qy5a/zHghwEIWRinDWAkk2Vxw4iu/Q/UPk=,tag:Wyk0FqLTOWelznWHg/anxg==,type:str] - cloudflare: ENC[AES256_GCM,data:nrtHnQR0Oon9BrSN0AeAjl8H8B7quuwSu/Qjabe9HFpWgcZq9n1JCA==,iv:ovyHqy5iKXDYXe4H7eRA51+kODhP+vAWoc98cS/6zG0=,tag:JyktO6EMRZ00CRhTb03+fg==,type:str] - telegram_bot: ENC[AES256_GCM,data:qGJx1Bph94oU2USjZL4h2NqV5ueCiYIvEbx84Xg687F5//MItLAS58MZdUPSuQ==,iv:WmldN5Je4miamLXCK6Cv17TTGmaBq/lde2czsEgNBi4=,tag:aU27eDE5PbYAniKEXk+MRA==,type:str] -librechat: - creds_key: ENC[AES256_GCM,data:/fzPgZiDnyWZalJUBFpFQ2/anxvbX3XLp18n+x1xfzOMisq52ISB5VJOzi9xaNRNruQEoh/lva9gDbIgNyzduA==,iv:xGgufMc/tPOLCKEb2MnEkxmf0FPpENGW1FcCm15CW6k=,tag:9aR+DndXkCg1sboxTFuygQ==,type:str] - creds_iv: ENC[AES256_GCM,data:fbBD9RsuEHwDETwiYtAS9kBxgTy6zubrxHWpcuoEsR0=,iv:uZcwIfDPPn4XUf8IZkI29VH9CiKvEOlWuUaWgSjl1Kc=,tag:qbgiQU7bWSFjoGEwoptCpg==,type:str] - jwt_secret: ENC[AES256_GCM,data:ZhDNIXrCaRWWfrlPxpBfnmeUluW0z72KGpQv9mGyf1kCCnfx3V2lPMm6QS6biajC+4oPVfgwqcXc4Lvs8OqU9g==,iv:1Ecj8fh+M5kw8cmVD96U6QgE7fNy9cbQV9v2Q305puc=,tag:U1ZglGWdTH1TGfcIIORMHQ==,type:str] - jwt_refresh_secret: ENC[AES256_GCM,data:/4X6h51oRRaOg7UZ/zUcS1L8QyFnhsTYrz8D6R3ZP/tFAEMO/IfYJHHQQ8UtgKjAEwIVYcpIco8lUDhm06folw==,iv:02/LgoiMZ6MzBSd+JAi+iuF3dzqsVyqX6gQfWPY8sIc=,tag:5VrCh7ZKNJD3ynjcyQpVyg==,type:str] -sops: - age: - - recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrUDN6TFlTVHdlWCsrWkFn - R1g5UjVLVk1NQzJRRE9NbDZlRVVJUjVvbmlnCk93NFhSRS9vbDUzNVd6Q3RuTEtZ - cFZvY0JML2tDSUZIbkcyVWVWWVFMY0UKLS0tIDlCbmxhUThUaHRGNkgySEp2QTB1 - WXFKbjNMWDF0LzNyekJJMGFva2diemcKQTc8ODuK6IWqRhulHiCF92aU+3p23riY - M94Nzh+VT6QTFOgb3J7bBJMLhRH/fkQb6L6ia2n9QrVXFyYYMJ0oBw== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-07-01T21:34:46Z" - mac: ENC[AES256_GCM,data:NvJ6lCb80dsVMH4T4f4ZPO0b4JI44LfMvdanVaWtXDpi6FHJsF4OY8dftIyTBjacaLzdrVoT+JFfP3BrAnuEaZrCrfE1E+IRF4x/9NG4c4Cw++Jxgs7z7d01iYEjWJoVVPCLVnV32LGIq6nQltx2GFEVAsvV5zukJ/aJjvcIpQA=,iv:FWGaIdok23jgxMUs3d5ddK2iyJoOBliwv/yJDxmKLE0=,tag:FfLYymjZEJtW4cfFNhlNFg==,type:str] - unencrypted_suffix: _unencrypted - version: 3.10.2 diff --git a/secrets/tailscale.yaml b/secrets/tailscale.yaml new file mode 100644 index 0000000..0913120 --- /dev/null +++ b/secrets/tailscale.yaml @@ -0,0 +1,17 @@ +tailscale: + client-secret: ENC[AES256_GCM,data:qAJUDTHxnzhgUtpe/DaH8Vv72jy/DWU/1UKzp2Pg/GtayClZXGFz00bCNKmZJCE7NYHERgr2Ssnhpz90eRCjKg==,iv:aWp2lvIFpUH6OMTkD8V1HNMyxUPxiVA+Il4NvlVKjOA=,tag:OzkdsOKerKiSHzHSkScIQA==,type:str] +sops: + age: + - recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5ZytHNnlKcWFPVVNpTkxX + cFgxRjFDdWJkMzB2NUk1N2VLSWx3cVpvY20wCkdHbjZ4ZUlHTWp1QUFJVGxaV2cx + K0NlaFdnYlEvektieDJJVkY2cEtmL1UKLS0tIDFHQlM4OEIzaGVvUThCbUJZNTU3 + ZGNJd3NvSCsrdDNFb0VuMDJOU09DVEEKrDnezqYWRuEyS6/WRWq0jMfv4DQ3TS1L + Zic6TBIA3qNEjUlqXKRfq//H3vDRz4dzZCqbbh+5+FXDGBIVLL2DaA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-07T11:12:16Z" + mac: ENC[AES256_GCM,data:rOuEqjHByaGaYredcMFGds+pB1rIgh0qu245Vt2gVGjjqOJtfEYcuvziVKgvV5yvBVhizcjeFIzCFdQ2KpflvwOLjiOZ594UaZChPGtO5hDc1VY/Gz86t8x6DYuHjWu4S1XOrBWgv2ebD0iBgbjuRNgBEhkWfVS2/7hn1PtqGD0=,iv:ZQ0b7pHG3NM2mwQdSVoGr4WsluIrp+/YUQi6KoMneC0=,tag:5E5bNxdRPQpTRVrQ+qoxfQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/secrets/users.yaml b/secrets/users.yaml new file mode 100644 index 0000000..76fe7e0 --- /dev/null +++ b/secrets/users.yaml @@ -0,0 +1,18 @@ +rafiq: + password: ENC[AES256_GCM,data:8KAfatz+YSaNozd5VGo=,iv:LNRxt47iBKSWzMZuBHSxv/qDZ2h6JiTIPps7OK/o7uU=,tag:oiSfLyRVswb/wxSTE69QMA==,type:str] + hashedPassword: ENC[AES256_GCM,data:NogYQ3kR1TseC79HIXARrXhIncCnvxzf9zMF2QrUyTmojTffPXRGtMdjNpfMEFj5dkKfZujBL/QTIpPFFTm1py7Dreg5/9VSKQ==,iv:IwfZsrsJbLYG1ELte6aBHUtff6hIQu9rHT5tSvILIGQ=,tag:oav3paDcUY+cl4FJlZa90A==,type:str] +sops: + age: + - recipient: age12l33pas8eptwjc7ewux3d8snyzfzwz0tn9qg5kw8le79fswmjgjqdjgyy6 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVd09tYkhKUkVjNTBRdld6 + a1RkUnZqdnRqMlFTSGgwUFVCZlRhL0tLTnpVCjNXVjZldzNUOE9DQ0ZGejhWakY2 + TmRIZnpobE0ydDhNSDdJQUp2U3pSTzgKLS0tIDkxU3Fxa2lMUkhZY0g1Wm02T2ZE + UkQwOWZtVXVPSGJiRk1qRHVHYkN2cDgKLiYiA0q5se/oHfGRqvHLn3gRRDfmefEZ + z2U2N1Tjt0QgCfYOOXVfPV9F36a7PpabFva5ElSazawHgvI+Bot6og== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-07-07T08:56:26Z" + mac: ENC[AES256_GCM,data:2uGjIMxRgk7uWToQC4MrHpHFAt4bI7sEhaHvPU6Ae3bvRVH/TdJxZtikSPe95LEwReOuBmPajbcM580/d3Jt6VbA7nZzj1JduVscrRkSAFCzZp9Ti/mbOGITPJa6xWSGwVF1wSN3BnHXYIHDcKeSGtUdP7L7nBZr1KXPkok4NCo=,iv:+ELIes7lzb8M6CvOemAcyoq7Rx7L6NkNmHwntJN/RSc=,tag:ubyxO6VllH9cQK3VbvxiGg==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/systems/x86_64-linux/apollo/default.nix b/systems/x86_64-linux/apollo/default.nix deleted file mode 100644 index 6e9ba08..0000000 --- a/systems/x86_64-linux/apollo/default.nix +++ /dev/null @@ -1,62 +0,0 @@ -{ - lib, - pkgs, - inputs, - ... -}: -{ - imports = lib.singleton ../common.nix; - hostname = "apollo"; - - machine = { - platform.type = "intel"; - bootloader.type = "systemd-boot"; - drives.btrfs = { - enable = true; - drive = "/dev/disk/by-id/nvme-eui.002538d221b47b01"; - ephemeralRoot = true; - }; - }; - - server = { - networking.ddns = { - enable = true; - domains = [ - "aenyrathia.wiki" - "slayment.com" - ]; - }; - databases = { - mongodb.enable = true; - mysql.enable = true; - postgresql.enable = true; - }; - web-apps = { - librechat.enable = true; - librechat.domain = "chat.bwfiq.com"; - forgejo.enable = true; - forgejo.domain = "git.rrv.sh"; - forgejo.openFirewall = true; - glance.enable = true; - glance.domain = "glance.bwfiq.com"; - rrv-sh.enable = true; - rrv-sh.domain = "rrv.sh"; - }; - web-servers = { - enableSSL = true; - nginx = { - enable = true; - proxies = [ - { - source = "aenyrathia.wiki"; - target = "http://helios:5896"; - } - { - source = "il.bwfiq.com"; - target = "http://helios:2283"; - } - ]; - }; - }; - }; -} diff --git a/systems/x86_64-linux/common.nix b/systems/x86_64-linux/common.nix deleted file mode 100644 index 0954fff..0000000 --- a/systems/x86_64-linux/common.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ pkgs, ... }: -{ - mainUser = { - name = "rafiq"; - publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILdsZyY3gu8IGB8MzMnLdh+ClDxQQ2RYG9rkeetIKq8n"; - email = "rafiq@rrv.sh"; - shell = pkgs.fish; - }; - server.mountHelios = true; - stylix.base16Scheme = "${pkgs.base16-schemes}/share/themes/atelier-cave.yaml"; - programs.fish.enable = true; - programs.nix-ld.enable = true; -} diff --git a/systems/x86_64-linux/desktop.nix b/systems/x86_64-linux/desktop.nix deleted file mode 100644 index 4e15184..0000000 --- a/systems/x86_64-linux/desktop.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - desktop = { - enable = true; - lockscreen.hyprlock.enable = true; - launcher.fuzzel.enable = true; - media-player.vlc.enable = true; - window-manager.hyprland.enable = true; - }; - - machine.usb = { - automount = true; - enableQmk = true; - }; -} diff --git a/systems/x86_64-linux/mellinoe/default.nix b/systems/x86_64-linux/mellinoe/default.nix deleted file mode 100644 index 6bcc25f..0000000 --- a/systems/x86_64-linux/mellinoe/default.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - imports = [ - ../common.nix - ../desktop.nix - ]; - hostname = "mellinoe"; - - machine = { - platform.type = "intel"; - bootloader.type = "systemd-boot"; - drives.btrfs = { - enable = true; - drive = "/dev/disk/by-id/nvme-KBG40ZPZ128G_TOSHIBA_MEMORY_Z0U103PCNCDL"; - ephemeralRoot = true; - }; - }; - - desktop.mainMonitor = { - id = "BOE 0x088B"; - scale = "2"; - resolution = "1920x1280"; - refresh-rate = "60"; - }; -} diff --git a/systems/x86_64-linux/nemesis/default.nix b/systems/x86_64-linux/nemesis/default.nix deleted file mode 100644 index de55267..0000000 --- a/systems/x86_64-linux/nemesis/default.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ - imports = [ - ../common.nix - ../desktop.nix - ]; - hostname = "nemesis"; - - machine = { - platform.type = "amd"; - gpu.nvidia.enable = true; - bootloader.type = "systemd-boot"; - drives.btrfs = { - enable = true; - drive = "/dev/disk/by-id/nvme-CT2000P3SSD8_2325E6E77434"; - ephemeralRoot = true; - }; - virtualisation.distrobox.enable = true; - }; - - desktop = { - browser.tor-browser.enable = true; - gaming = { - prism-launcher.enable = true; - steam.enable = true; - }; - services = { - sunshine.enable = true; - spotifyd.enable = true; - }; - mainMonitor = { - id = "desc:OOO AN-270W04K"; - scale = "2"; - resolution = "3840x2160"; - refresh-rate = "60"; - }; - }; - - server.web-apps.sd-webui-forge.enable = true; - server.web-apps.comfy-ui.enable = true; -}