commit 786af32daf8455dcb83498e61de8900f14b1bfaf Author: Christopher Mühl Date: Wed Jul 30 23:32:24 2025 +0200 Publish my config This is the result of ~100 commits to my NixOS config. Since I haven't always used `agenix-rekey`, this is another initial commit so that none of the secrets in my git history are leaked diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aeec145 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +result +secrets/rekeyed diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..43813b9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: + - repo: https://github.com/gitleaks/gitleaks + rev: v8.28.0 + hooks: + - id: gitleaks + diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..9f4a9e5 --- /dev/null +++ b/Justfile @@ -0,0 +1,52 @@ +set shell := ["nu", "-c"] +editor := env('EDITOR') + +default: + @just --list --justfile {{justfile()}} + +# Runs `nixos-rebuild` +[group('nix')] +deploy: + nixos-rebuild switch --flake . --use-remote-sudo + +europium: + nixos-rebuild switch --flake .#europium --target-host europium --build-host europium --use-remote-sudo + +# Opens the elements configuration in the default editor +edit: + {{editor}} {{shell('pwd')}} + +# Runs nix-output-monitor in debug mode +[group('nix')] +debug: + nom build ".#nixosConfigurations.{{shell('hostname')}}.config.system.build.toplevel" --show-trace --verbose + +[group('nix')] +repl: + nix repl --expr "builtins.getFlake \"{{shell('pwd')}}\"" + +# Enter a flake dev shell +[group('nix')] +shell name: + nix develop .#{{name}} + +# Updates nix flakes +[group('nix')] +up: + nix flake update + +# Updates a specific flake input +[group('nix')] +upp input: + nix flake update {{input}} + +# Collects old garbage +[group('nix')] +gc: + sudo nix-collect-garbage --delete-old + +# Exits the current user session +[group('desktop')] +[confirm] +logout: + hyprctl dispatch exit diff --git a/README.md b/README.md new file mode 100644 index 0000000..915283e --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +## My NixOS systems +This repository contains all my NixOS (and nix-darwin) system and home manager configurations. +It's not meant to be deployable by anyone other than me, but just as a reference for others. + +## General principles +Every wheels user will have a command available called `elements` with which they +are able to interface with this main Nix flake. Internally this command is an alias +for the [just command runner][just] which automatically links to the flake's Justfile. + +Additionally, every dev shell can also expand on the available `elements` recipes +depending on the context. In order to enter one of the configured devshells, one +can use either the command `elements shell ` (if elements is already +available) or run `nix develop .#name` in the flake root directory. + +### Todo +Since this is pretty much always a work-in-progress I do not expect it to be in the +most presentable state at all times. Whenever I have time I try to streamline some of +the config, but especially when trying out new tools the code could be a bit wild. + +There's a couple of ideas I have for this: +- [ ] Build a deployment dev shell +- [ ] Deploy base tooling to all hosts. This mainly includes `nushell` and `helix` configs. They should still be configurable per-host. Potential issue here could be hosts where I don't use home manager +- [ ] Make everything more composable. Can make use of the `elements` config some more, like how it's done for `quirks` + +[just]: https://github.com/casey/just diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..8776985 --- /dev/null +++ b/flake.lock @@ -0,0 +1,1249 @@ +{ + "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1750173260, + "narHash": "sha256-9P1FziAwl5+3edkfFcr5HeGtQUtrSdk/MksX39GieoA=", + "owner": "ryantm", + "repo": "agenix", + "rev": "531beac616433bac6f9e2a19feb8e99a22a66baf", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, + "agenix-rekey": { + "inputs": { + "devshell": "devshell", + "flake-parts": "flake-parts", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1749289693, + "narHash": "sha256-fSMlofc9z/G/bfwgtDD+zy9RBqKR71FsLNU8mfLwPq0=", + "owner": "oddlama", + "repo": "agenix-rekey", + "rev": "57cb67bc61f8421c576085d595d902f02828d953", + "type": "github" + }, + "original": { + "owner": "oddlama", + "repo": "agenix-rekey", + "type": "github" + } + }, + "aquamarine": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1751740947, + "narHash": "sha256-35040CHH7P3JGmhGVfEb2oJHL/A5mI2IXumhkxrBnao=", + "owner": "hyprwm", + "repo": "aquamarine", + "rev": "dfc1db15a08c4cd234288f66e1199c653495301f", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "aquamarine", + "type": "github" + } + }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744478979, + "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "43975d782b418ebf4969e9ccba82466728c2851b", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "darwin_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1751313918, + "narHash": "sha256-HsJM3XLa43WpG+665aGEh8iS8AfEwOIQWk3Mke3e7nk=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "e04a388232d9a6ba56967ce5b53a8a6f713cdfcf", + "type": "github" + }, + "original": { + "owner": "lnl7", + "repo": "nix-darwin", + "type": "github" + } + }, + "devshell": { + "inputs": { + "nixpkgs": [ + "agenix-rekey", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1728330715, + "narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=", + "owner": "numtide", + "repo": "devshell", + "rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, + "docker-compose-1": { + "locked": { + "lastModified": 1624397714, + "narHash": "sha256-mtIXSGsYIIK8IM6bY02bZ9ENkOpPNQEMAoHE43Dg8HE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "b0f0b5c6c021ebafbd322899aa9a54b87d75a313", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "rev": "b0f0b5c6c021ebafbd322899aa9a54b87d75a313", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_3": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_4": { + "flake": false, + "locked": { + "lastModified": 1650374568, + "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "b4a34015c698c7793d592d66adbab377907a2be8", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "agenix-rekey", + "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-utils": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils-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_6" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_7" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "agenix-rekey", + "pre-commit-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" + } + }, + "gitignore_2": { + "inputs": { + "nixpkgs": [ + "hyprland", + "pre-commit-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" + } + }, + "grub2-themes": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1734412921, + "narHash": "sha256-JeMqc7lLowKn6klrCcOkcOg38yNqF7MPbN4Elh6Xvq0=", + "owner": "vinceliuice", + "repo": "grub2-themes", + "rev": "f6ab2438e124f60a340a526543e498e5e33b3c53", + "type": "github" + }, + "original": { + "owner": "vinceliuice", + "repo": "grub2-themes", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1745494811, + "narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1751986323, + "narHash": "sha256-EuYWd8FMsqAiAtrAB34LBDe8wgixhMtx1O75fprygX0=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "5751fa774fa61837f35efb82f3b6e105d4c63ced", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "hyprcursor": { + "inputs": { + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1749155331, + "narHash": "sha256-XR9fsI0zwLiFWfqi/pdS/VD+YNorKb3XIykgTg4l1nA=", + "owner": "hyprwm", + "repo": "hyprcursor", + "rev": "45fcc10b4c282746d93ec406a740c43b48b4ef80", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprcursor", + "type": "github" + } + }, + "hyprgraphics": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1751808145, + "narHash": "sha256-OXgL0XaKMmfX2rRQkt9SkJw+QNfv0jExlySt1D6O72g=", + "owner": "hyprwm", + "repo": "hyprgraphics", + "rev": "b841473a0bd4a1a74a0b64f1ec2ab199035c349f", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprgraphics", + "type": "github" + } + }, + "hypridle": { + "inputs": { + "hyprland-protocols": "hyprland-protocols", + "hyprlang": "hyprlang", + "hyprutils": "hyprutils", + "hyprwayland-scanner": "hyprwayland-scanner", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems_2" + }, + "locked": { + "lastModified": 1750503503, + "narHash": "sha256-UWxbL6a81GWBg990pcct1dzm4HuWIEd1Q6mpV7bHrnM=", + "owner": "hyprwm", + "repo": "hypridle", + "rev": "25578b71370d1ba7bf08127ca4b0959452df4d04", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hypridle", + "type": "github" + } + }, + "hyprland": { + "inputs": { + "aquamarine": "aquamarine", + "hyprcursor": "hyprcursor", + "hyprgraphics": "hyprgraphics", + "hyprland-protocols": "hyprland-protocols_2", + "hyprland-qtutils": "hyprland-qtutils", + "hyprlang": "hyprlang_2", + "hyprutils": "hyprutils_2", + "hyprwayland-scanner": "hyprwayland-scanner_2", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks_2", + "systems": "systems_3", + "xdph": "xdph" + }, + "locked": { + "lastModified": 1752064776, + "narHash": "sha256-vdvG6f7hWS8stxiN/uhxk777E7MI5RyWzcZ+WJ5KhoA=", + "owner": "hyprwm", + "repo": "hyprland", + "rev": "c6497a719379e36c25df5f1980a5b2a1a78d3536", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland", + "type": "github" + } + }, + "hyprland-protocols": { + "inputs": { + "nixpkgs": [ + "hypridle", + "nixpkgs" + ], + "systems": [ + "hypridle", + "systems" + ] + }, + "locked": { + "lastModified": 1749046714, + "narHash": "sha256-kymV5FMnddYGI+UjwIw8ceDjdeg7ToDVjbHCvUlhn14=", + "owner": "hyprwm", + "repo": "hyprland-protocols", + "rev": "613878cb6f459c5e323aaafe1e6f388ac8a36330", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-protocols", + "type": "github" + } + }, + "hyprland-protocols_2": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1749046714, + "narHash": "sha256-kymV5FMnddYGI+UjwIw8ceDjdeg7ToDVjbHCvUlhn14=", + "owner": "hyprwm", + "repo": "hyprland-protocols", + "rev": "613878cb6f459c5e323aaafe1e6f388ac8a36330", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-protocols", + "type": "github" + } + }, + "hyprland-qt-support": { + "inputs": { + "hyprlang": [ + "hyprland", + "hyprland-qtutils", + "hyprlang" + ], + "nixpkgs": [ + "hyprland", + "hyprland-qtutils", + "nixpkgs" + ], + "systems": [ + "hyprland", + "hyprland-qtutils", + "systems" + ] + }, + "locked": { + "lastModified": 1749154592, + "narHash": "sha256-DO7z5CeT/ddSGDEnK9mAXm1qlGL47L3VAHLlLXoCjhE=", + "owner": "hyprwm", + "repo": "hyprland-qt-support", + "rev": "4c8053c3c888138a30c3a6c45c2e45f5484f2074", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-qt-support", + "type": "github" + } + }, + "hyprland-qtutils": { + "inputs": { + "hyprland-qt-support": "hyprland-qt-support", + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprland-qtutils", + "hyprlang", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1750371812, + "narHash": "sha256-D868K1dVEACw17elVxRgXC6hOxY+54wIEjURztDWLk8=", + "owner": "hyprwm", + "repo": "hyprland-qtutils", + "rev": "b13c7481e37856f322177010bdf75fccacd1adc8", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-qtutils", + "type": "github" + } + }, + "hyprlang": { + "inputs": { + "hyprutils": [ + "hypridle", + "hyprutils" + ], + "nixpkgs": [ + "hypridle", + "nixpkgs" + ], + "systems": [ + "hypridle", + "systems" + ] + }, + "locked": { + "lastModified": 1749145882, + "narHash": "sha256-qr0KXeczF8Sma3Ae7+dR2NHhvG7YeLBJv19W4oMu6ZE=", + "owner": "hyprwm", + "repo": "hyprlang", + "rev": "1bfb84f54d50c7ae6558c794d3cfd5f6a7e6e676", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlang", + "type": "github" + } + }, + "hyprlang_2": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1750371198, + "narHash": "sha256-/iuJ1paQOBoSLqHflRNNGyroqfF/yvPNurxzcCT0cAE=", + "owner": "hyprwm", + "repo": "hyprlang", + "rev": "cee01452bca58d6cadb3224e21e370de8bc20f0b", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlang", + "type": "github" + } + }, + "hyprutils": { + "inputs": { + "nixpkgs": [ + "hypridle", + "nixpkgs" + ], + "systems": [ + "hypridle", + "systems" + ] + }, + "locked": { + "lastModified": 1749135356, + "narHash": "sha256-Q8mAKMDsFbCEuq7zoSlcTuxgbIBVhfIYpX0RjE32PS0=", + "owner": "hyprwm", + "repo": "hyprutils", + "rev": "e36db00dfb3a3d3fdcc4069cb292ff60d2699ccb", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprutils", + "type": "github" + } + }, + "hyprutils_2": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1751888065, + "narHash": "sha256-F2SV9WGqgtRsXIdUrl3sRe0wXlQD+kRRZcSfbepjPJY=", + "owner": "hyprwm", + "repo": "hyprutils", + "rev": "a8229739cf36d159001cfc203871917b83fdf917", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprutils", + "type": "github" + } + }, + "hyprwayland-scanner": { + "inputs": { + "nixpkgs": [ + "hypridle", + "nixpkgs" + ], + "systems": [ + "hypridle", + "systems" + ] + }, + "locked": { + "lastModified": 1749145760, + "narHash": "sha256-IHaGWpGrv7seFWdw/1A+wHtTsPlOGIKMrk1TUIYJEFI=", + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "rev": "817918315ea016cc2d94004bfb3223b5fd9dfcc6", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "type": "github" + } + }, + "hyprwayland-scanner_2": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1751881472, + "narHash": "sha256-meB0SnXbwIe2trD041MLKEv6R7NZ759QwBcVIhlSBfE=", + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "rev": "8fb426b3e5452fd9169453fd6c10f8c14ca37120", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "type": "github" + } + }, + "nix-filter": { + "locked": { + "lastModified": 1693833173, + "narHash": "sha256-hlMABKrGbEiJD5dwUSfnw1CQ3bG7KKwDV+Nx3bEZd7U=", + "owner": "numtide", + "repo": "nix-filter", + "rev": "ac030bd9ba98e318e1f4c4328d60766ade8ebe8b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nix-filter", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1751792365, + "narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1fd8bada0b6117e6c7eb54aad5813023eed37ccb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-ruby": { + "inputs": { + "flake-compat": "flake-compat_3", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1747288354, + "narHash": "sha256-OcnnbsQ0cKLhXA6T1ytaLUVZViBn5cZoXFsdlvRruSI=", + "owner": "bobvanderlinden", + "repo": "nixpkgs-ruby", + "rev": "5d7598f3059fff0cbd0dc4756f9d87f8cb7f3f7c", + "type": "github" + }, + "original": { + "owner": "bobvanderlinden", + "repo": "nixpkgs-ruby", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1751792365, + "narHash": "sha256-J1kI6oAj25IG4EdVlg2hQz8NZTBNYvIS0l4wpr9KcUo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1fd8bada0b6117e6c7eb54aad5813023eed37ccb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1731755305, + "narHash": "sha256-v5P3dk5JdiT+4x69ZaB18B8+Rcu3TIOrcdG4uEX7WZ8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "057f63b6dc1a2c67301286152eb5af20747a9cb4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1682134069, + "narHash": "sha256-TnI/ZXSmRxQDt2sjRYK/8j8iha4B4zP2cnQCZZ3vp7k=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "fd901ef4bf93499374c5af385b2943f5801c0833", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": [ + "agenix-rekey", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1735882644, + "narHash": "sha256-3FZAG+pGt3OElQjesCAWeMkQ7C/nB1oTHLRQ8ceP110=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "a5a961387e75ae44cc20f0a57ae463da5e959656", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "pre-commit-hooks_2": { + "inputs": { + "flake-compat": "flake-compat_2", + "gitignore": "gitignore_2", + "nixpkgs": [ + "hyprland", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1750779888, + "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "agenix": "agenix", + "agenix-rekey": "agenix-rekey", + "darwin": "darwin_2", + "docker-compose-1": "docker-compose-1", + "grub2-themes": "grub2-themes", + "home-manager": "home-manager_2", + "hypridle": "hypridle", + "hyprland": "hyprland", + "nixpkgs": "nixpkgs_2", + "nixpkgs-ruby": "nixpkgs-ruby", + "rose-pine-hyprcursor": "rose-pine-hyprcursor", + "snowfall": "snowfall", + "split-monitor-workspaces": "split-monitor-workspaces", + "vscode-server": "vscode-server" + } + }, + "rose-pine-hyprcursor": { + "inputs": { + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1748096947, + "narHash": "sha256-ouuA8LVBXzrbYwPW2vNjh7fC9H2UBud/1tUiIM5vPvM=", + "owner": "ndom91", + "repo": "rose-pine-hyprcursor", + "rev": "4b02963d0baf0bee18725cf7c5762b3b3c1392f1", + "type": "github" + }, + "original": { + "owner": "ndom91", + "repo": "rose-pine-hyprcursor", + "type": "github" + } + }, + "snowfall": { + "inputs": { + "flake-compat": "flake-compat_4", + "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" + } + }, + "split-monitor-workspaces": { + "inputs": { + "hyprland": [ + "hyprland" + ], + "nix-filter": "nix-filter" + }, + "locked": { + "lastModified": 1751646985, + "narHash": "sha256-QQQr6iyOh8Mn6+sze9+mg57C/7aVA4na5gfVTHJ2WGY=", + "owner": "Duckonaut", + "repo": "split-monitor-workspaces", + "rev": "e9acfbc08f443f98c691e22f0a89b035eb060070", + "type": "github" + }, + "original": { + "owner": "Duckonaut", + "repo": "split-monitor-workspaces", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_7": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "agenix-rekey", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1735135567, + "narHash": "sha256-8T3K5amndEavxnludPyfj3Z1IkcFdRpR23q+T0BVeZE=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "9e09d30a644c57257715902efbb3adc56c79cf28", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems_5" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "vscode-server": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1750353031, + "narHash": "sha256-Bx7DOPLhkr8Z60U9Qw4l0OidzHoqLDKQH5rDV5ef59A=", + "owner": "nix-community", + "repo": "nixos-vscode-server", + "rev": "4ec4859b12129c0436b0a471ed1ea6dd8a317993", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-vscode-server", + "type": "github" + } + }, + "xdph": { + "inputs": { + "hyprland-protocols": [ + "hyprland", + "hyprland-protocols" + ], + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1751300244, + "narHash": "sha256-PFuv1TZVYvQhha0ac53E3YgdtmLShrN0t4T6xqHl0jE=", + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "rev": "6115f3fdcb2c1a57b4a80a69f3c797e47607b90a", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c58427c --- /dev/null +++ b/flake.nix @@ -0,0 +1,102 @@ +{ + # References: + # * https://github.com/Misterio77/nix-starter-config + description = "Padarom's system configuration"; + + outputs = {self, ...} @ inputs: + (inputs.snowfall.mkFlake { + inherit inputs; + src = ./.; + + # Exposes all internal libs and packages as `lib._elements` or `pkgs._elements` respectively + snowfall.namespace = "_elements"; + + # Global system modules to be included for all systems + systems.modules = with inputs; { + nixos = [ + agenix.nixosModules.default + agenix-rekey.nixosModules.default + ]; + darwin = []; + }; + + # Add modules only to specific hosts + systems.hosts = with inputs; { + cobalt.modules = [ + grub2-themes.nixosModules.default + ]; + mercury.modules = [ + vscode-server.nixosModules.default + ]; + }; + + # Configure nixpkgs when instantiating the package set + # TODO: This is already specified elsewhere. Still needed here? + channels-config = { + allowUnfree = true; + permittedInsecurePackages = []; + }; + + outputs-builder = channels: { + formatter = channels.nixpkgs.alejandra; + }; + }) + // { + agenix-rekey = inputs.agenix-rekey.configure { + userFlake = inputs.self; + nixosConfigurations = inputs.self.nixosConfigurations; + homeConfigurations = inputs.self.homeConfigurations; + }; + }; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + # Opinionated flake library, just the way I want it + snowfall = { + url = "github:snowfallorg/lib"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # For using home-manager on Darwin (macOS) devices + darwin.url = "github:lnl7/nix-darwin"; + darwin.inputs.nixpkgs.follows = "nixpkgs"; + + nixpkgs-ruby.url = "github:bobvanderlinden/nixpkgs-ruby"; + + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Encrypting secrets with automatic rekeying for different hosts + agenix.url = "github:ryantm/agenix"; + agenix.inputs.nixpkgs.follows = "nixpkgs"; + agenix-rekey.url = "github:oddlama/agenix-rekey"; + agenix-rekey.inputs.nixpkgs.follows = "nixpkgs"; + + hyprland.url = "github:hyprwm/hyprland"; + + hypridle = { + url = "github:hyprwm/hypridle"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + rose-pine-hyprcursor = { + url = "github:ndom91/rose-pine-hyprcursor"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.hyprlang.follows = "hyprland/hyprlang"; + }; + + split-monitor-workspaces = { + url = "github:Duckonaut/split-monitor-workspaces"; + inputs.hyprland.follows = "hyprland"; + }; + + vscode-server.url = "github:nix-community/nixos-vscode-server"; + docker-compose-1.url = github:nixos/nixpkgs/b0f0b5c6c021ebafbd322899aa9a54b87d75a313; + + grub2-themes.url = github:vinceliuice/grub2-themes; + grub2-themes.inputs.nixpkgs.follows = "nixpkgs"; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config.nix b/homes/x86_64-linux/christopher@cobalt/config.nix new file mode 100644 index 0000000..d0d809a --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config.nix @@ -0,0 +1,6 @@ +{lib, ...}: +with builtins; let + # Determines whether the given file name ends with ".nix" + endsWithNix = fileName: substring (lib.trivial.max 0 (stringLength fileName - 4)) 4 fileName == ".nix"; +in + map (name: ./config + "/${name}") (filter endsWithNix (attrNames (readDir ./config))) diff --git a/homes/x86_64-linux/christopher@cobalt/config/appearance.nix b/homes/x86_64-linux/christopher@cobalt/config/appearance.nix new file mode 100644 index 0000000..7cda8c7 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/appearance.nix @@ -0,0 +1,33 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + lxappearance + ]; + + gtk = { + enable = true; + + iconTheme = { + name = "oomox-rose-pine"; + package = pkgs.rose-pine-icon-theme; + }; + + theme = { + name = "rose-pine"; + package = pkgs.rose-pine-gtk-theme; + }; + + cursorTheme = { + name = "BreezeX-RoséPine"; + package = pkgs.rose-pine-cursor; + }; + + gtk3.extraConfig.gtk-application-prefer-dark-theme = 1; + gtk4.extraConfig.gtk-application-prefer-dark-theme = 1; + }; + + home.sessionVariables = { + GTK_USE_PORTAL = "1"; + GTK_THEME = "rose-pine"; + XCURSOR_SIZE = "32"; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/bin.nix b/homes/x86_64-linux/christopher@cobalt/config/bin.nix new file mode 100644 index 0000000..e262f37 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/bin.nix @@ -0,0 +1,9 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + jq # JSON processor + yq # YAML processor + jo # Construct JSON via CLI + socat # Socket cat + gum + ]; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/cron.nix b/homes/x86_64-linux/christopher@cobalt/config/cron.nix new file mode 100644 index 0000000..cf1fd47 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/cron.nix @@ -0,0 +1,61 @@ +{ + pkgs, + config, + ... +}: let + bin = '' + #/usr/bin/env bash + + ORG="hausgold" + OUTPUT_FILE="/home/christopher/.gh/$ORG-repos" + TOKEN=$(cat ${config.age.secrets.repoUpdatePAT.path}) + + API_URL="https://api.github.com/orgs/$ORG/repos" + + mkdir -p "$(dirname $OUTPUT_FILE)" + echo -n "" > $OUTPUT_FILE + + fetch_repositories() { + local page=$1 + if [ -z "$TOKEN" ]; then + curl -s "$API_URL?page=$page&per_page=100" + else + curl -s -H "Authorization: token $TOKEN" "$API_URL?page=$page&per_page=100" + fi + } + + # Pagination loop + page=1 + while : ; do + response=$(fetch_repositories $page) + repo_names=$(echo "$response" | jq -r '.[] | select(.archived == false) | .name') + + if [ -z "$repo_names" ]; then + break + fi + + echo "$repo_names" >> $OUTPUT_FILE + ((page++)) + done + + echo "Repositories have been listed in $OUTPUT_FILE" + ''; + + update-hausgold-gh = pkgs.writeShellApplication { + name = "update-hausgold-gh"; + text = bin; + }; +in { + systemd.user.timers."update-hausgold-github" = { + Install.WantedBy = ["timers.target"]; + Timer = { + OnBootSec = "1min"; + OnUnitActiveSec = "2h"; + Unit = "update-hausgold-github.service"; + }; + }; + + systemd.user.services."update-hausgold-github" = { + Service.ExecStart = "${update-hausgold-gh}/bin/update-hausgold-gh"; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/dev.nix b/homes/x86_64-linux/christopher@cobalt/config/dev.nix new file mode 100644 index 0000000..6847ea4 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/dev.nix @@ -0,0 +1,50 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + # Dev tools + direnv + silver-searcher # ag search tool + zx # Tool for writing better scripts + trurl # Parsing and manipulating URLs via CLI + onefetch # Git information tool + cloc # Line-of-code calc for entire project + tokei # Like cloc + delta # Diffing tool + zeal # Offline documentation browser + just # Just a command runner + + # Build tools + cargo + glibc + gcc + + claude-code + + php82 + php82Packages.composer + + bun + nodejs_20 + nodejs_20.pkgs.pnpm + ]; + + # `nix-shell` replacement for project development + # Most useful with `pkgs.direnv` + services.lorri.enable = true; + programs.direnv.enable = true; + programs.direnv.nix-direnv.enable = true; + + programs.go.enable = true; + + programs.neovim = { + enable = false; + # defaultEditor = true; + viAlias = true; + vimAlias = true; + + # extraConfig = lib.fileContents ../fixtures/neovim/init.vim; + + #plugins = with pkgs.vimPlugins; [ + # nvim-treesitter.withAllGrammars + #]; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/dunst.nix b/homes/x86_64-linux/christopher@cobalt/config/dunst.nix new file mode 100644 index 0000000..2b68445 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/dunst.nix @@ -0,0 +1,47 @@ +# Dunst is used for displaying system notifications. +# It is configured here, so that its styling looks better. +{...}: { + services.dunst = { + enable = true; + + settings = { + global = { + font = "Roboto 11"; + format = "%s\\n%b"; + width = 300; + height = 100; + offset = "7x7"; + + frame_color = "#8AADF4"; + frame_width = 2; + gap_size = 8; + line_height = 2; + + sort = true; + + # Not really relevant for single-monitor setup, but doesn't hurt either + monitor = 0; + follow = "mouse"; + }; + + urgency_low = { + background = "#24273A"; + foreground = "#CAD3F5"; + timeout = 10; + }; + + urgency_normal = { + background = "#24273A"; + foreground = "#CAD3F5"; + timeout = 10; + }; + + urgency_critical = { + background = "#24273A"; + foreground = "#CAD3F5"; + frame_color = "#F5A97F"; + timeout = 0; + }; + }; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/editors.nix b/homes/x86_64-linux/christopher@cobalt/config/editors.nix new file mode 100644 index 0000000..be3164a --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/editors.nix @@ -0,0 +1,14 @@ +{pkgs, ...}: { + # Install common editors + home.packages = with pkgs; [ + vscode + zed-editor + + # Language Servers + lua-language-server + rust-analyzer + nodePackages.typescript + nodePackages.typescript-language-server + nil # nix lsp + ]; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/fixtures.nix b/homes/x86_64-linux/christopher@cobalt/config/fixtures.nix new file mode 100644 index 0000000..1e6fee5 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/fixtures.nix @@ -0,0 +1,14 @@ +{config, ...}: { + # SSH keys and settings + # Don't copy SSH settings as they would not be readable by Docker containers + # that require them. + # home.file.".ssh" = { + # source = ../fixtures/ssh; + # recursive = true; + # }; + + home.file."${config.xdg.configHome}/eww" = { + source = ../fixtures/eww; + recursive = true; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/fonts.nix b/homes/x86_64-linux/christopher@cobalt/config/fonts.nix new file mode 100644 index 0000000..481d895 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/fonts.nix @@ -0,0 +1,19 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + nerd-fonts.monaspace # Patched fonts + google-fonts # Google fonts + monaspace + ]; + + fonts.fontconfig.enable = true; + + home.file.".local/share/fonts" = { + # This includes FontAwesome and other proprietary fonts which are licensed, + # so I have to download them from a private repository + source = builtins.fetchGit { + url = "git@github.com:padarom/fonts.git"; + rev = "2defdedf6642865648c8e57b3851a77ac0ae2d7b"; + }; + recursive = true; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/git.nix b/homes/x86_64-linux/christopher@cobalt/config/git.nix new file mode 100644 index 0000000..e539885 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/git.nix @@ -0,0 +1,42 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + # Dev tools + git + gh + gitAndTools.git-absorb + delta + + pkgs._elements.git-delete-stale + ]; + + programs.git = { + enable = true; + userName = "Christopher Mühl"; + userEmail = "christopher@muehl.dev"; + signing = { + signByDefault = true; + key = "E919B0F59E14FD47"; + }; + extraConfig = { + users.email = "padarom@users.noreply.github.com"; + push = { + default = "current"; + autoSetupRemote = true; + followTags = true; + }; + column.ui = "auto"; # Display columns in `git branch` automatically + branch.sort = "-committerdate"; # Sort `git branch` by last commit date + rerere.enabled = true; # Enable reuse recorded resolution, for automatic merge resolution + alias.force-push = "push --force-with-lease"; # Safe force pushes + fetch.writeCommitGraph = true; # Automatically write the commit graph on fetches + init.defaultBranch = "main"; + core.pager = "delta"; + interactive.diffFilter = "delta --color-only"; + delta = { + navigate = true; + dark = true; + }; + merge.conflictstyle = "zdiff3"; + }; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/hausgold.nix b/homes/x86_64-linux/christopher@cobalt/config/hausgold.nix new file mode 100644 index 0000000..94db026 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/hausgold.nix @@ -0,0 +1,29 @@ +{ + pkgs, + inputs, + ... +}: let + #ruby = pkgs."ruby-2.5"; + #bundler = pkgs.bundler.override { inherit ruby; }; +in { + home.packages = with pkgs; [ + # docker has to be installed globally because we have to enable virtualization + inputs.docker-compose-1.legacyPackages."x86_64-linux".docker-compose + + # Ruby environment + # bundler + # ruby + bundix + + # Dev environment specifics + libxcrypt # maklerportal-frontend-test-suite + postgresql + geos + + # mDNS support + nssmdns + avahi + + slack + ]; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/terminal.nix b/homes/x86_64-linux/christopher@cobalt/config/terminal.nix new file mode 100644 index 0000000..e2a4914 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/terminal.nix @@ -0,0 +1,17 @@ +{...}: { + programs.kitty = { + enable = true; + + settings = { + window_padding_width = "5 10"; + font_family = "Monaspace Krypton"; + paste_actions = "no-op"; + }; + + extraConfig = '' + modify_font cell_height 7px + ''; + + themeFile = "Catppuccin-Frappe"; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/config/wayland.nix b/homes/x86_64-linux/christopher@cobalt/config/wayland.nix new file mode 100644 index 0000000..c1a9a63 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/config/wayland.nix @@ -0,0 +1,221 @@ +{ + pkgs, + inputs, + ... +}: let + inputPkg = inputName: pluginName: inputs.${inputName}.packages.${pkgs.system}.${pluginName}; +in { + home.packages = with pkgs; [ + wl-clipboard + cliphist # Wayland clipboard + hyprpicker # Color picker + hyprpaper # Wallpaper utility + ]; + + services.hyprpaper = { + enable = true; + settings.splash = false; + }; + + wayland.windowManager.hyprland = { + enable = true; + # systemd.variables = ["--all"]; + package = inputPkg "hyprland" "hyprland"; + + plugins = [ + (inputPkg "split-monitor-workspaces" "split-monitor-workspaces") + # (inputPkg "hypridle" "hypridle") + ]; + + extraConfig = '' + # See https://wiki.hyprland.org/Configuring/Monitors + monitor=desc:Samsung Electric Company C49HG9x HTRJ901269, 3840x1080, 0x0, 1 # Left + monitor=desc:Ancor Communications Inc ASUS VE278 C5LMTF047320, 1920x1080, 3840x-550, 1, transform, 1 # Right + + # Any other random monitor + monitor=,preferred,auto,1 + + # Gaps for eww + monitor=DP-1,addreserved,40,0,0,0 + # monitor=,addreserved,40,0,0,0 + + # Single tiled windows in a workspace on my main monitor + # should be displayed with a padding on both sides + workspace=w[t1] m[0],gapsout:15 840 15 840 + + # See https://wiki.hyprland.org/Configuring/Keywords/ for more + + exec-once = ibus-daemon -drxR + exec-once = hyprpaper & # Wallpaper util + exec-once = swaync & # Notification center + exec-once = udiskie # Automatic mounting of USBs + exec-once = sleep 2; ${pkgs._elements.generate-wallpaper}/bin/generate-wallpaper + # exec-once = eval $(gnome-keyring-daemon --start --components=pkcs11,secrets,ssh) & + exec-once = eww daemon + exec-once = eww open spraggins + exec-once = wl-paste --type text --watch cliphist store + exec-once = wl-paste --type image --watch cliphist store + + # Source a file (multi-file configs) + # source = ~/.config/hypr/myColors.conf + + # Some default env vars. + env = XCURSOR_SIZE,28 + env = HYPRCURSOR_THEME,rose-pine-hyprcursor + env = HYPRCURSOR_SIZE,28 + env = WLR_NO_HARDWARE_CURSORS,1 + env = NIXOS_OZONE_WL,1 + + debug { + disable_logs = false + } + + # For all categories, see https://wiki.hyprland.org/Configuring/Variables/ + input { + kb_layout = us + kb_variant = intl + kb_model = + kb_options = + kb_rules = + + follow_mouse = 2 + + touchpad { + natural_scroll = no + } + + sensitivity = 0 # -1.0 - 1.0, 0 means no modification. + } + + general { + # See https://wiki.hyprland.org/Configuring/Variables/ for more + + gaps_in = 8 + gaps_out = 15 + border_size = 3 + col.active_border = rgba(bf616aee) rgba(ebcb8bee) 45deg + col.inactive_border = rgba(5e81acaa) + + layout = dwindle + } + + decoration { + # See https://wiki.hyprland.org/Configuring/Variables/ for more + + rounding = 2 + blur { + enabled = true + xray = true + size = 4 + noise = 0.3 + passes = 2 + } + + shadow { + enabled = true + range = 4 + render_power = 3 + color = 0xee1a1a1a + } + } + + animations { + enabled = yes + + # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more + + bezier = myBezier, 0.05, 0.9, 0.1, 1.05 + + animation = windows, 1, 7, myBezier + animation = windowsOut, 1, 7, default, popin 80% + animation = border, 1, 10, default + animation = borderangle, 1, 8, default + animation = fade, 1, 7, default + animation = workspaces, 1, 6, default + } + + plugin { + split-monitor-workspaces { + count = 10 + } + } + + dwindle { + # See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more + pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below + preserve_split = yes # you probably want this + } + + master { + # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more + # new_is_master = true + slave_count_for_center_master = 2 + orientation = center + } + + misc { + disable_hyprland_logo = true + disable_splash_rendering = true + } + + windowrule = float, class:(.*zeal.*) + windowrule = center 1, class:(.*zeal.*) + windowrule = size 50% 80%, class:(.*zeal.*) + windowrule = minsize 1400 500, class:(.*zeal.*) + + windowrule = float, class:(.*speedcrunch.*) + windowrule = center 1, class:(.*speedcrunch.*) + windowrule = size 30% 60%, class:(.*speedcrunch.*) + + windowrule = float, title:DevTools + + # See https://wiki.hyprland.org/Configuring/Keywords/ for more + $mainMod = SUPER + + # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more + bind = $mainMod, C, exec, ${pkgs._elements.spawn-term}/bin/spawn-term + bind = $mainMod, W, killactive, + # bind = $mainMod, M, exit, + bind = $mainMod, M, fullscreen, 1 + bind = $mainMod, E, exec, thunar + bind = $mainMod, V, togglefloating, + bind = $mainMod, G, exec, ${pkgs._elements.tofi-hg}/bin/tofi-hg + bind = $mainMod, D, exec, ${pkgs._elements.quick-zeal}/bin/quick-zeal + bind = $mainMod, space, exec, tofi-drun | xargs hyprctl dispatch exec -- + bind = $mainMod, P, pseudo, # dwindle + bind = $mainMod, J, togglesplit, # dwindle + + # Move focus with mainMod + arrow keys + bind = $mainMod, left, movefocus, l + bind = $mainMod, right, movefocus, r + bind = $mainMod, up, movefocus, u + bind = $mainMod, down, movefocus, d + + # Switch workspaces with mainMod + [0-9] + bind = $mainMod, 1, split-workspace, 1 + bind = $mainMod, 2, split-workspace, 2 + bind = $mainMod, 3, split-workspace, 3 + bind = $mainMod, 4, split-workspace, 4 + bind = $mainMod, 5, split-workspace, 5 + bind = $mainMod, 6, split-workspace, 6 + bind = $mainMod, 7, split-workspace, 7 + bind = $mainMod, 8, split-workspace, 8 + bind = $mainMod, 9, split-workspace, 9 + + # Move active window to a workspace with mainMod + SHIFT + [0-9] + bind = $mainMod SHIFT, 1, split-movetoworkspacesilent, 1 + bind = $mainMod SHIFT, 2, split-movetoworkspacesilent, 2 + bind = $mainMod SHIFT, 3, split-movetoworkspacesilent, 3 + bind = $mainMod SHIFT, 4, split-movetoworkspacesilent, 4 + bind = $mainMod SHIFT, 5, split-movetoworkspacesilent, 5 + bind = $mainMod SHIFT, 6, split-movetoworkspacesilent, 6 + bind = $mainMod SHIFT, 7, split-movetoworkspacesilent, 7 + bind = $mainMod SHIFT, 8, split-movetoworkspacesilent, 8 + bind = $mainMod SHIFT, 9, split-movetoworkspacesilent, 9 + + # Move/resize windows with mainMod + LMB/RMB and dragging + bindm = $mainMod, mouse:272, movewindow + bindm = $mainMod, mouse:273, resizewindow + ''; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/default.nix b/homes/x86_64-linux/christopher@cobalt/default.nix new file mode 100644 index 0000000..0191fb4 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/default.nix @@ -0,0 +1,59 @@ +{ + pkgs, + config, + lib, + ... +} @ all: { + imports = + [ + ./ssh.nix + ./gpg + ./misc/launcher.nix + ./misc/browser.nix + ./misc/gaming.nix + ./misc/onedrive.nix + ./misc/everything.nix # TODO: Determine if we really always want all these programs or they should be composable + ./global/terminal + ./global/current-packages.nix + ./editors/helix + ./editors/jetbrains + ] + ++ (import ./config.nix all); + + elements.secrets = { + rekeyPath = "christopher_cobalt"; + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHl33DPxxzxrNNjM8rL4ktAj4ExzCyGiU8rKog0csxNA"; + + needs = { + repoUpdatePAT = "repo-update-pat.age"; + npmrc = { + rekeyFile = "npmrc.age"; + path = "${config.home.homeDirectory}/.npmrc"; + }; + }; + }; + + home = { + extraOutputsToInstall = ["doc" "devdoc"]; + + # Until Home Manager 24.11 releases + stateVersion = "23.11"; + enableNixpkgsReleaseCheck = false; + + packages = with pkgs._elements; [ + quick-zeal + spawn-term + to-s3 + tofi-hg + open-url + generate-wallpaper + + # Required for eww. Move this somewhere else. + pkgs.lm_sensors + ]; + }; + + programs.home-manager.enable = true; + + # home.file.".config/Yubico/u2f_keys".text = "christopher:C7akk/T8XYov6fOk3rGo0ZW66QPMtdLnGznPuK+tTh/qmPecvECzGVMKJuh5M7nYsMoT6r/idAP88FGinf/rpw==,ydS/PgUALZriaaHYS81u3x8rRFulq727GDJRlvbJhP2yeKK7Ih+xqRceyabLR3MxRN8PT/MtC1I/Xjaxl0S2Rg==,es256,+presence"; +} diff --git a/homes/x86_64-linux/christopher@cobalt/editors/helix/default.nix b/homes/x86_64-linux/christopher@cobalt/editors/helix/default.nix new file mode 100644 index 0000000..75d087b --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/editors/helix/default.nix @@ -0,0 +1,63 @@ +{pkgs, ...}: let + catppuccin = pkgs.stdenv.mkDerivation { + name = "catppuccin-helix-theme"; + src = pkgs.fetchFromGitHub { + owner = "catppuccin"; + repo = "helix"; + rev = "3b1b0b2446791812e4a76ba147223dd5f3d4319b"; + sha256 = "7TJ1CDts0i3QPRWz/gvRpkXzh8wGGLW5cv9+Vg3K1zc="; + }; + installPhase = '' + mkdir -p $out + cp -r ./themes/* $out + ''; + }; +in { + home.packages = [pkgs.helix]; + + xdg.configFile."helix/themes/catppuccin".source = catppuccin; + + programs.helix = { + enable = true; + defaultEditor = true; + + settings = { + theme = "catppuccin"; + + editor = { + rulers = [80]; + shell = ["nu" "-c"]; + line-number = "relative"; + + auto-format = true; + file-picker.hidden = false; + + # TODO: Why does the clipboard not work? + # clipboard-provider.custom = { + # yank = {command = "wl-copy";}; + # paste = {command = "wl-paste";}; + # }; + + whitespace.render = { + tabpad = "all"; + }; + }; + }; + + languages.language = [ + { + name = "nix"; + auto-format = true; + formatter.command = "${pkgs.alejandra}/bin/alejandra"; + } + ]; + + themes = { + catppuccin = { + inherits = "catppuccin/default/catppuccin_frappe"; + "ui.background" = {}; + # "ui.virtual.whitespace" = {style = "dim";}; + }; + }; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/editors/jetbrains/default.nix b/homes/x86_64-linux/christopher@cobalt/editors/jetbrains/default.nix new file mode 100644 index 0000000..a40b53a --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/editors/jetbrains/default.nix @@ -0,0 +1,15 @@ +{ + pkgs, + config, + ... +}: let + # We install these with JetBrains toolbox for convenience' sake, but we still want them + # available in our PATH, so they are defined here. + jetbrainsIDEs = ["phpstorm" "rubymine" "rustrover" "webstorm"]; +in { + home.packages = with pkgs; [ + jetbrains-toolbox + ]; + + home.sessionPath = map (ide: "${config.home.homeDirectory}/.local/share/JetBrains/Toolbox/apps/${ide}/bin") jetbrainsIDEs; +} diff --git a/homes/x86_64-linux/christopher@cobalt/editors/nvim/config/.keep b/homes/x86_64-linux/christopher@cobalt/editors/nvim/config/.keep new file mode 100644 index 0000000..e69de29 diff --git a/homes/x86_64-linux/christopher@cobalt/editors/nvim/default.nix b/homes/x86_64-linux/christopher@cobalt/editors/nvim/default.nix new file mode 100644 index 0000000..af74d53 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/editors/nvim/default.nix @@ -0,0 +1,19 @@ +{ + pkgs, + lib, + ... +}: { + home.packages = with pkgs; [neovim ripgrep]; + + xdg.configFile.nvim.source = ./config; + + # Install the packer.nvim plugin manager + home.file = { + ".local/state/nix/profile/share/nvim/site/pack/packer/start/packer.nvim".source = pkgs.fetchFromGitHub { + owner = "wbthomason"; + repo = "packer.nvim"; + rev = "ea0cc3c"; + sha256 = "fLM+ptjMd1YNoJQEI0vvr4sjaay7dfpaGhvWUy91d1M="; + }; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/README.md b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/README.md new file mode 100644 index 0000000..0851bbe --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/README.md @@ -0,0 +1,5 @@ +In order to develop these widgets (with live reloading) do the following: + +1. Kill the original eww daemon using `eww kill` +2. Start the new daemon using `eww open main_menu --config /home/christopher/.dotfiles/home/fixtures/eww` +3. Now all changes to the original dotfiles defining the config will be hot-reloaded \ No newline at end of file diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/_catppuccin.scss b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/_catppuccin.scss new file mode 100644 index 0000000..880dcd7 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/_catppuccin.scss @@ -0,0 +1,121 @@ +// Installed via `npm install @catppuccin/palette`. +// File copied from `node_modules/@catppuccin/palette/scss`. + +// Copied here so that we don't need to run npm install for +// eww configuration. Also this file shouldn't really change +// ever, so it's fine to include it statically. + +$palette: ( + "latte": ( + "rosewater": #dc8a78, + "flamingo": #dd7878, + "pink": #ea76cb, + "mauve": #8839ef, + "red": #d20f39, + "maroon": #e64553, + "peach": #fe640b, + "yellow": #df8e1d, + "green": #40a02b, + "teal": #179299, + "sky": #04a5e5, + "sapphire": #209fb5, + "blue": #1e66f5, + "lavender": #7287fd, + "text": #4c4f69, + "subtext1": #5c5f77, + "subtext0": #6c6f85, + "overlay2": #7c7f93, + "overlay1": #8c8fa1, + "overlay0": #9ca0b0, + "surface2": #acb0be, + "surface1": #bcc0cc, + "surface0": #ccd0da, + "base": #eff1f5, + "mantle": #e6e9ef, + "crust": #dce0e8, + ), + "frappe": ( + "rosewater": #f2d5cf, + "flamingo": #eebebe, + "pink": #f4b8e4, + "mauve": #ca9ee6, + "red": #e78284, + "maroon": #ea999c, + "peach": #ef9f76, + "yellow": #e5c890, + "green": #a6d189, + "teal": #81c8be, + "sky": #99d1db, + "sapphire": #85c1dc, + "blue": #8caaee, + "lavender": #babbf1, + "text": #c6d0f5, + "subtext1": #b5bfe2, + "subtext0": #a5adce, + "overlay2": #949cbb, + "overlay1": #838ba7, + "overlay0": #737994, + "surface2": #626880, + "surface1": #51576d, + "surface0": #414559, + "base": #303446, + "mantle": #292c3c, + "crust": #232634, + ), + "macchiato": ( + "rosewater": #f4dbd6, + "flamingo": #f0c6c6, + "pink": #f5bde6, + "mauve": #c6a0f6, + "red": #ed8796, + "maroon": #ee99a0, + "peach": #f5a97f, + "yellow": #eed49f, + "green": #a6da95, + "teal": #8bd5ca, + "sky": #91d7e3, + "sapphire": #7dc4e4, + "blue": #8aadf4, + "lavender": #b7bdf8, + "text": #cad3f5, + "subtext1": #b8c0e0, + "subtext0": #a5adcb, + "overlay2": #939ab7, + "overlay1": #8087a2, + "overlay0": #6e738d, + "surface2": #5b6078, + "surface1": #494d64, + "surface0": #363a4f, + "base": #24273a, + "mantle": #1e2030, + "crust": #181926, + ), + "mocha": ( + "rosewater": #f5e0dc, + "flamingo": #f2cdcd, + "pink": #f5c2e7, + "mauve": #cba6f7, + "red": #f38ba8, + "maroon": #eba0ac, + "peach": #fab387, + "yellow": #f9e2af, + "green": #a6e3a1, + "teal": #94e2d5, + "sky": #89dceb, + "sapphire": #74c7ec, + "blue": #89b4fa, + "lavender": #b4befe, + "text": #cdd6f4, + "subtext1": #bac2de, + "subtext0": #a6adc8, + "overlay2": #9399b2, + "overlay1": #7f849c, + "overlay0": #6c7086, + "surface2": #585b70, + "surface1": #45475a, + "surface0": #313244, + "base": #1e1e2e, + "mantle": #181825, + "crust": #11111b, + ), +); diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/eww.scss b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/eww.scss new file mode 100644 index 0000000..983d2f3 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/eww.scss @@ -0,0 +1,102 @@ +@use "sass:map"; +@import "catppuccin"; + +@mixin icon { + font-family: "Font Awesome 6 Pro Dutone"; + font-weight: 900; + font-size: 22px; +} + +$font-family: ""; +$used-palette: "frappe"; +$colors: map.get($palette, $used-palette); + +$gradient: + "rosewater", "flamingo", "pink", "mauve", "red", "maroon", "peach", + "yellow", "green", "teal", "sky"; + +@each $name, $color in $colors { + .color-#{$name} { + color: $color; + } + + .bg-#{$name} { + background: $color; + } +} + +@for $i from 1 through length($gradient) { + $color: map.get($colors, nth($gradient, $i)); + + .gradient-#{$i} { + color: $color; + } + + .gradient-#{$i}:hover { + color: desaturate($color: $color, $amount: 20); + } + + .bg-gradient-#{$i} { + background: $color; + } +} + +* { + all: unset; +} + +.spraggins { + padding: 5px 15px 0; + font-family: $font-family; + color: map.get($colors, "text"); +} + +.box { + background: map.get($colors, "base"); + border-radius: 4px; + // border: 2px solid $blue; + padding: 0 12px; +} + +.icon { + @include icon; + + &.smol { + font-size: 14px; + } +} + +.time { + font-size: 18px; +} + +.date { + font-size: 12px; +} + +.workspaceButton { + &.active { + color: white; + } + + &.empty { + font-weight: 300; + opacity: 0.3; + } + + &.empty.active { + opacity: 0.6; + } +} + +.sys { + padding: 8px 0; + + label { + padding: 0 8px; + } + + .icon { + font-size: 19px; + } +} diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/eww.yuck b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/eww.yuck new file mode 100644 index 0000000..4656b37 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/eww.yuck @@ -0,0 +1,96 @@ +(include './variables.yuck') + +(defwidget workspaceButton [workspace] + (box + (eventbox + :class "workspaceButton icon gradient-${workspace.id} ${workspace.id == activeWorkspace ? 'active' : ''} ${workspace.windows == 0 ? 'empty' : ''}" + :cursor "pointer" + ; :visible {workspace.windows != 0 || workspace.id == activeWorkspace} + "${workspace.name}"))) + +(defwidget applauncher [] + (box + (eventbox + :class "icon gradient-10 applauncher" + :cursor "pointer" + :onclick "tofi-drun | xargs hyprctl dispatch exec --" + "\\ue196"))) + +(defwidget left [] + (box :class "box" :space-evenly false + (applauncher) + (box :style "padding-left: 25px;" :spacing 8 + (for space in workspaces + (workspaceButton :workspace space))))) + +(defwidget sysinfo [] + (box :space-evenly false :class "sys" + (children))) + +(defwidget system [] + (box :space-evenly false :spacing 8 + (sysinfo + (label + :class "icon intern bg-teal color-crust" + :text "\\uf2db") + (box :class "bg-crust color-text" :space-evenly false + "${round(EWW_CPU.avg, 2)} %" + (label + :class "color-overlay0" + :style "padding: 0;" + :text " |") + "${temps.cpu}")) + (sysinfo + (label + :class "icon intern bg-maroon color-base" + :text "\\uf538") + (label + :class "bg-surface0 color-text" + :text "${memory.used}")) + (sysinfo + (label + :class "icon intern bg-surface1 color-blue" + :text "\\uf0a0") + (label + :class "bg-surface2 color-text" + :text "${round(EWW_DISK["/"].used_perc, 2)} %")) + (sysinfo + (label :class "icon color-overlay2" :text "\\uf1b2") + (label + :class "color-overlay2" + :style "padding-left: 0;" + :text "${pkgCount}")))) + +(defwidget right [] + (box :spacing 20 :halign "end" :hexpand true :space-evenly false + (box :class "box" + (system)) + (box :class "box time" :space-evenly false :spacing 10 + (label + :valign "center" + :class "icon gradient-5" + :text "\\uf017") + (label + :valign "center" + :text "${time.hour}:${time.min}") + (label + :valign "center" + :class "date" + :text "${date}")))) + +(defwidget layout [] + (box + :class "layout" + :orientation "horizontal" + :space-evenly false + (left) + (right))) + +(defwindow spraggins + :monitor 0 + :stacking "bg" + :windowtype "normal" + :wm-ignore true + :exclusive true + :geometry (geometry :width "100%" :height "45") + (layout)) diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/get-active-workspace b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/get-active-workspace new file mode 100755 index 0000000..6394389 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/get-active-workspace @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +MONITOR=$1 + +if [ -z "$MONITOR" ]; then + echo "Usage: $0 " + exit 1 +fi + +PREFIX="$MONITOR" +if [ "$MONITOR" == 0 ]; then + PREFIX="" +fi + +# Output the currently selected workspace +workspace () { + hyprctl monitors -j | jq ".[] | select(.id == $MONITOR) | .activeWorkspace.id" +} +workspace + +socat -u UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | while read -r line; do + workspace +done diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/get-workspaces b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/get-workspaces new file mode 100755 index 0000000..fe23a56 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/get-workspaces @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +MONITOR=$1 + +if [ -z "$MONITOR" ]; then + echo "Usage: $0 " + exit 1 +fi + +KANJI='["一","二","三","四","五","六","七","八","九"]' +ICONS='["\\ue0ee","\\ue0ef","\\ue0f0","\\ue0f1","\\ue0f2","\\ue0f3","\\ue0f4","\\ue0f5","\\ue0f6"]' + +spaces () { + WORKSPACE_WINDOWS=$(hyprctl workspaces -j | jq "[.[] | select(.monitorID == $MONITOR)] | map({ key: (.id | tostring), value: .windows }) | from_entries") + seq 1 9 | jq --argjson windows "${WORKSPACE_WINDOWS}" --argjson kanji "${ICONS}" --slurp -Mc 'map({id: ., name: ($kanji[. - 1]), windows: ($windows[. | tostring]//0)})' +} +spaces + +socat -u UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock - | while read -r line; do + spaces +done diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/memory b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/memory new file mode 100755 index 0000000..703d2ab --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/memory @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +total="$(free -m | grep Mem | awk '{ print $2 }')" +used="$(free -m | grep Mem | awk '{ print $3 }')" +free=$(expr $total - $used) + +total_human=$(numfmt --to=iec --format="%.1f" $(( $total * 1000 * 1000 ))) +used_human=$(numfmt --to=iec --format="%.1f" $(( $used * 1000 * 1000 ))) +free_human=$(numfmt --to=iec --format="%.1f" $(( $free * 1000 * 1000 ))) + +if [ "$1" = "total" ]; then + echo $total_human +elif [ "$1" = "used" ]; then + echo $used_human +elif [ "$1" = "free" ]; then + echo $free_human +elif [ "$1" = "json" ]; then + jo total=$total_human used=$used_human free=$free_human +fi diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/pkgs b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/pkgs new file mode 100755 index 0000000..6ba372b --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/pkgs @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +global_pkgs=$(cat /etc/current-system-packages | wc -l) +hm_pkgs=$(cat /home/christopher/.cache/current-home-manager-packages | wc -l) + +echo $(( $global_pkgs + $hm_pkgs )) diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/temps b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/temps new file mode 100755 index 0000000..fe0b676 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/scripts/temps @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +cpu=$(sensors | grep 'Tctl' | head -n 1 | awk '{ print $2 }' | sed 's/\+\([0-9]\+\.\?[0-9]*\)/\1 /') + +jo cpu="$cpu" diff --git a/homes/x86_64-linux/christopher@cobalt/fixtures/eww/variables.yuck b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/variables.yuck new file mode 100644 index 0000000..7d2f07d --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/fixtures/eww/variables.yuck @@ -0,0 +1,20 @@ +(defpoll time :interval "5s" :initial `{"hour":"00","min":"00"}` + `date +'{"hour":"%H","min":"%M"}'`) + +(defpoll date :interval "5s" :initial `` + `date +'%a, %b %d'`) + +(defpoll pkgCount :interval "1m" :initial `0` + `./scripts/pkgs`) + +(defpoll temps :interval "2s" :initial "{}" + `./scripts/temps`) + +(defpoll memory :interval "2s" :initial "{}" + `./scripts/memory json`) + +(deflisten workspaces :initial "[{}]" + `./scripts/get-workspaces 0`) + +(deflisten activeWorkspace + `./scripts/get-active-workspace 0`) diff --git a/homes/x86_64-linux/christopher@cobalt/global/current-packages.nix b/homes/x86_64-linux/christopher@cobalt/global/current-packages.nix new file mode 100644 index 0000000..e8bc871 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/current-packages.nix @@ -0,0 +1,12 @@ +{ + config, + pkgs, + ... +}: { + home.file.".cache/current-home-manager-packages".text = let + packages = builtins.map (p: "${p.name}") config.home.packages; + sortedUnique = builtins.sort builtins.lessThan (pkgs.lib.lists.unique packages); + formatted = builtins.concatStringsSep "\n" sortedUnique; + in + formatted; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/default.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/default.nix new file mode 100644 index 0000000..07b5ff3 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/default.nix @@ -0,0 +1,28 @@ +{config, ...}: let + data = config.xdg.dataHome; + conf = config.xdg.configHome; + cache = config.xdg.cacheHome; +in { + imports = [ + ./programs + ./shell/aliases.nix + ./shell/nu + ./shell/zsh + ]; + + # add environment variables + home.sessionVariables = { + # clean up ~ + LESSHISTFILE = "${cache}/less/history"; + LESSKEY = "${conf}/less/lesskey"; + DIRENV_LOG_FORMAT = ""; + + BROWSER = "firefox"; + TERMINAL = "kitty"; + EDITOR = "hx"; + # QT_QPA_PLATFORMTHEME = "qt5ct"; + + # auto-run programs using nix-index-database + NIX_AUTO_RUN = "1"; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/cli.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/cli.nix new file mode 100644 index 0000000..e5e5ab9 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/cli.nix @@ -0,0 +1,37 @@ +{ + pkgs, + config, + ... +}: { + home.packages = with pkgs; [ + # Shell software + fzf # Fuzzy finding + eza # ls alternative + httpie # HTTP client / CURL alternative + yazi # Terminal file manager + + # Little thingies + gum + + gh + gitAndTools.git-absorb + direnv + + zellij # terminal workspace + silver-searcher # ag search tool + zx # Tool for writing better scripts + trurl # Parsing and manipulating URLs via CLI + onefetch # Git information tool + cloc # Line-of-code calc for entire project + delta # Diffing tool + + genact # Jibberish output ("I'm waiting for a compile.") + cbonsai # Create bonsai trees + wtfutil + ]; + + programs = { + atuin.enable = true; # Better shell history + atuin.enableNushellIntegration = true; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/default.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/default.nix new file mode 100644 index 0000000..8817b55 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./tmux.nix + ./cli.nix + ]; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/tmux.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/tmux.nix new file mode 100644 index 0000000..0f04b8c --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/programs/tmux.nix @@ -0,0 +1,16 @@ +{pkgs, ...}: { + home.packages = [pkgs.tmux]; + + home.file.".tmux.inspect.conf".text = '' + set -g status-position top + set-option -g status-bg default + set -g 'status-format[0]' '#[fill=colour202 bg=colour202 fg=colour231 bold]Danger! HAUSGOLD Inspector ' + set-option -g status-justify centre + #set -g 'status-format[1]' '#[bg=default]' + #set -g status 2 + + #set -g status-left ''' + #set -g window-status-current-format ''' + #set -g window-status-format ''' + ''; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/aliases.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/aliases.nix new file mode 100644 index 0000000..028a87f --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/aliases.nix @@ -0,0 +1,15 @@ +{lib, ...}: { + home.shellAliases = { + elements = "just -f ~/.dotfiles/Justfile -d ~/.dotfiles"; + elem = "elements"; + g = "git"; + copy = lib.mkDefault "xclip -sel clip"; + inspect = "tmux -f ~/.tmux.inspect.conf new-session ssh inspect"; + ansi = "sed -r \"s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g\""; + ssh = "TERM=xterm-color ssh"; + calc = "numbat --pretty-print never -e"; + pcalc = "numbat --pretty-print always -e"; + vim = "hx"; + vi = "hx"; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/nu/default.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/nu/default.nix new file mode 100644 index 0000000..2f73c6f --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/nu/default.nix @@ -0,0 +1,102 @@ +{ + pkgs, + config, + ... +}: { + programs.zoxide.enable = true; + programs.zoxide.enableNushellIntegration = true; + + programs.nushell = { + enable = true; + + shellAliases = config.home.shellAliases; + + plugins = with pkgs; [ + nushellPlugins.query + nushellPlugins.gstat + nushellPlugins.skim + # nushellPlugins.net + # nushellPlugins.units + ]; + + environmentVariables = config.home.sessionVariables; + + extraConfig = '' + let carapace_completer = { |spans| + carapace $spans.0 nushell ...$spans + | from json + | if ($in | default [] | where value =~ '^-.*ERR$' | is-empty) { $in } else { null } + } + + # zoxide completions https://www.nushell.sh/cookbook/external_completers.html#zoxide-completer + let zoxide_completer = { |spans| + $spans | skip 1 | zoxide query -l ...$in | lines | where { |x| $x != $env.PWD } + } + + # https://www.nushell.sh/cookbook/external_completers.html#alias-completions + let multiple_completers = { |spans| + ## alias fixer start https://www.nushell.sh/cookbook/external_completers.html#alias-completions + let expanded_alias = scope aliases + | where name == $spans.0 + | get -i 0.expansion + + let spans = if $expanded_alias != null { + $spans + | skip 1 + | prepend ($expanded_alias | split row ' ' | take 1) + } else { + $spans + } + ## alias fixer end + + match $spans.0 { + __zoxide_z | __zoxide_zi => $zoxide_completer + _ => $carapace_completer + } | do $in $spans + } + + $env.config = { + show_banner: false, + completions: { + case_sensitive: false # case-sensitive completions + quick: true # set to false to prevent auto-selecting completions + partial: true # set to false to prevent partial filling of the prompt + algorithm: "fuzzy" # prefix or fuzzy + external: { + # set to false to prevent nushell looking into $env.PATH to find more suggestions + enable: true + # set to lower can improve completion performance at the cost of omitting some options + max_results: 100 + completer: $multiple_completers + } + } + } + + $env.PATH = ($env.PATH | + split row (char esep) | + prepend /home/myuser/.apps | + append /usr/bin/env + ) + + def agx [search] { + hx (ag $search | fzf | cut -d : -f 1,2) + } + ''; + + envFile.text = '' + $env.PATH = ( + $env.PATH + | split row (char esep) + | append $"($env.HOME)/code/hausgold/snippets/bin" + | append $"($env.HOME)/.bun/bin" + | append $"($env.HOME)/.npm/bin" + ) + ''; + }; + + # Shell completions + programs.carapace = { + enable = true; + enableNushellIntegration = true; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/antigen.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/antigen.nix new file mode 100644 index 0000000..719a39a --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/antigen.nix @@ -0,0 +1,45 @@ +{ + config, + pkgs, + ... +}: { + home.packages = [pkgs.antigen]; + + # Antigen (Zsh Plugin Manager) + home.file.".antigenrc".text = '' + # Load oh-my-zsh + antigen use oh-my-zsh + + # Load bundles from the default oh-my-zsh repo + antigen bundle git + antigen bundle docker + antigen bundle command-not-found + antigen bundle vscode + # antigen bundle vi-mode + # antigen bundle gh # gh autocompletion + # antigen bundle 1password + # antigen bundle marlonrichert/zsh-autocomplete@main + # antigen bundle supercrabtree/k + antigen bundle fzf + antigen bundle zoxide + antigen bundle safe-paste + antigen bundle colored-man-pages + antigen bundle zsh-users/zsh-syntax-highlighting + antigen bundle zsh-users/zsh-autosuggestions + + # Configure a default theme + THEME="https://github.com/caiogondim/bullet-train-oh-my-zsh-theme bullet-train" + + # Change the theme configuration if the terminal was started via VS Code + if [[ "$TERM_PROGRAM" == "vscode" ]]; then + THEME="robbyrussel" + fi + + # Enable the configured theme + # eval "antigen theme $THEME" + # eval "$(starship init zsh)" + + # And we're done + antigen apply + ''; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/default.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/default.nix new file mode 100644 index 0000000..71ce799 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/default.nix @@ -0,0 +1,51 @@ +{ + pkgs, + config, + ... +}: { + imports = [ + ./antigen.nix + ./prompt.nix + ]; + + programs.zoxide.enableZshIntegration = true; + + programs.zsh = { + enable = true; + dotDir = ".config/zsh"; + oh-my-zsh.enable = true; + + shellAliases = config.home.shellAliases; + + # Add our own binaries to the PATH variable + initContent = '' + # Load Antigen as our package manager. + # The .antigenrc file is copied via the fixtures.nix + source ${pkgs.antigen.outPath}/share/antigen/antigen.zsh + antigen init ~/.antigenrc + + export PATH="$HOME/code/hausgold/snippets/bin:$PATH" + export PATH="$HOME/.bun/bin:$HOME/.npm/bin:$PATH" + + art() + { + if [ -f "./vendor/bin/sail" ]; + then + ./vendor/bin/sail artisan "$@" + else + php artisan "$@" + fi + } + + sail() + { + if [ -f "./vendor/bin/sail" ]; + then + ./vendor/bin/sail "$@" + else + echo "Sail is not installed. Run 'composer require laravel/sail' to install it." + fi + } + ''; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/prompt.nix b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/prompt.nix new file mode 100644 index 0000000..305ac85 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/global/terminal/shell/zsh/prompt.nix @@ -0,0 +1,46 @@ +{ + programs.starship.enable = true; + + # (https://starship.rs/guide/) + # Define a Pure-ish prompt + programs.starship.settings = { + format = '' + $username$hostname$directory$git_branch$git_state$git_status$cmd_duration$line_break$character + ''; + + directory.style = "blue"; + + character = { + success_symbol = "[❯](purple)"; + error_symbol = "[❯](red)"; + vimcmd_symbol = "[❮](green)"; + }; + + git_branch = { + format = "[$branch]($style)"; + style = "bright-black"; + }; + + git_status = { + format = "[[(*$conflicted$untracked$modified$staged$renamed$deleted)](218) ($ahead_behind$stashed)]($style)"; + style = "cyan"; + conflicted = "​"; + untracked = "​"; + modified = "​"; + staged = "​"; + renamed = "​"; + deleted = "​"; + stashed = "≡"; + }; + + git_state = { + format = "\([$state( $progress_current/$progress_total)]($style)\) "; + style = "bright-black"; + }; + + cmd_duration = { + format = "[$duration]($style) "; + style = "yellow"; + }; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/gpg/default.nix b/homes/x86_64-linux/christopher@cobalt/gpg/default.nix new file mode 100644 index 0000000..7fef4d7 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/gpg/default.nix @@ -0,0 +1,15 @@ +{pkgs, ...}: { + # TODO: Is this needed if `services.gpg-agent.pinentryPackage` is specified? + home.packages = [pkgs.pinentry-qt]; + + programs.gpg.enable = true; + + services.gpg-agent = { + enable = true; + pinentry.package = pkgs.pinentry-qt; + }; + + # home.file.".gnupg/gpg-agent.conf".text = '' + # pinentry-program /run/current-system/sw/bin/pinentry + # ''; +} diff --git a/homes/x86_64-linux/christopher@cobalt/misc/browser.nix b/homes/x86_64-linux/christopher@cobalt/misc/browser.nix new file mode 100644 index 0000000..cd7ca5e --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/misc/browser.nix @@ -0,0 +1,19 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + firefox + ]; + + xdg.mimeApps = { + enable = true; + defaultApplications = { + "x-scheme-handler/http" = "open-url.desktop"; + "x-scheme-handler/https" = "open-url.desktop"; + }; + }; + + # profile-sync-daemon manages browser profiles in tmpfs + services.psd = { + enable = true; + resyncTimer = "10m"; + }; +} diff --git a/homes/x86_64-linux/christopher@cobalt/misc/everything.nix b/homes/x86_64-linux/christopher@cobalt/misc/everything.nix new file mode 100644 index 0000000..fbbf370 --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/misc/everything.nix @@ -0,0 +1,46 @@ +{pkgs, ...}: { + # TODO: Move these into individual modules rather than a catch-all + home.packages = with pkgs; [ + gnupg + unzip + tldr # Quick man-page replacement + hyperfine # Terminal benchmarks + numbat # Scientific calculations + hexyl # Hex viewer + pastel # Color analyzer + yubikey-manager + croc # File transfer + zotero # Collect research sources + solaar # Logitech mouse driver + btop # Better resource monitor + bottom # System resource monitor + + # GUI + # obsidian # Note taking + vlc # Video player + todoist-electron # Todo application + logseq # Knowledge Base + obsidian # Same as above + calibre # eBook Manager + vesktop # Discord Messenger + obs-studio # OBS Studio + wasistlos # WhatsApp client + libreoffice # Productivity Suite (like Microsoft Office) + cider # Apple Music player + filezilla # FTP Client + zathura # Document viewer + orca-slicer # Bambu Lab Slicer + Control + weylus # Use iPad Pro as graphics tablet + krita # Drawing software + mochi # SRS flashcards + # spacedrive # File explorer (Alpha, not usable yet) + thunderbird # Email client + speedcrunch # GUI calculator app + shotcut # Video editing + naps2 # Scanning + + feh # Image viewer + xarchiver # Archive viewer/extractor + evince # Document viewer + ]; +} diff --git a/homes/x86_64-linux/christopher@cobalt/misc/gaming.nix b/homes/x86_64-linux/christopher@cobalt/misc/gaming.nix new file mode 100644 index 0000000..eb11f1e --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/misc/gaming.nix @@ -0,0 +1,23 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + prismlauncher # minecraft launcher + heroic # gog/epic launcher + + # game manager + (lutris.override { + extraLibraries = pkgs: + with pkgs; [ + libadwaita + libunwind + gtk4 + ]; + }) + + # wine + #(wineWowPackages.stable.override {waylandSupport = true;}) + #winetricks + + gamemode # performance mode + mangohud # performance overlays + ]; +} diff --git a/homes/x86_64-linux/christopher@cobalt/misc/launcher.nix b/homes/x86_64-linux/christopher@cobalt/misc/launcher.nix new file mode 100644 index 0000000..0f219da --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/misc/launcher.nix @@ -0,0 +1,13 @@ +{ + pkgs, + lib, + ... +}: { + home.packages = with pkgs; [tofi]; + + # Clear the tofi cache after each activation so that newly installed packages + # are immediately available using tofi-drun. + home.activation.cleanTofiCache = lib.hm.dag.entryAfter ["writeBoundary"] '' + rm -rf ~/.cache/tofi-drun + ''; +} diff --git a/homes/x86_64-linux/christopher@cobalt/misc/onedrive.nix b/homes/x86_64-linux/christopher@cobalt/misc/onedrive.nix new file mode 100644 index 0000000..2e896ed --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/misc/onedrive.nix @@ -0,0 +1,14 @@ +{config, ...}: let + mountpoint = "${config.home.homeDirectory}/OneDrive"; +in { + # onedriver sets up its own systemd service. + programs.onedrive = { + enable = true; + # settings = { + # skip_dir = "Dokumente|Backup"; + # skip_dir_strict_match = "true"; + # }; + }; + + home.file."Dokumente".source = config.lib.file.mkOutOfStoreSymlink "${mountpoint}/_EchteDokumente"; +} diff --git a/homes/x86_64-linux/christopher@cobalt/misc/udiskie.nix b/homes/x86_64-linux/christopher@cobalt/misc/udiskie.nix new file mode 100644 index 0000000..81fc5df --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/misc/udiskie.nix @@ -0,0 +1,3 @@ +{...}: { + services.udiskie.enable = true; +} diff --git a/homes/x86_64-linux/christopher@cobalt/ssh.nix b/homes/x86_64-linux/christopher@cobalt/ssh.nix new file mode 100644 index 0000000..a21f69c --- /dev/null +++ b/homes/x86_64-linux/christopher@cobalt/ssh.nix @@ -0,0 +1,27 @@ +{ + pkgs, + config, + lib, + ... +}: let + keys = [ + "id_ethnuc" + "id_europium" + "id_github" + "id_hausgold" + "id_homeassistant" + "id_rhenium" + ]; +in with lib.attrsets; { + elements.secrets.needs = builtins.listToAttrs ( + builtins.map + (key: lib.attrsets.nameValuePair key { + rekeyFile = "ssh/${key}.age"; + path = "${config.home.homeDirectory}/.ssh/${key}"; + + symlink = false; + mode = "0600"; + }) + keys + ); +} diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 0000000..5b2d379 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,42 @@ +{lib, ...}: rec { + rootPath = ./..; + secret = name: ./../secrets/${name}; + + commonHomeModule = module: ./../homes/common + "/${module}"; + + enabled = {enable = true;}; + disabled = {enable = false;}; + + agenixRekeyConfig = self: config: { + rekey = { + hostPubkey = config.key; + + # See https://github.com/oddlama/agenix-rekey?tab=readme-ov-file#local for + # potential effects of this decision. + storageMode = "local"; + localStorageDir = self + "/secrets/rekeyed/${config.rekeyPath}"; + + # Used to decrypt stored secrets for rekeying. + masterIdentities = [ + (self + "/secrets/keys/master-identity.pub") + ]; + + # Keys that will always be encrypted for. These act as backup keys in case the + # master identities are somehow lost. + extraEncryptionPubkeys = [ + "age1zd8wxnmgf04qcan9cvs0736valy8407f497fw9j0auwf072yadzqqdqsj9" + ]; + }; + + secrets = + lib.attrsets.mapAttrs + ( + name: secret: ( + if builtins.isString secret + then {rekeyFile = self + "/secrets/${secret}";} + else secret // {rekeyFile = self + "/secrets/${secret.rekeyFile}";} + ) + ) + config.needs; + }; +} diff --git a/modules/darwin/secrets/default.nix b/modules/darwin/secrets/default.nix new file mode 100644 index 0000000..ff748aa --- /dev/null +++ b/modules/darwin/secrets/default.nix @@ -0,0 +1,6 @@ +{...}: { + # Use the same secrets (agenix) module for darwin as we have already configured + # for nixos as its functionality is not system-dependent. + + imports = [../../nixos/secrets]; +} diff --git a/modules/home/secrets/default.nix b/modules/home/secrets/default.nix new file mode 100644 index 0000000..a678484 --- /dev/null +++ b/modules/home/secrets/default.nix @@ -0,0 +1,40 @@ +{ + pkgs, + inputs, + lib, + config, + ... +}: +with lib; let + cfg = config.elements.secrets; +in { + imports = [ + inputs.agenix.homeManagerModules.default + inputs.agenix-rekey.homeManagerModules.default + ]; + + options = { + elements.secrets = { + rekeyPath = mkOption { + type = types.str; + }; + + key = mkOption { + type = types.str; + }; + + needs = mkOption { + type = types.attrsOf (types.either types.str types.attrs); + default = {}; + }; + }; + }; + + config.age = + (lib._elements.agenixRekeyConfig inputs.self cfg) + // { + identityPaths = ["${config.home.homeDirectory}/.ssh/key"]; + secretsDir = "${config.home.homeDirectory}/.local/share/agenix/agenix"; + secretsMountPoint = "${config.home.homeDirectory}/.local/share/agenix/agenix.d"; + }; +} diff --git a/modules/nixos/common/core/default.nix b/modules/nixos/common/core/default.nix new file mode 100644 index 0000000..35223ae --- /dev/null +++ b/modules/nixos/common/core/default.nix @@ -0,0 +1,15 @@ +{lib, ...}: { + documentation.dev.enable = true; + + i18n = { + defaultLocale = "en_US.UTF-8"; + supportedLocales = [ + "en_US.UTF-8/UTF-8" + "de_DE.UTF-8/UTF-8" + ]; + }; + + system.stateVersion = lib.mkDefault "24.11"; + + time.timeZone = lib.mkDefault "Europe/Berlin"; +} diff --git a/modules/nixos/common/core/nix.nix b/modules/nixos/common/core/nix.nix new file mode 100644 index 0000000..d7c3150 --- /dev/null +++ b/modules/nixos/common/core/nix.nix @@ -0,0 +1,37 @@ +{ + self, + pkgs, + config, + ... +}: { + # Needed for Nix flakes + environment.systemPackages = [pkgs.git]; + + nix.settings = { + # auto-optimize-store = true; + # builders-use-substitutes = true; + experimental-features = ["nix-command" "flakes"]; + flake-registry = "/etc/nix/registry.json"; + + keep-derivations = true; + keep-outputs = true; + + trusted-users = ["root" "@wheel"]; + }; + + nixpkgs = { + config.allowUnfree = true; + config.permittedInsecurePackages = [ + "nixos-config" + "electron-27.3.11" + "dotnet-sdk-6.0.428" + ]; + }; + + environment.etc."current-system-packages".text = let + packages = builtins.map (p: "${p.name}") config.environment.systemPackages; + sortedUnique = builtins.sort builtins.lessThan (pkgs.lib.lists.unique packages); + formatted = builtins.concatStringsSep "\n" sortedUnique; + in + formatted; +} diff --git a/modules/nixos/common/core/users.nix b/modules/nixos/common/core/users.nix new file mode 100644 index 0000000..affa1d2 --- /dev/null +++ b/modules/nixos/common/core/users.nix @@ -0,0 +1,50 @@ +{ + inputs, + config, + pkgs, + lib, + ... +}: let + cfg = config.elements; +in + with lib; + with builtins; { + options = { + elements = { + users = mkOption { + type = types.listOf types.str; + default = []; + }; + }; + }; + + config = let + mkIfUser = name: mkIf (elem name cfg.users); + #secretFor = name: file: mkIfUser name {rekeyFile = ./../../../.. + "/secrets/${file}";}; + in { + # age.secrets.christopher-password = secretFor "christopher" "christopher-password.age"; + + users = { + users.christopher = mkIfUser "christopher" { + isNormalUser = true; + # passwordFile = config.age.secrets.christopher-password.path; + shell = pkgs.nushell; + extraGroups = [ + "wheel" + "docker" + "dialout" + "uinput" + "pico" + ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBEqcR3f71g7yuxQtUewrqdoEh8jDHtkB1973GF0EQ6q christopher@all" + ]; + }; + + groups.christopher = { + members = ["christopher"]; + gid = 1000; + }; + }; + }; + } diff --git a/modules/nixos/common/default.nix b/modules/nixos/common/default.nix new file mode 100644 index 0000000..f27dfa0 --- /dev/null +++ b/modules/nixos/common/default.nix @@ -0,0 +1,19 @@ +{ + inputs, + pkgs, + ... +}: { + imports = [ + ./core + ./core/users.nix + ./core/nix.nix + + ./programs/home-manager.nix + ./programs/zsh.nix + ]; + + environment.systemPackages = with pkgs; [ + pre-commit + gitleaks + ]; +} diff --git a/modules/nixos/common/programs/home-manager.nix b/modules/nixos/common/programs/home-manager.nix new file mode 100644 index 0000000..112feae --- /dev/null +++ b/modules/nixos/common/programs/home-manager.nix @@ -0,0 +1,7 @@ +{inputs, ...}: { + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + backupFileExtension = "hm.bak"; + }; +} diff --git a/modules/nixos/common/programs/zsh.nix b/modules/nixos/common/programs/zsh.nix new file mode 100644 index 0000000..1d9c7bd --- /dev/null +++ b/modules/nixos/common/programs/zsh.nix @@ -0,0 +1,26 @@ +{ + environment.pathsToLink = ["/share/zsh"]; + + programs = { + less.enable = true; + + zsh = { + enable = true; + autosuggestions.enable = true; + syntaxHighlighting = { + enable = true; + patterns = { + "rm -rf *" = "fg=black,bg=red"; + }; + styles = { + "aliases" = "fg=magenta"; + }; + highlighters = [ + "main" + "brackets" + "pattern" + ]; + }; + }; + }; +} diff --git a/modules/nixos/common/services/shutdown.nix b/modules/nixos/common/services/shutdown.nix new file mode 100644 index 0000000..76760f6 --- /dev/null +++ b/modules/nixos/common/services/shutdown.nix @@ -0,0 +1,42 @@ +{pkgs, ...}: let + # The command to run in order to shut down the computer + command = "${pkgs.systemd}/bin/systemctl poweroff -i"; + + # Write this command into a shell script + bin = pkgs.writeShellScriptBin "shutdown" command; +in { + users.users.hass = { + isNormalUser = true; + home = "/home/hass"; + description = "HomeAssistant automations"; + extraGroups = []; + openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICzLKowPwiQtAIgrY1wSvdolcDkbXokWrda//EEzQfR5 root@homeassistant"]; + }; + + # Create a symlink to the shell script we created to the absolute path + # /etc/shutdown-script + environment.etc.shutdown-script.source = "${bin}/bin/shutdown"; + + security.sudo.extraRules = [ + { + users = ["hass"]; + commands = [ + { + # Allow the 'hass' user to run the shutdown script + command = "/etc/shutdown-script"; + options = ["NOPASSWD"]; + } + ]; + } + ]; + + # Allow the 'hass' user to log in, but not via password authentication. + # The authorized key is specified above. + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + AllowUsers = ["hass"]; + }; + }; +} diff --git a/modules/nixos/common/services/ssh.nix b/modules/nixos/common/services/ssh.nix new file mode 100644 index 0000000..eef589e --- /dev/null +++ b/modules/nixos/common/services/ssh.nix @@ -0,0 +1,9 @@ +{pkgs, ...}: { + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + AllowUsers = ["christopher"]; + }; + }; +} diff --git a/modules/nixos/elements/default.nix b/modules/nixos/elements/default.nix new file mode 100644 index 0000000..552683e --- /dev/null +++ b/modules/nixos/elements/default.nix @@ -0,0 +1,18 @@ +{ + config, + lib, + ... +}: +with lib; let + cfg = config.elements; +in { + options = { + elements = { + hostname = mkOption {type = types.str;}; + }; + }; + + config = { + networking.hostName = cfg.hostname; + }; +} diff --git a/modules/nixos/quirks/avahi.nix b/modules/nixos/quirks/avahi.nix new file mode 100644 index 0000000..054cae6 --- /dev/null +++ b/modules/nixos/quirks/avahi.nix @@ -0,0 +1,42 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + config = lib.mkIf (builtins.elem "avahi" config.elements.quirks) { + services = { + # Name Server Caching Daemon + nscd = { + enable = true; + enableNsncd = true; + }; + + # Avahi mDNS service discovery + avahi = { + enable = true; + + # Due to some quirk this has to stay disabled. Instead, we have to specify + # system.nssModules = [pkgs.nssmdns]; + nssmdns4 = false; + ipv6 = false; + + publish = { + enable = true; + addresses = true; + domain = true; + userServices = true; + workstation = true; + }; + }; + }; + + system = { + nssModules = [pkgs.nssmdns]; + + # This order is required for avahi to work (uses mdns4 rather than mdns_minimal). + nssDatabases.hosts = lib.mkForce ["files myhostname mdns4 [NOTFOUND=return] resolve [!UNAVAIL=return] dns"]; + }; + }; +} diff --git a/modules/nixos/quirks/default.nix b/modules/nixos/quirks/default.nix new file mode 100644 index 0000000..2d139c1 --- /dev/null +++ b/modules/nixos/quirks/default.nix @@ -0,0 +1,16 @@ +{lib, ...}: { + # All quirks are imported and check themselves whether they are enabled + # via `(builtins.elem "quirk" config.elements.quirks)`. + imports = [ + ./avahi.nix + ./docker.nix + ./nix-ld.nix + ]; + + options.elements = with lib; { + quirks = mkOption { + type = types.listOf types.str; + default = []; + }; + }; +} diff --git a/modules/nixos/quirks/docker.nix b/modules/nixos/quirks/docker.nix new file mode 100644 index 0000000..ab2713d --- /dev/null +++ b/modules/nixos/quirks/docker.nix @@ -0,0 +1,30 @@ +{ + config, + inputs, + lib, + ... +}: { + config = lib.mkIf (builtins.elem "avahi" config.elements.quirks) { + # Use legacy docker compose v1 + environment.systemPackages = [ + inputs.docker-compose-1.legacyPackages."x86_64-linux".docker-compose + ]; + + virtualisation = { + docker = { + enable = true; + + # https://github.com/hausgold/knowledge/blob/master/troubleshooting/local-env-quirks.md#haproxy--docker-ulimit-glitch + daemon.settings = { + default-ulimits = { + nofile = { + Hard = 100000; + Soft = 100000; + Name = "nofile"; + }; + }; + }; + }; + }; + }; +} diff --git a/modules/nixos/quirks/nix-ld.nix b/modules/nixos/quirks/nix-ld.nix new file mode 100644 index 0000000..b549288 --- /dev/null +++ b/modules/nixos/quirks/nix-ld.nix @@ -0,0 +1,125 @@ +{ + config, + pkgs, + lib, + ... +}: { + config = lib.mkIf (builtins.elem "nix-ld" config.elements.quirks) { + programs.nix-ld.enable = true; + programs.nix-ld.libraries = with pkgs; [ + SDL + SDL2 + SDL2_image + SDL2_mixer + SDL2_ttf + SDL_image + SDL_mixer + SDL_ttf + alsa-lib + at-spi2-atk + at-spi2-core + atk + bzip2 + cairo + cups + curlWithGnuTls + dbus + dbus-glib + desktop-file-utils + e2fsprogs + expat + flac + fontconfig + freeglut + freetype + fribidi + fuse + fuse3 + gdk-pixbuf + glew110 + glib + gmp + gst_all_1.gst-plugins-base + gst_all_1.gst-plugins-ugly + gst_all_1.gstreamer + gtk2 + harfbuzz + icu + keyutils.lib + libGL + libGLU + libappindicator-gtk2 + libcaca + libcanberra + libcap + libclang.lib + libdbusmenu + libdrm + libgcrypt + libgpg-error + libidn + libjack2 + libjpeg + libmikmod + libogg + libpng12 + libpulseaudio + librsvg + libsamplerate + libthai + libtheora + libtiff + libudev0-shim + libusb1 + libuuid + libvdpau + libvorbis + libvpx + libxcrypt-legacy + libxkbcommon + libxml2 + mesa + nspr + nss + openssl + p11-kit + pango + pixman + python3 + speex + stdenv.cc.cc + tbb + udev + vulkan-loader + wayland + xorg.libICE + xorg.libSM + xorg.libX11 + xorg.libXScrnSaver + xorg.libXcomposite + xorg.libXcursor + xorg.libXdamage + xorg.libXext + xorg.libXfixes + xorg.libXft + xorg.libXi + xorg.libXinerama + xorg.libXmu + xorg.libXrandr + xorg.libXrender + xorg.libXt + xorg.libXtst + xorg.libXxf86vm + xorg.libpciaccess + xorg.libxcb + xorg.xcbutil + xorg.xcbutilimage + xorg.xcbutilkeysyms + xorg.xcbutilrenderutil + xorg.xcbutilwm + xorg.xkeyboardconfig + xz + zlib + ]; + }; +} diff --git a/modules/nixos/secrets/default.nix b/modules/nixos/secrets/default.nix new file mode 100644 index 0000000..2640abc --- /dev/null +++ b/modules/nixos/secrets/default.nix @@ -0,0 +1,40 @@ +# All hosts automatically include this module. This also means that it is necessary for +# every host to specify the option `elements.secrets.key = "key";`. +{ + config, + system, + inputs, + pkgs, + lib, + ... +}: +with lib; let + cfg = config.elements.secrets; +in { + options = { + elements.secrets = { + rekeyPath = mkOption { + type = types.str; + default = config.elements.hostname; + }; + + key = mkOption { + type = types.str; + }; + + needs = mkOption { + type = types.attrsOf (types.either types.str types.attrs); + default = {}; + }; + }; + }; + + config = { + environment.systemPackages = [ + pkgs.age-plugin-yubikey + inputs.agenix-rekey.packages.${system}.default + ]; + + age = lib._elements.agenixRekeyConfig inputs.self cfg; + }; +} diff --git a/overlays/.gitkeep b/overlays/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/packages/scripts/connect-to-mercury/connect-to-mercury b/packages/scripts/connect-to-mercury/connect-to-mercury new file mode 100755 index 0000000..cd9f112 --- /dev/null +++ b/packages/scripts/connect-to-mercury/connect-to-mercury @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +hostname="mercury.local" +ip=$(dscacheutil -q host -a name ${hostname} | tail -n2 | head -n1 | cut -d' ' -f 2) + +if [ -z "${ip}" ]; then + echo "Host ${hostname} seems to be down. Are you sure the VM is running?" + exit 1 +fi + +echo "${hostname}: ${ip}" + +sudo route -n delete 172.17.0.0/16 &>/dev/null +sudo route -n add 172.17.0.0/16 "${ip}" &>/dev/null diff --git a/packages/scripts/connect-to-mercury/default.nix b/packages/scripts/connect-to-mercury/default.nix new file mode 100644 index 0000000..1fc8da2 --- /dev/null +++ b/packages/scripts/connect-to-mercury/default.nix @@ -0,0 +1,5 @@ +{pkgs, ...}: +pkgs.writeShellApplication { + name = "connect-to-mercury"; + text = builtins.readFile ./connect-to-mercury; +} diff --git a/packages/scripts/generate-wallpaper/default.nix b/packages/scripts/generate-wallpaper/default.nix new file mode 100644 index 0000000..c01cbee --- /dev/null +++ b/packages/scripts/generate-wallpaper/default.nix @@ -0,0 +1,5 @@ +{pkgs, ...}: +pkgs.writeShellApplication { + name = "generate-wallpaper"; + text = builtins.readFile ./generate-wallpaper; +} diff --git a/packages/scripts/generate-wallpaper/generate-wallpaper b/packages/scripts/generate-wallpaper/generate-wallpaper new file mode 100755 index 0000000..934ec28 --- /dev/null +++ b/packages/scripts/generate-wallpaper/generate-wallpaper @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +THEME_FILE_YAML="/tmp/base16.yml" +THEME_FILE_JSON="/tmp/base16.json" + +wget https://raw.githubusercontent.com/catppuccin/base16/refs/heads/main/base16/macchiato.yaml -O "$THEME_FILE_YAML" +yq '.' "$THEME_FILE_YAML" > "$THEME_FILE_JSON" + +THEME_NAME=$(jq -r '.scheme' "$THEME_FILE_JSON") +THEME_NAME_LWR=$(echo "$THEME_NAME" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') + +WALLPAPER_BASE="/tmp/wallpaper" +WALLPAPER_PATH="$WALLPAPER_BASE/$THEME_NAME/Circuits wallpaper/themer-$THEME_NAME_LWR-dark" +WALLPAPER_DIR=$(dirname "$WALLPAPER_PATH") + +npx themer -t wallpaper-circuits -o "$WALLPAPER_BASE" --color-set "$THEME_FILE_JSON" -s 3840x1080 -s 1080x1920 +find "$WALLPAPER_DIR" -type f -iname '*.svg' | sed 'p;s/\.svg/\.png/' | sed 's/.*/"&"/' | xargs -n2 magick + +hyprctl hyprpaper reload DP-1,"$WALLPAPER_PATH-3840x1080.png" +hyprctl hyprpaper reload DP-3,"$WALLPAPER_PATH-1080x1920.png" diff --git a/packages/scripts/git-delete-stale/default.nix b/packages/scripts/git-delete-stale/default.nix new file mode 100644 index 0000000..0cdc08b --- /dev/null +++ b/packages/scripts/git-delete-stale/default.nix @@ -0,0 +1,39 @@ +{pkgs, ...}: +pkgs.writeTextFile rec { + name = "git-delete-stale"; + destination = "/bin/${name}"; + executable = true; + + text = '' + #!${pkgs.nushell}/bin/nu + + let localBranches = ( + git branch + | lines + | str trim + | where not ($it | str starts-with '* ') + | where $it != 'master' + ) + + let remoteBranches = ( + git branch -r + | lines + | str trim + | str replace 'origin/' "" + ) + + let staleBranches = ($localBranches | where { |$local| $local not-in $remoteBranches }) + + if ($staleBranches | is-empty) { + print 'No stale branches found.' + exit 0 + } + + let deleteBranches = (gum choose --header "Stale branches to delete" --no-limit ...($staleBranches) | lines | compact -e) + if ($deleteBranches | length) > 0 { + git branch -D ...($deleteBranches) + } else { + print 'No branches selected.' + } + ''; +} diff --git a/packages/scripts/open-url/default.nix b/packages/scripts/open-url/default.nix new file mode 100644 index 0000000..c240a76 --- /dev/null +++ b/packages/scripts/open-url/default.nix @@ -0,0 +1,17 @@ +{pkgs, ...}: let + name = "open-url"; + bin = pkgs.writeShellApplication { + inherit name; + text = builtins.readFile ./open-url; + }; + + desktopItem = pkgs.makeDesktopItem { + inherit name; + desktopName = "Open URL in a Browser"; + exec = "${bin}/bin/${name}"; + }; +in + pkgs.symlinkJoin { + inherit name; + paths = [bin desktopItem]; + } diff --git a/packages/scripts/open-url/open-url b/packages/scripts/open-url/open-url new file mode 100755 index 0000000..a36945e --- /dev/null +++ b/packages/scripts/open-url/open-url @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Go up the parent chain of this process to determine if the link was clicked on +# in Slack. If so, open the `Work` profile on firefox. +parent=$PPID +while [ "$parent" -ne 1 ]; do + cmd=$(ps -o comm= -p "$parent") + if [[ "$cmd" == "slack" ]]; then + firefox -P 'Work' "$@" + exit 0 + fi + parent=$(ps -o ppid= -p "$parent" | tail -n 1 | awk '{print $1}') +done + +if [[ $1 == "https://github.com/hausgold"* ]]; then + # Also use the `Work` profile for hausgold Github links + firefox -P 'Work' "$@" +else + # Otherwise just use the default profile of Firefox directly + firefox "$@" +fi diff --git a/packages/scripts/quick-zeal/default.nix b/packages/scripts/quick-zeal/default.nix new file mode 100644 index 0000000..7efb1bd --- /dev/null +++ b/packages/scripts/quick-zeal/default.nix @@ -0,0 +1,5 @@ +{pkgs, ...}: +pkgs.writeShellApplication { + name = "quick-zeal"; + text = builtins.readFile ./quick-zeal; +} diff --git a/packages/scripts/quick-zeal/quick-zeal b/packages/scripts/quick-zeal/quick-zeal new file mode 100755 index 0000000..aa76705 --- /dev/null +++ b/packages/scripts/quick-zeal/quick-zeal @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Define a function to extract the major version and normalize version strings +extract_major_version() { + echo "$1" | grep -oP "\d+" | head -1 +} + +# Detects the focused window and checks if it's Kitty +ACTIVE_WINDOW=$(hyprctl activewindow -j | jq -r '.class') + +# Check if the focused window is a Kitty terminal and if it's in a Git repository. +# If so, determine the project type and open Zeal with the appropriate argument +zeal_argument="" +if [[ $ACTIVE_WINDOW == "kitty" ]]; then + PID=$(hyprctl activewindow -j | jq -r '.pid') + CHILD_PID=$(pgrep -P "$PID" | tail -1) + + SHELL_CWD=$(readlink -f "/proc/${CHILD_PID}/cwd") + echo "Current path: $SHELL_CWD" + + cd "$SHELL_CWD" || exit + echo "Kitty terminal is focused." + + if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + echo " - This is a Git repository." + + if [[ -f "Gemfile" ]]; then + echo " - Detected a Ruby project." + # Check for ActiveSupport or Rails + if grep -q "activesupport\|rails" Gemfile.lock; then + framework_version=$(grep -oP "(activesupport|rails) \(\K=[^)]+" Gemfile.lock | head -1 | tr -d ' =' | cut -d '.' -f1) + echo " - Framework major version: $framework_version" + zeal_argument="ror$framework_version," + fi + + ruby_version=$(ruby -v | grep -oP "\d+\.\d+\.\d+" | cut -d '.' -f1) + echo " - Ruby major version: $ruby_version" + zeal_argument+="ruby$ruby_version:" + + elif [[ -f "Cargo.toml" ]]; then + echo " - Detected a Rust project." + zeal_argument="rust:" + + elif [[ -f "package.json" ]]; then + if grep -q '"typescript":' package.json; then + echo " - Detected a TypeScript project." + zeal_argument="typescript:" + else + echo " - Detected a JavaScript or Node project." + zeal_argument="javascript:" + fi + + else + echo " - Project type could not be determined." + fi + + else + echo " - Not a Git repository." + fi +fi + +# Launch Zeal with or without arguments based on detection +(&>/dev/null zeal "$zeal_argument" &) diff --git a/packages/scripts/spawn-term/default.nix b/packages/scripts/spawn-term/default.nix new file mode 100644 index 0000000..1f410eb --- /dev/null +++ b/packages/scripts/spawn-term/default.nix @@ -0,0 +1,5 @@ +{pkgs, ...}: +pkgs.writeShellApplication { + name = "spawn-term"; + text = builtins.readFile ./spawn-term; +} diff --git a/packages/scripts/spawn-term/spawn-term b/packages/scripts/spawn-term/spawn-term new file mode 100755 index 0000000..8d8229b --- /dev/null +++ b/packages/scripts/spawn-term/spawn-term @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +ACTIVE_WINDOW=$(hyprctl activewindow -j ) +ACTIVE_CLASS=$(echo "$ACTIVE_WINDOW" | jq -r .initialClass) + +if [[ $ACTIVE_CLASS == *"kitty"* ]] +then + PID=$(echo "$ACTIVE_WINDOW" | jq -r .pid) + if [[ "$PID" == "" ]] + then + kitty + fi + + CHILD_PID=$(pgrep -P "$PID" | tail -1) + if [[ "$PID" == "" ]] + then + kitty + fi + + pushd "/proc/${CHILD_PID}/cwd" + SHELL_CWD=$(pwd -P) + popd + + kitty --directory "$SHELL_CWD" +else + kitty +fi diff --git a/packages/scripts/to-s3/default.nix b/packages/scripts/to-s3/default.nix new file mode 100644 index 0000000..f3c43b0 --- /dev/null +++ b/packages/scripts/to-s3/default.nix @@ -0,0 +1,5 @@ +{pkgs, ...}: +pkgs.writeShellApplication { + name = "to-s3"; + text = builtins.readFile ./to-s3; +} diff --git a/packages/scripts/to-s3/to-s3 b/packages/scripts/to-s3/to-s3 new file mode 100755 index 0000000..2d798f9 --- /dev/null +++ b/packages/scripts/to-s3/to-s3 @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -eo pipefail + +# Get only the base name for when using relative paths +base=$(basename "$1") +extension=${base//^.*\.//} + +if [ "png" == "$extension" ]; then + bucket_path="screenshots" +else + bucket_path="snippets" +fi + +# Upload the file + +oci os object put -bn share.muehl.dev --name "${bucket_path}/${base}" --file "${1}" --force + +# Send notifications and copy the URL to the clipboard +notify-send "File Uploaded" "https://share.muehl.dev/${bucket_path}/${base}" +echo "https://share.muehl.dev/${bucket_path}/${base}" +echo -n "https://share.muehl.dev/${bucket_path}/${base}" | xclip +(xclip -o) | xclip -selection clipboard diff --git a/packages/scripts/tofi-hg/default.nix b/packages/scripts/tofi-hg/default.nix new file mode 100644 index 0000000..bd074f1 --- /dev/null +++ b/packages/scripts/tofi-hg/default.nix @@ -0,0 +1,5 @@ +{pkgs, ...}: +pkgs.writeShellApplication { + name = "tofi-hg"; + text = builtins.readFile ./tofi-hg; +} diff --git a/packages/scripts/tofi-hg/tofi-hg b/packages/scripts/tofi-hg/tofi-hg new file mode 100755 index 0000000..b014275 --- /dev/null +++ b/packages/scripts/tofi-hg/tofi-hg @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +HOME=/home/$(whoami) +BASE_URI="https://github.com/hausgold/" + +REPO=$(< "$HOME/.gh/hausgold-repos" tofi) + +if [[ -n $REPO ]]; then + firefox -P 'Work' "$BASE_URI$REPO" +fi diff --git a/secrets/keys/master-identity.pub b/secrets/keys/master-identity.pub new file mode 100644 index 0000000..918469e --- /dev/null +++ b/secrets/keys/master-identity.pub @@ -0,0 +1,7 @@ +# Serial: 9614315, Slot: 1 +# Name: age identity NixOS_agenix +# Created: Thu, 17 Apr 2025 23:51:27 +0000 +# PIN policy: Once (A PIN is required once per session, if set) +# Touch policy: Always (A physical touch is required for every decryption) +# Recipient: age1yubikey1qfquku0arzqqgmna0gqzvt0xyqqx0f6u740pqg73n6q7x8qx590mshsfuum +AGE-PLUGIN-YUBIKEY-1AWEEYQYZ9F5LWWGV8PGXT diff --git a/secrets/npmrc.age b/secrets/npmrc.age new file mode 100644 index 0000000..2ce66df --- /dev/null +++ b/secrets/npmrc.age @@ -0,0 +1,10 @@ +age-encryption.org/v1 +-> X25519 EvVlZlt07tJ5uXp/orOI6sYBiV/Ml+fcHanmTknKIns +jPbVgh3H2ZbrMzyMx4PVV3Iq/PRH9xpXUTgiojmVPho +-> piv-p256 Kmn3OQ Az/HkZDILIjudpGWKDuDl72rcV5yJrzmON7ZPYX4HTg3 +Muy8oafGcxpNZFq4/vUyJj8wsjQ7lJZAYqytSi5OKd4 +-> y=NqE-grease \(C?Vn4 +Exi2RtcM3jWBFpk6mwjUk8LaZz7fZFrmUECla0wvBAKfaNi/08Fqic4M1q63i07m +5qNKUcff8qS3fVN6JGO+afaqnA +--- tmzPchf4s0l58ako+acHmDaI/S0btrmN4woFPLyviWk +dǢk<6V'0<~j4{\Uz7Bi_z j@4E# dմcr,,'A MS{2an/^9 6v6k_mj9 \ No newline at end of file diff --git a/secrets/repo-update-pat.age b/secrets/repo-update-pat.age new file mode 100644 index 0000000..74a01a2 Binary files /dev/null and b/secrets/repo-update-pat.age differ diff --git a/secrets/ssh/id_ethnuc.age b/secrets/ssh/id_ethnuc.age new file mode 100644 index 0000000..604e515 --- /dev/null +++ b/secrets/ssh/id_ethnuc.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> X25519 sF7bjCyfkdF9lNGX/7OchzxHCwiWEtmkVDmfnA557xw +VTug66hCUUlJdF0Vx3X/ac5f1n77CQupZhbINCcWjb0 +-> piv-p256 Kmn3OQ AzEEF2jn1v7b0/W0eiMZLCh8DfSmT3juI0cp8WcrtWl7 +veBGSBIiUKlkUx7IQ1xoEiywx7wpvxS7exr2cHTMT0Y +-> 1S-grease -/7=y- +6DV3KrmELs9zxg +--- HgOdaVY/vd9Uk6u3LDKSnoCmbek8LXg80VeDqB6BMfc +Ыs*5k&Ie^QՈo0*3[! #g+1(]~RgĿջ=H Tp4/I&QMЋfXxbX,Iap|Aэ²^t ԷቊG%݊[(ݸa'Ta|Qa9o$ec#Pu o?*dksNo!AF"Br\\XḦYr51@EL10V[e!l_U6^cؘgJD Gf X25519 4wUTKVzrQqX8lotGZ79CxsFNkFBzTuES/j9dwE5UKDw +AF/eIADCu6SguHA2g4WXX/IiwsLB0K2ghNJpTZwcghE +-> piv-p256 Kmn3OQ A8SjMBlsmyMChxDLfJyBmXZZUK4pIswG5nQR6Vuwb7ru +9sf5Yp8YtJgiAsHI3AY1V72dBuPF3Z5oAHRCVR4Xqpw +-> nkbab_u-grease >lSnK&( F32jrU! 7 G +V7pqDFE5L4vRAt+3bOBVxlEkN2zkegC9Wzkxo/mVysZ3MNlhA51qu48T5YvnbEjw +2JwyLw +--- FqiZX+m+uhHlyaeygF6HQnA/JV9MYa7XUfAmvvnaed0 +DJa]k@ɉ~Isc \wd{\b6G\Ge~{U}u` +YbגtR*(P +u)o씽!O٠3a}٤uZodQHUv_벲v"7܃>xȈp"7=:W|m7hvGmht [,Y庬* `w:[h3'&3*%1lmiK6SZݺ"#cP:VȢ^K+vdk#`@Tr+H)_(J 3ѣ=箥F^bo~oRrJgVwY|vb1>..lx/4zsP4LҊjÍaoHF@o]0=s[q2ß#RA +1<tfaWz \ No newline at end of file diff --git a/secrets/ssh/id_homeassistant.age b/secrets/ssh/id_homeassistant.age new file mode 100644 index 0000000..402b82a Binary files /dev/null and b/secrets/ssh/id_homeassistant.age differ diff --git a/secrets/ssh/id_rhenium.age b/secrets/ssh/id_rhenium.age new file mode 100644 index 0000000..aa3ec2b Binary files /dev/null and b/secrets/ssh/id_rhenium.age differ diff --git a/secrets/stalwart-compose.yaml.age b/secrets/stalwart-compose.yaml.age new file mode 100644 index 0000000..578930a Binary files /dev/null and b/secrets/stalwart-compose.yaml.age differ diff --git a/secrets/stalwart-config.toml.age b/secrets/stalwart-config.toml.age new file mode 100644 index 0000000..7d1b075 Binary files /dev/null and b/secrets/stalwart-config.toml.age differ diff --git a/secrets/stalwart-traefik.yml.age b/secrets/stalwart-traefik.yml.age new file mode 100644 index 0000000..a7b45cd Binary files /dev/null and b/secrets/stalwart-traefik.yml.age differ diff --git a/shells/deploy/Justfile b/shells/deploy/Justfile new file mode 100644 index 0000000..f1e55ff --- /dev/null +++ b/shells/deploy/Justfile @@ -0,0 +1,5 @@ +# TODO: Figure out how to link to the root Justfile and import +# it with `import '../../Justfile`. + +say word: + @cowsay {{word}} diff --git a/shells/deploy/default.nix b/shells/deploy/default.nix new file mode 100644 index 0000000..a2d08a9 --- /dev/null +++ b/shells/deploy/default.nix @@ -0,0 +1,13 @@ +{pkgs, ...}: +pkgs.mkShell { + packages = with pkgs; [ + just + cowsay + ]; + + # Define an alias to use a Justfile specifically with + # deployment tooling enabled. + shellHook = '' + alias elements="just -f ${././Justfile} -d ${../..}" + ''; +} diff --git a/systems/aarch64-linux/neptunium/default.nix b/systems/aarch64-linux/neptunium/default.nix new file mode 100644 index 0000000..a1da04d --- /dev/null +++ b/systems/aarch64-linux/neptunium/default.nix @@ -0,0 +1,11 @@ +# ++ 93_Np: Neptunium +# +# Raspberry Pi / Mini home server environment +{...}: { + elements = { + hostname = "neptunium"; + secrets = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD"; + }; + }; +} diff --git a/systems/x86_64-darwin/molybdenum/default.nix b/systems/x86_64-darwin/molybdenum/default.nix new file mode 100644 index 0000000..268a879 --- /dev/null +++ b/systems/x86_64-darwin/molybdenum/default.nix @@ -0,0 +1,15 @@ +# ++ 42_Mo: Molybdenum +# +# MacBook Pro work environment +{self, ...}: { + system.stateVersion = 5; + + elements = { + hostname = "molybdenum"; + secrets = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD"; + }; + }; + + users.users.christopher = {}; # For some reason this is required for hm to work. +} diff --git a/systems/x86_64-linux/beryllium/default.nix b/systems/x86_64-linux/beryllium/default.nix new file mode 100644 index 0000000..38e840f --- /dev/null +++ b/systems/x86_64-linux/beryllium/default.nix @@ -0,0 +1,11 @@ +# ++ 4_Be: Beryllium +# +# NUC environment +{lib, ...}: { + elements = { + hostname = "beryllium"; + secrets = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEp5oRV7VbOlQ172/mLskChJwK6snXD9P4ZeROxniJtJ"; + }; + }; +} diff --git a/systems/x86_64-linux/cobalt/beszel-agent.nix b/systems/x86_64-linux/cobalt/beszel-agent.nix new file mode 100644 index 0000000..a86d2b8 --- /dev/null +++ b/systems/x86_64-linux/cobalt/beszel-agent.nix @@ -0,0 +1,20 @@ +{pkgs, ...}: { + environment.systemPackages = [ + pkgs.beszel + pkgs.rocmPackages.rocm-smi # Interface with AMD GPUs + ]; + + systemd.services.beszel-agent = { + enable = true; + description = "Beszel Agent (remote monitoring)"; + + environment = { + KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMkUPOw28Cu2LMuzfmvjT/L2ToNHcADwGyGvSpJ4wH2T"; + LISTEN = "45876"; + }; + + serviceConfig = { + ExecStart = "${pkgs.beszel}/bin/beszel-agent"; + }; + }; +} diff --git a/systems/x86_64-linux/cobalt/default.nix b/systems/x86_64-linux/cobalt/default.nix new file mode 100644 index 0000000..0872c75 --- /dev/null +++ b/systems/x86_64-linux/cobalt/default.nix @@ -0,0 +1,231 @@ +# ++ 27_Co: Cobalt +# +# Main tower workstation environment +{ + pkgs, + inputs, + lib, + config, + ... +}: +with lib._elements; { + imports = [ + ./hardware.nix + "${builtins.fetchTarball { + url = "https://github.com/nix-community/disko/archive/master.tar.gz"; + sha256 = "0mzm7digdksivdhikxvrx6l0j2b9lj167ndcimsy9i24k4b91wsk"; + }}/module.nix" + ./disk-config.nix + ./beszel-agent.nix + + ./wayland.nix + "${inputs.self}/modules/nixos/common/services/shutdown.nix" + ]; + + elements = { + hostname = "cobalt"; + users = ["christopher"]; + quirks = ["avahi" "docker" "nix-ld"]; + + secrets = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD"; + }; + }; + + # Set the default drive + disko.devices.disk.main.device = "/dev/nvme1n1"; + + qt = { + enable = true; + platformTheme = "gnome"; + style = "adwaita-dark"; + }; + + networking = { + hostName = "cobalt"; + firewall.enable = false; + }; + + # Set your time zone. + time.timeZone = "Europe/Berlin"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + console = { + font = "Lat2-Terminus16"; + useXkbConfig = true; # use xkbOptions in tty. + }; + + xdg.portal = { + enable = true; + config.common.default = ["hyprland"]; + config.hyprland.default = ["wlr" "gtk"]; + extraPortals = [ + pkgs.xdg-desktop-portal-gtk + ]; + wlr.enable = true; + }; + + programs = { + weylus.users = ["christopher"]; + + dconf.enable = true; + + steam = { + enable = true; + protontricks.enable = true; + remotePlay.openFirewall = true; + }; + # VR support + envision.enable = true; + + # For game-related system optimisations + gamemode.enable = true; + + _1password.enable = true; + _1password-gui = { + enable = true; + # Certain features, including CLI integration and system authentication support, + # require enabling PolKit integration on some desktop environments (e.g. Plasma). + polkitPolicyOwners = ["christopher"]; + }; + }; + + services = { + # Bluetooth manager + blueman.enable = true; + + pulseaudio.enable = true; + pulseaudio.support32Bit = true; + pipewire.enable = lib.mkForce false; + + # Automatic mounting of removable media + udisks2.enable = true; + + gvfs.enable = true; # Mount/trash/... + tumbler.enable = true; # Thumbnail support in Thunar + + gnome.gnome-keyring.enable = true; + + # Enable CUPS to print documents. + printing = { + enable = true; + drivers = with pkgs; [ + brlaser + ]; + }; + + # Smartcard support, necessary for Yubikey logins + pcscd.enable = true; + }; + + programs = { + thunar.enable = true; + thunar.plugins = with pkgs.xfce; [ + thunar-archive-plugin + ]; + + gnupg.agent = { + enable = true; + pinentryPackage = pkgs.pinentry-gtk2; + enableSSHSupport = true; + }; + + zsh.enable = true; + }; + + environment = { + # List packages installed in system profile. To search, run: + # $ nix search wget + systemPackages = with pkgs; [ + # Global apps + vim + wget + htop + gnumake + libnotify + xarchiver # GUI archiving tool, used with Thunar + + lact + + # Oxidized coreutils + uutils-coreutils-noprefix + + wally-cli + keymapp + + # SANE frontend + xsane + + # Desktop environment + pavucontrol + eww + + nix-tree + nix-output-monitor + + xdg-desktop-portal + xdg-desktop-portal-gtk + ]; + }; + + users.groups.pico = {}; + + systemd.packages = [pkgs.lact]; + systemd.services.lactd.wantedBy = ["multi-user.target"]; + + hardware = { + amdgpu = { + opencl.enable = true; + overdrive.enable = true; + # amdvlk = { + # enable = true; + # support32Bit.enable = true; + # }; + }; + + bluetooth = { + enable = true; + powerOnBoot = true; + }; + + graphics = { + enable = true; + enable32Bit = true; + }; + + # SANE scanner support + sane = { + enable = true; + extraBackends = [pkgs.brscan4]; + }; + + # Input emulation from userspace (see weylus). + uinput.enable = true; + + # Enable zsa keyboard (Moonlander) support. + keyboard.zsa.enable = true; + }; + + system.stateVersion = "23.05"; # Do not change this value! + + # Set up our bootloader + boot.loader = { + efi.canTouchEfiVariables = true; + grub = { + enable = true; + device = "nodev"; + efiSupport = true; + gfxmodeEfi = lib.mkForce "3840x1080,auto"; + gfxmodeBios = lib.mkForce "3840x1080,auto"; + }; + grub2-theme = { + enable = true; + icon = "white"; + theme = "tela"; + screen = "ultrawide2k"; + # resolution = "3840x1080"; + }; + }; +} diff --git a/systems/x86_64-linux/cobalt/disk-config.nix b/systems/x86_64-linux/cobalt/disk-config.nix new file mode 100644 index 0000000..660b17c --- /dev/null +++ b/systems/x86_64-linux/cobalt/disk-config.nix @@ -0,0 +1,36 @@ +{ + disko.devices = { + disk = { + main = { + type = "disk"; + content = { + type = "gpt"; + partitions = { + boot = { + size = "1M"; + type = "EF02"; # for grub MBR + }; + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = ["umask=0077"]; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/systems/x86_64-linux/cobalt/hardware.nix b/systems/x86_64-linux/cobalt/hardware.nix new file mode 100644 index 0000000..1be511f --- /dev/null +++ b/systems/x86_64-linux/cobalt/hardware.nix @@ -0,0 +1,73 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"]; + boot.initrd.kernelModules = ["amdgpu"]; + boot.kernelModules = ["kvm-amd" "uinput"]; + boot.extraModulePackages = []; + boot.supportedFilesystems = ["ntfs"]; + + fileSystems."/mnt/games/ssd" = { + device = "/dev/disk/by-label/GAMESSSD"; + fsType = "ext4"; + options = [ + "nofail" + "exec" + "users" + ]; + }; + + fileSystems."/mnt/games/hdd" = { + device = "/dev/disk/by-label/Spiele"; + fsType = "ntfs"; + options = [ + "nofail" + "exec" + "users" + "permissions" + ]; + }; + + environment.systemPackages = [pkgs.rclone]; + environment.etc."rclone-beryllium.conf".text = '' + [beryllium] + type = sftp + host = 10.3.0.1 + port = 7319 + user = christopher-sftp + key_file = /home/christopher/.ssh/id_ethnuc + ''; + + fileSystems."/mnt/beryllium" = { + device = "beryllium:/var/sftp"; + fsType = "rclone"; + options = [ + "nofail" + "nodev" + "allow_other" + "args2env" + "config=/etc/rclone-beryllium.conf" + ]; + }; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.eno1.useDHCP = lib.mkDefault true; + + powerManagement.cpuFreqGovernor = lib.mkDefault "performance"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/systems/x86_64-linux/cobalt/wayland.nix b/systems/x86_64-linux/cobalt/wayland.nix new file mode 100644 index 0000000..5e263e4 --- /dev/null +++ b/systems/x86_64-linux/cobalt/wayland.nix @@ -0,0 +1,42 @@ +{ + pkgs, + inputs, + ... +}: let + tuigreet = "${pkgs.greetd.tuigreet}/bin/tuigreet"; + hyprland-pkg = inputs.hyprland.packages.${pkgs.system}.hyprland; + hyprland-portal-pkg = inputs.hyprland.packages.${pkgs.system}.xdg-desktop-portal-hyprland; + hyprland-session = "${hyprland-pkg}/share/wayland-sessions"; +in { + environment.systemPackages = with pkgs; [ + swaynotificationcenter # Notification daemon for Wayland + inputs.rose-pine-hyprcursor.packages.${pkgs.system}.default + hyprshot + ]; + + programs.hyprland = { + enable = true; + package = hyprland-pkg; + portalPackage = hyprland-portal-pkg; + }; + + services.greetd = { + enable = true; + settings = rec { + default_session = { + command = "${tuigreet} --asterisks --time --remember --remember-session --sessions ${hyprland-session}"; + user = "greeter"; + }; + }; + }; + + systemd.services.greetd.serviceConfig = { + Type = "idle"; + StandardInput = "tty"; + StandardOutput = "tty"; + StandardError = "journal"; + TTYReset = true; + TTYVHangup = true; + TTYVTDisallocate = true; + }; +} diff --git a/systems/x86_64-linux/europium/default.nix b/systems/x86_64-linux/europium/default.nix new file mode 100644 index 0000000..a9cf089 --- /dev/null +++ b/systems/x86_64-linux/europium/default.nix @@ -0,0 +1,91 @@ +# ++ 63_Eu: Europium +# +# Hosted VPS used primarily as an email server +{pkgs, ...}: { + imports = [./hardware.nix]; + + system.stateVersion = "23.11"; + + elements = { + hostname = "europium"; + secrets = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAzw6hzrX3zDJAiMfhVpU+t1xr9C2PxJ9rf4HUfRzTiU"; + + needs = { + compose = { + rekeyFile = "stalwart-compose.yaml.age"; + path = "/opt/stalwart/compose.yaml"; + symlink = false; + mode = "0644"; + }; + + stalwart = { + rekeyFile = "stalwart-config.toml.age"; + path = "/opt/stalwart/stalwart/etc/config.toml"; + symlink = false; + mode = "0644"; + }; + + traefik = { + rekeyFile = "stalwart-traefik.yml.age"; + path = "/opt/stalwart/loadbalancer/traefik.yml"; + symlink = false; + mode = "0644"; + }; + }; + }; + }; + + boot.tmp.cleanOnBoot = true; + zramSwap.enable = true; + + # Used to generate a FQDN in the internal contabo network + networking = { + domain = "contaboserver.net"; + firewall = { + enable = true; + allowedTCPPorts = [ + # ssh + 22 + # http + https + 80 + 443 + # stalwart ports + 143 + 993 + 587 + 465 + 110 + 995 + 4190 + ]; + }; + }; + + services.openssh.enable = true; + users.users.root.openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOJO3cs5ldXTibguhJQKwopdssnfGwwIHS5vyOQTvzbm christopher@cobalt"]; + + virtualisation.docker.enable = true; + environment.systemPackages = with pkgs; [ + docker-compose + vim + ]; + + system.activationScripts = { + dockerNetwork = { + text = '' + # Don't fail in case the network can't be created (in case it already exists) + ${pkgs.docker}/bin/docker network create traefik-proxy || true + ''; + }; + }; + + users.users.stalwart = { + home = "/opt/stalwart"; + isSystemUser = true; + group = "stalwart"; + extraGroups = ["docker"]; + }; + + users.groups.stalwart = {}; +} diff --git a/systems/x86_64-linux/europium/hardware.nix b/systems/x86_64-linux/europium/hardware.nix new file mode 100644 index 0000000..353d235 --- /dev/null +++ b/systems/x86_64-linux/europium/hardware.nix @@ -0,0 +1,10 @@ +{modulesPath, ...}: { + imports = [(modulesPath + "/profiles/qemu-guest.nix")]; + boot.loader.grub.device = "/dev/sda"; + boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi"]; + boot.initrd.kernelModules = ["nvme"]; + fileSystems."/" = { + device = "/dev/sda3"; + fsType = "ext4"; + }; +} diff --git a/systems/x86_64-linux/mercury/default.nix b/systems/x86_64-linux/mercury/default.nix new file mode 100644 index 0000000..a597cee --- /dev/null +++ b/systems/x86_64-linux/mercury/default.nix @@ -0,0 +1,84 @@ +# ++ 80_Hg: Mercury +# +# Minimal environment for a workbase VirtualBox on macOS +{ + lib, + pkgs, + inputs, + ... +}: +with lib._elements; { + imports = [ + ./hardware.nix + "${builtins.fetchTarball { + url = "https://github.com/nix-community/disko/archive/master.tar.gz"; + sha256 = "0acvrmfhk86glp59dphbrp9xwcxd8r3zpn18760nzs4930nhhsi3"; + }}/module.nix" + ./disk-config.nix + ]; + + elements = { + hostname = "mercury"; + users = ["christopher"]; + quirks = ["avahi" "docker"]; + + secrets = { + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD"; + }; + }; + + system.stateVersion = "24.11"; + + # Enable nix flakes + nix = { + package = pkgs.nixVersions.stable; + extraOptions = '' + experimental-features = nix-command flakes + ''; + }; + + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + AllowUsers = ["christopher"]; + }; + }; + + # Set the default drive, which in the case of Mercury is + # a VirtualBox image. + disko.devices.disk.main.device = "/dev/sda"; + + boot.loader.grub.enable = true; + networking.hostName = "mercury"; + time.timeZone = "Europe/Berlin"; + + environment.systemPackages = with pkgs; [ + inputs.docker-compose-1.legacyPackages."x86_64-linux".docker-compose + gnumake + ]; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + + console = { + font = "Lat2-Terminus16"; + keyMap = lib.mkForce "de"; + }; + + programs.zsh.enable = true; + programs.vim.enable = true; + programs.git.enable = true; + + # Disable the firewall so that all traffic is allowed + networking.firewall.enable = false; + + # Reflect mDNS to host network + services.avahi.reflector = true; + + # Forward external traffic internally + boot.kernel.sysctl."net.ipv4.ip_forward" = 1; + + # Enable the VSCode Remote server + services.vscode-server.enable = true; +} diff --git a/systems/x86_64-linux/mercury/disk-config.nix b/systems/x86_64-linux/mercury/disk-config.nix new file mode 100644 index 0000000..660b17c --- /dev/null +++ b/systems/x86_64-linux/mercury/disk-config.nix @@ -0,0 +1,36 @@ +{ + disko.devices = { + disk = { + main = { + type = "disk"; + content = { + type = "gpt"; + partitions = { + boot = { + size = "1M"; + type = "EF02"; # for grub MBR + }; + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = ["umask=0077"]; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/systems/x86_64-linux/mercury/hardware.nix b/systems/x86_64-linux/mercury/hardware.nix new file mode 100644 index 0000000..95c25fc --- /dev/null +++ b/systems/x86_64-linux/mercury/hardware.nix @@ -0,0 +1,26 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: { + imports = []; + + boot.initrd.availableKernelModules = ["ata_piix" "ohci_pci" "ehci_pci" "ahci" "sd_mod" "sr_mod"]; + boot.initrd.kernelModules = []; + boot.kernelModules = []; + boot.extraModulePackages = []; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp0s3.useDHCP = lib.mkDefault true; + + virtualisation.virtualbox.guest.enable = true; +}