├── overlays ├── .git-keep ├── default.nix ├── last-known-good.nix ├── nixpkgs-mine-packages.nix └── overrides.nix ├── configs ├── ssh │ └── .gitignore └── doom │ ├── wtf.clj │ ├── test.js │ ├── user.clj │ ├── custom.el │ └── +helpers.el ├── hosts ├── quine │ ├── .gitignore │ ├── secrets │ │ └── local.nix │ ├── wireplumber │ │ └── 91-user-scripts.lua │ ├── ipfs.nix │ ├── startover.sh │ ├── test-quadlet-nix2.nix │ ├── microvm-test-impl.nix │ ├── roon-bridge.nix │ ├── install.sh │ └── README.md ├── mali │ ├── secrets │ │ ├── host.pub │ │ └── local.nix │ ├── startover.sh │ ├── nfs.nix │ ├── minio.nix │ ├── avahi.nix │ ├── README.md │ ├── install.sh │ ├── acme.nix │ └── borgbackup-server.nix ├── witt │ ├── secrets │ │ └── host.pub │ ├── home.nix │ └── hardware.nix ├── addams │ ├── secrets │ │ └── local.nix │ ├── modules │ │ ├── kea │ │ │ ├── default.nix │ │ │ ├── helpers.nix │ │ │ └── ddns.nix │ │ ├── chrony.nix │ │ ├── udpbroadcastrelay.nix │ │ ├── podman.nix │ │ └── ntopng.nix │ └── hardware.nix ├── debord │ ├── secrets │ │ └── local.nix │ ├── hardware.nix │ └── prometheus.nix ├── dewey │ ├── secrets │ │ └── local.nix │ ├── hardware.nix │ └── guests.nix └── james │ ├── secrets │ └── local.nix │ ├── hardware.nix │ └── web │ ├── personal3.nix │ ├── personal.nix │ └── personals.nix ├── .envrc ├── modules ├── desktop │ ├── programs │ │ ├── kitty │ │ │ ├── configs │ │ │ │ ├── kitty.session │ │ │ │ └── kitty-monitor.session │ │ │ └── default.nix │ │ ├── junction.nix │ │ ├── aseprite.nix │ │ ├── owncloud.nix │ │ ├── calibre.nix │ │ ├── fritzing.nix │ │ ├── morgen.nix │ │ ├── slack.nix │ │ ├── kicad.nix │ │ ├── nextcloud.nix │ │ ├── 1password.nix │ │ ├── nheko.nix │ │ ├── discord.nix │ │ ├── ghostty │ │ │ └── default.nix │ │ ├── musescore.nix │ │ ├── kdeconnect.nix │ │ ├── cad.nix │ │ ├── obs.nix │ │ ├── signal.nix │ │ ├── waydroid.nix │ │ └── logseq.nix │ ├── hyprland │ │ ├── template.nix │ │ └── theme.nix │ ├── niri │ │ ├── rules.kdl │ │ ├── outputs.kdl │ │ └── emacs.kdl │ ├── mako.nix │ ├── hyprpaper.nix │ ├── services │ │ └── ha-shutdown.nix │ ├── browser │ │ └── firefox.nix │ └── random-apps.nix ├── dev │ ├── jetbrains │ │ ├── configs │ │ │ ├── ideavimrc │ │ │ └── ideavim │ │ │ │ ├── custom.vim │ │ │ │ ├── _all.vim │ │ │ │ ├── settings.vim │ │ │ │ └── projects.vim │ │ └── default.nix │ ├── node │ │ ├── configs │ │ │ └── npm │ │ │ │ └── npmrc │ │ └── default.nix │ ├── janet │ │ └── default.nix │ ├── fennel.nix │ ├── k8s │ │ └── default.nix │ ├── python.nix │ ├── clojure │ │ └── configs │ │ │ └── clj-kondo │ │ │ └── config.edn │ └── radicle.nix ├── editors │ └── emacs │ │ └── configs │ │ ├── icons │ │ └── doom.png │ │ └── doom.sh ├── site-net │ └── default.nix ├── impermanence │ └── default.nix ├── microvm-guest │ ├── default.nix │ └── home-manager.nix ├── sops.nix ├── telemetry │ ├── smartd.nix │ ├── prometheus-zfs-exporter.nix │ ├── prometheus-ipmi-exporter.nix │ ├── prometheus-node-exporter.nix │ ├── prometheus-nut-exporter.nix │ ├── prometheus-borgmatic-exporter.nix │ ├── prometheus-smartctl-exporter.nix │ ├── thanos.nix │ └── prometheus.nix ├── shell │ ├── zsh │ │ └── configs │ │ │ ├── init.zsh │ │ │ ├── privacy.zsh │ │ │ ├── gpg-ssh.zsh │ │ │ └── keybindings.zsh │ ├── aria2.nix │ ├── zoxide.nix │ ├── ssh │ │ └── default.nix │ ├── ffsend.nix │ ├── isd.nix │ ├── mpv.nix │ ├── direnv.nix │ ├── attic.nix │ ├── htop │ │ └── default.nix │ ├── gpg-agent.nix │ └── zellij │ │ ├── config.kdl │ │ └── default.nix ├── meta.nix ├── services │ ├── ingress-options.nix │ ├── docker.nix │ ├── printing.nix │ ├── attic-watch-store.nix │ ├── matrix-irc.nix │ ├── podman.nix │ ├── github-runner.nix │ ├── nomad.nix │ ├── sshd.nix │ ├── soju.nix │ ├── grafana.nix │ ├── atuin-sync.nix │ ├── audiobookshelf.nix │ └── mariadb.nix ├── hardware │ ├── brother-ql-web.nix │ ├── misc.nix │ └── ryzen.nix ├── SKELETON.nix.txt ├── security │ └── default.nix └── vpn │ └── tailscale.nix ├── secrets ├── site.nix ├── global.nix ├── home-ops.nix ├── age-keychain.pub ├── age-mini-quine.pub ├── ocis-work-csp.yaml └── age-disaster-recovery.pub ├── config ├── offsite.nix ├── default.nix ├── secrets.nix ├── secrets_old.nix ├── ramblurr.nix ├── guests.nix ├── nix-lan-cache.nix ├── hetzner-cloud-ccx.nix └── home-wifi.nix ├── modules-unstable ├── default.nix ├── hardware │ └── nvidia │ │ └── de-compat.nix └── services │ └── microsocks.nix ├── pkgs ├── java-mission-control │ ├── src │ │ └── share │ │ │ └── icons │ │ │ └── adoptium.png │ └── default.nix ├── udpbroadcastrelay.nix ├── netns-proxy.nix ├── invoiceninja │ ├── invoiceninja-redis.patch │ ├── invoiceninja.patch │ └── package.nix ├── nvidia │ ├── package.nix │ └── update.nu ├── beets-dynamicrange.nix ├── qobuz-dl.nix ├── default.nix ├── swhkd │ └── default.nix ├── kwin6-bismuth-decoration.nix ├── gitbutler-bin.nix ├── mcp-inspector.nix └── beets-filetote.nix ├── lib ├── my.nix ├── nix-std.nix ├── default.nix └── network.nix ├── .git-crypt ├── keys │ └── default │ │ └── 0 │ │ └── 978C4D08058BA26EB97CB51820782DBCACFAACDA.gpg └── .gitattributes ├── .gitignore ├── TODO.md ├── .gitattributes ├── scripts ├── pass.py ├── restic-restore.sh ├── pgbackrest-restore.sh └── enumerate-ports.py ├── .editorconfig ├── shell.nix ├── .github ├── lint │ ├── .yamllint.yaml │ └── gitleaks.toml └── renovate │ └── groups.json5 ├── guests ├── claude-test │ └── default.nix └── hello-world │ └── default.nix ├── .pre-commit-config.yaml ├── LICENSE └── flake ├── iso-test.nix └── pkgs.nix /overlays/.git-keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /configs/ssh/.gitignore: -------------------------------------------------------------------------------- 1 | hosts.nix 2 | -------------------------------------------------------------------------------- /hosts/quine/.gitignore: -------------------------------------------------------------------------------- 1 | archive 2 | -------------------------------------------------------------------------------- /configs/doom/wtf.clj: -------------------------------------------------------------------------------- 1 | (ns wtf) 2 | 3 | (wut) 4 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | watch_file flake/devshell.nix 2 | use flake 3 | -------------------------------------------------------------------------------- /modules/desktop/programs/kitty/configs/kitty.session: -------------------------------------------------------------------------------- 1 | launch zsh 2 | -------------------------------------------------------------------------------- /modules/desktop/programs/kitty/configs/kitty-monitor.session: -------------------------------------------------------------------------------- 1 | launch btop 2 | -------------------------------------------------------------------------------- /secrets/site.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/secrets/site.nix -------------------------------------------------------------------------------- /overlays/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { } 8 | -------------------------------------------------------------------------------- /secrets/global.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/secrets/global.nix -------------------------------------------------------------------------------- /secrets/home-ops.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/secrets/home-ops.nix -------------------------------------------------------------------------------- /secrets/age-keychain.pub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/secrets/age-keychain.pub -------------------------------------------------------------------------------- /secrets/age-mini-quine.pub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/secrets/age-mini-quine.pub -------------------------------------------------------------------------------- /secrets/ocis-work-csp.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/secrets/ocis-work-csp.yaml -------------------------------------------------------------------------------- /hosts/mali/secrets/host.pub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/hosts/mali/secrets/host.pub -------------------------------------------------------------------------------- /hosts/mali/secrets/local.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/hosts/mali/secrets/local.nix -------------------------------------------------------------------------------- /hosts/witt/secrets/host.pub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/hosts/witt/secrets/host.pub -------------------------------------------------------------------------------- /hosts/addams/secrets/local.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/hosts/addams/secrets/local.nix -------------------------------------------------------------------------------- /hosts/debord/secrets/local.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/hosts/debord/secrets/local.nix -------------------------------------------------------------------------------- /hosts/dewey/secrets/local.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/hosts/dewey/secrets/local.nix -------------------------------------------------------------------------------- /hosts/james/secrets/local.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/hosts/james/secrets/local.nix -------------------------------------------------------------------------------- /hosts/quine/secrets/local.nix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/hosts/quine/secrets/local.nix -------------------------------------------------------------------------------- /secrets/age-disaster-recovery.pub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/secrets/age-disaster-recovery.pub -------------------------------------------------------------------------------- /modules/dev/jetbrains/configs/ideavimrc: -------------------------------------------------------------------------------- 1 | source ~/.config/ideavim/settings.vim 2 | source ~/.config/ideavim/major.vim 3 | -------------------------------------------------------------------------------- /hosts/addams/modules/kea/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | imports = [ 4 | ./ddns.nix 5 | ./dhcp.nix 6 | ]; 7 | } 8 | -------------------------------------------------------------------------------- /hosts/quine/wireplumber/91-user-scripts.lua: -------------------------------------------------------------------------------- 1 | load_script("/home/ramblurr/.config/wireplumber/scripts/auto-connect-ports.lua") 2 | -------------------------------------------------------------------------------- /config/offsite.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | ./secrets.nix 5 | ./ramblurr.nix 6 | ./root.nix 7 | ]; 8 | } 9 | -------------------------------------------------------------------------------- /modules/editors/emacs/configs/icons/doom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/modules/editors/emacs/configs/icons/doom.png -------------------------------------------------------------------------------- /modules-unstable/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | 3 | { 4 | imports = [ 5 | ./hardware/nvidia 6 | ./services/microsocks.nix 7 | ]; 8 | } 9 | -------------------------------------------------------------------------------- /modules/dev/node/configs/npm/npmrc: -------------------------------------------------------------------------------- 1 | prefix=${XDG_DATA_HOME}/npm 2 | cache=${XDG_CACHE_HOME}/npm 3 | init-module=${XDG_CONFIG_HOME}/npm/config/npm-init.js 4 | -------------------------------------------------------------------------------- /hosts/quine/ipfs.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { 8 | services.kubo = { 9 | enable = true; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /pkgs/java-mission-control/src/share/icons/adoptium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/pkgs/java-mission-control/src/share/icons/adoptium.png -------------------------------------------------------------------------------- /modules/site-net/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | hostName, 3 | config, 4 | lib, 5 | ... 6 | }: 7 | { 8 | imports = [ 9 | ./network.nix 10 | ]; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /lib/my.nix: -------------------------------------------------------------------------------- 1 | _inputs: _final: prev: { 2 | lib = prev.lib // { 3 | my = { 4 | # just a clean little placeholder that will be filled in 5 | }; 6 | }; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /modules/impermanence/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | ... 4 | }: 5 | { 6 | options.modules.impermanence = { 7 | enable = lib.mkEnableOption ""; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /.git-crypt/keys/default/0/978C4D08058BA26EB97CB51820782DBCACFAACDA.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ramblurr/nixcfg/HEAD/.git-crypt/keys/default/0/978C4D08058BA26EB97CB51820782DBCACFAACDA.gpg -------------------------------------------------------------------------------- /config/default.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | ./secrets.nix 5 | ./nix-lan-cache.nix 6 | ./site.nix 7 | ./ramblurr.nix 8 | ./root.nix 9 | ]; 10 | } 11 | -------------------------------------------------------------------------------- /hosts/quine/startover.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | swapoff /dev/mapper/cryptswap 5 | cryptsetup close /dev/mapper/cryptswap 6 | cryptsetup close /dev/mapper/cryptkey 7 | zpool destroy rpool 8 | -------------------------------------------------------------------------------- /modules/microvm-guest/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | ... 3 | }: 4 | { 5 | imports = [ 6 | ./options.nix 7 | ./common.nix 8 | ./home-manager.nix 9 | ./dev-sandbox.nix 10 | ]; 11 | } 12 | -------------------------------------------------------------------------------- /.git-crypt/.gitattributes: -------------------------------------------------------------------------------- 1 | # Do not edit this file. To specify the files to encrypt, create your own 2 | # .gitattributes file in the directory where your files are. 3 | * !filter !diff 4 | *.gpg binary 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | result 2 | modules-new 3 | modules-old 4 | archive 5 | 6 | .clj-kondo 7 | .lsp 8 | modules/editors/emacs/configs/doom.d/flycheck_* 9 | .direnv 10 | dumps 11 | tmp 12 | 13 | dns-migrate 14 | -------------------------------------------------------------------------------- /lib/nix-std.nix: -------------------------------------------------------------------------------- 1 | inputs: _final: prev: { 2 | lib = prev.lib // { 3 | # A sane standard library of pure functions 4 | # ref: https://github.com/chessai/nix-std 5 | std = inputs.nix-std.lib; 6 | }; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /modules/dev/jetbrains/configs/ideavim/custom.vim: -------------------------------------------------------------------------------- 1 | set visualbell 2 | set noerrorbells 3 | 4 | set clipboard+=unnamed 5 | 6 | nnoremap yy "+yy 7 | vnoremap y "+y 8 | 9 | nnoremap p "+p 10 | vnoremap p "+p 11 | nnoremap P "+P 12 | vnoremap P "+P 13 | -------------------------------------------------------------------------------- /modules/editors/emacs/configs/doom.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | DOOM="$XDG_CONFIG_HOME/emacs" 4 | 5 | if [ ! -d "$DOOM" ]; then 6 | echo "Doom emacs is not installed at $DOOM" 7 | exit 1 8 | else 9 | kitty $DOOM/bin/doom sync 10 | fi 11 | -------------------------------------------------------------------------------- /configs/doom/test.js: -------------------------------------------------------------------------------- 1 | function playSound(filename) { 2 | try { 3 | const audio = new Audio(`resourcdes/${filename}`); 4 | audio.volume = 0.5; 5 | audio.play().catch(()=> {})); 6 | } catch (e) { 7 | //ignore audio erros 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | - [ ] debord: 10GbE/sonnet is not working 4 | - [ ] debord: zfs replication to mali is not working, because of 10GbE not working 5 | - [ ] debord: is the tailscale router to offsite1, but it isn't routing correctly for other nodes in the lan 6 | -------------------------------------------------------------------------------- /modules/desktop/hyprland/template.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | cfg = config.modules.desktop.hyprland; 10 | in 11 | 12 | { 13 | config = lib.mkIf cfg.enable { 14 | 15 | myhm = { ... }@hm: { }; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | **/*.secrets/** filter=git-crypt diff=git-crypt 2 | **/secrets/** filter=git-crypt diff=git-crypt 3 | # Just in case, never filter git files 4 | .gitattributes !filter !diff 5 | .gitignore !filter !diff 6 | **/*.sops.yaml !filter !diff 7 | **/*.sops.yml !filter !diff 8 | -------------------------------------------------------------------------------- /scripts/pass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import getpass 3 | from passlib.hash import sha512_crypt 4 | 5 | 6 | password = getpass.getpass("Enter password: ") 7 | 8 | # Hash passwords using SHA-512 9 | h = sha512_crypt.hash(password) 10 | 11 | 12 | print(f"password_hash: {h}") 13 | -------------------------------------------------------------------------------- /modules/dev/jetbrains/configs/ideavim/_all.vim: -------------------------------------------------------------------------------- 1 | """ This file contains all my custom settings 2 | 3 | " base settings 4 | source ~/.config/ideavim/settings.vim 5 | 6 | " project management 7 | source ~/.config/ideavim/projects.vim 8 | 9 | " major modes 10 | source ~/.config/ideavim/major.vim 11 | -------------------------------------------------------------------------------- /modules/sops.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { 8 | options = { 9 | modules.sops.secretsFile = lib.mkOption { 10 | type = lib.types.str; 11 | default = ""; 12 | description = "Path to the decrypted SOPS secrets file."; 13 | }; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /hosts/james/hardware.nix: -------------------------------------------------------------------------------- 1 | { modulesPath, ... }: 2 | { 3 | imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; 4 | boot.initrd.availableKernelModules = [ 5 | "ata_piix" 6 | "uhci_hcd" 7 | "xen_blkfront" 8 | "vmw_pvscsi" 9 | ]; 10 | boot.initrd.kernelModules = [ "nvme" ]; 11 | } 12 | -------------------------------------------------------------------------------- /scripts/restic-restore.sh: -------------------------------------------------------------------------------- 1 | export AWS_ACCESS_KEY_ID=volsync-CHANGEME 2 | export AWS_SECRET_ACCESS_KEY='CHANGEME' 3 | export RESTIC_REPOSITORY="s3:https://s3.CHANGEME/volsync-CHANGEME/restic" 4 | export RESTIC_PASSWORD="CHANGEME" 5 | #restic --verbose unlock 6 | restic --no-lock --verbose restore latest --target ./restored/ 7 | -------------------------------------------------------------------------------- /hosts/mali/startover.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | if [ -d "/home/ramblurr" ];then 5 | echo "WHAT ARE YOU DOING?" 6 | exit 1 7 | fi 8 | 9 | 10 | umount /mnt/boot 11 | swapoff /dev/mapper/cryptswap 12 | cryptsetup close /dev/mapper/cryptswap 13 | cryptsetup close /dev/mapper/cryptkey 14 | zpool destroy rpool 15 | -------------------------------------------------------------------------------- /config/secrets.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | inputs, 4 | lib, 5 | ... 6 | }: 7 | 8 | let 9 | local = config.node.secretsDir + "/local.nix"; 10 | in 11 | { 12 | # Define local repo secrets 13 | repo.secretFiles = { 14 | global = ../secrets/global.nix; 15 | } // lib.optionalAttrs (lib.pathExists local) { inherit local; }; 16 | } 17 | -------------------------------------------------------------------------------- /config/secrets_old.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | inputs, 4 | lib, 5 | ... 6 | }: 7 | 8 | let 9 | local = config.node.secretsDir + "/local.nix"; 10 | in 11 | { 12 | # Define local repo secrets 13 | repo.secretFiles_old = { 14 | global = ../secrets/global.nix; 15 | } // lib.optionalAttrs (lib.pathExists local) { inherit local; }; 16 | } 17 | -------------------------------------------------------------------------------- /lib/default.nix: -------------------------------------------------------------------------------- 1 | inputs: final: prev: 2 | prev.lib.composeManyExtensions ( 3 | # Order is important to allow using prev instead of final in more places to 4 | # speed up evaluation. 5 | map (x: import x inputs) [ 6 | ./nix-std.nix 7 | ./nix-clj.nix 8 | ./my.nix 9 | ./attrs.nix 10 | ./uint.nix 11 | ./network.nix 12 | ] 13 | ) final prev 14 | -------------------------------------------------------------------------------- /configs/doom/user.clj: -------------------------------------------------------------------------------- 1 | (ns user) 2 | 3 | (defmacro oget [obj key] 4 | (list 'js* "(~{}" obj key)) 5 | 6 | (defmacro js-fn [& body] 7 | (if (:ns &env) 8 | @body 9 | (do 10 | (set! body (/ 1.0 3)) 11 | nil))) 12 | 13 | (defn my-name 14 | "much wow" 15 | [] 16 | ;; cool 17 | #_(wow nice)) 18 | 19 | #_disabled 20 | ;; WOW YES 21 | 22 | oget 23 | js-fn 24 | -------------------------------------------------------------------------------- /hosts/addams/modules/chrony.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | environment.persistence."/persist".directories = [ "/var/lib/chrony" ]; 4 | services.chrony = { 5 | enable = true; 6 | servers = [ "id.pool.ntp.org" ]; 7 | serverOption = "iburst"; 8 | extraConfig = '' 9 | allow 127.0.0.0/8 10 | allow 10.0.0.0/8 11 | allow 172.16.0.0/12 12 | allow 192.168.0.0/16 13 | ''; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [Makefile] 13 | indent_style = tab 14 | indent_size = 4 15 | 16 | [Makefile.j2] 17 | indent_style = tab 18 | indent_size = 4 19 | 20 | [*.{bash,sh}] 21 | indent_style = space 22 | indent_size = 4 23 | -------------------------------------------------------------------------------- /modules/telemetry/smartd.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: 6 | let 7 | cfg = config.modules.telemetry.smartd; 8 | in 9 | { 10 | options.modules.telemetry.smartd = { 11 | enable = lib.mkEnableOption "smartd"; 12 | }; 13 | 14 | config = lib.mkIf cfg.enable { 15 | services.smartd = { 16 | enable = true; 17 | notifications = { 18 | test = true; 19 | }; 20 | }; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { 2 | system ? "x86_64-linux", 3 | pkgs ? import { inherit system; }, 4 | }: 5 | let 6 | packages = with pkgs; [ 7 | python3 8 | python3Packages.passlib 9 | python3Packages.ruamel-yaml 10 | python3Packages.pyyaml 11 | python3Packages.simple-term-menu 12 | ]; 13 | in 14 | pkgs.mkShell { 15 | buildInputs = packages; 16 | shellHook = '' 17 | export SHELL=${pkgs.zsh} 18 | ''; 19 | } 20 | -------------------------------------------------------------------------------- /config/ramblurr.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { 8 | modules.users.primaryUser = { 9 | username = "ramblurr"; 10 | name = "Casey Link"; 11 | homeDirectory = "/home/ramblurr"; 12 | signingKey = "978C4D08058BA26EB97CB51820782DBCACFAACDA"; 13 | email = "unnamedrambler@gmail.com"; 14 | passwordSecretKey = "ramblurr-password"; 15 | authorizedKeys = config.repo.secrets.global.pubKeys; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /modules/shell/zsh/configs/init.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | source $ZDOTDIR/autocompletion.zsh .zsh 4 | source $ZDOTDIR/environment.zsh 5 | source $ZDOTDIR/keybindings.zsh 6 | source $ZDOTDIR/privacy.zsh 7 | #source $ZDOTDIR/gpg-ssh.zsh 8 | 9 | if command -v starship &>/dev/null; then 10 | if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then 11 | eval "$(starship init zsh)" 12 | fi 13 | else 14 | source $ZDOTDIR/prompt.zsh 15 | fi 16 | -------------------------------------------------------------------------------- /.github/lint/.yamllint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ignore: | 3 | .direnv/ 4 | .private/ 5 | .vscode/ 6 | 7 | extends: default 8 | 9 | rules: 10 | truthy: 11 | allowed-values: ["true", "false", "on"] 12 | 13 | comments: 14 | min-spaces-from-content: 1 15 | 16 | line-length: disable 17 | 18 | braces: 19 | min-spaces-inside: 0 20 | max-spaces-inside: 1 21 | 22 | brackets: 23 | min-spaces-inside: 0 24 | max-spaces-inside: 0 25 | 26 | indentation: enable 27 | -------------------------------------------------------------------------------- /modules/telemetry/prometheus-zfs-exporter.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: 6 | let 7 | cfg = config.modules.telemetry.prometheus-zfs-exporter; 8 | in 9 | { 10 | options.modules.telemetry.prometheus-zfs-exporter = { 11 | enable = lib.mkEnableOption "prometheus-zfs-exporter"; 12 | }; 13 | 14 | config = lib.mkIf cfg.enable { 15 | services.prometheus.exporters.zfs = { 16 | enable = true; 17 | openFirewall = true; 18 | }; 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /modules/telemetry/prometheus-ipmi-exporter.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | let 8 | cfg = config.modules.telemetry.prometheus-ipmi-exporter; 9 | in 10 | { 11 | 12 | options.modules.telemetry.prometheus-ipmi-exporter = { 13 | enable = lib.mkEnableOption "prometheus-ipmi-exporter"; 14 | }; 15 | 16 | config = lib.mkIf cfg.enable { 17 | services.prometheus.exporters.ipmi = { 18 | enable = true; 19 | openFirewall = true; 20 | }; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /modules/shell/zsh/configs/privacy.zsh: -------------------------------------------------------------------------------- 1 | # ██ 2 | # ░██ 3 | # ██████ ██████░██ 4 | # ░░░░██ ██░░░░ ░██████ 5 | # ██ ░░█████ ░██░░░██ 6 | # ██ ░░░░░██░██ ░██ 7 | # ██████ ██████ ░██ ░██ 8 | # ░░░░░░ ░░░░░░ ░░ ░░ 9 | # 10 | # ▓▓▓▓▓▓▓▓▓▓ 11 | # ░▓ author ▓ casey 12 | # ░▓ code ▓ https://code.caseylink.com 13 | # ░▓ thanks ▓ https://github.com/xero 14 | # ░▓▓▓▓▓▓▓▓▓▓ 15 | # ░░░░░░░░░░ 16 | # 17 | #█▓▒░ 18 | export DOTNET_CLI_TELEMETRY_OPTOUT=1 19 | -------------------------------------------------------------------------------- /guests/claude-test/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | config, 4 | pkgs, 5 | ... 6 | }: 7 | let 8 | inherit (config.repo.secrets.global) domain; 9 | in 10 | { 11 | system.stateVersion = "24.11"; 12 | microvm = { 13 | mem = 4096; 14 | }; 15 | modules.microvm-guest = { 16 | host = "quine"; 17 | hostFQDN = "quine.prim.${domain.home}"; 18 | devSandbox = { 19 | enable = true; 20 | sharedDirs = [ 21 | ".config/claude" 22 | "nixcfg" 23 | "src/nixpkgs" 24 | ]; 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /guests/hello-world/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | config, 4 | pkgs, 5 | ... 6 | }: 7 | let 8 | inherit (config.repo.secrets.global) domain; 9 | in 10 | { 11 | system.stateVersion = "24.11"; 12 | microvm = { 13 | mem = 4096; 14 | }; 15 | modules.microvm-guest = { 16 | host = "quine"; 17 | hostFQDN = "quine.prim.${domain.home}"; 18 | devSandbox = { 19 | enable = true; 20 | sharedDirs = [ 21 | ".config/claude" 22 | "nixcfg" 23 | "src/nixpkgs" 24 | ]; 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /modules/meta.nix: -------------------------------------------------------------------------------- 1 | { lib, config, ... }: 2 | let 3 | inherit (lib) mkOption types; 4 | in 5 | { 6 | options.node = { 7 | name = mkOption { 8 | description = "A unique name for this node (host) in the repository. Defines the default hostname, but this can be overwritten."; 9 | type = types.str; 10 | }; 11 | secretsDir = mkOption { 12 | description = "Path to the secrets directory for this node."; 13 | type = types.path; 14 | }; 15 | }; 16 | config = { 17 | networking.hostName = config.node.name; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /hosts/mali/nfs.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { 8 | services.nfs.server = { 9 | enable = true; 10 | statdPort = 4000; 11 | lockdPort = 4001; 12 | mountdPort = 4002; 13 | exports = config.repo.secrets.local.nfsExports; 14 | }; 15 | networking.firewall.allowedTCPPorts = [ 16 | 111 17 | 2049 18 | 4000 19 | 4001 20 | 4002 21 | 20048 22 | ]; 23 | networking.firewall.allowedUDPPorts = [ 24 | 111 25 | 2049 26 | 4000 27 | 4001 28 | 4002 29 | 20048 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /modules/telemetry/prometheus-node-exporter.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: 6 | let 7 | cfg = config.modules.telemetry.prometheus-node-exporter; 8 | in 9 | { 10 | options.modules.telemetry.prometheus-node-exporter = { 11 | enable = lib.mkEnableOption "prometheus-node-exporter"; 12 | }; 13 | 14 | config = lib.mkIf cfg.enable { 15 | services.prometheus.exporters.node = { 16 | enable = true; 17 | openFirewall = true; 18 | enabledCollectors = [ "systemd" ]; 19 | disabledCollectors = [ "textfile" ]; 20 | }; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /.github/lint/gitleaks.toml: -------------------------------------------------------------------------------- 1 | title = "gitleaks config" 2 | 3 | [extend] 4 | useDefault = true 5 | 6 | [[ rules ]] 7 | id = "generic-api-key" 8 | [ rules.allowlist ] 9 | paths = [ 'secrets/.*\.nix', 'secrets/.*\.secrets' ] 10 | regexTarget = "line" 11 | regexes= [ 12 | "signing.key =.*", 13 | "signingKey =.*" 14 | ] 15 | 16 | [allowlist] 17 | description = "ignore sops encrypted secrets" 18 | paths = [ 19 | '.*\.sops\.yaml', 20 | ] 21 | regexTarget = "line" 22 | regexes= [ 23 | '''ExAmPl3PA55W0rD''', 24 | '''.*ENC\[AES256_GCM,data:.*''', 25 | ] 26 | -------------------------------------------------------------------------------- /config/guests.nix: -------------------------------------------------------------------------------- 1 | { inputs, config, ... }: 2 | { 3 | imports = [ 4 | ./common-server.nix 5 | ./root.nix 6 | ./site.nix 7 | ./secrets.nix 8 | ../modules/services/sshd.nix 9 | ../modules/microvm-guest 10 | ../modules/meta.nix 11 | ../modules/secrets.nix 12 | ../modules/sops.nix 13 | ../modules/impermanence/default.nix 14 | ]; 15 | 16 | home-manager = { 17 | useGlobalPkgs = true; 18 | useUserPackages = true; 19 | sharedModules = [ 20 | { 21 | home.stateVersion = config.system.stateVersion; 22 | } 23 | ]; 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /modules/services/ingress-options.nix: -------------------------------------------------------------------------------- 1 | { config, lib, ... }: 2 | 3 | { 4 | options = { 5 | external = lib.mkOption { 6 | type = lib.types.bool; 7 | default = false; 8 | description = "Whether to expose the service externally"; 9 | }; 10 | domain = lib.mkOption { 11 | type = lib.types.str; 12 | example = "example.com"; 13 | description = "The ingress domain to use"; 14 | }; 15 | forwardAuth = lib.mkOption { 16 | type = lib.types.bool; 17 | default = true; 18 | description = "Whether to use forward authentication"; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /overlays/last-known-good.nix: -------------------------------------------------------------------------------- 1 | # Living life on unstable can sometimes be... unstable 2 | # This overlay is a way to pin down a known-good version of nixpkgs for certain packages 3 | final: prev: 4 | 5 | let 6 | nixpkgs = 7 | args@{ 8 | rev, 9 | sha256, 10 | config ? { }, 11 | }: 12 | import 13 | (prev.fetchFromGitHub ( 14 | removeAttrs args [ "config" ] 15 | // { 16 | owner = "NixOS"; 17 | repo = "nixpkgs"; 18 | } 19 | )) 20 | { 21 | inherit config; 22 | system = final.system; 23 | }; 24 | in 25 | { 26 | } 27 | -------------------------------------------------------------------------------- /modules/desktop/niri/rules.kdl: -------------------------------------------------------------------------------- 1 | // Window rules let you adjust behavior for individual windows. 2 | // Find more information on the wiki: 3 | // https://yalter.github.io/niri/Configuration:-Window-Rules 4 | 5 | window-rule { 6 | match app-id="wezterm" 7 | default-column-width {} 8 | } 9 | 10 | window-rule { 11 | match app-id=r#"firefox$"# title="^Picture-in-Picture$" 12 | open-floating true 13 | } 14 | 15 | window-rule { 16 | match app-id=r#"^org\.keepassxc\.KeePassXC$"# 17 | match app-id=r#"^org\.gnome\.World\.Secrets$"# 18 | match app-id=r#"^1Password$"# 19 | block-out-from "screen-capture" 20 | } 21 | -------------------------------------------------------------------------------- /hosts/mali/minio.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { 8 | environment.systemPackages = with pkgs; [ minio-client ]; 9 | sops.secrets.minio-root-credentials = { 10 | owner = "minio"; 11 | }; 12 | services.minio = { 13 | enable = true; 14 | dataDir = [ "/mnt/tank2/services/minio" ]; 15 | package = pkgs.minio; 16 | rootCredentialsFile = config.sops.secrets.minio-root-credentials.path; 17 | listenAddress = "127.0.0.1:9000"; 18 | consoleAddress = "127.0.0.1:8999"; 19 | }; 20 | 21 | environment.persistence."/persist" = { 22 | directories = [ "/var/lib/minio/" ]; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /modules/telemetry/prometheus-nut-exporter.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | let 8 | cfg = config.modules.telemetry.prometheus-nut-exporter; 9 | in 10 | { 11 | 12 | options.modules.telemetry.prometheus-nut-exporter = { 13 | enable = lib.mkEnableOption "prometheus-nut-exporter"; 14 | }; 15 | 16 | config = lib.mkIf cfg.enable { 17 | services.prometheus.exporters.nut = { 18 | enable = true; 19 | openFirewall = true; 20 | extraFlags = [ "--nut.vars_enable=''" ]; 21 | nutUser = "admin"; 22 | group = "nut"; 23 | passwordPath = config.sops.secrets.upsAdminPassword.path; 24 | }; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /modules/shell/zsh/configs/gpg-ssh.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | if [[ ! -f /usr/lib/systemd/user/gpg-agent.socket ]]; then 4 | # well we're on an older system without the systemd services 5 | 6 | # use a tty for gpg 7 | # solves error: "gpg: signing failed: Inappropriate ioctl for device" 8 | GPG_TTY=$(tty) 9 | export GPG_TTY 10 | 11 | # add alias for ssh to update the tty 12 | #alias ssh="gpg-connect-agent updatestartuptty /bye >/dev/null; ssh" 13 | gpgconf --launch gpg-agent 14 | export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) 15 | fi 16 | if [[ -z "$SSH_AUTH_SOCK" ]]; then 17 | export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) 18 | fi 19 | -------------------------------------------------------------------------------- /modules/desktop/niri/outputs.kdl: -------------------------------------------------------------------------------- 1 | output "HDMI-A-1" { 2 | transform "90" 3 | //position x=-2160 y=-1250 4 | position x=-1080 y=-800 5 | scale 2 6 | layout { 7 | preset-column-widths { 8 | proportion 0.33333 9 | proportion 0.5 10 | proportion 0.66667 11 | } 12 | default-column-width { proportion 1.0; } 13 | } 14 | } 15 | 16 | output "DP-2" { 17 | position x=0 y=0 18 | 19 | layout { 20 | preset-column-widths { 21 | proportion 0.16667 22 | proportion 0.33333 23 | proportion 0.5 24 | proportion 0.66667 25 | } 26 | default-column-width { proportion 0.16667; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /modules/desktop/programs/junction.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.junction; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.junction = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = 22 | { pkgs, config, ... }@hm: 23 | { 24 | home.packages = [ pkgs.junction ]; 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /modules/dev/janet/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | options, 4 | lib, 5 | pkgs, 6 | my, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | devCfg = config.modules.dev; 12 | cfg = devCfg.janet; 13 | username = config.modules.users.primaryUser.username; 14 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 15 | withImpermanence = config.modules.impermanence.enable; 16 | in 17 | { 18 | options.modules.dev.janet = { 19 | enable = lib.mkEnableOption ""; 20 | }; 21 | 22 | config = mkIf cfg.enable { 23 | 24 | myhm = 25 | { ... }@hm: 26 | { 27 | 28 | home.packages = with pkgs; [ 29 | janet 30 | jpm 31 | ]; 32 | }; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /modules/services/docker.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.services.docker; 12 | withImpermanence = config.modules.impermanence.enable; 13 | in 14 | { 15 | options.modules.services.docker = { 16 | enable = lib.mkEnableOption ""; 17 | enableOnBoot = lib.mkOption { 18 | type = lib.types.bool; 19 | default = true; 20 | }; 21 | }; 22 | config = mkIf cfg.enable { 23 | environment.persistence."/persist" = { 24 | directories = [ "/var/lib/docker" ]; 25 | }; 26 | virtualisation.docker = { 27 | enable = true; 28 | enableOnBoot = cfg.enableOnBoot; 29 | }; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /modules/services/printing.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.services.printing; 12 | in 13 | { 14 | options.modules.services.printing = { 15 | enable = lib.mkEnableOption ""; 16 | drivers = mkOption { 17 | type = types.listOf types.package; 18 | default = [ ]; 19 | }; 20 | }; 21 | config = mkIf cfg.enable { 22 | services.printing.enable = true; 23 | services.printing.drivers = cfg.drivers; 24 | services.avahi.enable = mkDefault true; 25 | services.avahi.nssmdns4 = mkDefault true; 26 | # for a WiFi printer 27 | services.avahi.openFirewall = mkDefault true; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /config/nix-lan-cache.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | config, 4 | lib, 5 | ... 6 | }: 7 | let 8 | cfg = config.home.nix-lan-cache; 9 | in 10 | { 11 | options.home.nix-lan-cache = { 12 | enable = lib.mkEnableOption "Enable local nix cache"; 13 | }; 14 | config = lib.mkIf cfg.enable { 15 | nix = { 16 | settings = { 17 | substituters = [ 18 | config.repo.secrets.global.nixCacheSubstituter 19 | ]; 20 | trusted-public-keys = [ 21 | config.repo.secrets.global.nixCachePublicKey 22 | ]; 23 | }; 24 | extraOptions = '' 25 | # Ensure we can still build when missing-server is not accessible 26 | fallback = true 27 | ''; 28 | }; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /modules/telemetry/prometheus-borgmatic-exporter.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: 6 | let 7 | cfg = config.modules.telemetry.prometheus-borgmatic-exporter; 8 | in 9 | { 10 | options.modules.telemetry.prometheus-borgmatic-exporter = { 11 | enable = lib.mkEnableOption "prometheus-borgmatic-exporter"; 12 | }; 13 | 14 | config = lib.mkIf cfg.enable { 15 | services.prometheus.exporters.borgmatic = { 16 | enable = true; 17 | openFirewall = true; 18 | 19 | configFile = "/etc/borgmatic.d/"; 20 | }; 21 | 22 | systemd.services.prometheus-borgmatic-exporter.serviceConfig = { 23 | User = lib.mkForce "borgmatic"; 24 | Group = lib.mkForce "borgmatic"; 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /pkgs/udpbroadcastrelay.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | stdenv, 4 | fetchFromGitHub, 5 | }: 6 | 7 | with lib; 8 | 9 | stdenv.mkDerivation { 10 | name = "udpbroadcastrelay"; 11 | src = fetchFromGitHub { 12 | owner = "marjohn56"; 13 | repo = "udpbroadcastrelay"; 14 | rev = "07d747947047f4c01a3b7dd26bb15beafffeadff"; 15 | sha256 = "sha256-tFkn4hWky77UdXzgZWCf5aaiFKeQl3E/71EVh8kXO/I="; 16 | }; 17 | 18 | installPhase = '' 19 | mkdir -p $out/bin 20 | cp udpbroadcastrelay $out/bin/ 21 | ''; 22 | 23 | meta = { 24 | description = "UDP multicast/unicast relayer"; 25 | homepage = "https://github.com/marjohn56/udpbroadcastrelay"; 26 | license = licenses.gpl2; 27 | platforms = platforms.linux; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /modules/telemetry/prometheus-smartctl-exporter.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: 6 | let 7 | cfg = config.modules.telemetry.prometheus-smartctl-exporter; 8 | in 9 | { 10 | options.modules.telemetry.prometheus-smartctl-exporter = { 11 | enable = lib.mkEnableOption "prometheus-smartctl-exporter"; 12 | }; 13 | 14 | config = lib.mkIf cfg.enable { 15 | services.prometheus.exporters.smartctl = { 16 | enable = true; 17 | openFirewall = true; 18 | }; 19 | 20 | # Required for SMART to access NVMe disks 21 | # https://github.com/NixOS/nixpkgs/issues/210041#issuecomment-1694704611 22 | services.udev.extraRules = '' 23 | SUBSYSTEM=="nvme", KERNEL=="nvme[0-9]*", GROUP="disk" 24 | ''; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /pkgs/netns-proxy.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | rustPlatform, 4 | fetchFromGitHub, 5 | ... 6 | }: 7 | 8 | rustPlatform.buildRustPackage rec { 9 | pname = "netns-proxy"; 10 | version = "unstable-2023-09-17"; 11 | 12 | src = fetchFromGitHub { 13 | owner = "fooker"; 14 | repo = "netns-proxy"; 15 | rev = "6d9ccbfde4375cd614735ea5f6ee5aba2b6cfd2b"; 16 | sha256 = "sha256-N+my6cTuA7yNoYxocpRiLNcy7OwrJLvO2cGLJGv8a/I="; 17 | }; 18 | 19 | cargoLock = { 20 | lockFile = src + /Cargo.lock; 21 | }; 22 | 23 | meta = with lib; { 24 | description = "A simple and slim proxy to forward ports from and into linux network namespaces"; 25 | homepage = "https://github.com/fooker/netns-proxy"; 26 | license = licenses.mit; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /modules/shell/aria2.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.aria2; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.aria2 = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = { 22 | programs.aria2 = { 23 | enable = true; 24 | settings = { 25 | listen-port = "6881-6999"; 26 | dht-listen-port = "6881-6999"; 27 | }; 28 | }; 29 | }; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /modules/shell/zoxide.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.zoxide; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.zoxide = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = { 22 | programs.zoxide = { 23 | enable = true; 24 | }; 25 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 26 | directories = [ ".local/share/zoxide" ]; 27 | }; 28 | }; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /hosts/addams/modules/udpbroadcastrelay.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | ... 4 | }: 5 | { 6 | services.udpbroadcastrelay = { 7 | enable = false; 8 | instances = { 9 | roon = { 10 | port = 9003; 11 | id = 1; 12 | interfaces = [ 13 | "me-prim" 14 | "lan0" 15 | "me-iot" 16 | ]; 17 | }; 18 | mdns = { 19 | port = 5353; 20 | id = 2; 21 | interfaces = [ 22 | "me-prim" 23 | "lan0" 24 | "me-iot" 25 | "me-not" 26 | ]; 27 | multicast = "224.0.0.251"; 28 | }; 29 | syncthing = { 30 | port = 21027; 31 | id = 3; 32 | interfaces = [ 33 | "me-prim" 34 | "lan0" 35 | ]; 36 | }; 37 | }; 38 | 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /modules/desktop/programs/aseprite.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.aseprite; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.aseprite = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | myhm = { 22 | home.packages = with pkgs; [ pkgs.aseprite ]; 23 | persistence = mkIf withImpermanence { 24 | directories = [ 25 | ".config/libresprite" 26 | ".config/aseprite" 27 | ]; 28 | }; 29 | }; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /modules/desktop/programs/owncloud.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.owncloud; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.owncloud = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | 22 | environment.persistence."/persist" = mkIf withImpermanence { 23 | users.${username} = { 24 | directories = [ ".config/ownCloud" ]; 25 | }; 26 | }; 27 | myhm = { 28 | home.packages = [ pkgs.owncloud-client ]; 29 | }; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /modules/dev/jetbrains/configs/ideavim/settings.vim: -------------------------------------------------------------------------------- 1 | """ Settings to behave as similar as possible to spacemacs defaults 2 | 3 | " as the leader key 4 | let mapleader = " " 5 | 6 | " Show current vim mode 7 | set showmode 8 | 9 | " Use the clipboard register '*' for all yank, delete, change and put operations 10 | " which would normally go to the unnamed register. 11 | set clipboard+=unnamedplus 12 | 13 | " Search as characters are entered 14 | set incsearch 15 | 16 | " Highlight search results 17 | set hlsearch 18 | 19 | " If a pattern contains an uppercase letter, searching is case sensitive, 20 | " otherwise, it is not. 21 | set ignorecase 22 | set smartcase 23 | 24 | " Emulate vim-surround. Commands: ys, cs, ds, S. 25 | set surround 26 | 27 | set history=1000 28 | 29 | set relativenumber 30 | set number 31 | -------------------------------------------------------------------------------- /hosts/quine/test-quadlet-nix2.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | { 9 | 10 | virtualisation.quadlet.enable = true; 11 | users.users.quadlet = { 12 | isSystemUser = true; 13 | uid = 444; 14 | linger = true; 15 | home = "/var/lib/quadlet"; 16 | createHome = true; 17 | shell = pkgs.shadow; 18 | autoSubUidGidRange = true; 19 | group = "quadlet"; 20 | }; 21 | users.groups.quadlet = { 22 | gid = 444; 23 | }; 24 | virtualisation.quadlet = { 25 | containers = { 26 | nginx = { 27 | containerConfig = { 28 | Image = "docker-archive:${pkgs.dockerTools.examples.nginx}"; 29 | PublishPort = [ "8080:80" ]; 30 | Environment = { 31 | TZ = "Europe/Berlin"; 32 | }; 33 | }; 34 | }; 35 | }; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /modules/desktop/programs/calibre.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.calibre; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.calibre = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = 22 | { pkgs, config, ... }@hm: 23 | { 24 | home.packages = with pkgs; [ calibre ]; 25 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 26 | directories = [ ".config/calibre" ]; 27 | }; 28 | }; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /modules/desktop/programs/fritzing.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.fritzing; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.fritzing = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = 22 | { pkgs, config, ... }@hm: 23 | { 24 | home.packages = [ pkgs.fritzing ]; 25 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 26 | directories = [ ".config/Fritzing" ]; 27 | }; 28 | }; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /modules/desktop/programs/morgen.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.morgen; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.morgen = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | environment.persistence."/persist" = lib.mkIf withImpermanence { 22 | users.${username} = { 23 | directories = [ 24 | ".config/Morgen" 25 | ]; 26 | }; 27 | }; 28 | myhm = { 29 | home.packages = with pkgs; [ 30 | morgen 31 | ]; 32 | }; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /hosts/addams/modules/podman.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | virtualisation = { 4 | containers.enable = true; 5 | oci-containers.backend = "podman"; 6 | podman = { 7 | enable = true; 8 | defaultNetwork.settings = { 9 | network_interface = "ctr0"; 10 | # setting this to true ironically breaks the dns because dns server is not running in the gateway ip 11 | # even setting `dns_name_servers` here doesn't work with this set to true 12 | dns_enabled = false; 13 | subnets = [ 14 | # change these 15 | { 16 | subnet = "10.12.0.0/24"; 17 | gateway = "10.12.0.1"; 18 | lease_range = { 19 | start_ip = "10.12.0.50"; 20 | end_ip = "10.12.0.200"; 21 | }; 22 | } 23 | ]; 24 | }; 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /hosts/mali/avahi.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { 8 | services.avahi = { 9 | enable = false; 10 | nssmdns4 = true; 11 | openFirewall = true; 12 | publish = { 13 | enable = true; 14 | addresses = true; 15 | domain = true; 16 | hinfo = true; 17 | userServices = true; 18 | workstation = true; 19 | }; 20 | allowInterfaces = [ "prim" ]; 21 | extraServiceFiles = { 22 | smb = '' 23 | 24 | 25 | 26 | %h 27 | 28 | _smb._tcp 29 | 445 30 | 31 | 32 | ''; 33 | }; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /modules/desktop/programs/slack.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.slack; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.slack = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | 22 | environment.persistence."/persist" = mkIf withImpermanence { 23 | users.${username} = { 24 | directories = [ ".config/Slack" ]; 25 | }; 26 | }; 27 | home-manager.users."${username}" = 28 | { pkgs, config, ... }@hm: 29 | { 30 | home.packages = [ pkgs.slack ]; 31 | }; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /modules/services/attic-watch-store.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | let 10 | cfg = config.modules.services.attic-watch-store; 11 | username = config.modules.users.primaryUser.username; 12 | in 13 | { 14 | options.modules.services.attic-watch-store = { 15 | enable = lib.mkEnableOption "attic-watch-store"; 16 | }; 17 | config = lib.mkIf cfg.enable { 18 | environment.systemPackages = [ pkgs.attic-client ]; 19 | systemd.services.attic-watch-store = { 20 | enable = true; 21 | wantedBy = [ "multi-user.target" ]; 22 | description = "attic-watch-store"; 23 | serviceConfig = { 24 | User = username; 25 | ExecStart = "${pkgs.attic-client}/bin/attic watch-store socozy"; 26 | Restart = "always"; 27 | RestartSec = 30; 28 | }; 29 | }; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /hosts/james/web/personal3.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | inherit (config.repo.secrets.global.domain) personal3 home; 10 | domain = personal3; 11 | in 12 | { 13 | security.acme.certs.${domain} = { 14 | domain = "${domain}"; 15 | extraDomainNames = [ 16 | "www.${domain}" 17 | ]; 18 | }; 19 | 20 | services.nginx.virtualHosts.${domain} = { 21 | serverAliases = [ "www.${domain}" ]; 22 | useACMEHost = domain; 23 | forceSSL = true; 24 | kTLS = true; 25 | http3 = true; 26 | quic = true; 27 | root = "/var/lib/static-web/${domain}"; 28 | locations."= /.well-known/carddav".extraConfig = '' 29 | return 301 https://dav.${home}/dav/; 30 | ''; 31 | locations."= /.well-known/caldav".extraConfig = '' 32 | return 301 https://dav.${home}/dav/; 33 | ''; 34 | }; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /pkgs/invoiceninja/invoiceninja-redis.patch: -------------------------------------------------------------------------------- 1 | --- config/database.php 2024-10-25 09:02:12.000000000 +0200 2 | +++ config/database.php 11:25:56.661620943 +0100 3 | @@ -160,6 +160,8 @@ 4 | 'client' => 'predis', 5 | 6 | 'default' => [ 7 | + 'scheme' => env('REDIS_SCHEME', 'tcp'), 8 | + 'path' => env('REDIS_PATH'), 9 | 'host' => env('REDIS_HOST', '127.0.0.1'), 10 | 'password' => env('REDIS_PASSWORD', null), 11 | 'port' => env('REDIS_PORT', 6379), 12 | @@ -167,6 +169,8 @@ 13 | ], 14 | 15 | 'cache' => [ 16 | + 'scheme' => env('REDIS_SCHEME', 'tcp'), 17 | + 'path' => env('REDIS_PATH'), 18 | 'host' => env('REDIS_HOST', '127.0.0.1'), 19 | 'password' => env('REDIS_PASSWORD', null), 20 | 'port' => env('REDIS_PORT', 6379), 21 | 22 | -------------------------------------------------------------------------------- /hosts/james/web/personal.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | inherit (config.repo.secrets.global.domain) 10 | home 11 | work 12 | personal1 13 | ; 14 | domain = personal1; 15 | in 16 | { 17 | security.acme.certs.${domain} = { 18 | domain = "${domain}"; 19 | extraDomainNames = [ 20 | "www.${domain}" 21 | ]; 22 | }; 23 | 24 | services.nginx.virtualHosts.${domain} = { 25 | serverAliases = [ "www.${domain}" ]; 26 | useACMEHost = domain; 27 | forceSSL = true; 28 | kTLS = true; 29 | http3 = true; 30 | quic = true; 31 | globalRedirect = work; 32 | locations."= /.well-known/carddav".extraConfig = '' 33 | return 301 https://dav.${home}/dav/; 34 | ''; 35 | locations."= /.well-known/caldav".extraConfig = '' 36 | return 301 https://dav.${home}/dav/; 37 | ''; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /pkgs/nvidia/package.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | lib, 4 | ast-grep, 5 | nushellPlugins, 6 | nix-prefetch-github, 7 | }: 8 | let 9 | inherit (inputs.self.nixosConfigurations.quine.config.boot) kernelPackages; 10 | in 11 | (kernelPackages.nvidiaPackages.mkDriver { 12 | version = "580.105.08"; 13 | sha256_64bit = "sha256-2cboGIZy8+t03QTPpp3VhHn6HQFiyMKMjRdiV2MpNHU="; 14 | openSha256 = "sha256-FGmMt3ShQrw4q6wsk8DSvm96ie5yELoDFYinSlGZcwQ="; 15 | 16 | useSettings = false; 17 | usePersistenced = false; 18 | }).overrideAttrs 19 | (pkg: { 20 | passthru = pkg.passthru // { 21 | updateScript = lib.writeUpdateScript { 22 | packageToUpdate = "nvidia"; 23 | 24 | utils = [ 25 | ast-grep 26 | nix-prefetch-github 27 | ]; 28 | nushellPlugins = [ nushellPlugins.query ]; 29 | 30 | script = ./update.nu; 31 | }; 32 | }; 33 | }) 34 | -------------------------------------------------------------------------------- /modules/desktop/programs/kicad.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.kicad; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.kicad = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = 22 | { pkgs, config, ... }@hm: 23 | { 24 | home.packages = with pkgs; [ kicad ]; 25 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 26 | directories = [ 27 | ".config/kicad" 28 | ".config/kicad5" 29 | ]; 30 | }; 31 | }; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /modules/desktop/programs/nextcloud.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.nextcloud; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.nextcloud = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | 22 | environment.persistence."/persist" = mkIf withImpermanence { 23 | users.${username} = { 24 | directories = [ 25 | ".config/Nextcloud" 26 | ]; 27 | }; 28 | }; 29 | myhm = { 30 | services.nextcloud-client = { 31 | enable = true; 32 | startInBackground = true; 33 | }; 34 | }; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /modules/shell/ssh/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.ssh; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.ssh = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | 22 | environment.persistence."/persist" = mkIf withImpermanence { 23 | users.${username} = { 24 | directories = [ ".ssh" ]; 25 | }; 26 | }; 27 | home-manager.users."${username}" = { 28 | # note using home-manager programs.ssh because of 29 | # https://github.com/nix-community/home-manager/issues/322 30 | home.file.".ssh/control/.keep".text = ""; 31 | }; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /modules/desktop/programs/1password.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.onepassword; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.onepassword = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | programs._1password = { 22 | enable = true; 23 | }; 24 | programs._1password-gui = { 25 | enable = true; 26 | polkitPolicyOwners = [ username ]; 27 | }; 28 | 29 | environment.persistence."/persist" = mkIf withImpermanence { 30 | users.${username} = { 31 | directories = [ ".config/1Password" ]; 32 | }; 33 | }; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /.github/renovate/groups.json5: -------------------------------------------------------------------------------- 1 | { 2 | $schema: "https://docs.renovatebot.com/renovate-schema.json", 3 | packageRules: [ 4 | { 5 | matchDatasources: ["maven", "deps-edn"], 6 | groupName: "clojure deps.edn", 7 | group: { 8 | commitMessageTopic: "{{{groupName}}} group", 9 | }, 10 | }, 11 | { 12 | description: "opconnect", 13 | groupName: "onepasswordconnect", 14 | matchPackagePatterns: ["1password"], 15 | matchDatasources: ["docker"], 16 | group: { 17 | commitMessageTopic: "{{{groupName}}} group", 18 | }, 19 | separateMinorPatch: true, 20 | }, 21 | { 22 | description: "Immich Group", 23 | groupName: "Immich", 24 | matchPackagePatterns: ["immich"], 25 | matchDatasources: ["docker"], 26 | group: { 27 | commitMessageTopic: "{{{groupName}}} group", 28 | }, 29 | separateMinorPatch: true, 30 | }, 31 | ], 32 | } 33 | -------------------------------------------------------------------------------- /modules/shell/ffsend.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | ... 7 | }: 8 | let 9 | cfg = config.modules.shell.ffsend; 10 | username = config.modules.users.primaryUser.username; 11 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 12 | withImpermanence = config.modules.impermanence.enable; 13 | in 14 | { 15 | options.modules.shell.ffsend = { 16 | enable = lib.mkEnableOption ""; 17 | }; 18 | config = lib.mkIf cfg.enable { 19 | environment.persistence."/persist" = lib.mkIf withImpermanence { 20 | users.${username} = { 21 | directories = [ 22 | ".cache/ffsend" 23 | ]; 24 | }; 25 | }; 26 | systemd.tmpfiles.rules = lib.mkIf withImpermanence [ 27 | "d '/persist${homeDirectory}/.cache/ffsend' - ${username} ${username} - -" 28 | ]; 29 | home-manager.users."${username}" = { 30 | home.packages = [ pkgs.ffsend ]; 31 | }; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /modules/desktop/mako.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | cfg = config.modules.desktop.mako; 10 | username = config.modules.users.primaryUser.username; 11 | in 12 | { 13 | options.modules.desktop.mako = { 14 | enable = lib.mkEnableOption "Enable mako"; 15 | }; 16 | config = lib.mkIf cfg.enable { 17 | myhm = 18 | { pkgs, ... }@hm: 19 | { 20 | services.mako = { 21 | enable = true; 22 | settings = { 23 | font = "monospace 18"; 24 | anchor = "top-center"; 25 | markup = true; 26 | padding = "5"; 27 | background-color = "#282828"; 28 | text-color = "#ebdbb2"; 29 | progress-color = "#ebdbb2"; 30 | border-color = "#928374"; 31 | border-size = 3; 32 | border-radius = 6; 33 | width = 600; 34 | }; 35 | }; 36 | }; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /modules/desktop/programs/nheko.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.nheko; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.nheko = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | environment.persistence."/persist" = mkIf withImpermanence { 22 | users.${username} = { 23 | directories = [ 24 | ".config/nheko" 25 | ".cache/nheko" 26 | ".local/share/nheko" 27 | ]; 28 | }; 29 | }; 30 | home-manager.users."${username}" = 31 | { pkgs, config, ... }@hm: 32 | { 33 | home.packages = with pkgs; [ nheko ]; 34 | }; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /hosts/addams/modules/ntopng.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkg, 4 | lib, 5 | ... 6 | }: 7 | { 8 | 9 | sops.secrets."maxmind/licenseKey" = { }; 10 | services.geoipupdate = { 11 | enable = true; 12 | settings = { 13 | AccountID = config.repo.secrets.local.maxmind.accountId; 14 | EditionIDs = [ 15 | "GeoLite2-ASN" 16 | "GeoLite2-City" 17 | "GeoLite2-Country" 18 | ]; 19 | LicenseKey = config.sops.secrets."maxmind/licenseKey".path; 20 | }; 21 | }; 22 | environment.persistence."/persist".directories = [ "/var/lib/ntopng" ]; 23 | services.ntopng = { 24 | enable = true; 25 | interfaces = [ 26 | "wan0" 27 | "lan0" 28 | "iot" 29 | "inot" 30 | "mgmt" 31 | "vpn" 32 | "prim" 33 | "guest" 34 | "svc" 35 | "data" 36 | ]; 37 | }; 38 | systemd.services.ntopng.serviceConfig = { 39 | Restart = "always"; 40 | RestartSec = "20s"; 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /modules/desktop/programs/discord.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.discord; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.discord = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = 22 | { pkgs, config, ... }@hm: 23 | { 24 | home.packages = with pkgs; [ 25 | discord 26 | betterdiscordctl 27 | ]; 28 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 29 | directories = [ 30 | ".config/BetterDiscord" 31 | ".config/discord" 32 | ]; 33 | }; 34 | }; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /modules/desktop/hyprland/theme.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | cfg = config.modules.desktop.hyprland; 10 | nerdfonts = with pkgs; [ 11 | nerd-fonts.iosevka 12 | nerd-fonts.fira-code 13 | nerd-fonts.mononoki 14 | nerd-fonts.jetbrains-mono 15 | nerd-fonts.symbols-only 16 | ]; 17 | 18 | #font.mono = "Iosevka Comfy Fixed"; 19 | #font.mono = "Berkeley Mono Trial"; 20 | font.mono = "Iosevka"; 21 | font.term = "Iosevka Nerd Font Mono"; 22 | font.serif = "Noto Serif"; 23 | font.sans = "Nokia Sans Wide"; 24 | font.emoji = "Noto Color Emoji"; 25 | 26 | theme = { 27 | name = "adw-gtk3-dark"; 28 | package = pkgs.adw-gtk3; 29 | }; 30 | cursorTheme = { 31 | name = "Adwaita"; 32 | size = 24; 33 | package = pkgs.adwaita-icon-theme; 34 | }; 35 | iconTheme = { 36 | name = "Adwaita"; 37 | package = pkgs.adwaita-icon-theme; 38 | }; 39 | in 40 | 41 | { 42 | config = lib.mkIf cfg.enable { }; 43 | } 44 | -------------------------------------------------------------------------------- /modules/shell/isd.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.isd; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.isd = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | environment.persistence."/persist" = lib.mkIf withImpermanence { 22 | users.${username} = { 23 | directories = [ 24 | ".config/isd_tui" 25 | ".local/share/isd_tui" 26 | ".cache/isd_tui" 27 | ]; 28 | }; 29 | }; 30 | myhm = { 31 | home.packages = [ 32 | pkgs.isd 33 | ]; 34 | xdg.configFile."isd_tui/config.yaml".text = builtins.toJSON { 35 | theme = "gruvbox"; 36 | }; 37 | }; 38 | 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /hosts/quine/microvm-test-impl.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | inputs, 6 | 7 | ... 8 | }: 9 | 10 | let 11 | 12 | inherit (config.networking) hostName; 13 | nets = config.site.net; 14 | hostConfig = config.site.hosts.${hostName}; 15 | hostBridges = builtins.attrNames ( 16 | lib.filterAttrs (_: { type, ... }: type == "bridge") hostConfig.interfaces 17 | ); 18 | 19 | genGuestSecret = hostname: { 20 | "microvm-${hostname}-sops-key" = { 21 | sopsFile = ../../guests/${hostname}/secrets.sops.yaml; 22 | key = "ssh_host_ed25519_key"; 23 | owner = "microvm"; 24 | mode = "400"; 25 | }; 26 | }; 27 | guests = [ 28 | "claude-test" 29 | ]; 30 | in 31 | { 32 | imports = [ 33 | ../../modules/site 34 | ../../modules/site-net 35 | ]; 36 | 37 | home-ops.microvm-host = { 38 | enable = true; 39 | baseZfsDataset = "rpool/encrypted/safe/microvms"; 40 | }; 41 | 42 | sops.secrets = lib.mori.reduceAttrs genGuestSecret guests; 43 | } 44 | -------------------------------------------------------------------------------- /modules/shell/mpv.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.mpv; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.mpv = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = { 22 | programs.mpv = { 23 | enable = true; 24 | config = { 25 | #hwdec = "auto-safe"; 26 | #vo = "gpu"; 27 | #profile = "gpu-hq"; 28 | }; 29 | scripts = [ 30 | pkgs.mpvScripts.uosc 31 | # pkgs.mpvScripts.cutter 32 | pkgs.mpvScripts.memo 33 | pkgs.mpvScripts.sponsorblock 34 | pkgs.mpvScripts.quality-menu 35 | ]; 36 | }; 37 | }; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /modules/shell/direnv.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.direnv; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.direnv = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | programs.direnv = { 22 | enable = true; 23 | package = pkgs.direnv; 24 | nix-direnv.enable = true; 25 | }; 26 | # Nix options for derivations to persist garbage collection 27 | nix.extraOptions = '' 28 | keep-outputs = true 29 | keep-derivations = true 30 | ''; 31 | environment.pathsToLink = [ "/share/nix-direnv" ]; 32 | 33 | myhm = { 34 | persistence = mkIf withImpermanence { directories = [ ".local/share/direnv" ]; }; 35 | }; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /scripts/pgbackrest-restore.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -ex 3 | 4 | workdir=~/work/pg 5 | image="docker.io/library/postgres:15-bullseye" 6 | 7 | podman pull $image 8 | 9 | mkdir -p $workdir 10 | cd $workdir 11 | mkdir -p log spool 12 | podman run --name pg-restore --userns keep-id -p 127.0.0.1:5433:5432 -v $workdir:/var/lib/postgresql/data -e POSTGRES_PASSWORD=postgres -d $image 13 | 14 | until [ -f ./pg/global/pg_control ]; do 15 | sleep 1 16 | done 17 | 18 | sleep 1 19 | 20 | podman stop pg-restore 21 | 22 | rm ./pg/global/pg_control 23 | find ./pg -mindepth 1 -delete 24 | 25 | cat < ./pgbackrest.conf 26 | [global] 27 | archive-async=y 28 | archive-push-queue-max = 4GiB 29 | archive-timeout = 60 30 | compress-level = 9 31 | compress-type = lz4 32 | delta = y 33 | log-path = $PWD/log 34 | spool-path = $PWD/spool 35 | repo1-block = y 36 | repo1-bundle = y 37 | repo1-path = $PWD/matrix/repo1 38 | [db] 39 | pg1-path = $PWD/pg 40 | EOF 41 | 42 | pgbackrest --config $(pwd)/pgbackrest.conf --stanza=repo1 restore 43 | -------------------------------------------------------------------------------- /modules/hardware/brother-ql-web.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | config, 4 | pkgs, 5 | inputs, 6 | ... 7 | }: 8 | let 9 | cfg = config.modules.hardware.brother-ql; 10 | pkg = inputs.brother_ql_web.packages.${pkgs.system}.default; 11 | in 12 | { 13 | 14 | options = { 15 | modules.hardware.brother-ql.enable = lib.mkEnableOption ""; 16 | }; 17 | config = lib.mkIf cfg.enable { 18 | systemd.services.brother-ql-web = { 19 | after = [ "network.target" ]; 20 | description = "Brother QL Web Interface"; 21 | wantedBy = [ "multi-user.target" ]; 22 | environment = { 23 | FLASK_PRINTER = "tcp://10.9.5.2:9100"; 24 | FLASK_MODEL = "QL-800"; 25 | #FLASK_SERVER_PORT = "8013"; 26 | #FLASK_LABEL_DEFAULT_SIZE = "d24"; 27 | #FLASK_LABEL_DEFAULT_QR_SIZE = "7"; 28 | }; 29 | serviceConfig = { 30 | ExecStart = "${pkg}/bin/brother_ql_web"; 31 | DynamicUser = true; 32 | SupplementaryGroups = "lp"; 33 | Restart = "always"; 34 | }; 35 | }; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /modules/desktop/programs/ghostty/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.ghostty; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | termFont = config.modules.desktop.fonts.terminal; 16 | in 17 | { 18 | options.modules.desktop.programs.ghostty = { 19 | enable = lib.mkEnableOption ""; 20 | }; 21 | config = mkIf cfg.enable { 22 | home-manager.users."${username}" = 23 | { pkgs, config, ... }@hm: 24 | { 25 | home.packages = [ pkgs.ghostty ]; 26 | programs.ghostty = { 27 | enable = true; 28 | settings = { 29 | font-family = termFont.name; 30 | font-size = termFont.size; 31 | theme = "Gruvbox Dark Hard"; 32 | background-opacity = 0.8; 33 | }; 34 | }; 35 | }; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /pkgs/beets-dynamicrange.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | fetchFromGitHub, 4 | python3Packages, 5 | beets, 6 | dr14_tmeter, 7 | }: 8 | python3Packages.buildPythonApplication rec { 9 | pname = "beets-dynamicrange"; 10 | version = "unstable-2023-12-05"; 11 | 12 | src = fetchFromGitHub { 13 | owner = "auchter"; 14 | repo = pname; 15 | rev = "62fc157f85293d1d2dcc36b5afa33d5322cc8c5f"; 16 | sha256 = "sha256-ALNGrpZOKdUE3g4np8Ms+0s8uWi6YixF2IVHSgaQVj4="; 17 | }; 18 | 19 | nativeBuildInputs = [ beets ]; 20 | 21 | propagatedBuildInputs = [ dr14_tmeter ]; 22 | 23 | postPatch = '' 24 | substituteInPlace beetsplug/dynamicrange.py \ 25 | --replace dr14_tmeter ${dr14_tmeter}/bin/dr14_tmeter 26 | ''; 27 | 28 | doCheck = false; 29 | 30 | meta = with lib; { 31 | homepage = "https://github.com/auchter/beets-dynamicrange"; 32 | description = "Calculate and store dynamic range of music for beets"; 33 | license = licenses.mit; 34 | maintainers = with maintainers; [ auchter ]; 35 | platforms = platforms.linux; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /pkgs/nvidia/update.nu: -------------------------------------------------------------------------------- 1 | let self = "pkgs/packages/nvidia/package.nix" 2 | 3 | mut updates = {} 4 | 5 | $updates.version = ( 6 | http get https://www.nvidia.com/en-us/drivers/unix/ | 7 | # There is no better selector, sadly; the Linux x86 8 | # production driver *should* be the first link in the first 9 | # paragraph, though 10 | query web --query '#rightContent p:first-child a:first-of-type' | get 0 | get 0 | str trim 11 | ) 12 | 13 | $updates.sha256_64bit = ( 14 | ^nix-prefetch-url https://us.download.nvidia.com/XFree86/Linux-x86_64/($updates.version)/NVIDIA-Linux-x86_64-($updates.version).run 15 | | nix hash to-sri --type sha256 $in 16 | ) 17 | $updates.openSha256 = ( 18 | ^nix-prefetch-github --rev $updates.version NVIDIA open-gpu-kernel-modules 19 | | from json 20 | | $in.hash 21 | ) 22 | 23 | for $update in ($updates | transpose key value) { 24 | ( 25 | ast-grep run 26 | --pattern $'{($update.key) = $VALUE;}' 27 | --selector binding 28 | --rewrite $'($update.key) = "($update.value)";' 29 | --update-all 30 | $self 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | fail_fast: false 3 | 4 | repos: 5 | - repo: local 6 | hooks: 7 | - id: nixfmt 8 | name: nixfmt 9 | entry: nixfmt 10 | language: system 11 | files: \.nix$ 12 | pass_filenames: true 13 | args: 14 | - --width=100 15 | - repo: https://github.com/pre-commit/pre-commit-hooks 16 | rev: v4.4.0 17 | hooks: 18 | - id: trailing-whitespace 19 | #- id: end-of-file-fixer 20 | - id: fix-byte-order-marker 21 | - id: mixed-line-ending 22 | - id: check-added-large-files 23 | args: [--maxkb=2048] 24 | - id: check-merge-conflict 25 | - id: check-executables-have-shebangs 26 | - repo: https://github.com/Lucas-C/pre-commit-hooks 27 | rev: v1.5.4 28 | hooks: 29 | - id: remove-crlf 30 | - id: remove-tabs 31 | exclude: (Makefile) 32 | 33 | - repo: https://github.com/zricethezav/gitleaks 34 | rev: v8.23.3 35 | hooks: 36 | - id: gitleaks 37 | args: 38 | - --config 39 | - .github/lint/gitleaks.toml 40 | -------------------------------------------------------------------------------- /modules/SKELETON.nix.txt: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | cfg = config.modules.shell.ZZNAME; 11 | username = config.modules.users.primaryUser.username; 12 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 13 | withImpermanence = config.modules.impermanence.enable; 14 | in { 15 | options.modules.shell.ZZNAME = { 16 | enable = lib.mkEnableOption ""; 17 | }; 18 | config = mkIf cfg.enable { 19 | home-manager.users."${username}" = { 20 | home.packages = with pkgs; [ 21 | ]; 22 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 23 | directories = [ 24 | ]; 25 | }; 26 | }; 27 | }; 28 | } 29 | 30 | 31 | { 32 | options, 33 | config, 34 | lib, 35 | pkgs, 36 | inputs, 37 | ... 38 | }: 39 | with lib; 40 | cfg = config.modules.services.ZZNAME; 41 | withImpermanence = config.modules.impermanence.enable; 42 | in { 43 | options.modules.services.ZZNAME = { 44 | enable = lib.mkEnableOption ""; 45 | }; 46 | config = mkIf cfg.enable { 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /modules/dev/fennel.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | inputs, 4 | options, 5 | lib, 6 | pkgs, 7 | my, 8 | ... 9 | }: 10 | with lib; 11 | let 12 | devCfg = config.modules.dev; 13 | cfg = devCfg.fennel; 14 | username = config.modules.users.primaryUser.username; 15 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 16 | withImpermanence = config.modules.impermanence.enable; 17 | nur = import inputs.nur { 18 | nurpkgs = pkgs; 19 | inherit pkgs; 20 | }; 21 | in 22 | { 23 | options.modules.dev.fennel = { 24 | enable = lib.mkEnableOption ""; 25 | }; 26 | 27 | config = mkIf cfg.enable { 28 | environment.systemPackages = with pkgs; [ 29 | lua 30 | luajit 31 | lua-language-server 32 | fennel 33 | fnlfmt 34 | nur.repos.bandithedoge.fennel-language-server 35 | love 36 | ]; 37 | home-manager.users."${username}" = { 38 | #home.packages = with pkgs; [ 39 | #]; 40 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 41 | directories = [ ".config/fennel" ]; 42 | }; 43 | }; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /modules/shell/attic.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.attic; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.attic = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | environment.systemPackages = [ pkgs.attic-client ]; 22 | systemd.tmpfiles.rules = mkIf withImpermanence [ 23 | "d /persist${homeDirectory}/.config/attic 700 ${username} ${username}" 24 | "d /persist${homeDirectory}/.local/share/attic 700 ${username} ${username}" 25 | ]; 26 | home-manager.users."${username}" = 27 | { pkgs, config, ... }@hm: 28 | { 29 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 30 | directories = [ 31 | ".config/attic" 32 | ".local/share/attic" 33 | ]; 34 | }; 35 | }; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /modules/desktop/hyprpaper.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | cfg = config.modules.desktop.hyprpaper; 10 | hyprland = config.programs.hyprland.package; 11 | in 12 | { 13 | 14 | options.modules.desktop.hyprpaper = { 15 | enable = lib.mkEnableOption "Enable hyprpaper"; 16 | }; 17 | config = lib.mkIf cfg.enable { 18 | myhm = 19 | { ... }@hm: 20 | { 21 | services.hyprpaper = { 22 | enable = true; 23 | settings = { 24 | preload = [ 25 | #"~/docs/img/walls/safe-landing.jpg" 26 | "~/docs/img/walls/hyprland/gruv-vertical.jpg" 27 | #"~/docs/img/walls/hyprland/abstract-4.png" 28 | #"~/docs/img/walls/safe-landing-vertical.jpg" 29 | "~/docs/img/walls/hyprland/gruvbox_astro_wide.jpg" 30 | ]; 31 | wallpaper = [ 32 | "HDMI-A-1,~/docs/img/walls/hyprland/gruv-vertical.jpg" 33 | "DP-2,contain:~/docs/img/walls/hyprland/gruvbox_astro_wide.jpg" 34 | ]; 35 | }; 36 | }; 37 | }; 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /modules/desktop/niri/emacs.kdl: -------------------------------------------------------------------------------- 1 | binds { 2 | Mod+Left { spawn "@emacsWM@" "focus-column-left"; } 3 | Mod+Down { spawn "@emacsWM@" "focus-window-or-workspace-down"; } 4 | Mod+Up { spawn "@emacsWM@" "focus-window-or-workspace-up"; } 5 | Mod+Right { spawn "@emacsWM@" "focus-column-right"; } 6 | Mod+H { spawn "@emacsWM@" "focus-column-left"; } 7 | Mod+J { spawn "@emacsWM@" "focus-window-or-workspace-down"; } 8 | Mod+K { spawn "@emacsWM@" "focus-window-or-workspace-up"; } 9 | Mod+L { spawn "@emacsWM@" "focus-column-right"; } 10 | 11 | Mod+Shift+Left { spawn "@emacsWM@" "move-column-left"; } 12 | Mod+Shift+Down { spawn "@emacsWM@" "move-window-down"; } 13 | Mod+Shift+Up { spawn "@emacsWM@" "move-window-up"; } 14 | Mod+Shift+Right { spawn "@emacsWM@" "move-column-right"; } 15 | Mod+Shift+H { spawn "@emacsWM@" "move-column-left"; } 16 | Mod+Shift+J { spawn "@emacsWM@" "move-window-down-or-to-workspace-down"; } 17 | Mod+Shift+K { spawn "@emacsWM@" "move-window-up-or-to-workspace-up"; } 18 | Mod+Shift+L { spawn "@emacsWM@" "move-column-right"; } 19 | } 20 | -------------------------------------------------------------------------------- /modules/shell/htop/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.htop; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.htop = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | home-manager.users."${username}" = { 22 | xdg.configFile."btop/themes/gruvbox_dark_v2.theme".source = ./configs/btop/gruvbox_dark_v2.theme; 23 | programs.btop = { 24 | enable = true; 25 | settings = { 26 | color_theme = "gruvbox_dark_v2"; 27 | theme_background = true; 28 | rounded_corners = true; 29 | vim_keys = true; 30 | }; 31 | }; 32 | programs.htop = { 33 | enable = true; 34 | settings = { 35 | hide_kernel_threads = 1; 36 | hide_userland_threads = 1; 37 | }; 38 | }; 39 | }; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /hosts/james/web/personals.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | 10 | inherit (config.repo.secrets.global) domain; 11 | inherit (config.repo.secrets.local) atprotoDid; 12 | work = domain.work; 13 | domains = [ 14 | domain.personal4 15 | domain.personal5 16 | domain.personal6 17 | ]; 18 | certFor = domain: { 19 | ${domain} = { 20 | domain = "${domain}"; 21 | extraDomainNames = [ 22 | "www.${domain}" 23 | ]; 24 | }; 25 | }; 26 | vhostFor = d: { 27 | ${d} = { 28 | serverAliases = [ "www.${d}" ]; 29 | useACMEHost = d; 30 | forceSSL = true; 31 | kTLS = true; 32 | http3 = true; 33 | quic = true; 34 | globalRedirect = work; 35 | 36 | locations."= /.well-known/atproto-did".extraConfig = lib.mkIf (d == domain.personal2) '' 37 | add_header Content-Type text/plain; 38 | return 200 '${atprotoDid}'; 39 | ''; 40 | }; 41 | }; 42 | in 43 | { 44 | security.acme.certs = lib.mkMerge (map certFor domains); 45 | services.nginx.virtualHosts = lib.mkMerge (map vhostFor domains); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /hosts/addams/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | modulesPath, 6 | ... 7 | }: 8 | { 9 | 10 | imports = [ 11 | (modulesPath + "/profiles/all-hardware.nix") 12 | ./disk-config.nix 13 | ]; 14 | 15 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 16 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 17 | 18 | services.getty.autologinUser = "ramblurr"; 19 | boot = { 20 | loader.systemd-boot.enable = true; 21 | loader.efi.canTouchEfiVariables = true; 22 | zfs.devNodes = lib.mkForce "/dev/disk/by-partuuid"; 23 | kernelModules = [ "kvm-intel" ]; 24 | extraModulePackages = [ ]; 25 | 26 | initrd = { 27 | availableKernelModules = [ 28 | "xhci_pci" 29 | "thunderbolt" 30 | "ahci" 31 | "usbhid" 32 | "usb_storage" 33 | "sd_mod" 34 | "sr_mod" 35 | ]; 36 | kernelModules = [ ]; 37 | 38 | postDeviceCommands = lib.mkAfter '' 39 | zfs rollback -r rpool/encrypted/local/root@blank && \ 40 | echo "rollback complete" 41 | ''; 42 | }; 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /modules/dev/k8s/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | options, 4 | inputs, 5 | lib, 6 | pkgs, 7 | my, 8 | ... 9 | }: 10 | with lib; 11 | let 12 | devCfg = config.modules.dev; 13 | cfg = devCfg.k8s; 14 | username = config.modules.users.primaryUser.username; 15 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 16 | withImpermanence = config.modules.impermanence.enable; 17 | in 18 | { 19 | options.modules.dev.k8s = { 20 | enable = lib.mkEnableOption ""; 21 | }; 22 | 23 | config = mkIf cfg.enable { 24 | environment.systemPackages = with pkgs; [ ]; 25 | myhm = { 26 | home.packages = with pkgs; [ 27 | influxdb2-cli 28 | k9s 29 | kubernetes-helm 30 | kubectl 31 | kubeconform 32 | krew 33 | kustomize 34 | cilium-cli 35 | talosctl 36 | fluxcd 37 | cloudflared 38 | ]; 39 | 40 | persistence = mkIf withImpermanence { 41 | directories = [ 42 | ".config/k9s" 43 | ".config/kube" 44 | ".config/krew" 45 | ".influxdbv2" 46 | ]; 47 | }; 48 | }; 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /config/hetzner-cloud-ccx.nix: -------------------------------------------------------------------------------- 1 | # As of Aug 2023 Hetzner Cloud CCX* vms support UEFI by default 2 | { 3 | config, 4 | modulesPath, 5 | lib, 6 | pkgs, 7 | ... 8 | }: 9 | 10 | { 11 | imports = [ 12 | "${modulesPath}/profiles/qemu-guest.nix" 13 | ]; 14 | 15 | boot.loader.grub.enable = lib.mkForce false; 16 | boot.loader.systemd-boot.enable = true; 17 | boot.loader.efi.canTouchEfiVariables = true; 18 | networking.useNetworkd = true; 19 | networking.useDHCP = true; 20 | networking.dhcpcd.enable = false; 21 | systemd.network = { 22 | enable = true; 23 | wait-online.ignoredInterfaces = [ 24 | "lo" 25 | "tailscale0" 26 | ]; 27 | }; 28 | 29 | services.timesyncd.enable = true; 30 | services.timesyncd.servers = [ 31 | "ntp1.hetzner.de" 32 | "ntp2.hetzner.com" 33 | "ntp3.hetzner.net" 34 | ]; 35 | services.resolved.enable = true; 36 | 37 | # Needed by the Hetzner Cloud password reset feature. 38 | services.qemuGuest.enable = lib.mkDefault true; 39 | # https://discourse.nixos.org/t/qemu-guest-agent-on-hetzner-cloud-doesnt-work/8864/2 40 | systemd.services.qemu-guest-agent.path = [ pkgs.shadow ]; 41 | } 42 | -------------------------------------------------------------------------------- /modules/desktop/programs/musescore.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.musescore; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.musescore = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | 22 | environment.persistence."/persist" = mkIf withImpermanence { 23 | users.${username} = { 24 | directories = [ 25 | ".config/MuseScore" 26 | ".local/share/MuseScore" 27 | ".local/state/MuseScore" 28 | ".local/state/muse-sounds-manager" 29 | ".local/share/MuseSampler" 30 | ".muse-hub" 31 | ]; 32 | }; 33 | }; 34 | home-manager.users."${username}" = 35 | { pkgs, config, ... }@hm: 36 | { 37 | home.packages = [ 38 | pkgs.musescore 39 | pkgs.muse-sounds-manager 40 | ]; 41 | }; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /modules/hardware/misc.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | with lib; 8 | let 9 | cfg = config.modules.hardware; 10 | in 11 | { 12 | options = { 13 | modules.hardware = { 14 | fwupd.enable = lib.mkOption { 15 | type = lib.types.bool; 16 | default = true; 17 | }; 18 | udisks2.enable = lib.mkOption { 19 | type = lib.types.bool; 20 | default = true; 21 | }; 22 | enableRedistributableFirmware = lib.mkOption { 23 | type = lib.types.bool; 24 | default = true; 25 | }; 26 | usbModeSwitch.enable = lib.mkEnableOption ""; 27 | }; 28 | }; 29 | config = { 30 | ## MISC HARDWARE RELATED ################################################ 31 | services.fwupd.enable = cfg.fwupd.enable; 32 | services.udisks2.enable = cfg.udisks2.enable; 33 | hardware.enableRedistributableFirmware = cfg.enableRedistributableFirmware; 34 | hardware.usb-modeswitch.enable = cfg.usbModeSwitch.enable; 35 | hardware.cpu.amd.updateMicrocode = pkgs.hostPlatform.system == "x86_64-linux"; 36 | hardware.cpu.intel.updateMicrocode = pkgs.hostPlatform.system == "x86_64-linux"; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /modules/services/matrix-irc.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | let 8 | cfg = config.modules.services.matrix-synapse.bridges.irc; 9 | rootCfg = config.modules.services.matrix-synapse; 10 | dataDir = "${rootCfg.dataDir}/mautrix-irc"; 11 | in 12 | { 13 | options.modules.services.matrix-synapse.bridges.irc = { 14 | enable = lib.mkEnableOption "heisenbridge for personal irc matrix bridging"; 15 | }; 16 | config = lib.mkIf cfg.enable { 17 | services.heisenbridge = { 18 | enable = true; 19 | homeserver = "https://${config.modules.services.matrix-synapse.domain}"; 20 | }; 21 | 22 | systemd.services.heisenbridge = { 23 | before = [ "matrix-synapse.service" ]; 24 | wantedBy = [ "multi-user.target" ]; 25 | serviceConfig = { 26 | Restart = "on-failure"; 27 | }; 28 | unitConfig = { 29 | StartLimitBurst = 3; 30 | StartLimitIntervalSec = "30s"; 31 | }; 32 | }; 33 | # TODO: Make work in cases where this isn't on the same machine. 34 | services.matrix-synapse.settings.app_service_config_files = [ 35 | "/var/lib/heisenbridge/registration.yml" 36 | ]; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /hosts/mali/README.md: -------------------------------------------------------------------------------- 1 | # Mali - a NAS 2 | 3 | ## Flake Install 4 | 5 | 1. Boot into installer 6 | 7 | 2. Follow: 8 | ``` sh 9 | # 1. 10 | # from workstation 11 | ssh-copy-id -f -i ~/.ssh/casey.pub nixos 12 | rsync -avr ~/nixcfg nixos: 13 | 14 | # WARNING: ensure target disks are correct 15 | lsblk -a -o NAME,SIZE,VENDOR,NAME,MODEL,PARTLABEL 16 | 17 | # 2. 18 | # from target 19 | cd /home/nixos/nixcfg/hosts/stable/x86_64-linux/mali 20 | sudo ./disks.sh 21 | 22 | # 3. Save hdd.key and boot.key 23 | scp nixos:/home/nixos/nixcfg/hosts/stable/x86_64-linux/mali/boot.key . 24 | scp nixos:/home/nixos/nixcfg/hosts/stable/x86_64-linux/mali/hdd.key . 25 | # Add them to your password manager 26 | 27 | # 3. 28 | # go into a root shell 29 | sudo -i 30 | nix-shell -p git htop 31 | 32 | # 4. Resolve TODO(qemu) in hardware-configuration.nix 33 | 34 | # 5. 35 | bash ./install.sh 36 | 37 | # 6. 38 | # when prompted 39 | # from workstation 40 | # sops -d --extract "['ssh_host_ed25519_key']" ./secrets.sops.yaml | ssh nixos 'cat - | sudo tee -a /mnt/persist/etc/ssh/ssh_host_ed25519_key' 41 | # then on target type YES 42 | ``` 43 | 44 | 3. Reboot 45 | 4. Login 46 | -------------------------------------------------------------------------------- /hosts/witt/home.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | inputs, 6 | ... 7 | }: 8 | 9 | let 10 | mainSansFont = "Cabin"; 11 | in 12 | { 13 | #home-manager.sharedModules = [ inputs.plasma-manager.homeManagerModules.plasma-manager ]; 14 | myhm = 15 | { ... }@hm: 16 | { 17 | # Starship prompt color - something very different to distinguish it from my main workstation 18 | programs.starship.settings = pkgs.lib.importTOML ./gruvbox-rainbow.toml; 19 | 20 | # Make certain user services happy 21 | # https://github.com/nix-community/home-manager/issues/2064 22 | systemd.user.targets.tray = { 23 | Unit = { 24 | Description = "Home Manager System Tray"; 25 | Requires = [ "graphical-session-pre.target" ]; 26 | }; 27 | }; 28 | 29 | # Apps, apps, apps 30 | home.packages = with pkgs; [ 31 | appimage-run 32 | musescore 33 | audacity 34 | pavucontrol 35 | brightnessctl 36 | meld 37 | gimp 38 | pdfarranger 39 | qpwgraph # pipewire wiring gui tool 40 | easyeffects # pipewire eq 41 | ]; 42 | 43 | }; # end home manager 44 | } 45 | -------------------------------------------------------------------------------- /modules/desktop/programs/kdeconnect.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.kdeconnect; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.kdeconnect = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | networking.firewall.allowedTCPPortRanges = [ 22 | { 23 | from = 1714; 24 | to = 1764; 25 | } 26 | ]; 27 | networking.firewall.allowedUDPPortRanges = [ 28 | { 29 | from = 1714; 30 | to = 1764; 31 | } 32 | ]; 33 | home-manager.users."${username}" = 34 | { pkgs, config, ... }@hm: 35 | { 36 | services.kdeconnect = { 37 | enable = true; 38 | indicator = true; 39 | }; 40 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 41 | directories = [ ".config/kdeconnect" ]; 42 | }; 43 | }; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /configs/doom/custom.el: -------------------------------------------------------------------------------- 1 | ;;; -*- lexical-binding: t -*- 2 | (custom-set-variables 3 | ;; custom-set-variables was added by Custom. 4 | ;; If you edit it by hand, you could mess it up, so be careful. 5 | ;; Your init file should contain only one such instance. 6 | ;; If there is more than one, they won't work right. 7 | '(custom-safe-themes 8 | '("f1e8339b04aef8f145dd4782d03499d9d716fdc0361319411ac2efc603249326" 9 | "48042425e84cd92184837e01d0b4fe9f912d875c43021c3bcb7eeb51f1be5710" default)) 10 | '(safe-local-variable-values 11 | '((cider-redirect-server-output-to-repl . t) 12 | (cider-preferred-build-tool . clojure-cli) (cider-repl-display-help-banner)))) 13 | (custom-set-faces 14 | ;; custom-set-faces was added by Custom. 15 | ;; If you edit it by hand, you could mess it up, so be careful. 16 | ;; Your init file should contain only one such instance. 17 | ;; If there is more than one, they won't work right. 18 | '(lsp-face-highlight-read ((t (:background "#32302f" :bold t :foreground unspecified)))) 19 | '(lsp-face-highlight-textual ((t (:background "#32302f" :bold t :foreground unspecified)))) 20 | '(lsp-face-highlight-write ((t (:background "#32302f" :bold t :foreground unspecified))))) 21 | -------------------------------------------------------------------------------- /scripts/enumerate-ports.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | 3 | items = [ 4 | "9003/udp", 5 | "9100-9200/tcp", 6 | "30000-30010/tcp", 7 | "9330-9339/tcp", 8 | "49863/tcp", 9 | "52667/tcp", 10 | "52709/tcp", 11 | "63098-63100/tcp", 12 | ] 13 | 14 | 15 | def enumerate_ports(items): 16 | services = {} 17 | service_id = 0 18 | for item in items: 19 | if "-" in item: 20 | port_range, protocol = item.split("/") 21 | start_port, end_port = map(int, port_range.split("-")) 22 | for port in range(start_port, end_port + 1): 23 | services[f"service{service_id}"] = { 24 | "port": port, 25 | "protocol": protocol.upper(), 26 | } 27 | service_id += 1 28 | else: 29 | port, protocol = item.split("/") 30 | services[f"service{service_id}"] = { 31 | "port": int(port), 32 | "protocol": protocol.upper(), 33 | } 34 | service_id += 1 35 | return services 36 | 37 | 38 | services_dict = enumerate_ports(items) 39 | yaml_output = yaml.dump(services_dict, sort_keys=False) 40 | print(yaml_output) 41 | -------------------------------------------------------------------------------- /modules/dev/python.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | options, 4 | lib, 5 | pkgs, 6 | my, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | devCfg = config.modules.dev; 12 | cfg = devCfg.python; 13 | username = config.modules.users.primaryUser.username; 14 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 15 | withImpermanence = config.modules.impermanence.enable; 16 | in 17 | { 18 | options.modules.dev.python = { 19 | enable = lib.mkEnableOption ""; 20 | }; 21 | 22 | config = mkIf cfg.enable { 23 | environment.systemPackages = with pkgs; [ 24 | uv 25 | python3Packages.python-lsp-server 26 | python3Packages.netaddr 27 | (python3.withPackages ( 28 | ps: with ps; [ 29 | pip 30 | pytest 31 | virtualenv 32 | black 33 | isort 34 | setuptools 35 | wheel 36 | requests 37 | netaddr 38 | ] 39 | )) 40 | ]; 41 | home-manager.users."${username}" = { 42 | home.packages = with pkgs; [ pyright ]; 43 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 44 | directories = [ ".cache/pypoetry/virtualenvs/" ]; 45 | }; 46 | }; 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2021 Henrik Lissner. 4 | Copyright (c) 2022 David Li. 5 | Copyright (c) 2022-2023 Casey Link. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | "Software"), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /modules/dev/node/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | options, 4 | lib, 5 | pkgs, 6 | my, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | devCfg = config.modules.dev; 12 | cfg = devCfg.node; 13 | username = config.modules.users.primaryUser.username; 14 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 15 | withImpermanence = config.modules.impermanence.enable; 16 | in 17 | { 18 | options.modules.dev.node = { 19 | enable = lib.mkEnableOption ""; 20 | }; 21 | 22 | config = mkIf cfg.enable { 23 | environment.systemPackages = with pkgs; [ ]; 24 | 25 | environment.persistence."/persist" = mkIf withImpermanence { 26 | users.${username} = { 27 | directories = [ 28 | ".config/npm" 29 | ".cache/npm-packages" 30 | ".config/yarn/" 31 | ".local/share/npm" 32 | ".local/share/volta" 33 | ]; 34 | }; 35 | }; 36 | home-manager.users."${username}" = { 37 | home.packages = with pkgs; [ 38 | nodejs_20 39 | yarn 40 | deno 41 | #volta 42 | ]; 43 | 44 | #xdg.configFile."npm" = { 45 | # source = ./configs/npm; 46 | # recursive = true; 47 | #}; 48 | }; 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /pkgs/qobuz-dl.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | python3, 4 | fetchPypi, 5 | }: 6 | 7 | let 8 | pick = python3.pkgs.buildPythonApplication rec { 9 | pname = "pick"; 10 | version = "1.6.0"; 11 | format = "pyproject"; 12 | 13 | src = fetchPypi { 14 | inherit pname version; 15 | hash = "sha256-Kv1GyJtQIxHTuDHs7hoA6Kv4kq1elubLr5PxcrKa4cU="; 16 | }; 17 | 18 | nativeBuildInputs = with python3.pkgs; [ poetry-core ]; 19 | }; 20 | 21 | in 22 | 23 | python3.pkgs.buildPythonApplication rec { 24 | pname = "qobuz-dl"; 25 | version = "0.9.9.10"; 26 | format = "setuptools"; 27 | 28 | src = fetchPypi { 29 | inherit pname version; 30 | hash = "sha256-q7TUl3scg+isoLB0xJvJLCtvJU7O+ogMlftt0O73qb4="; 31 | }; 32 | 33 | propagatedBuildInputs = with python3.pkgs; [ 34 | beautifulsoup4 35 | colorama 36 | mutagen 37 | pathvalidate 38 | pick 39 | requests 40 | tqdm 41 | ]; 42 | 43 | pythonImportsCheck = [ "qobuz_dl" ]; 44 | 45 | meta = with lib; { 46 | description = "The complete Lossless and Hi-Res music downloader for Qobuz"; 47 | homepage = "https://pypi.org/project/qobuz-dl/"; 48 | license = licenses.gpl3Only; 49 | maintainers = with maintainers; [ ]; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /configs/doom/+helpers.el: -------------------------------------------------------------------------------- 1 | ;;; $DOOMDIR/+helpers.el -*- lexical-binding: t; -*- 2 | 3 | ;; Define a specific timeout error (safe if re-evaluated) 4 | (unless (get 'await-timeout 'error-conditions) 5 | (define-error 'await-timeout "await-callback: timed out")) 6 | 7 | (defun await-callback (starter &optional timeout) 8 | "STARTER is (lambda (resolve reject) ...). Block until it calls one. 9 | 10 | TIMEOUT is seconds (float or integer). Defaults to 1.0s. 11 | On timeout, signals `await-timeout'. C-g aborts and signals `quit'. 12 | 13 | Example: 14 | (await-callback 15 | (lambda (resolve _reject) 16 | (run-at-time 0.2 nil (lambda () (funcall resolve :ok))))) ;; => :ok" 17 | (let* ((timeout (or timeout 1.0)) 18 | (deadline (+ (float-time) timeout)) 19 | (done nil) (value nil) (err nil)) 20 | (funcall starter 21 | (lambda (v) (setq value v done t)) 22 | (lambda (e) (setq err e done t))) 23 | (with-local-quit 24 | (while (not done) 25 | (when (> (float-time) deadline) 26 | (signal 'await-timeout (list timeout))) 27 | (accept-process-output nil 0.1))) 28 | (when quit-flag 29 | (setq quit-flag nil) 30 | (signal 'quit nil)) 31 | (if err (signal (car err) (cdr err)) value))) 32 | -------------------------------------------------------------------------------- /modules/hardware/ryzen.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | with lib; 8 | let 9 | cfg = config.modules.hardware.ryzen; 10 | in 11 | { 12 | options = { 13 | modules.hardware.ryzen = { 14 | enable = lib.mkEnableOption ""; 15 | undervolt = { 16 | enable = lib.mkEnableOption ""; 17 | value = mkOption { 18 | type = types.str; 19 | default = "-p 0 -v 30 -f A8"; # Pstate 0, 1.25 voltage, 4200 clock speed 20 | }; 21 | }; 22 | }; 23 | }; 24 | 25 | config = mkIf cfg.enable { 26 | boot.kernelModules = [ "msr" ]; # Needed for zenstates 27 | hardware.cpu.amd.updateMicrocode = true; 28 | # Ryzen cpu control 29 | systemd.services.zenstates = mkIf cfg.undervolt.enable { 30 | enable = true; 31 | description = "Ryzen Undervolt"; 32 | after = [ 33 | "syslog.target" 34 | "systemd-modules-load.service" 35 | ]; 36 | 37 | unitConfig = { 38 | ConditionPathExists = "${pkgs.zenstates}/bin/zenstates"; 39 | }; 40 | 41 | serviceConfig = { 42 | User = "root"; 43 | ExecStart = "${pkgs.zenstates}/bin/zenstates ${cfg.undervolt.value}"; 44 | }; 45 | 46 | wantedBy = [ "multi-user.target" ]; 47 | }; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /modules/dev/clojure/configs/clj-kondo/config.edn: -------------------------------------------------------------------------------- 1 | {:lint-as {com.fulcrologic.fulcro.components/defsc clojure.core/defn 2 | com.fulcrologic.fulcro.routing.dynamic-routing/defrouter clojure.core/defn 3 | mount.core/defstate clojure.core/def 4 | com.wsscode.pathom.connect/defresolver clojure.core/defn 5 | com.wsscode.pathom.connect/defmutation clojure.core/defn 6 | nubank.workspaces.core/defcard clojure.core/def 7 | com.fulcrologic.guardrails.core/>defn clojure.core/defn 8 | taoensso.encore/if-let clojure.core/if-let 9 | ctmx.core/defcomponent clojure.core/defn 10 | simpleui.core/defcomponent clojure.core/defn 11 | helix.core/defnc clojure.core/defn 12 | uix.core/defui clojure.core/defn 13 | day8.re-frame.tracing/fn-traced clojure.core/fn} 14 | 15 | :linters {:unresolved-var {:level :error} 16 | :unresolved-symbol {:exclude [(app.ui/tw) 17 | (ctmx.core/defcomponent [path id value self]) 18 | (ctmx.core/with-req [post? put? patch? delete?]) 19 | (simpleui.core/defcomponent [path id value self]) 20 | (simpleui.core/with-req [post? put? patch? delete?])]}}} 21 | -------------------------------------------------------------------------------- /pkgs/default.nix: -------------------------------------------------------------------------------- 1 | inputs: [ 2 | (_final: prev: { 3 | nvidia = prev.callPackage ./nvidia/package.nix { inherit inputs; }; 4 | pdns-unstable = prev.callPackage ./pdns-unstable/package.nix { }; 5 | gitbutler-bin = prev.callPackage ./gitbutler-bin.nix { }; 6 | java-mission-control = prev.callPackage ./java-mission-control { }; 7 | netns-proxy = prev.callPackage ./netns-proxy.nix { }; 8 | mcp-inspector = prev.callPackage ./mcp-inspector.nix { }; 9 | udpbroadcastrelay = prev.callPackage ./udpbroadcastrelay.nix { }; 10 | deploy = prev.callPackage ./deploy.nix { }; 11 | swhkd = prev.callPackage ./swhkd { }; 12 | overseerr = prev.callPackage ./overseerr/package.nix { }; 13 | actual-server = prev.callPackage ./actual-server.nix { }; 14 | qobuz-dl = prev.callPackage ./qobuz-dl.nix { }; 15 | #kwin6-bismuth-decoration = prev.callPackage ./kwin6-bismuth-decoration.nix { }; 16 | #klassy = prev.callPackage ./klassy.nix { }; 17 | #invoiceninja-mine = prev.callPackage ./invoiceninja/package.nix { }; 18 | beets-dynamicrange = prev.callPackage ./beets-dynamicrange.nix { 19 | beets = prev.beetsPackages.beets-minimal; 20 | }; 21 | beets-filetote = prev.callPackage ./beets-filetote.nix { 22 | poetry-core = prev.python3Packages.poetry-core; 23 | beets = prev.beetsPackages.beets-minimal; 24 | }; 25 | }) 26 | ] 27 | -------------------------------------------------------------------------------- /hosts/debord/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | modulesPath, 6 | ... 7 | }: 8 | { 9 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; 10 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 11 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 12 | 13 | boot = { 14 | zfs.devNodes = lib.mkForce "/dev/disk/by-partuuid"; 15 | loader = { 16 | efi = { 17 | canTouchEfiVariables = true; 18 | }; 19 | systemd-boot = { 20 | enable = true; 21 | configurationLimit = 20; 22 | }; 23 | }; 24 | kernelModules = [ "kvm-intel" ]; 25 | extraModulePackages = [ ]; 26 | 27 | initrd = { 28 | availableKernelModules = [ 29 | "xhci_pci" 30 | "thunderbolt" 31 | "ahci" 32 | "usbhid" 33 | "usb_storage" 34 | "sd_mod" 35 | "sr_mod" 36 | ]; 37 | kernelModules = [ ]; 38 | 39 | postDeviceCommands = lib.mkAfter '' 40 | zfs rollback -r rpool/encrypted/local/root@blank && \ 41 | echo "rollback complete" 42 | ''; 43 | }; 44 | }; 45 | services.udev.extraRules = '' 46 | # Authorize Sonnet 10GbE Thunderbolt devices 47 | ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{vendor}=="0x8", ATTR{device}=="0x36", ATTR{authorized}="1" 48 | ''; 49 | } 50 | -------------------------------------------------------------------------------- /modules/desktop/programs/cad.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.cad; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.cad = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = lib.mkIf cfg.enable { 21 | 22 | environment.persistence."/persist" = lib.mkIf withImpermanence { 23 | 24 | users.${username} = { 25 | directories = [ 26 | ".config/FreeCAD" 27 | ".cache/FreeCAD" 28 | ".local/share/FreeCAD" 29 | ".config/OpenSCAD" 30 | ".local/share/OpenSCAD" 31 | ]; 32 | files = [ 33 | ".config/CQ-editorrc" 34 | ".config/OpenSCADrc" 35 | ]; 36 | 37 | }; 38 | }; 39 | home-manager.users."${username}" = 40 | { pkgs, config, ... }@hm: 41 | { 42 | home.packages = with pkgs; [ 43 | freecad 44 | # BLOCKED: https://github.com/NixOS/nixpkgs/issues/375763 45 | #(inputs.cadquery.packages.${pkgs.system}.cq-editor) 46 | openscad 47 | #openscad-lsp 48 | ]; 49 | }; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /modules/services/podman.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.services.podman; 12 | withImpermanence = config.modules.impermanence.enable; 13 | in 14 | { 15 | options.modules.services.podman = { 16 | enable = lib.mkEnableOption ""; 17 | }; 18 | config = mkIf cfg.enable { 19 | environment.persistence."/persist" = { 20 | directories = [ "/var/lib/containers" ]; 21 | }; 22 | virtualisation.podman = { 23 | enable = true; 24 | autoPrune.enable = true; 25 | autoPrune.dates = "weekly"; 26 | defaultNetwork.settings.dns_enabled = true; 27 | extraPackages = [ pkgs.zfs ]; 28 | }; 29 | environment.systemPackages = with pkgs; [ 30 | docker-compose 31 | podman-tui 32 | ]; 33 | systemd.services.podman-auto-update = { 34 | wants = [ "network-online.target" ]; 35 | after = [ "network-online.target" ]; 36 | serviceConfig = { 37 | Type = "oneshot"; 38 | ExecStart = "${pkgs.podman}/bin/podman auto-update"; 39 | ExecStartPost = "${pkgs.podman}/bin/podman image prune -f"; 40 | }; 41 | }; 42 | 43 | systemd.timers.podman-auto-update = { 44 | wantedBy = [ "timers.target" ]; 45 | timerConfig = { 46 | OnCalendar = "03:30"; 47 | Persistent = true; 48 | }; 49 | }; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /modules/services/github-runner.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.services.github-runner; 12 | withImpermanence = config.modules.impermanence.enable; 13 | in 14 | { 15 | options.modules.services.github-runner = { 16 | enable = lib.mkEnableOption ""; 17 | runnerName = lib.mkOption { 18 | type = lib.types.uniq lib.types.str; 19 | default = "my-runner"; 20 | }; 21 | url = lib.mkOption { 22 | type = lib.types.uniq lib.types.str; 23 | default = ""; 24 | }; 25 | extraLabels = mkOption { 26 | type = types.listOf types.str; 27 | default = [ ]; 28 | }; 29 | }; 30 | config = mkIf cfg.enable { 31 | sops.secrets."github-runner.token" = { }; 32 | services.github-runners."${cfg.runnerName}" = { 33 | enable = true; 34 | replace = true; 35 | name = cfg.runnerName; 36 | nodeRuntimes = [ "node20" ]; 37 | extraPackages = with pkgs; [ 38 | gh 39 | docker 40 | gawk 41 | nix 42 | ]; 43 | url = cfg.url; 44 | tokenFile = "/run/secrets/github-runner.token"; 45 | extraLabels = cfg.extraLabels; 46 | serviceOverrides = { 47 | Group = "docker"; 48 | }; 49 | }; 50 | #environment.persistence."/persist" = { 51 | # directories = [ 52 | # ]; 53 | #}; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /pkgs/invoiceninja/invoiceninja.patch: -------------------------------------------------------------------------------- 1 | diff --git a/config/database.php b/config/database.php 2 | index 32dedf8154..7052612d8a 100644 3 | --- a/config/database.php 4 | +++ b/config/database.php 5 | @@ -41,6 +41,7 @@ return [ 6 | 'username' => env('DB_USERNAME1', env('DB_USERNAME', 'forge')), 7 | 'password' => env('DB_PASSWORD1', env('DB_PASSWORD', '')), 8 | 'port' => env('DB_PORT1', env('DB_PORT', '3306')), 9 | + 'unix_socket' => env('DB_SOCKET1', env('DB_SOCKET', '')), 10 | 'charset' => 'utf8mb4', 11 | 'collation' => 'utf8mb4_unicode_ci', 12 | 'prefix' => '', 13 | @@ -175,6 +176,8 @@ return [ 14 | 'client' => 'predis', 15 | 16 | 'default' => [ 17 | + 'scheme' => env('REDIS_SCHEME', 'tcp'), 18 | + 'path' => env('REDIS_PATH'), 19 | 'host' => env('REDIS_HOST', '127.0.0.1'), 20 | 'password' => env('REDIS_PASSWORD', null), 21 | 'port' => env('REDIS_PORT', 6379), 22 | @@ -182,6 +185,8 @@ return [ 23 | ], 24 | 25 | 'cache' => [ 26 | + 'scheme' => env('REDIS_SCHEME', 'tcp'), 27 | + 'path' => env('REDIS_PATH'), 28 | 'host' => env('REDIS_HOST', '127.0.0.1'), 29 | 'password' => env('REDIS_PASSWORD', null), 30 | 'port' => env('REDIS_PORT', 6379), 31 | -------------------------------------------------------------------------------- /hosts/dewey/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | modulesPath, 6 | ... 7 | }: 8 | { 9 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; 10 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 11 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 12 | 13 | boot = { 14 | zfs.devNodes = lib.mkForce "/dev/disk/by-partuuid"; 15 | loader = { 16 | efi = { 17 | canTouchEfiVariables = true; 18 | }; 19 | systemd-boot = { 20 | enable = true; 21 | configurationLimit = 20; 22 | }; 23 | }; 24 | kernelModules = [ "kvm-intel" ]; 25 | extraModulePackages = [ ]; 26 | initrd = { 27 | availableKernelModules = [ 28 | "xhci_pci" 29 | "ahci" 30 | "nvme" 31 | "usbhid" 32 | "usb_storage" 33 | "sd_mod" 34 | "sr_mod" 35 | "sdhci_pci" 36 | ]; 37 | kernelModules = [ ]; 38 | postDeviceCommands = lib.mkAfter '' 39 | zfs rollback -r rpool/encrypted/local/root@blank && \ 40 | zfs rollback -r rpool/encrypted/vms@blank && \ 41 | echo "rollback complete" 42 | ''; 43 | }; 44 | }; 45 | services.udev.extraRules = '' 46 | # Authorize Sonnet 10GbE Thunderbolt devices 47 | ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{vendor}=="0x8", ATTR{device}=="0x36", ATTR{authorized}="1" 48 | ''; 49 | } 50 | -------------------------------------------------------------------------------- /modules/desktop/programs/obs.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.obs; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.obs = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | boot.extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ]; 22 | 23 | environment.systemPackages = with pkgs; [ 24 | v4l-utils 25 | 26 | (pkgs.writeScriptBin "obs-v4l2loopback-setup.sh" '' 27 | set -x 28 | sudo modprobe \ 29 | v4l2loopback \ 30 | devices=1 \ 31 | video_nr=13 \ 32 | card_label="''${CAMERA_NAME:-"OBS Virtual Camera"}" \ 33 | exclusive_caps=1 34 | '') 35 | ]; 36 | 37 | home-manager.users."${username}" = 38 | { pkgs, config, ... }@hm: 39 | { 40 | programs.obs-studio = { 41 | enable = true; 42 | 43 | # TODO: is this even needed? isn't it built in? 44 | plugins = with pkgs; [ 45 | # obs-studio-plugins.wlrobs 46 | ]; 47 | }; 48 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { directories = [ ]; }; 49 | }; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /modules/security/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.security.default; 12 | in 13 | { 14 | options = { 15 | modules.security.default = { 16 | enable = lib.mkOption { 17 | type = types.bool; 18 | default = true; 19 | }; 20 | }; 21 | }; 22 | 23 | config = mkIf cfg.enable { 24 | # TODO Use systemd.settings.Manager instead. 25 | #systemd.extraConfig = "DefaultLimitNOFILE=1048576"; 26 | security = { 27 | sudo.enable = true; 28 | sudo.wheelNeedsPassword = false; 29 | sudo.extraRules = 30 | let 31 | # systemPath is the path where the system being activated is uploaded by `deploy`. 32 | systemPath = "/nix/store/*-activatable-nixos-system-${config.networking.hostName}-*"; 33 | nopasswd = command: { 34 | inherit command; 35 | options = [ 36 | "NOPASSWD" 37 | "SETENV" 38 | ]; 39 | }; 40 | in 41 | [ 42 | { 43 | groups = [ "wheel" ]; 44 | runAs = "root"; 45 | commands = [ (nopasswd "/run/current-system/sw/bin/systemctl reboot") ]; 46 | } 47 | ]; 48 | #pam.loginLimits = [ 49 | # { 50 | # domain = "*"; 51 | # type = "soft"; 52 | # item = "nofile"; 53 | # value = "1048576"; 54 | # } 55 | #]; 56 | }; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /pkgs/swhkd/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, 3 | fetchFromGitHub, 4 | lib, 5 | rustPlatform, 6 | writeShellScript, 7 | udev, 8 | pkg-config, 9 | }: 10 | let 11 | 12 | swhkd = writeShellScript "swhkd" '' 13 | DIR="$(cd "$(dirname "$0")" && pwd)" 14 | if [ "$1" = "stop" ]; then 15 | pkill swhkd 16 | #exit 0 17 | else 18 | "$DIR"/.swhkd-wrapped $@ 19 | #exit 0 20 | fi 21 | ''; 22 | in 23 | rustPlatform.buildRustPackage { 24 | name = "swhkd"; 25 | version = "unstable-2024-09-23"; 26 | src = fetchFromGitHub { 27 | owner = "waycrate"; 28 | repo = "swhkd"; 29 | rev = "f2bee30146eda2b7f10347ce93f3c2236f73ae93"; 30 | hash = "sha256-0b0vod0CxLLMFS+28kbpfYxLjyok3lioz3oiKSUTzoU="; 31 | }; 32 | cargoLock = { 33 | lockFile = ./Cargo.lock; 34 | outputHashes = { 35 | "sweet-0.3.0" = "sha256-swSE1CE39cGojp8HAziw0Bzjr+s4XaVU+4OqQDO60fE="; 36 | }; 37 | }; 38 | 39 | nativeBuildInputs = [ pkg-config ]; 40 | 41 | buildInputs = [ 42 | udev 43 | ]; 44 | 45 | postBuild = '' 46 | $src/scripts/build-polkit-policy.sh \ 47 | --swhkd-path=$out/bin/swhkd 48 | ''; 49 | 50 | postInstall = '' 51 | install -D ./com.github.swhkd.pkexec.policy -t $out/share/polkit-1/actions 52 | ''; 53 | 54 | meta = with lib; { 55 | description = "Sxhkd clone for Wayland (works on TTY and X11 too)"; 56 | homepage = "https://github.com/waycrate/swhkd"; 57 | license = licenses.bsd2; 58 | maintainers = [ maintainers.uningan ]; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /modules/desktop/programs/signal.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.signal; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.signal = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | 22 | environment.persistence."/persist" = mkIf withImpermanence { 23 | users.${username} = { 24 | directories = [ ".config/Signal" ]; 25 | }; 26 | }; 27 | home-manager.users."${username}" = 28 | { pkgs, config, ... }@hm: 29 | { 30 | home.packages = [ pkgs.signal-desktop ]; 31 | home.file.".local/share/applications/signal-desktop.desktop" = { 32 | text = '' 33 | [Desktop Entry] 34 | Name=Signal Desktop (nix) 35 | Exec=${pkgs.signal-desktop}/bin/signal-desktop --ozone-platform-hint=auto --no-sandbox %U 36 | Terminal=false 37 | Type=Application 38 | Icon=signal-desktop 39 | StartupWMClass=signal 40 | Comment=Private messaging from your desktop 41 | MimeType=x-scheme-handler/sgnl;x-scheme-handler/signalcaptcha; 42 | Categories=Network;InstantMessaging;Chat; 43 | ''; 44 | }; 45 | }; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /pkgs/kwin6-bismuth-decoration.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | #, mkDerivation 4 | fetchFromGitHub, 5 | stdenv, 6 | pkgs, 7 | #, kdePackages 8 | #, kcoreaddons 9 | #, kwindowsystem 10 | #, plasma-framework 11 | #, systemsettings 12 | #, cmake 13 | #, extra-cmake-modules 14 | }: 15 | 16 | stdenv.mkDerivation rec { 17 | pname = "kwin6-bismuth-decoration"; 18 | version = "603f3cca4d9b1c383a352f6e570a2e56138ecedb"; 19 | 20 | src = fetchFromGitHub { 21 | owner = "ivan-cukic"; 22 | repo = pname; 23 | rev = "${version}"; 24 | hash = "sha256-4M8LwnR7Cl/iN2PR+pX0vauOyyilbPEtzFxTxD2ouA8="; 25 | }; 26 | 27 | nativeBuildInputs = [ 28 | pkgs.cmake 29 | pkgs.extra-cmake-modules 30 | #esbuild 31 | ]; 32 | 33 | buildInputs = [ 34 | pkgs.kdePackages.kcoreaddons 35 | pkgs.kdePackages.kwindowsystem 36 | #pkgs.kdePackages.plasma-framework 37 | pkgs.kdePackages.systemsettings 38 | pkgs.kdePackages.wrapQtAppsHook 39 | pkgs.kdePackages.qtbase 40 | pkgs.kdePackages.qtsvg 41 | pkgs.kdePackages.frameworkintegration 42 | pkgs.kdePackages.libplasma 43 | pkgs.kdePackages.ki18n 44 | pkgs.kdePackages.kdeclarative 45 | pkgs.kdePackages.kdecoration 46 | ]; 47 | 48 | meta = with lib; { 49 | description = "Bismuth window decoration for kwin 6"; 50 | license = licenses.mit; 51 | maintainers = with maintainers; [ ]; 52 | homepage = "https://github.com/ivan-cukic/kwin6-bismuth-decoration"; 53 | inherit (pkgs.kdePackages.kwindowsystem.meta) platforms; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /pkgs/gitbutler-bin.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, 3 | dpkg, 4 | autoPatchelfHook, 5 | wrapGAppsHook3, 6 | fetchurl, 7 | webkitgtk_4_1, 8 | libsoup_3, 9 | lib, 10 | makeWrapper, 11 | }: 12 | let 13 | version = "0.18.2"; 14 | build = "2660"; 15 | in 16 | stdenv.mkDerivation (finalAttrs: { 17 | inherit version; 18 | pname = "gitbutler-bin"; 19 | src = fetchurl { 20 | url = "https://releases.gitbutler.com/releases/release/${version}-${build}/linux/x86_64/GitButler_${version}_amd64.deb"; 21 | hash = "sha256-wCt0i+w//tpInpdaggnAWjrmP3e8LkXq4RPtpLWH2xs="; 22 | }; 23 | 24 | unpackPhase = "dpkg-deb -x $src unpack"; 25 | 26 | nativeBuildInputs = [ 27 | dpkg 28 | wrapGAppsHook3 29 | autoPatchelfHook 30 | makeWrapper 31 | ]; 32 | 33 | buildInputs = [ 34 | webkitgtk_4_1 35 | libsoup_3 36 | ]; 37 | 38 | # TODO: check that the desktop file points to the right binary! Otherwise, use `substituteInPlace` 39 | installPhase = '' 40 | install -Dm755 unpack/usr/bin/gitbutler-tauri $out/bin/gitbutler-tauri 41 | install -Dm755 unpack/usr/bin/gitbutler-git-setsid $out/bin/gitbutler-git-setsid 42 | install -Dm755 unpack/usr/bin/gitbutler-git-askpass $out/bin/gitbutler-git-askpass 43 | 44 | cp -r unpack/usr/share $out/share 45 | ''; 46 | 47 | meta = { 48 | description = "Git client for simultaneous branches on top of your existing workflow"; 49 | license = lib.licenses.fsl11Mit; 50 | mainProgram = "gitbutler-tauri"; 51 | platforms = [ "x86_64-linux" ]; 52 | }; 53 | }) 54 | -------------------------------------------------------------------------------- /hosts/mali/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | export COLOR_RESET="\033[0m" 4 | export RED_BG="\033[41m" 5 | export BLUE_BG="\033[44m" 6 | 7 | HOST_DIR=hosts/stable/x86_64-linux/mali 8 | 9 | function err { 10 | echo -e "${RED_BG}$1${COLOR_RESET}" 11 | } 12 | 13 | function info { 14 | echo -e "${BLUE_BG}$1${COLOR_RESET}" 15 | } 16 | 17 | function check_key { 18 | if [[ -f "/mnt/persist/etc/ssh/ssh_host_ed25519_key" ]]; 19 | then 20 | echo 21 | info "Here we go..." 22 | chown -R root:root /mnt/persist/etc/ssh/ssh_host_ed25519_key 23 | chmod 0600 /mnt/persist/etc/ssh/ssh_host_ed25519_key 24 | else 25 | mkdir -p /mnt/persist/etc/ssh 26 | echo 27 | echo "Please create /mnt/persist/etc/ssh/ssh_host_ed25519_key" 28 | echo "It is used to decrypt secrets." 29 | echo 30 | read -p "Are you ready? (type 'yes' in capital letters to begin installation): " -r 31 | if ! [[ $REPLY == "YES" ]]; 32 | then 33 | err "Aborting" 34 | exit 1 35 | fi 36 | check_key 37 | fi 38 | } 39 | 40 | if [[ "$EUID" -gt 0 ]]; then 41 | err "Must run as root" 42 | exit 1 43 | fi 44 | 45 | if [[ ! -d /mnt/boot ]]; then 46 | err "No /mnt/boot directory found. Did you run disks.sh first?" 47 | exit 1 48 | fi 49 | 50 | check_key 51 | rm -f /mnt/etc/nixos/configuration.nix 52 | 53 | 54 | nixos-install --flake '.#mali' 55 | 56 | info "Done." 57 | echo 58 | info "You can now reboot into your new NixOS installation." 59 | -------------------------------------------------------------------------------- /modules-unstable/hardware/nvidia/de-compat.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | config, 4 | lib, 5 | ... 6 | }: 7 | let 8 | cfg = config.modules.hardware.easyNvidia; 9 | in 10 | lib.mkMerge [ 11 | 12 | (lib.mkIf (cfg.desktopEnvironment == "wlroots") { 13 | environment.variables = lib.mkMerge [ 14 | (lib.mkIf (!cfg.offload.enable) { 15 | GBM_BACKEND = "nvidia-drm"; 16 | # Apparently, without this nouveau may attempt to be used instead 17 | # (despite it being blacklisted) 18 | __GLX_VENDOR_LIBRARY_NAME = "nvidia"; 19 | # Hardware cursors are currently broken on wlroots 20 | WLR_NO_HARDWARE_CURSORS = "1"; 21 | }) 22 | (lib.mkIf cfg.offload.enable { WLR_DRM_DEVICES = "/dev/dri/igpu1:/dev/dri/dgpu1"; }) 23 | ]; 24 | }) 25 | 26 | # Both GNOME and Plasma guess which GPU should be used, so this 27 | # *may* not be necessary. However, given NixOS configuration, we 28 | # already should have an explicit setting from the user, and clearly 29 | # the guess isn't always correct, so we explicitly set the GPU to 30 | # use anyway. 31 | (lib.mkIf (cfg.desktopEnvironment == "gnome") { 32 | services.udev.packages = lib.mkIf cfg.offload.enable ( 33 | pkgs.writeTextDir "lib/udev/rules.d/62-gnome-gpu-priority.rules" '' 34 | SYMLINK=="dri/igpu1", TAG+="mutter-device-preferred-primary" 35 | '' 36 | ); 37 | }) 38 | 39 | (lib.mkIf (cfg.desktopEnvironment == "plasma") { 40 | environment.variables.KWIN_DRM_DEVICES = lib.mkIf cfg.offload.enable "/dev/dri/igpu1:/dev/dri/dgpu1"; 41 | }) 42 | ] 43 | -------------------------------------------------------------------------------- /config/home-wifi.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | config, 4 | lib, 5 | ... 6 | }: 7 | let 8 | inherit (config.repo.secrets.global) wifi; 9 | cfg = config.home; 10 | in 11 | { 12 | options.home.wifi = { 13 | iot = { 14 | enable = lib.mkEnableOption "WiFi for IoT"; 15 | interface = lib.mkOption { 16 | type = lib.types.str; 17 | default = "wlan0"; 18 | description = "The WiFi interface to use"; 19 | }; 20 | }; 21 | primary = { 22 | enable = lib.mkEnableOption "WiFi"; 23 | interface = lib.mkOption { 24 | type = lib.types.str; 25 | default = "wlan0"; 26 | description = "The WiFi interface to use"; 27 | }; 28 | }; 29 | }; 30 | config = lib.mkIf (cfg.wifi.iot.enable || cfg.wifi.primary.enable) { 31 | networking = 32 | if cfg.wifi.iot.enable then 33 | { 34 | interfaces."${cfg.wifi.iot.interface}".useDHCP = true; 35 | wireless = { 36 | interfaces = [ "${cfg.wifi.iot.interface}" ]; 37 | enable = true; 38 | networks = { 39 | "${wifi.iot.ssid}".psk = "${wifi.iot.password}"; 40 | }; 41 | }; 42 | } 43 | else if cfg.wifi.primary.enable then 44 | { 45 | wireless = { 46 | interfaces = [ "${cfg.wifi.primary.interface}" ]; 47 | enable = true; 48 | networks = { 49 | "${wifi.primary.ssid}".psk = "${wifi.primary.password}"; 50 | }; 51 | }; 52 | } 53 | else 54 | { }; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /modules/telemetry/thanos.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: 6 | let 7 | cfg = config.modules.telemetry.thanos; 8 | in 9 | { 10 | options.modules.telemetry.thanos = { 11 | enable = lib.mkEnableOption "thanos"; 12 | }; 13 | 14 | config = lib.mkIf cfg.enable { 15 | sops.secrets = { 16 | thanos_sidecar_object_storage_configuration = { 17 | format = "yaml"; 18 | mode = "0777"; 19 | owner = "prometheus"; 20 | }; 21 | }; 22 | 23 | services.thanos = { 24 | sidecar = { 25 | enable = true; 26 | objstore.config-file = config.sops.secrets.thanos_sidecar_object_storage_configuration.path; 27 | grpc-address = "127.0.0.1:10901"; 28 | http-address = "127.0.0.1:10902"; 29 | }; 30 | 31 | store = { 32 | enable = true; 33 | objstore.config-file = config.sops.secrets.thanos_sidecar_object_storage_configuration.path; 34 | grpc-address = "127.0.0.1:10903"; 35 | http-address = "127.0.0.1:10904"; 36 | }; 37 | 38 | query = { 39 | enable = true; 40 | grpc-address = "127.0.0.1:10905"; 41 | http-address = "127.0.0.1:10906"; 42 | endpoints = [ 43 | config.services.thanos.sidecar.grpc-address 44 | config.services.thanos.store.grpc-address 45 | ]; 46 | }; 47 | 48 | compact = { 49 | enable = true; 50 | objstore.config-file = config.sops.secrets.thanos_sidecar_object_storage_configuration.path; 51 | http-address = "127.0.0.1:10907"; 52 | }; 53 | }; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /modules/services/nomad.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | cfg = config.modules.services.nomad; 10 | in 11 | { 12 | options.modules.services.nomad = { 13 | enable = lib.mkEnableOption "nomad"; 14 | }; 15 | config = lib.mkIf cfg.enable { 16 | services.nomad = { 17 | enable = true; 18 | package = pkgs.nomad_1_9; 19 | extraSettingsPlugins = [ pkgs.nomad-driver-podman ]; 20 | enableDocker = false; 21 | dropPrivileges = false; # root-less nomad is not well supported: https://github.com/hashicorp/nomad/issues/13669 22 | settings = { 23 | client.enabled = true; 24 | server = { 25 | enabled = true; 26 | bootstrap_expect = 1; 27 | }; 28 | plugin = [ 29 | { 30 | nomad-driver-podman = { 31 | config = { 32 | socket_path = 33 | # Rootfull Nomad on Rootfull containers 34 | #if !dockerEnabled 35 | #then "unix://run/user/1000/podman/podman.sock" 36 | #else "unix://run/podman/podman.sock"; 37 | "unix://run/podman/podman.sock"; 38 | }; 39 | }; 40 | } 41 | ]; 42 | }; 43 | }; 44 | 45 | #systemd.services.nomad.wantedBy = lib.mkForce [ ]; 46 | 47 | environment.systemPackages = with pkgs; [ 48 | nomad-driver-podman # Podman driver plugin 49 | cni-plugins # Networking plugins, needed for bridge. Might not be needed? 50 | damon # TUI for Nomad 51 | ]; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /overlays/nixpkgs-mine-packages.nix: -------------------------------------------------------------------------------- 1 | # Overlay to selectively import packages from nixpkgs-mine 2 | inputs: final: prev: 3 | let 4 | # Import nixpkgs-mine with the same system and config as the main nixpkgs 5 | nixpkgs-mine = import inputs.nixpkgs-mine { 6 | inherit (final) system; 7 | config = final.config; 8 | }; 9 | in 10 | { 11 | # Packages that should come from nixpkgs-mine instead of regular nixpkgs 12 | # claude-code = (nixpkgs-mine.claude-code.override { nodejs_20 = nixpkgs-mine.nodejs_24; }); 13 | claude-code = nixpkgs-mine.claude-code; 14 | codex = nixpkgs-mine.codex; 15 | opencode = nixpkgs-mine.opencode; 16 | gemini-cli = nixpkgs-mine.gemini-cli; 17 | clojure-lsp = nixpkgs-mine.clojure-lsp; 18 | davis = nixpkgs-mine.davis; 19 | plex = nixpkgs-mine.plex; 20 | emacs-pgtk = nixpkgs-mine.emacs-pgtk; 21 | gost = nixpkgs-mine.gost; 22 | ocis = nixpkgs-mine.ocis; 23 | ocis_71-bin = nixpkgs-mine.ocis_71-bin; 24 | roon-server = nixpkgs-mine.roon-server; 25 | #chromium = nixpkgs-mine.chromium; 26 | #chromedriver = nixpkgs-mine.chromedriver; 27 | babashka = nixpkgs-mine.babashka; 28 | bbin = nixpkgs-mine.bbin; 29 | crush = nixpkgs-mine.crush; 30 | llm = nixpkgs-mine.llm; 31 | jdk25 = nixpkgs-mine.jdk25; 32 | jdk25_headless = nixpkgs-mine.jdk25_headless; 33 | yubioath-flutter = nixpkgs-mine.yubioath-flutter; 34 | _1password-gui = nixpkgs-mine._1password-gui; 35 | _1password-cli = nixpkgs-mine._1password-cli; 36 | sops = ( 37 | nixpkgs-mine.sops.withAgePlugins (p: [ 38 | p.age-plugin-fido2-hmac 39 | p.age-plugin-yubikey 40 | p.age-plugin-tpm 41 | ]) 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /modules/dev/jetbrains/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | options, 4 | inputs, 5 | lib, 6 | pkgs, 7 | my, 8 | ... 9 | }: 10 | with lib; 11 | let 12 | devCfg = config.modules.dev; 13 | cfg = devCfg.jetbrains; 14 | username = config.modules.users.primaryUser.username; 15 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 16 | withImpermanence = config.modules.impermanence.enable; 17 | in 18 | { 19 | options.modules.dev.jetbrains = { 20 | enable = lib.mkEnableOption ""; 21 | }; 22 | 23 | config = mkIf cfg.enable { 24 | environment.systemPackages = with pkgs; [ ]; 25 | 26 | environment.persistence."/persist" = mkIf withImpermanence { 27 | users.${username} = { 28 | directories = [ 29 | ".config/JetBrains" 30 | ".cache/JetBrains" 31 | ".local/share/JetBrains" 32 | ".java/.userPrefs/jetbrains" 33 | ]; 34 | }; 35 | }; 36 | myhm = { 37 | home.packages = with pkgs; [ 38 | jetbrains.idea-ultimate 39 | #jetbrains.datagrip 40 | #jetbrains.gateway 41 | #jetbrains.clion 42 | #java-mission-control 43 | #dotnet-sdk_7 44 | #dotnet-sdk 45 | #msbuild 46 | #mono 47 | #mono4 48 | #(with dotnetCorePackages; 49 | # combinePackages [ 50 | # sdk_6_0 51 | # sdk_7_0 52 | # ]) 53 | ]; 54 | 55 | home.file.".ideavimrc" = { 56 | source = ./configs/ideavimrc; 57 | }; 58 | xdg.configFile."ideavim" = { 59 | source = ./configs/ideavim; 60 | recursive = true; 61 | }; 62 | }; 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /hosts/mali/acme.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | pkgs, 4 | config, 5 | ... 6 | }: 7 | let 8 | inherit (config.repo.secrets.global) domain email; 9 | in 10 | { 11 | security.acme = { 12 | acceptTerms = true; 13 | defaults = { 14 | email = email.acme; 15 | dnsProvider = "bunny"; 16 | dnsPropagationCheck = false; 17 | credentialsFile = config.sops.templates.acme-credentials.path; 18 | reloadServices = [ "nginx.service" ]; 19 | }; 20 | }; 21 | 22 | sops.secrets.bunnyApiKey = { 23 | sopsFile = ../../configs/home-ops/shared.sops.yml; 24 | restartUnits = [ ]; 25 | }; 26 | 27 | sops.templates.acme-credentials.content = '' 28 | BUNNY_API_KEY=${config.sops.placeholder.bunnyApiKey} 29 | ''; 30 | security.acme.certs = { 31 | #"mali" = { 32 | # domain = "mali.int.${domain.home}"; 33 | # extraDomainNames = []; 34 | # group = "nginx"; 35 | # directory = "/persist/var/lib/acme/mali"; 36 | #}; 37 | "s3.data.${domain.home}" = { 38 | domain = "s3.data.${domain.home}"; 39 | extraDomainNames = [ 40 | "*.s3.data.${domain.home}" 41 | "minio.data.${domain.home}" 42 | "*.s3.mgmt.${domain.home}" 43 | "minio.mgmt.${domain.home}" 44 | "s3.mgmt.${domain.home}" 45 | ]; 46 | group = "nginx"; 47 | }; 48 | "attic.mgmt.${domain.home}" = { 49 | domain = "attic.mgmt.${domain.home}"; 50 | group = "nginx"; 51 | extraDomainNames = [ 52 | "attic.int.${domain.home}" 53 | ]; 54 | }; 55 | }; 56 | 57 | environment.persistence = { 58 | "/persist" = { 59 | directories = [ "/var/lib/acme" ]; 60 | }; 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /pkgs/mcp-inspector.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | buildNpmPackage, 4 | fetchFromGitHub, 5 | nodejs, 6 | jq, 7 | ... 8 | }: 9 | # Source: https://github.com/andoriyu/flakes/blob/501a8d446c40e914a9e1b27f3cd40484807a6848/packages/mcp-inspector/default.nix 10 | # Modified to set PATH to include node (See https://github.com/andoriyu/flakes/pull/258) 11 | buildNpmPackage rec { 12 | pname = "mcp-inspector"; 13 | version = "0.17.1"; 14 | 15 | src = fetchFromGitHub { 16 | owner = "modelcontextprotocol"; 17 | repo = "inspector"; 18 | rev = version; 19 | hash = "sha256-xiNBMCtDAoNxgB4Vh+m/2hrBBwzzAB9/37J0qsDlSaE="; 20 | }; 21 | 22 | postPatch = '' 23 | ${jq}/bin/jq '.packages["node_modules/router/node_modules/path-to-regexp"] += { 24 | resolved: "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", 25 | integrity: "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==" 26 | }' package-lock.json > package-lock.json.new 27 | mv package-lock.json.new package-lock.json 28 | sed -i 's/\.allowExcessArguments()/\.allowExcessArguments?.()/g' cli/src/cli.ts 29 | ''; 30 | 31 | makeWrapperArgs = [ 32 | "--prefix PATH : ${ 33 | lib.makeBinPath [ 34 | nodejs 35 | ] 36 | }" 37 | ]; 38 | 39 | npmDepsHash = "sha256-QuG+RLsduOplFEY92sQC4R7w04Pk/nIIvaQaEHYLzXU="; 40 | 41 | doCheck = false; 42 | 43 | meta = with lib; { 44 | description = "Visual testing tool for MCP servers"; 45 | homepage = "https://github.com/modelcontextprotocol/inspector"; 46 | license = licenses.mit; 47 | maintainers = [ ]; 48 | platforms = platforms.all; 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /hosts/quine/roon-bridge.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | { 8 | boot.extraModprobeConfig = '' 9 | options snd-aloop id=RoonLoopback 10 | ''; 11 | services.avahi.enable = true; 12 | services.roon-bridge = { 13 | enable = false; 14 | user = "ramblurr"; 15 | group = "ramblurr"; 16 | openFirewall = true; 17 | }; 18 | # These ports are required for roon-bridge to work 19 | networking.firewall = { 20 | allowedTCPPortRanges = [ 21 | { 22 | from = 9100; 23 | to = 9200; 24 | } 25 | { 26 | from = 32768; 27 | to = 60999; 28 | } 29 | ]; 30 | allowedUDPPorts = [ 9003 ]; 31 | allowedUDPPortRanges = [ 32 | { 33 | from = 32768; 34 | to = 60999; 35 | } 36 | ]; 37 | }; 38 | myhm = 39 | { ... }@hm: 40 | { 41 | #persistence = { 42 | # directories = [ 43 | # ]; 44 | #}; 45 | home.file.".local/share/applications/roon.desktop" = { 46 | text = '' 47 | [Desktop Entry] 48 | Name=Roon 49 | Exec=bottles-cli run -p Roon -b 'Roon' -- %u 50 | Type=Application 51 | Terminal=false 52 | Categories=Application; 53 | Icon=/srv/data/roon-client/Roon/icons/Roon.png 54 | Comment=Launch Roon using Bottles. 55 | StartupWMClass=Roon 56 | Actions=Configure; 57 | [Desktop Action Configure] 58 | Name=Configure in Bottles 59 | Exec=bottles -b 'Roon' 60 | ''; 61 | }; 62 | }; 63 | environment.persistence."/persist" = { 64 | directories = [ "/var/lib/roon-bridge" ]; 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /modules/services/sshd.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.services.sshd; 12 | withImpermanence = config.modules.impermanence.enable; 13 | in 14 | { 15 | options.modules.services.sshd = { 16 | enable = lib.mkOption { 17 | type = lib.types.bool; 18 | default = true; 19 | }; 20 | }; 21 | config = mkIf cfg.enable { 22 | # Should exist already as it is used for sops bootstrapping 23 | # sops.secrets.ssh_host_ed25519_key = { 24 | # path = "/persist/etc/ssh/ssh_host_ed25519_key"; 25 | # }; 26 | 27 | sops.secrets.ssh_host_ed25519_key_pub = { 28 | path = "${lib.optionalString withImpermanence "/persist"}/etc/ssh/ssh_host_ed25519_key.pub"; 29 | }; 30 | networking.firewall.allowedTCPPorts = [ 22 ]; 31 | 32 | services.openssh = { 33 | enable = true; 34 | authorizedKeysFiles = lib.mkForce [ "/etc/ssh/authorized_keys.d/%u" ]; 35 | settings = { 36 | AcceptEnv = "SYSTEMD_PAGER"; 37 | LoginGraceTime = 30; 38 | PermitRootLogin = lib.mkOverride 900 "prohibit-password"; 39 | PasswordAuthentication = false; 40 | KbdInteractiveAuthentication = false; 41 | StreamLocalBindUnlink = true; 42 | }; 43 | hostKeys = [ 44 | { 45 | path = "${lib.optionalString withImpermanence "/persist"}/etc/ssh/ssh_host_ed25519_key"; 46 | type = "ed25519"; 47 | } 48 | ]; 49 | }; 50 | 51 | environment.persistence."/persist" = mkIf withImpermanence { 52 | files = [ "${config.users.users.root.home}/.ssh/known_hosts" ]; 53 | }; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /modules/telemetry/prometheus.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | ... 5 | }: 6 | let 7 | cfg = config.modules.telemetry.prometheus; 8 | stateDir = "/var/lib/prometheus2"; 9 | 10 | serviceDeps = [ 11 | "var-lib-prometheus2.mount" 12 | "zfs-datasets.service" 13 | ]; 14 | in 15 | { 16 | options.modules.telemetry.prometheus = { 17 | enable = lib.mkEnableOption "prometheus"; 18 | }; 19 | 20 | config = lib.mkIf cfg.enable { 21 | services.prometheus = { 22 | enable = true; 23 | 24 | # Thanos stores long term metrics 25 | retentionTime = "1d"; 26 | 27 | extraFlags = [ 28 | "--web.enable-admin-api" 29 | "--storage.tsdb.min-block-duration=2h" 30 | "--storage.tsdb.max-block-duration=2h" 31 | ]; 32 | 33 | globalConfig.external_labels.prometheus = "${config.networking.hostName}"; 34 | }; 35 | 36 | modules.zfs.datasets.properties = { 37 | "rpool/encrypted/safe/svc/prometheus"."mountpoint" = stateDir; 38 | }; 39 | 40 | systemd.tmpfiles.rules = [ 41 | "z '${stateDir}' 750 prometheus prometheus - -" 42 | ]; 43 | 44 | networking.firewall.allowedTCPPorts = [ 45 | config.services.prometheus.port 46 | ]; 47 | 48 | services.borgmatic.configurations.system.exclude_patterns = [ "${stateDir}/data/wal" ]; 49 | systemd.services.thanos-query = { 50 | requires = serviceDeps; 51 | after = serviceDeps; 52 | }; 53 | systemd.services.thanos-store = { 54 | requires = serviceDeps; 55 | after = serviceDeps; 56 | }; 57 | systemd.services.thanos-compact = { 58 | requires = serviceDeps; 59 | after = serviceDeps; 60 | }; 61 | }; 62 | 63 | } 64 | -------------------------------------------------------------------------------- /modules/services/soju.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | let 10 | cfg = config.modules.services.soju; 11 | home-ops = config.repo.secrets.home-ops; 12 | ircPort = toString cfg.ports.irc; 13 | stateDirActual = "/var/lib/private/soju"; 14 | stateDirEffective = "/var/lib/soju"; 15 | in 16 | { 17 | options.modules.services.soju = { 18 | enable = lib.mkEnableOption "soju"; 19 | domain = lib.mkOption { 20 | type = lib.types.str; 21 | example = "soju.example.com"; 22 | description = "The domain to use for soju"; 23 | }; 24 | ports = { 25 | irc = lib.mkOption { 26 | type = lib.types.port; 27 | description = "The irc port to use for soju"; 28 | }; 29 | }; 30 | #ingress = lib.mkOption { 31 | # type = lib.types.submodule ( 32 | # lib.recursiveUpdate (import ./ingress-options.nix { inherit config lib; }) { } 33 | # ); 34 | #}; 35 | }; 36 | 37 | config = lib.mkIf cfg.enable { 38 | modules.zfs.datasets.properties = { 39 | "rpool/encrypted/safe/svc/soju"."mountpoint" = stateDirActual; 40 | }; 41 | #modules.services.ingress.domains = lib.mkIf cfg.ingress.external { 42 | # "${cfg.ingress.domain}" = { 43 | # externalDomains = [ cfg.domain ]; 44 | # }; 45 | #}; 46 | #modules.services.ingress.virtualHosts.${cfg.domain} = { 47 | # acmeHost = cfg.ingress.domain; 48 | # upstream = "http://127.0.0.1:${httpPort}"; 49 | # forwardAuth = false; 50 | #}; 51 | services.soju = { 52 | enable = true; 53 | hostName = cfg.domain; 54 | listen = [ "irc+insecure://:${ircPort}" ]; 55 | }; 56 | networking.firewall.allowedTCPPorts = [ ircPort ]; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /overlays/overrides.nix: -------------------------------------------------------------------------------- 1 | final: prev: { 2 | nginxQuic = prev.nginxQuic.override { 3 | modules = prev.lib.unique ( 4 | prev.nginxQuic.modules 5 | ++ [ 6 | prev.nginxModules.brotli 7 | prev.nginxModules.zstd 8 | ] 9 | ); 10 | }; 11 | 12 | #roon-server = prev.roon-server.overrideAttrs ( 13 | # old: 14 | # let 15 | # version = "2.50.1528"; 16 | # urlVersion = builtins.replaceStrings [ "." ] [ "0" ] version; 17 | # in 18 | # { 19 | # version = version; 20 | # src = prev.fetchurl { 21 | # url = "https://download.roonlabs.com/updates/production/RoonServer_linuxx64_${urlVersion}.tar.bz2"; 22 | # hash = "sha256-8Dxxjj/5JSuXeTxTV2l37ZAmf6BDdhykPSinmgZeEVY="; 23 | # }; 24 | # } 25 | #); 26 | 27 | logseq = prev.logseq.overrideAttrs (oldAttrs: { 28 | postFixup = '' 29 | makeWrapper ${prev.electron}/bin/electron $out/bin/${oldAttrs.pname} \ 30 | --set "LOCAL_GIT_DIRECTORY" ${prev.git} \ 31 | --add-flags $out/share/${oldAttrs.pname}/resources/app \ 32 | --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform-hint=auto --enable-features=WaylandWindowDecorations}}" \ 33 | --prefix LD_LIBRARY_PATH : "${prev.lib.makeLibraryPath [ prev.stdenv.cc.cc.lib ]}" 34 | ''; 35 | }); 36 | 37 | #quickemu = prev.quickemu.overrideAttrs (oldAttrs: { 38 | # postPatch = 39 | # (oldAttrs.postPatch or "") 40 | # + '' 41 | # substituteInPlace quickemu \ 42 | # --replace-fail 'args+=(-nic bridge,br=''${network},model=virtio-net-pci''${MAC})' \ 43 | # 'args+=(-nic bridge,br=''${network},helper=/run/wrappers/bin/qemu-bridge-helper,model=virtio-net-pci''${MAC})' 44 | # ''; 45 | #}); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /hosts/mali/borgbackup-server.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | let 8 | backupUser = "borg"; 9 | backupDir = "/mnt/tank2/backups/borg_repos"; 10 | in 11 | { 12 | users.users."${backupUser}" = { }; 13 | systemd.tmpfiles.rules = [ "d ${backupDir} 0755 root root - -" ]; 14 | services.borgbackup.repos = { 15 | aquinas = { 16 | path = "/mnt/tank2/backups/borg_repos/aquinas"; 17 | authorizedKeys = [ 18 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFUmi4lHn11g1eo0KFax0R2gQEKmn3J+quvM5Nx0UipJ" 19 | "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBM9LkzTZXu/qsSuj+rdy24BBySWOLSmjcfA142AZcXJ5bDIrjWPHBg5pm0iroaRqC5eArWCD6VFA4e8cQzTzJE4=" 20 | ]; 21 | }; 22 | work = { 23 | path = "/mnt/tank2/backups/borg_repos/work"; 24 | authorizedKeys = [ 25 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDu4mlO4RTeRKGY0Whb2r0u9iM2I6+Rr2hKlQhhlLv25" 26 | ]; 27 | }; 28 | proxmox = { 29 | path = "/mnt/tank2/backups/borg_repos/proxmox"; 30 | authorizedKeys = [ 31 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDVhO6fCS/WBKebnGaNLxUDg5jWyMTv7nXvirPONXY3a" 32 | ]; 33 | }; 34 | }; 35 | systemd.services = lib.mapAttrs' (repo: repoCfg: { 36 | name = "borgbackup-compact-${repo}"; 37 | value = { 38 | path = with pkgs; [ borgbackup ]; 39 | script = "borg compact --verbose ${repoCfg.path}"; 40 | serviceConfig = { 41 | CPUSchedulingPolicy = "idle"; 42 | IOSchedulingClass = "idle"; 43 | PrivateTmp = true; 44 | ProtectSystem = "strict"; 45 | ReadWritePaths = repoCfg.path; 46 | User = backupUser; 47 | }; 48 | startAt = "Mon 4:55"; 49 | }; 50 | }) config.services.borgbackup.repos; 51 | } 52 | -------------------------------------------------------------------------------- /modules/desktop/programs/kitty/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.kitty; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | termFont = config.modules.desktop.fonts.terminal; 16 | in 17 | { 18 | options.modules.desktop.programs.kitty = { 19 | enable = lib.mkEnableOption ""; 20 | }; 21 | config = mkIf cfg.enable { 22 | home-manager.users."${username}" = 23 | { pkgs, config, ... }@hm: 24 | { 25 | home.file = { 26 | ".config/kitty/kitty.session" = { 27 | source = ./configs/kitty.session; 28 | }; 29 | ".config/kitty/kitty-monitor.session" = { 30 | source = ./configs/kitty-monitor.session; 31 | }; 32 | }; 33 | 34 | home.packages = [ pkgs.kitty ]; 35 | programs.kitty = { 36 | enable = true; 37 | themeFile = "gruvbox-dark"; 38 | font = { 39 | name = termFont.name; 40 | size = termFont.size; 41 | }; 42 | settings = { 43 | background_opacity = "0.90"; 44 | #font_size = "16"; 45 | #bold_font = "auto"; 46 | #italic_font = "auto"; 47 | #bold_italic_font = "auto"; 48 | #disable_ligatures = "never"; 49 | cursor_blink_interval = "1"; 50 | cursor_stop_blinking_after = "0.0"; 51 | select_by_word_characters = "@-./_~?&=%+#"; 52 | enable_audio_bell = "no"; 53 | }; 54 | }; 55 | }; 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /modules/shell/gpg-agent.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.gpg-agent; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.gpg-agent = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | services.pcscd.enable = true; 22 | myhm = 23 | { ... }@hm: 24 | { 25 | services.gpg-agent = { 26 | enable = true; 27 | enableSshSupport = true; 28 | enableZshIntegration = true; 29 | defaultCacheTtl = 60; 30 | maxCacheTtl = 120; 31 | enableExtraSocket = true; 32 | enableBashIntegration = true; 33 | sshKeys = [ "978C4D08058BA26EB97CB51820782DBCACFAACDA" ]; 34 | pinentry.package = pkgs.pinentry-gtk2; 35 | }; 36 | programs.gpg = { 37 | enable = true; 38 | homedir = "${hm.config.xdg.configHome}/.gnupg"; 39 | publicKeys = [ 40 | { 41 | source = ../../configs/casey-pub.asc; 42 | trust = "ultimate"; 43 | } 44 | ]; 45 | scdaemonSettings = { 46 | disable-ccid = true; 47 | card-timeout = "2"; 48 | pcsc-shared = true; 49 | debug-level = "basic"; 50 | log-file = "${hm.config.home.homeDirectory}/.cache/scdaemon.log"; 51 | }; 52 | }; 53 | 54 | persistence = mkIf withImpermanence { directories = [ "${hm.config.xdg.configHome}/.gnupg" ]; }; 55 | }; 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /modules-unstable/services/microsocks.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | let 10 | cfg = config.modules.services.microsocks; 11 | username = config.modules.users.primaryUser.username; 12 | withImpermanence = config.modules.impermanence.enable; 13 | useMullvad = config.modules.vpn.mullvad.enable; 14 | in 15 | { 16 | options.modules.services.microsocks = { 17 | enable = lib.mkEnableOption "microsocks"; 18 | }; 19 | config = lib.mkIf cfg.enable { 20 | environment.systemPackages = with pkgs; [ microsocks ]; 21 | services.microsocks = { 22 | enable = true; 23 | port = 1081; 24 | execWrapper = lib.optionalString useMullvad "${pkgs.mullvad-vpn}/bin/mullvad-exclude"; 25 | }; 26 | 27 | systemd.services.microsocks = lib.mkIf useMullvad { 28 | after = [ "mullvad-exclusion-init.service" ]; 29 | wants = [ "mullvad-exclusion-init.service" ]; 30 | requires = [ "mullvad-exclusion-init.service" ]; 31 | }; 32 | 33 | systemd.services.mullvad-exclusion-init = lib.mkIf useMullvad { 34 | enable = true; 35 | description = "sets up mullvad exclusion cgroup"; 36 | after = [ "mullvad-daemon.service" ]; 37 | wants = [ "mullvad-daemon.service" ]; 38 | restartIfChanged = true; 39 | serviceConfig = { 40 | User = "root"; 41 | ExecStart = "/bin/sh -c '${pkgs.coreutils}/bin/mkdir -p /sys/fs/cgroup/net_cls/mullvad-exclusions/ && ${pkgs.coreutils}/bin/touch /sys/fs/cgroup/net_cls/mullvad-exclusions/cgroup.procs && ${pkgs.coreutils}/bin/chmod 777 /sys/fs/cgroup/net_cls/mullvad-exclusions/cgroup.procs'"; 42 | NotifyAccess = "all"; 43 | Type = "oneshot"; 44 | RemainAfterExit = "yes"; 45 | }; 46 | path = [ pkgs.coreutils ]; 47 | }; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /hosts/quine/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | export COLOR_RESET="\033[0m" 4 | export RED_BG="\033[41m" 5 | export BLUE_BG="\033[44m" 6 | 7 | function err { 8 | echo -e "${RED_BG}$1${COLOR_RESET}" 9 | } 10 | 11 | function info { 12 | echo -e "${BLUE_BG}$1${COLOR_RESET}" 13 | } 14 | 15 | function check_key { 16 | if [[ -f "/mnt/persist/etc/ssh/ssh_host_ed25519_key" ]]; 17 | then 18 | echo 19 | info "Here we go..." 20 | else 21 | mkdir -p /mnt/persist/etc/ssh 22 | echo 23 | echo "Please create /mnt/persist/etc/ssh/ssh_host_ed25519_key" 24 | echo "It is used to decrypt secrets." 25 | echo 26 | read -p "Are you ready? (type 'yes' in capital letters to begin installation): " -r 27 | if ! [[ $REPLY == "YES" ]]; 28 | then 29 | err "Aborting" 30 | exit 1 31 | fi 32 | check_key 33 | fi 34 | } 35 | 36 | if [[ "$EUID" -gt 0 ]]; then 37 | err "Must run as root" 38 | exit 1 39 | fi 40 | 41 | if [[ ! -d /mnt/boot ]]; then 42 | err "No /mnt/boot directory found. Did you run disks.sh first?" 43 | exit 1 44 | fi 45 | 46 | check_key 47 | 48 | chown -R root:root /mnt/persist/etc/ssh/ssh_host_ed25519_key 49 | chmod 0600 /mnt/persist/etc/ssh/ssh_host_ed25519_key 50 | 51 | info "Generating NixOS configuration (/mnt/etc/nixos/*.nix) ..." 52 | nixos-generate-config --root /mnt 53 | 54 | 55 | cd /home/nixos/nixcfg 56 | rm /mnt/etc/nixos/configuration.nix 57 | mv /mnt/etc/nixos/hardware-configuration.nix ./hosts/quine/ 58 | 59 | 60 | nixos-install --no-root-passwd \ 61 | --flake '.#quine' 62 | 63 | #--option substituters "https://aseipp-nix-cache.global.ssl.fastly.net" \ 64 | 65 | info "Done." 66 | echo 67 | info "You can now reboot into your new NixOS installation." 68 | -------------------------------------------------------------------------------- /modules/shell/zellij/config.kdl: -------------------------------------------------------------------------------- 1 | keybinds { 2 | normal { 3 | // Quick access to common actions 4 | bind "Ctrl g" { SwitchToMode "Locked"; } 5 | bind "Ctrl p" { SwitchToMode "Pane"; } 6 | bind "Ctrl t" { SwitchToMode "Tab"; } 7 | bind "Ctrl s" { SwitchToMode "Session"; } 8 | 9 | // Quick navigation 10 | bind "Alt h" "Alt Left" { MoveFocusOrTab "Left"; } 11 | bind "Alt l" "Alt Right" { MoveFocusOrTab "Right"; } 12 | bind "Alt j" "Alt Down" { MoveFocus "Down"; } 13 | bind "Alt k" "Alt Up" { MoveFocus "Up"; } 14 | 15 | // Quick actions 16 | bind "Alt =" { Resize "Increase"; } 17 | bind "Alt -" { Resize "Decrease"; } 18 | bind "Alt [" { PreviousSwapLayout; } 19 | bind "Alt ]" { NextSwapLayout; } 20 | 21 | // iOS-friendly Shift+Tab for reverse tab completion 22 | bind "Ctrl Shift j" { WriteChars "\u{1b}[Z"; } 23 | } 24 | 25 | locked { 26 | bind "Ctrl g" { SwitchToMode "Normal"; } 27 | } 28 | } 29 | 30 | ui { 31 | pane_frames { 32 | rounded_corners true 33 | hide_session_name false 34 | } 35 | } 36 | mouse_mode true 37 | copy_clipboard "system" 38 | default_shell "zsh" 39 | session_serialization true 40 | 41 | plugins { 42 | tab-bar { path "tab-bar"; } 43 | status-bar { path "status-bar"; } 44 | strider { path "strider"; } 45 | compact-bar { path "compact-bar"; } 46 | } 47 | 48 | themes { 49 | mine { 50 | fg "#D8DEE9" 51 | bg "#2E3440" 52 | black "#3B4252" 53 | red "#BF616A" 54 | green "#A3BE8C" 55 | yellow "#EBCB8B" 56 | blue "#81A1C1" 57 | magenta "#B48EAD" 58 | cyan "#88C0D0" 59 | white "#E5E9F0" 60 | orange "#D08770" 61 | } 62 | } 63 | 64 | theme "gruvbox-dark" 65 | -------------------------------------------------------------------------------- /hosts/witt/hardware.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkgs, 4 | lib, 5 | inputs, 6 | ... 7 | }: 8 | { 9 | imports = [ inputs.nixos-hardware.nixosModules.framework-13-7040-amd ]; 10 | # The firmware on the fingerprint sensor needs a downgrade to make it work on Linux. The process is documented here. 11 | # However on recent NixOS versions also fwupd can no longer update the firmware. Using the following snippet allows 12 | # to temporarly downgrade fwupd to an old-enough version: 13 | services.fwupd = { 14 | enable = true; 15 | # we need fwupd 1.9.7 to downgrade the fingerprint sensor firmware 16 | # package = 17 | # (import (builtins.fetchTarball { 18 | # url = "https://github.com/NixOS/nixpkgs/archive/bb2009ca185d97813e75736c2b8d1d8bb81bde05.tar.gz"; 19 | # sha256 = "sha256:003qcrsq5g5lggfrpq31gcvj82lb065xvr7bpfa8ddsw8x4dnysk"; 20 | # }) { inherit (pkgs) system; }).fwupd; 21 | }; 22 | 23 | boot = { 24 | zfs.devNodes = lib.mkForce "/dev/disk/by-partuuid"; 25 | loader = { 26 | efi = { 27 | canTouchEfiVariables = true; 28 | }; 29 | systemd-boot = { 30 | enable = true; 31 | configurationLimit = 20; 32 | }; 33 | }; 34 | extraModulePackages = [ ]; 35 | kernelModules = [ "kvm-amd" ]; 36 | initrd = { 37 | availableKernelModules = [ 38 | "nvme" 39 | "xhci_pci" 40 | "thunderbolt" 41 | "usb_storage" 42 | "sd_mod" 43 | ]; 44 | kernelModules = [ ]; 45 | postDeviceCommands = lib.mkAfter '' 46 | zfs rollback -r rpool/encrypted/local/root@blank && \ 47 | echo "rollback complete" 48 | ''; 49 | }; 50 | }; 51 | 52 | hardware = { 53 | #bluetooth = { enable = true; powerOnBoot = false; }; 54 | enableRedistributableFirmware = true; # enables microcode updates 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /modules/desktop/programs/waydroid.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.waydroid; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.waydroid = { 18 | enable = lib.mkEnableOption ""; 19 | autoStart.enable = mkEnableOption "Waydroid auto start"; 20 | }; 21 | 22 | config = mkIf cfg.enable { 23 | 24 | virtualisation.waydroid.enable = true; 25 | environment.persistence."/persist" = mkIf withImpermanence { 26 | directories = [ 27 | "/var/lib/waydroid" 28 | ]; 29 | users.${username} = { 30 | directories = [ ".local/share/waydroid" ]; 31 | }; 32 | }; 33 | 34 | systemd.services."waydroid-container".wantedBy = mkForce ( 35 | optional cfg.autoStart.enable "multi-user.target" 36 | ); 37 | 38 | home-manager.users."${username}" = 39 | { pkgs, config, ... }@hm: 40 | { 41 | home.packages = [ pkgs.signal-desktop ]; 42 | home.file.".local/share/applications/signal-desktop.desktop" = { 43 | text = '' 44 | [Desktop Entry] 45 | Name=Signal Desktop (nix) 46 | Exec=${pkgs.signal-desktop}/bin/signal-desktop --ozone-platform-hint=auto --no-sandbox %U 47 | Terminal=false 48 | Type=Application 49 | Icon=signal-desktop 50 | StartupWMClass=signal 51 | Comment=Private messaging from your desktop 52 | MimeType=x-scheme-handler/sgnl;x-scheme-handler/signalcaptcha; 53 | Categories=Network;InstantMessaging;Chat; 54 | ''; 55 | }; 56 | }; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /flake/iso-test.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | perSystem = 4 | { 5 | config, 6 | self', 7 | inputs', 8 | pkgs, 9 | system, 10 | ... 11 | }: 12 | { 13 | packages.iso-test = pkgs.writeShellApplication { 14 | name = "iso-test"; 15 | runtimeInputs = with pkgs; [ 16 | qemu-utils 17 | qemu_kvm 18 | ]; 19 | text = '' 20 | disk1=disk1.qcow2 21 | if [ ! -f $disk1 ]; then 22 | qemu-img create -f qcow2 $disk1 8G 23 | fi 24 | exec qemu-kvm \ 25 | -boot c \ 26 | -cpu host \ 27 | -smp cores=2 \ 28 | -M pc \ 29 | -m 2G \ 30 | -device virtio-balloon \ 31 | -device virtio-rng-pci \ 32 | -device nvme,serial=deadbeef,drive=nvm \ 33 | -device usb-ehci \ 34 | -device usb-storage,drive=usbdisk \ 35 | -device e1000,netdev=wan0,mac=8c:16:45:ce:0f:f4 \ 36 | -netdev user,id=wan0 \ 37 | -device virtio-net-pci,netdev=lan0,mac=e4:1d:2d:bf:df:51 \ 38 | -netdev user,id=lan0 \ 39 | -device virtio-net-pci,netdev=lan1,mac=e4:1d:2d:bf:df:50 \ 40 | -netdev user,id=lan1 \ 41 | -device virtio-net-pci,netdev=testnet0,mac=8c:1d:2d:bf:df:53 \ 42 | -netdev user,id=testnet0,hostfwd=tcp::2222-:22 \ 43 | -drive file=$disk1,format=qcow2,if=none,id=nvm,cache=unsafe,werror=report \ 44 | -drive if=pflash,format=raw,unit=0,readonly=on,file=${pkgs.OVMF.firmware} \ 45 | -drive id=usbdisk,if=none,readonly=on,file="$(echo ${inputs.self.nixosConfigurations.addams-installer.config.system.build.isoImage}/iso/*.iso)" \ 46 | -virtfs local,path=./shared,mount_tag=host0,security_model=none,id=host0 47 | ''; 48 | }; 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /hosts/dewey/guests.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | pkgs, 4 | lib, 5 | inputs, 6 | ... 7 | }: 8 | let 9 | inherit (config.repo.secrets) global; 10 | inherit (config.repo.secrets) home-ops; 11 | 12 | guests = [ 13 | ]; 14 | 15 | genGuestSecret = hostname: { 16 | "microvm-${hostname}-sops-key" = { 17 | sopsFile = ../../guests/${hostname}/secrets.sops.yaml; 18 | key = "ssh_host_ed25519_key"; 19 | owner = "microvm"; 20 | mode = "400"; 21 | }; 22 | }; 23 | svcIp = hostname: lib.elemAt config.site.net.svc.hosts4.${hostname} 0; 24 | mkGuest = 25 | { 26 | hostname, 27 | domain, 28 | forwardAuth ? false, 29 | external ? false, 30 | acmeHost ? global.domain.home, 31 | pgEnable ? false, 32 | pgUsername ? hostname, 33 | pgDatabase ? hostname, 34 | ip ? svcIp hostname, 35 | dataset ? hostname, 36 | datasetMountpoint ? "/var/lib/${hostname}", 37 | }: 38 | { 39 | modules.services.ingress.virtualHosts."${domain}" = { 40 | acmeHost = acmeHost; 41 | upstream = "http://${ip}:8080"; 42 | forwardAuth = forwardAuth; 43 | }; 44 | modules.services.ingress.domains = lib.mkIf external { 45 | "${acmeHost}" = { 46 | externalDomains = [ domain ]; 47 | }; 48 | }; 49 | modules.services.postgresql.extraAuthentication = lib.mkIf pgEnable [ 50 | "host ${pgUsername} ${pgDatabase} ${ip}/32 scram-sha-256" 51 | ]; 52 | 53 | modules.zfs.datasets.properties = lib.mkIf (dataset != null && dataset != "") { 54 | "rpool/encrypted/safe/svc/${dataset}" = { 55 | "mountpoint" = datasetMountpoint; 56 | "com.sun:auto-snapshot" = "false"; 57 | }; 58 | }; 59 | }; 60 | in 61 | lib.mkMerge [ 62 | { 63 | sops.secrets = lib.mori.reduceAttrs genGuestSecret guests; 64 | } 65 | ] 66 | -------------------------------------------------------------------------------- /hosts/quine/README.md: -------------------------------------------------------------------------------- 1 | # Quine 2 | 3 | ## Bare Install 4 | 5 | 1. Boot into installer 6 | 7 | 2. Follow: 8 | ``` sh 9 | # go into a root shell 10 | sudo su 11 | 12 | # create this folder if necessary 13 | mkdir -p /mnt/etc/ 14 | 15 | git clone https://github.com/ramblurr/nixcfg.git /mnt/etc/nixos --recurse-submodules 16 | 17 | cd /mnt/etc/nixos/unstable/x86_64-linux/quine 18 | 19 | # edit disks.sh and verify vars 20 | 21 | # partition disk 22 | ./disks.sh 23 | 24 | # Edit /persist/etc/ssh/ssh_host_ed25519_key and place the private key 25 | # it is used to decrypt the secrets with sops 26 | 27 | # install 28 | ./bare-install.sh 29 | 30 | ``` 31 | 3. Reboot 32 | 33 | ## Flake Install 34 | 35 | > WARNING: This isn't working yet as of 2023-04-24 because of 36 | > ```error: filesystem error: cannot rename: Invalid cross-device link [/mnt/nix/store/1caynpxvnlc0a6bcyr35z4gpjiy1qacq-manifest.json.drv.chroot/nix/store/5b37nyxpghm0h2fsx8nn23qh9mpp3f65-manifest.json] [/nix/store/5b37nyxpghm0h2fsx8nn23qh9mpp3f65-manifest.json]``` 37 | > So in the meantime use the "Bare Install" 38 | 39 | 40 | 1. Boot into installer 41 | 42 | 2. Follow: 43 | ``` sh 44 | # go into a root shell 45 | sudo su 46 | 47 | # create this folder if necessary 48 | mkdir -p /mnt/etc/ 49 | 50 | git clone https://github.com/ramblurr/nixcfg.git /mnt/etc/nixos --recurse-submodules 51 | 52 | cd /mnt/etc/nixos/unstable/x86_64-linux/quine 53 | 54 | # edit disks.sh and verify vars 55 | 56 | # partition disk 57 | ./disks.sh 58 | 59 | # Edit /persist/etc/ssh/ssh_host_ed25519_key and place the private key 60 | # it is used to decrypt the secrets with sops 61 | 62 | # install 63 | ./install.sh 64 | 65 | ``` 66 | 67 | You could get some hashes errors, just change the bad hashes in the config file 68 | to the given ones by the Nix Output. 69 | 3. Reboot 70 | 4. Login 71 | 5. `chown -R $USER /etc/nixos` 72 | -------------------------------------------------------------------------------- /modules/dev/radicle.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | options, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.dev.radicle; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | #radicle = inputs.radicle.packages.${pkgs.system}.default; 17 | { 18 | options.modules.dev.radicle = { 19 | enable = lib.mkEnableOption ""; 20 | }; 21 | 22 | config = mkIf cfg.enable { 23 | systemd.tmpfiles.rules = mkIf withImpermanence [ 24 | "d '/persist${homeDirectory}/.config/radicle' - ${username} ${username} - -" 25 | ]; 26 | myhm = 27 | { ... }@hm: 28 | { 29 | home.packages = [ radicle ]; 30 | 31 | home.sessionVariables = { 32 | RAD_HOME = "${hm.config.xdg.configHome}/radicle"; 33 | }; 34 | 35 | home.persistence."/persist${homeDirectory}" = mkIf withImpermanence { 36 | directories = [ ".config/radicle" ]; 37 | }; 38 | 39 | systemd.user.services.radicle-node = { 40 | Unit = { 41 | Description = "radicle-cli node "; 42 | Documentation = "man:rad(1)"; 43 | }; 44 | Install = { 45 | WantedBy = [ "default.target" ]; 46 | }; 47 | Service = { 48 | Type = "simple"; 49 | Environment = [ 50 | "PATH=/run/wrappers/bin:/run/current-system/sw/bin:/etc/profiles/per-user/${username}/bin" 51 | "RAD_HOME=${hm.config.xdg.configHome}/radicle" 52 | "RUST_LOG=debug" 53 | "RUST_BACKTRACE=1" 54 | ]; 55 | Restart = "always"; 56 | RestartSec = "5"; 57 | ExecStart = "${radicle}/bin/rad node start --foreground"; 58 | }; 59 | }; 60 | }; 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /pkgs/beets-filetote.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | fetchFromGitHub, 5 | beets, 6 | poetry-core, 7 | python3Packages, 8 | }: 9 | python3Packages.buildPythonApplication rec { 10 | pname = "beets-filetote"; 11 | version = "0.4.9"; 12 | pyproject = true; 13 | 14 | src = fetchFromGitHub { 15 | owner = "gtronset"; 16 | repo = "beets-filetote"; 17 | rev = "v${version}"; 18 | hash = "sha256-pZ6c2XQMSiiPHyZMLSiSE+LXeCfi3HEWtsTK5DP9YZE="; 19 | }; 20 | 21 | build-system = [ 22 | python3Packages.poetry-core 23 | ]; 24 | 25 | postPatch = '' 26 | sed -i -e '/audible/d' tests/helper.py 27 | 28 | # beets v2.1.0 compat 29 | # 30 | sed -i -e 's/util\.py3_path/os.fsdecode/g' tests/_common.py 31 | ''; 32 | 33 | pytestFlagsArray = [ "-r fEs" ]; 34 | 35 | disabledTests = [ 36 | # XXX: Needs update for Beets v2.0.0 37 | # 38 | "test_move_on_modify_command" 39 | "test_prune_modify_query" 40 | ]; 41 | 42 | disabledTestPaths = [ 43 | "tests/test_audible_m4b_files.py" 44 | ]; 45 | nativeCheckInputs = with python3Packages; [ 46 | pytestCheckHook 47 | beets 48 | reflink 49 | toml 50 | typeguard 51 | ]; 52 | 53 | preBuild = '' 54 | export HOME=$(mktemp -d) 55 | ''; 56 | 57 | pythonImportsCheck = [ 58 | "beetsplug.filetote" 59 | "beetsplug.filetote_dataclasses" 60 | ]; 61 | 62 | meta = with lib; { 63 | description = "Beets plugin to move non-music files during the import process"; 64 | homepage = "https://github.com/gtronset/beets-filetote"; 65 | changelog = "https://github.com/gtronset/beets-filetote/blob/${src.rev}/CHANGELOG.md"; 66 | maintainers = with maintainers; [ dansbandit ]; 67 | license = licenses.mit; 68 | inherit (beets.meta) platforms; 69 | }; 70 | } 71 | -------------------------------------------------------------------------------- /modules/desktop/programs/logseq.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.programs.logseq; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.desktop.programs.logseq = { 18 | enable = lib.mkEnableOption ""; 19 | }; 20 | config = mkIf cfg.enable { 21 | 22 | environment.persistence."/persist" = mkIf withImpermanence { 23 | users.${username} = { 24 | directories = [ 25 | ".config/Logseq" 26 | ".logseq" 27 | ]; 28 | }; 29 | }; 30 | 31 | home-manager.users."${username}" = 32 | { pkgs, config, ... }@hm: 33 | { 34 | # I am using flatpak logseq, because it is more stable than the nix pkg (as of 2024-09) 35 | # ref: https://github.com/NixOS/nixpkgs/issues/264885 36 | # https://github.com/logseq/logseq/issues/10851 37 | home.packages = [ pkgs.logseq ]; 38 | #Exec=env -u NIXOS_OZONE_WL logseq %u 39 | #Icon=logseq 40 | home.file.".local/share/applications/logseq-wayland.desktop" = { 41 | text = '' 42 | [Desktop Entry] 43 | Name=Logseq (flatpak wayland) 44 | Exec=GDK_BACKEND=wayland flatpak run com.logseq.Logseq --enable-features=UseOzonePlatform --ozone-platform=wayland --enable-features=WaylandWindowDecorations %u 45 | Terminal=false 46 | Type=Application 47 | Icon=com.logseq.Logseq 48 | StartupWMClass=Logseq 49 | Comment=A privacy-first, open-source platform for knowledge management and collaboration. 50 | MimeType=x-scheme-handler/logseq 51 | Categories=Utility 52 | ''; 53 | }; 54 | }; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /lib/network.nix: -------------------------------------------------------------------------------- 1 | _inputs: _final: prev: { 2 | lib = prev.lib // { 3 | my = prev.lib.my // { 4 | /* 5 | cidrToIp :: string -> string 6 | 7 | Given an IP address in CIDR notation, returns the IP address without the CIDR suffix 8 | */ 9 | cidrToIp = ip: builtins.head (builtins.split "/" ip); 10 | 11 | generateHostId = 12 | hostName: 13 | prev.lib.concatStringsSep "" ( 14 | prev.lib.take 8 (prev.lib.stringToCharacters (builtins.hashString "sha256" hostName)) 15 | ); 16 | 17 | /* 18 | generateMacAddress :: string -> string 19 | 20 | Given a string, returns a MAC address. 21 | */ 22 | generateMacAddress = 23 | s: 24 | let 25 | hash = builtins.hashString "sha256" s; 26 | c = off: builtins.substring off 2 hash; 27 | in 28 | "${builtins.substring 0 1 hash}2:${c 2}:${c 4}:${c 6}:${c 8}:${c 10}"; 29 | 30 | /* 31 | eui64Suffix :: string -> string 32 | 33 | Given a MAC address, returns the EUI-64 suffix. The returned suffix can be appended to a prefix to create a valid ipv6 ip address. 34 | */ 35 | eui64Suffix = 36 | mac: 37 | let 38 | inherit (prev.lib.std) 39 | list 40 | regex 41 | string 42 | num 43 | ; 44 | inherit (prev.lib.my) uint; 45 | parts = list.map string.toLower (regex.splitOn ":" mac); 46 | part = list.unsafeIndex parts; 47 | part0 = 48 | part: 49 | let 50 | nibble1' = uint.fromHexDigit (string.unsafeIndex part 1); 51 | nibble1 = num.bits.bitXor 2 nibble1'; 52 | nibble0 = string.unsafeIndex part 0; 53 | in 54 | nibble0 + uint.toHexLower nibble1; 55 | in 56 | "${part0 (part 0)}${part 1}:${part 2}ff:fe${part 3}:${part 4}${part 5}"; 57 | }; 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /modules/services/grafana.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | let 8 | cfg = config.modules.services.grafana; 9 | stateDir = "/var/lib/grafana"; 10 | 11 | serviceDeps = [ 12 | "var-lib-grafana.mount" 13 | "zfs-datasets.service" 14 | ]; 15 | grafanaDomain = cfg.domain; 16 | in 17 | { 18 | options.modules.services.grafana = { 19 | enable = lib.mkEnableOption "grafana"; 20 | domain = lib.mkOption { 21 | type = lib.types.str; 22 | example = "code.example.com"; 23 | description = "The domain to use for the forgejo"; 24 | }; 25 | ingress = lib.mkOption { 26 | type = lib.types.submodule ( 27 | lib.recursiveUpdate (import ./ingress-options.nix { inherit config lib; }) { } 28 | ); 29 | }; 30 | }; 31 | 32 | config = lib.mkIf cfg.enable { 33 | 34 | modules.zfs.datasets.properties = { 35 | "rpool/encrypted/safe/svc/grafana"."mountpoint" = stateDir; 36 | }; 37 | 38 | systemd.tmpfiles.rules = [ 39 | "z '${stateDir}' 750 grafana grafana - -" 40 | ]; 41 | 42 | systemd.services.grafana = { 43 | requires = serviceDeps; 44 | after = serviceDeps; 45 | }; 46 | 47 | services.grafana = { 48 | enable = true; 49 | 50 | settings = { 51 | smtp = { 52 | enabled = true; 53 | host = "${config.repo.secrets.global.email.siteRelay}:25"; 54 | from_address = config.repo.secrets.global.email.home; 55 | }; 56 | server = { 57 | domain = grafanaDomain; 58 | root_url = "https://${grafanaDomain}"; 59 | protocol = "socket"; 60 | }; 61 | 62 | panels = { 63 | enable_alpha = "true"; 64 | disable_sanitize_html = "true"; 65 | }; 66 | }; 67 | declarativePlugins = with pkgs.grafanaPlugins; [ 68 | grafana-piechart-panel 69 | grafana-clock-panel 70 | frser-sqlite-datasource 71 | ]; 72 | }; 73 | }; 74 | 75 | } 76 | -------------------------------------------------------------------------------- /modules/desktop/services/ha-shutdown.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | with lib; 8 | let 9 | cfg = config.modules.desktop.services.ha-shutdown; 10 | shutdownScript = pkgs.writeScript "ha-shutdown.py" (builtins.readFile ./shutdown.py); 11 | username = config.modules.users.primaryUser.username; 12 | in 13 | { 14 | options.modules.desktop.services.ha-shutdown = { 15 | enable = mkEnableOption "ha-shutdown"; 16 | environmentFile = mkOption { 17 | description = "The full path to a file that contains the secret environment variables needed for the shutdown service"; 18 | type = with types; nullOr str; 19 | default = null; 20 | }; 21 | listenPort = mkOption { 22 | type = types.int; 23 | default = 5001; 24 | }; 25 | timeout = mkOption { 26 | type = types.int; 27 | default = 60000; 28 | description = "The number of milliseconds to wait for a response from Home Assistant before shutting down"; 29 | }; 30 | }; 31 | config = mkIf cfg.enable { 32 | networking.firewall.allowedTCPPorts = [ cfg.listenPort ]; 33 | sops.secrets.HA_SHUTDOWN_TOKEN = { 34 | owner = username; 35 | mode = "0400"; 36 | }; 37 | systemd.user.services.ha-shutdown = { 38 | description = "HA Shutdown Service"; 39 | wantedBy = [ "default.target" ]; 40 | after = [ 41 | "network.target" 42 | "network-online.target" 43 | "sops-nix.service" 44 | ]; 45 | path = with pkgs; [ 46 | python3 47 | dunst 48 | systemd 49 | ]; 50 | serviceConfig = { 51 | EnvironmentFile = config.sops.secrets.HA_SHUTDOWN_TOKEN.path; 52 | ExecStart = "${pkgs.python3}/bin/python -u ${shutdownScript} --timeout ${toString cfg.timeout} --port ${toString cfg.listenPort} "; 53 | Restart = "always"; 54 | RestartSec = "10s"; 55 | StandardError = "journal"; 56 | StandardOutput = "journal"; 57 | }; 58 | }; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /modules/services/atuin-sync.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | let 10 | cfg = config.modules.services.atuin-sync; 11 | home-ops = config.repo.secrets.home-ops; 12 | httpPort = toString cfg.ports.http; 13 | stateDirActual = "/var/lib/private/actual-budget"; 14 | stateDirEffective = "/var/lib/actual-budget"; 15 | cfgFile = pkgs.writeText "actual.json" ( 16 | builtins.toJSON { 17 | dataDir = stateDirEffective; 18 | hostname = "127.0.0.1"; 19 | port = cfg.ports.http; 20 | serverFiles = "${stateDirEffective}/server"; 21 | userFiles = "${stateDirEffective}/user"; 22 | loginMethod = "password"; 23 | trustedProxies = [ "127.0.0.1/24" ]; 24 | } 25 | ); 26 | in 27 | { 28 | options.modules.services.atuin-sync = { 29 | enable = lib.mkEnableOption "atuin-sync"; 30 | domain = lib.mkOption { 31 | type = lib.types.str; 32 | example = "atuin.example.com"; 33 | description = "The domain to use for the atuin-sync"; 34 | }; 35 | ports = { 36 | http = lib.mkOption { 37 | type = lib.types.port; 38 | description = "The HTTP port to use for the atuin-sync"; 39 | }; 40 | }; 41 | ingress = lib.mkOption { 42 | type = lib.types.submodule ( 43 | lib.recursiveUpdate (import ./ingress-options.nix { inherit config lib; }) { } 44 | ); 45 | }; 46 | }; 47 | 48 | config = lib.mkIf cfg.enable { 49 | services.atuin = { 50 | enable = true; 51 | openRegistration = false; 52 | port = cfg.ports.http; 53 | }; 54 | modules.services.ingress.domains = lib.mkIf cfg.ingress.external { 55 | "${cfg.ingress.domain}" = { 56 | externalDomains = [ cfg.domain ]; 57 | }; 58 | }; 59 | modules.services.ingress.virtualHosts.${cfg.domain} = { 60 | acmeHost = cfg.ingress.domain; 61 | upstream = "http://127.0.0.1:${toString cfg.ports.http}"; 62 | forwardAuth = false; 63 | }; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /modules/microvm-guest/home-manager.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | inputs, 4 | config, 5 | pkgs, 6 | ... 7 | }: 8 | let 9 | cfg = config.modules.microvm-guest; 10 | username = cfg.homeManager.username; 11 | uid = cfg.homeManager.uid; 12 | home = config.users.users.${username}.home; 13 | in 14 | lib.mkIf cfg.homeManager.enable { 15 | nix.settings.allowed-users = [ username ]; 16 | users.users.${username} = { 17 | name = username; 18 | isNormalUser = true; 19 | uid = uid; 20 | group = username; 21 | linger = true; 22 | home = "/home/${username}"; 23 | createHome = true; 24 | autoSubUidGidRange = true; 25 | }; 26 | 27 | users.groups.${username} = { 28 | name = username; 29 | gid = cfg.homeManager.gid; 30 | }; 31 | 32 | systemd.services."home-manager-${username}" = { 33 | serviceConfig.TimeoutStartSec = lib.mkOverride 99 "15m"; 34 | after = [ "network-online.target" ]; 35 | wants = [ "network-online.target" ]; 36 | }; 37 | home-manager.users.${username} = 38 | { pkgs, config, ... }@hm: 39 | { 40 | imports = [ 41 | inputs.impermanence.nixosModules.home-manager.impermanence 42 | inputs.sops-nix.homeManagerModule 43 | (lib.mkAliasOptionModule 44 | [ "persistence" ] 45 | [ 46 | "home" 47 | "persistence" 48 | "/persist${username}" 49 | ] 50 | ) 51 | ]; 52 | home.homeDirectory = home; 53 | home.sessionVariables = { 54 | EDITOR = "vim"; 55 | DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/user/${toString uid}/bus"; 56 | XDG_RUNTIME_DIR = "/run/user/${toString uid}"; 57 | }; 58 | systemd.user.startServices = "sd-switch"; 59 | programs.bash = { 60 | enable = true; 61 | initExtra = '' 62 | [[ -f "${hm.config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" ]] && source "${hm.config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh" 63 | ''; 64 | }; 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /pkgs/java-mission-control/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, 3 | makeDesktopItem, 4 | lib, 5 | fetchzip, 6 | autoPatchelfHook, 7 | makeWrapper, 8 | jdk, 9 | glibc, 10 | webkitgtk_4_0, 11 | gtk3, 12 | glib, 13 | ... 14 | }: 15 | 16 | let 17 | 18 | desktopItem = makeDesktopItem { 19 | name = "OpenJDK Java Mission Control"; 20 | exec = "java-mission-control"; 21 | comment = "Java Profiling Client"; 22 | desktopName = "Java Mission Control"; 23 | categories = [ "Development" ]; 24 | icon = ./src/share/icons/adoptium.png; 25 | }; 26 | 27 | libraryPath = lib.makeLibraryPath [ 28 | webkitgtk_4_0 29 | glibc 30 | gtk3 31 | glib 32 | ]; 33 | binPath = lib.makeBinPath [ jdk ]; 34 | 35 | in 36 | stdenv.mkDerivation rec { 37 | pname = "java-mission-control"; 38 | version = "9.1.1"; 39 | 40 | src = fetchzip { 41 | url = "https://github.com/adoptium/jmc-build/releases/download/${version}/org.openjdk.jmc-${version}-linux.gtk.x86_64.tar.gz"; 42 | hash = "sha256-BStLG94uNdll2Mipxm+rMtlxLpxjvOoA/oCzGcYOvDM="; 43 | stripRoot = false; 44 | }; 45 | 46 | nativeBuildInputs = [ autoPatchelfHook ]; 47 | 48 | buildInputs = [ makeWrapper ]; 49 | autoPatchelfIgnoreMissingDeps = [ 50 | "libc.so.8" 51 | ]; 52 | 53 | installPhase = '' 54 | mkdir -pv $out/bin $out/share/applications 55 | cp -r $src/JDK\ Mission\ Control/* $out 56 | chmod +x $out/jmc 57 | wrapProgram "$out/jmc" \ 58 | --prefix LD_LIBRARY_PATH : "${libraryPath}" \ 59 | --prefix PATH : "${binPath}" \ 60 | --prefix XDG_DATA_DIRS : "${gtk3}/share/gsettings-schemas/${gtk3.name}" \ 61 | --prefix PATH ':' "${jdk}/bin" 62 | ln -s $out/jmc $out/bin/java-mission-control 63 | ln -s ${desktopItem}/share/applications $out/share/applications 64 | ''; 65 | 66 | meta = with lib; { 67 | description = "Java Flight Recorder and Profiler"; 68 | homepage = "https://adoptium.net/jmc/"; 69 | license = licenses.upl; 70 | platforms = platforms.linux; 71 | }; 72 | } 73 | -------------------------------------------------------------------------------- /modules/shell/zsh/configs/keybindings.zsh: -------------------------------------------------------------------------------- 1 | # ██ 2 | # ░██ 3 | # ██████ ██████░██ 4 | # ░░░░██ ██░░░░ ░██████ 5 | # ██ ░░█████ ░██░░░██ 6 | # ██ ░░░░░██░██ ░██ 7 | # ██████ ██████ ░██ ░██ 8 | # ░░░░░░ ░░░░░░ ░░ ░░ 9 | # 10 | # ▓▓▓▓▓▓▓▓▓▓ 11 | # ░▓ author ▓ xero 12 | # ░▓ code ▓ http://code.xero.nu/dotfiles 13 | # ░▓ mirror ▓ http://git.io/.files 14 | # ░▓▓▓▓▓▓▓▓▓▓ 15 | # ░░░░░░░░░░ 16 | # 17 | #█▓▒░ keybindings 18 | typeset -A key 19 | 20 | key[Home]=${terminfo[khome]} 21 | key[End]=${terminfo[kend]} 22 | key[Insert]=${terminfo[kich1]} 23 | key[Delete]=${terminfo[kdch1]} 24 | key[Up]=${terminfo[kcuu1]} 25 | key[Down]=${terminfo[kcud1]} 26 | key[Left]=${terminfo[kcub1]} 27 | key[Right]=${terminfo[kcuf1]} 28 | key[PageUp]=${terminfo[kpp]} 29 | key[PageDown]=${terminfo[knp]} 30 | 31 | [[ -n "${key[Home]}" ]] && bindkey "${key[Home]}" beginning-of-line 32 | [[ -n "${key[End]}" ]] && bindkey "${key[End]}" end-of-line 33 | [[ -n "${key[Insert]}" ]] && bindkey "${key[Insert]}" overwrite-mode 34 | [[ -n "${key[Delete]}" ]] && bindkey "${key[Delete]}" delete-char 35 | [[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-history 36 | [[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-history 37 | [[ -n "${key[Left]}" ]] && bindkey "${key[Left]}" backward-char 38 | [[ -n "${key[Right]}" ]] && bindkey "${key[Right]}" forward-char 39 | [[ -n "${key[PageUp]}" ]] && bindkey "${key[PageUp]}" beginning-of-buffer-or-history 40 | [[ -n "${key[PageDown]}" ]] && bindkey "${key[PageDown]}" end-of-buffer-or-history 41 | bindkey "^[[1;5C" forward-word 42 | bindkey "^[[1;5D" backward-word 43 | 44 | #if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then 45 | # function zle-line-init () { 46 | # printf '%s' "${terminfo[smkx]}" 47 | # } 48 | # function zle-line-finish () { 49 | # printf '%s' "${terminfo[rmkx]}" 50 | # } 51 | # zle -N zle-line-init 52 | # zle -N zle-line-finish 53 | #fi 54 | -------------------------------------------------------------------------------- /hosts/addams/modules/kea/helpers.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | ... 4 | }: 5 | let 6 | # Takes a CIDR like "10.9.4.1/22" and returns a list of reverse zones 7 | toReverseZones = 8 | cidr: 9 | let 10 | # Split CIDR into address and prefix 11 | parts = builtins.split "/" cidr; 12 | addr = builtins.elemAt parts 0; 13 | prefix = builtins.fromJSON (builtins.elemAt parts 2); 14 | 15 | # Split address into octets 16 | octets = builtins.split "\\." addr; 17 | firstOctet = builtins.elemAt octets 0; 18 | secondOctet = builtins.elemAt octets 2; 19 | thirdOctet = builtins.fromJSON (builtins.elemAt octets 4); 20 | 21 | # Calculate number of /24 networks (2^(24-prefix) if prefix < 24, else 1) 22 | numNetworks = 23 | if prefix >= 24 then 24 | 1 25 | else if prefix == 23 then 26 | 2 27 | else if prefix == 22 then 28 | 4 29 | else if prefix == 21 then 30 | 8 31 | else if prefix == 20 then 32 | 16 33 | else 34 | 1; # fallback for larger networks 35 | 36 | # Generate list of third octets 37 | thirdOctets = builtins.genList (x: thirdOctet + x) numNetworks; 38 | in 39 | map (third: "${toString third}.${secondOctet}.${firstOctet}.in-addr.arpa.") thirdOctets; 40 | 41 | mkReverseDdns = 42 | keyName: dnsServers: vlans: 43 | let 44 | vlanToReverseDomains = 45 | vlan: 46 | map (zone: { 47 | dns-servers = dnsServers; 48 | key-name = keyName; 49 | name = zone; 50 | }) (toReverseZones vlan.cidr); 51 | 52 | # Combine all VLANs' reverse domains into a single list 53 | allReverseDomains = builtins.concatLists ( 54 | builtins.attrValues (builtins.mapAttrs (name: vlan: vlanToReverseDomains vlan) vlans) 55 | ); 56 | in 57 | allReverseDomains; 58 | 59 | joinList = lib.concatStringsSep ", "; 60 | in 61 | { 62 | inherit 63 | joinList 64 | toReverseZones 65 | mkReverseDdns 66 | ; 67 | } 68 | -------------------------------------------------------------------------------- /hosts/addams/modules/kea/ddns.nix: -------------------------------------------------------------------------------- 1 | { lib, config, ... }: 2 | let 3 | dhcpLib = import ./helpers.nix { inherit lib; }; 4 | keaddnsUser = "kea"; 5 | 6 | pdnsServer = [ 7 | { 8 | ip-address = "127.0.0.1"; 9 | port = 8853; 10 | } 11 | ]; 12 | 13 | vlans = [ 14 | "local" 15 | "guest" 16 | "prim" 17 | "mgmt" 18 | "data" 19 | #"iot" 20 | #"not" 21 | ]; 22 | in 23 | { 24 | # add user, needed to access the secret 25 | users = { 26 | users.${keaddnsUser} = { 27 | isSystemUser = true; 28 | group = keaddnsUser; 29 | }; 30 | groups.${keaddnsUser} = { }; 31 | }; 32 | 33 | sops.secrets."kea/tsig-key" = { 34 | owner = keaddnsUser; 35 | group = keaddnsUser; 36 | }; 37 | 38 | services.kea = { 39 | dhcp4.settings = { 40 | dhcp-ddns.enable-updates = true; 41 | ddns-replace-client-name = "when-not-present"; 42 | ddns-update-on-renew = true; # always update when a lease is renewed, in case I lost the DNS server database 43 | ddns-override-client-update = true; # always generate ddns update request ignoring the client's wishes not to 44 | ddns-override-no-update = true; # same as above but for different client's wishes 45 | }; 46 | dhcp-ddns = { 47 | enable = true; 48 | settings = { 49 | tsig-keys = [ 50 | { 51 | name = "kea"; 52 | algorithm = "hmac-sha512"; 53 | secret-file = "${config.sops.secrets."kea/tsig-key".path}"; 54 | } 55 | ]; 56 | forward-ddns = { 57 | ddns-domains = [ 58 | { 59 | name = "${config.repo.secrets.global.domain.home}."; 60 | key-name = "kea"; 61 | dns-servers = pdnsServer; 62 | } 63 | ]; 64 | }; 65 | reverse-ddns = { 66 | ddns-domains = map (zone: { 67 | key-name = "kea"; 68 | name = zone; 69 | dns-servers = pdnsServer; 70 | }) config.repo.secrets.local.reverseZones; 71 | }; 72 | }; 73 | }; 74 | }; 75 | } 76 | -------------------------------------------------------------------------------- /modules/desktop/browser/firefox.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.desktop.browsers.firefox; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | firefox-nightly = 16 | inputs.firefox-nightly.packages.${pkgs.stdenv.hostPlatform.system}.firefox-nightly-bin; 17 | firefox-devedition-bin = 18 | inputs.firefox-nightly.packages.${pkgs.stdenv.hostPlatform.system}.firefox-devedition-bin; 19 | firefox = pkgs.firefox-bin; 20 | in 21 | { 22 | options.modules.desktop.browsers.firefox = { 23 | enable = lib.mkEnableOption ""; 24 | }; 25 | config = mkIf cfg.enable { 26 | 27 | environment.systemPackages = [ pkgs.firefoxpwa ]; 28 | 29 | environment.persistence."/persist" = mkIf withImpermanence { 30 | users.${username} = { 31 | directories = [ 32 | ".mozilla/extensions" 33 | ".mozilla/firefox" 34 | ".cache/mozilla/firefox" 35 | ]; 36 | }; 37 | }; 38 | home-manager.users."${username}" = 39 | { pkgs, ... }@hm: 40 | { 41 | #home.packages = [ firefox-devedition-bin ]; 42 | programs.firefox = { 43 | enable = true; 44 | package = firefox; 45 | nativeMessagingHosts = [ pkgs.firefoxpwa ]; 46 | profiles.personal = { 47 | id = 0; 48 | path = "personal"; 49 | settings = { 50 | "browser.tabs.loadInBackground" = true; 51 | }; 52 | }; 53 | 54 | profiles.work = { 55 | id = 1; 56 | path = "work"; 57 | }; 58 | 59 | profiles.dev = { 60 | id = 2; 61 | path = "dev"; 62 | settings = { 63 | # always do a clean start 64 | "browser.sessionstore.resume_from_crash" = false; 65 | }; 66 | }; 67 | }; 68 | }; 69 | }; 70 | } 71 | -------------------------------------------------------------------------------- /modules/services/audiobookshelf.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | utils, 6 | pkgs, 7 | inputs, 8 | globals, 9 | ... 10 | }: 11 | let 12 | cfg = config.modules.services.audiobookshelf; 13 | home-ops = config.repo.secrets.home-ops; 14 | localPath = "/mnt/mali/${cfg.nfsShare}"; 15 | serviceDeps = [ "${utils.escapeSystemdPath localPath}.mount" ]; 16 | in 17 | { 18 | options.modules.services.audiobookshelf = { 19 | enable = lib.mkEnableOption "audiobookshelf"; 20 | domain = lib.mkOption { 21 | type = lib.types.str; 22 | example = "audiobookshelf.example.com"; 23 | description = "The domain to use for the audiobookshelf"; 24 | }; 25 | ingress = lib.mkOption { 26 | type = lib.types.submodule ( 27 | lib.recursiveUpdate (import ./ingress-options.nix { inherit config lib; }) { } 28 | ); 29 | }; 30 | nfsShare = lib.mkOption { type = lib.types.str; }; 31 | user = lib.mkOption { type = lib.types.unspecified; }; 32 | group = lib.mkOption { type = lib.types.unspecified; }; 33 | }; 34 | config = lib.mkIf cfg.enable { 35 | users.users.${cfg.user.name} = { 36 | name = cfg.user.name; 37 | uid = lib.mkForce cfg.user.uid; 38 | isSystemUser = true; 39 | group = lib.mkForce cfg.group.name; 40 | extraGroups = [ "media" ]; 41 | }; 42 | 43 | users.groups.${cfg.group.name} = { 44 | name = cfg.group.name; 45 | gid = lib.mkForce cfg.group.gid; 46 | }; 47 | 48 | fileSystems."${localPath}" = { 49 | device = "${lib.my.cidrToIp config.repo.secrets.global.nodes.mali.dataCIDR}:/mnt/${cfg.nfsShare}"; 50 | fsType = "nfs"; 51 | }; 52 | 53 | modules.zfs.datasets.properties = { 54 | "tank/encrypted/svc/audiobookshelf"."mountpoint" = config.services.audiobookshelf.dataDir; 55 | "tank/encrypted/svc/audiobookshelf"."com.sun:auto-snapshot" = "false"; 56 | }; 57 | 58 | services.audiobookshelf = { 59 | enable = true; 60 | openFirewall = false; 61 | user = cfg.user.name; 62 | group = cfg.group.name; 63 | }; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /modules/services/mariadb.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | cfg = config.modules.services.mariadb; 10 | mysqlUser = config.services.mysql.user; 11 | 12 | serviceDeps = [ 13 | "var-lib-mysql.mount" 14 | "zfs-datasets.service" 15 | ]; 16 | in 17 | { 18 | options.modules.services.mariadb = { 19 | enable = lib.mkEnableOption "mariadb"; 20 | package = lib.mkOption { 21 | type = lib.types.package; 22 | }; 23 | }; 24 | 25 | config = lib.mkIf cfg.enable { 26 | 27 | services.mysql = { 28 | enable = true; 29 | package = cfg.package; 30 | dataDir = "/var/lib/mysql/data"; 31 | settings = { 32 | mysqld = { 33 | skip-innodb_doublewrite = true; 34 | innodb_flush_method = "fsync"; 35 | innodb_doublewrite = 0; 36 | innodb_use_atomic_writes = 0; 37 | innodb_use_native_aio = 0; 38 | innodb_read_io_threads = 10; 39 | innodb_write_io_threads = 10; 40 | innodb_buffer_pool_size = "4G"; 41 | innodb_flush_log_at_trx_commit = 1; 42 | innodb_log_file_size = "1G"; 43 | innodb_flush_neighbors = 0; 44 | innodb_fast_shutdown = 2; 45 | }; 46 | }; 47 | }; 48 | 49 | systemd.services.mysql.requires = serviceDeps; 50 | systemd.services.mysql.wants = serviceDeps; 51 | 52 | # services.mysqlBackup = { 53 | # enable = true; 54 | # location = "/var/backup/mysql"; 55 | # calendar = "11:00:00"; 56 | # singleTransaction = true; 57 | # }; 58 | 59 | modules.zfs.datasets.properties = { 60 | "rpool/encrypted/safe/svc/mariadb"."mountpoint" = "/var/lib/mysql"; 61 | "rpool/encrypted/safe/svc/mariadb"."com.sun:auto-snapshot" = "false"; 62 | "rpool/encrypted/safe/svc/mariadb"."recordsize" = "16k"; 63 | "rpool/encrypted/safe/svc/mariadb"."primarycache" = "all"; 64 | "rpool/encrypted/safe/svc/mariadb"."logbias" = "throughput"; 65 | }; 66 | systemd.tmpfiles.rules = [ "z /var/lib/mysql 750 ${mysqlUser} ${mysqlUser}" ]; 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /hosts/debord/prometheus.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | let 8 | inherit (config.repo.secrets.global) domain; 9 | 10 | smartPort = toString config.services.prometheus.exporters.smartctl.port; 11 | zfsPort = toString config.services.prometheus.exporters.zfs.port; 12 | nutPort = toString config.services.prometheus.exporters.nut.port; 13 | ipmiPort = toString config.services.prometheus.exporters.ipmi.port; 14 | nodePort = toString config.services.prometheus.exporters.node.port; 15 | zreplPort = toString config.repo.secrets.home-ops.ports.zrepl-metrics; 16 | 17 | mkStaticConfig = (port: host: { targets = [ "${host}.mgmt.${domain.home}:${port}" ]; }); 18 | mkStaticConfigs = port: hosts: map (mkStaticConfig port) hosts; 19 | in 20 | { 21 | modules.telemetry.prometheus.enable = true; 22 | modules.telemetry.thanos.enable = true; 23 | services.prometheus.scrapeConfigs = 24 | [ 25 | { 26 | job_name = "node"; 27 | static_configs = mkStaticConfigs nodePort [ 28 | "dewey" 29 | "debord" 30 | "mali" 31 | "addams" 32 | ]; 33 | 34 | } 35 | { 36 | job_name = "smartd"; 37 | static_configs = mkStaticConfigs smartPort [ 38 | "dewey" 39 | "debord" 40 | "mali" 41 | "addams" 42 | ]; 43 | } 44 | { 45 | job_name = "zfs"; 46 | static_configs = mkStaticConfigs zfsPort [ 47 | "dewey" 48 | "debord" 49 | "mali" 50 | "addams" 51 | ]; 52 | } 53 | { 54 | job_name = "nut"; 55 | static_configs = mkStaticConfigs nutPort [ "mali" ]; 56 | } 57 | { 58 | job_name = "ipmi"; 59 | static_configs = mkStaticConfigs ipmiPort [ "mali" ]; 60 | } 61 | ] 62 | ++ (map 63 | (host: { 64 | job_name = "zrepl_${host}"; 65 | static_configs = mkStaticConfigs zreplPort [ 66 | host 67 | ]; 68 | }) 69 | [ 70 | "dewey" 71 | "debord" 72 | "mali" 73 | ] 74 | ); 75 | } 76 | -------------------------------------------------------------------------------- /pkgs/invoiceninja/package.nix: -------------------------------------------------------------------------------- 1 | { 2 | stdenv, 3 | lib, 4 | fetchurl, 5 | dataDir ? "/var/lib/invoiceninja", 6 | runtimeDir ? "/run/invoiceninja", 7 | }: 8 | 9 | stdenv.mkDerivation (finalAttrs: { 10 | pname = "invoiceninja"; 11 | version = "5.10.43"; 12 | 13 | src = fetchurl { 14 | url = "https://github.com/invoiceninja/invoiceninja/releases/download/v${finalAttrs.version}/invoiceninja.tar"; 15 | hash = "sha256-nFO9nZOy3gFP+gm2JpGqwMWhMQ2gaLrJCmXUj8RVp6c="; 16 | }; 17 | 18 | sourceRoot = "."; 19 | 20 | patchFlags = [ "-p0" ]; 21 | patches = [ 22 | # support connection redis with unix domain sockets 23 | # upstream has not yet accepted this patch 24 | ./invoiceninja-redis.patch 25 | ]; 26 | 27 | installPhase = '' 28 | runHook preInstall 29 | 30 | mkdir -p $out/share/invoiceninja 31 | cp -r . $out/share/invoiceninja 32 | 33 | pushd $out/share/invoiceninja 34 | chmod +x artisan 35 | mv bootstrap bootstrap-static 36 | mv storage storage-static 37 | mv resources resources-static 38 | ln -s ${dataDir}/.env $out/share/invoiceninja 39 | ln -s ${dataDir}/storage $out/share/invoiceninja 40 | ln -s ${dataDir}/storage-public $out/share/invoiceninja/public/storage 41 | ln -s ${runtimeDir}/bootstrap $out/share/invoiceninja/bootstrap 42 | ln -s ${runtimeDir}/resources $out/share/invoiceninja/resources 43 | popd 44 | 45 | # Create standard directory structure 46 | #mkdir -p $out/bin 47 | 48 | # Create wrapper script 49 | #cat > $out/bin/invoiceninja <p! :action ActivateTerminalToolWindow 3 | vnoremap p! :action ActivateTerminalToolWindow 4 | 5 | " Toggle between implementation file and its test file 6 | nnoremap pa :action GotoTest 7 | vnoremap pa :action GotoTest 8 | 9 | " Switch among recently opened files 10 | nnoremap pb :action RecentFiles 11 | vnoremap pb :action RecentFiles 12 | nnoremap ph :action RecentFiles 13 | vnoremap ph :action RecentFiles 14 | nnoremap pr :action RecentFiles 15 | vnoremap pr :action RecentFiles 16 | 17 | " Make project 18 | nnoremap pc :action CompileDirty 19 | vnoremap pc :action CompileDirty 20 | 21 | " Focus on project window. 22 | " Sadly when you are inside the project window this key binding does not work 23 | " anymore. You can use if you want to close the window or if you 24 | " want to leave the window opened and focus on the code. 25 | nnoremap pD :action ActivateProjectToolWindow 26 | vnoremap pD :action ActivateProjectToolWindow 27 | nnoremap pt :action ActivateProjectToolWindow 28 | vnoremap pt :action ActivateProjectToolWindow 29 | 30 | " Find files 31 | nnoremap pf :action GotoFile 32 | vnoremap pf :action GotoFile 33 | 34 | " Invalidate cache 35 | nnoremap pI :action InvalidateCaches 36 | vnoremap pI :action InvalidateCaches 37 | 38 | " Recent projects 39 | nnoremap pp :action ManageRecentProjects 40 | vnoremap pp :action ManageRecentProjects 41 | 42 | " Replace in path 43 | nnoremap pR :action ReplaceInPath 44 | vnoremap pR :action ReplaceInPath 45 | 46 | " Rerun tests 47 | nnoremap pT :action RerunTests 48 | vnoremap pT :action RerunTests 49 | 50 | " Show local changes (git status) 51 | nnoremap pv :action Vcs.Show.Local.Changes 52 | vnoremap pv :action Vcs.Show.Local.Changes 53 | -------------------------------------------------------------------------------- /flake/pkgs.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | imports = [ 4 | ( 5 | { lib, flake-parts-lib, ... }: 6 | flake-parts-lib.mkTransposedPerSystemModule { 7 | name = "pkgs"; 8 | file = ./pkgs.nix; 9 | option = lib.mkOption { type = lib.types.unspecified; }; 10 | } 11 | ) 12 | ]; 13 | perSystem = 14 | { pkgs, system, ... }: 15 | let 16 | # Import our overlays once 17 | ourOverlays = import ../pkgs/default.nix inputs; 18 | 19 | # Extract package names from all overlays 20 | getOverlayPackages = 21 | overlay: 22 | let 23 | # Call the overlay with dummy arguments to extract attribute names 24 | # Since the overlay just returns an attrset of package definitions, 25 | # we can get the keys without actually building anything 26 | dummyPrev = { }; 27 | overlayAttrs = overlay { } dummyPrev; 28 | in 29 | builtins.attrNames overlayAttrs; 30 | 31 | # Get all package names from all our overlays 32 | ourPackageNames = builtins.concatLists (builtins.map getOverlayPackages ourOverlays); 33 | in 34 | { 35 | _module.args.pkgs = import inputs.nixpkgs { 36 | inherit system; 37 | config.allowUnfree = true; 38 | overlays = ourOverlays ++ [ inputs.nixos-extra-modules.overlays.default ]; 39 | }; 40 | 41 | inherit pkgs; 42 | 43 | # Export packages for flake consumers 44 | packages = 45 | # Export each package that exists in pkgs 46 | builtins.listToAttrs ( 47 | builtins.filter (item: item != null) ( 48 | builtins.map ( 49 | name: 50 | if pkgs ? ${name} then 51 | { 52 | inherit name; 53 | value = pkgs.${name}; 54 | } 55 | else 56 | null 57 | ) ourPackageNames 58 | ) 59 | ); 60 | 61 | # Optionally, also export as legacyPackages if you want to expose 62 | # the entire modified pkgs set (useful for consumers who want access 63 | # to all packages with your overlays applied) 64 | legacyPackages = pkgs; 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /modules/shell/zellij/default.nix: -------------------------------------------------------------------------------- 1 | { 2 | options, 3 | config, 4 | lib, 5 | pkgs, 6 | inputs, 7 | ... 8 | }: 9 | with lib; 10 | let 11 | cfg = config.modules.shell.zellij; 12 | username = config.modules.users.primaryUser.username; 13 | homeDirectory = config.modules.users.primaryUser.homeDirectory; 14 | withImpermanence = config.modules.impermanence.enable; 15 | in 16 | { 17 | options.modules.shell.zellij = { 18 | enable = lib.mkEnableOption ""; 19 | web = { 20 | enable = lib.mkEnableOption ""; 21 | ip = lib.mkOption { 22 | type = lib.types.str; 23 | default = "127.0.0.1"; 24 | }; 25 | port = lib.mkOption { 26 | type = types.int; 27 | default = 8082; 28 | }; 29 | }; 30 | }; 31 | config = mkIf cfg.enable { 32 | myhm = { 33 | home.file.".config/zellij/config.kdl".source = ./config.kdl; 34 | home.packages = with pkgs; [ zellij ]; 35 | systemd.user.services.zellij-web = lib.mkIf cfg.web.enable { 36 | Unit = { 37 | Description = "Zellij Web (browser access to sessions)"; 38 | After = [ "network-online.target" ]; 39 | Wants = [ "network-online.target" ]; 40 | }; 41 | Service = { 42 | Type = "simple"; 43 | ExecStart = ''${pkgs.zellij}/bin/zellij web --start --ip ${cfg.web.ip} --port ${toString cfg.web.port}''; 44 | Restart = "on-failure"; 45 | RestartSec = 2; 46 | }; 47 | Install.WantedBy = [ "default.target" ]; 48 | }; 49 | }; 50 | 51 | systemd.services.tailscale-serve = 52 | lib.mkIf (cfg.web.enable && config.modules.vpn.tailscale.enable) 53 | { 54 | description = "zellij tailscale sserve"; 55 | after = [ 56 | "network-pre.target" 57 | "tailscale.service" 58 | ]; 59 | wants = [ 60 | "network-pre.target" 61 | "tailscale.service" 62 | ]; 63 | wantedBy = [ "multi-user.target" ]; 64 | serviceConfig.Type = "simple"; 65 | serviceConfig.Restart = "on-failure"; 66 | script = with pkgs; '' 67 | sleep 2 68 | ${tailscale}/bin/tailscale serve ${toString cfg.web.port}; 69 | ''; 70 | }; 71 | }; 72 | } 73 | --------------------------------------------------------------------------------