From d0fb48d1b0c4a67cd1d73206ef1073c0c64279b1 Mon Sep 17 00:00:00 2001 From: Danilo Reyes Date: Wed, 1 Oct 2025 13:40:05 -0600 Subject: [PATCH] initial commit --- .github/workflows/weekly-build-cache.yml | 99 ++ .gitignore | 4 + .sops.yaml | 48 + config/base.nix | 189 +++ config/home-manager.nix | 89 ++ config/jawz.nix | 180 +++ config/overlay.nix | 42 + config/schemes.nix | 108 ++ config/stylix.nix | 52 + dotfiles/doom/bookmarks | 10 + dotfiles/doom/config.org | 1076 ++++++++++++++ dotfiles/doom/custom.el | 21 + dotfiles/doom/init.el | 192 +++ dotfiles/doom/packages.el | 96 ++ dotfiles/doom/templates/default.org | 1 + dotfiles/doom/templates/events.org | 21 + dotfiles/doom/templates/programming.org | 13 + dotfiles/gallery-dl.nix | 203 +++ dotfiles/npmrc | 7 + dotfiles/pythonrc | 17 + dotfiles/stignore | 7 + dotfiles/unpackerr.conf | 222 +++ environments/cinnamon.nix | 21 + environments/gnome.nix | 45 + environments/hyprland.nix | 109 ++ flake.lock | 1259 +++++++++++++++++ flake.nix | 130 ++ hosts/emacs/configuration.nix | 49 + hosts/galaxy/configuration.nix | 7 + hosts/miniserver/configuration.nix | 52 + hosts/miniserver/hardware-configuration.nix | 139 ++ hosts/miniserver/toggles.nix | 50 + hosts/server/configuration.nix | 74 + hosts/server/hardware-configuration.nix | 187 +++ hosts/server/toggles.nix | 92 ++ hosts/workstation/configuration.nix | 173 +++ hosts/workstation/hardware-configuration.nix | 144 ++ hosts/workstation/toggles.nix | 51 + modules/apps/art.nix | 44 + modules/apps/dictionaries.nix | 21 + modules/apps/fonts.nix | 44 + modules/apps/gaming.nix | 60 + modules/apps/internet.nix | 56 + modules/apps/librewolf.nix | 79 ++ modules/apps/misc.nix | 20 + modules/apps/multimedia.nix | 25 + modules/apps/music.nix | 18 + modules/apps/office.nix | 22 + modules/dev/cc.nix | 36 + modules/dev/docker.nix | 38 + modules/dev/emacs.nix | 73 + modules/dev/go.nix | 44 + modules/dev/haskell.nix | 46 + modules/dev/javascript.nix | 50 + modules/dev/julia.nix | 30 + modules/dev/nix.nix | 43 + modules/dev/python.nix | 56 + modules/dev/ruby.nix | 40 + modules/dev/rust.nix | 41 + modules/dev/sh.nix | 36 + modules/dev/zig.nix | 33 + modules/factories/mkscript.nix | 80 ++ modules/factories/mkserver.nix | 110 ++ modules/modules.nix | 196 +++ modules/network/firewall.nix | 55 + modules/network/nginx.nix | 60 + modules/nix/build.nix | 47 + modules/nix/gitea-actions-runners/nixos.nix | 32 + modules/nix/gitea-actions-runners/ryujinx.nix | 59 + modules/scripts/download.nix | 121 ++ modules/scripts/ffmpeg4discord.nix | 11 + modules/scripts/ffmpreg.nix | 11 + modules/scripts/find-dup-episode.nix | 11 + modules/scripts/library-report.nix | 11 + modules/scripts/manage-library.nix | 13 + modules/scripts/pika-list.nix | 11 + modules/scripts/run.nix | 11 + modules/scripts/split-dir.nix | 11 + modules/scripts/stream-dl.nix | 60 + modules/scripts/tasks.nix | 13 + modules/scripts/tuh-activity-logger.nix | 13 + modules/scripts/update-dns.nix | 51 + modules/scripts/update-org-agenda-cache.nix | 22 + modules/servers/adguardhome.nix | 13 + modules/servers/atticd.nix | 33 + modules/servers/audiobookshelf.nix | 16 + modules/servers/bazarr.nix | 12 + modules/servers/drpp.nix | 19 + modules/servers/firefly-iii.nix | 25 + modules/servers/firefox-syncserver.nix | 23 + modules/servers/flame.nix | 47 + modules/servers/gitea.nix | 42 + modules/servers/homepage.nix | 35 + modules/servers/homepage/bookmarks/art.nix | 49 + .../homepage/bookmarks/development.nix | 49 + .../homepage/bookmarks/entertainment.nix | 49 + .../servers/homepage/bookmarks/secret-art.nix | 67 + .../homepage/bookmarks/secret-media.nix | 67 + .../homepage/bookmarks/secret-social.nix | 67 + .../servers/homepage/bookmarks/servers.nix | 58 + .../servers/homepage/bookmarks/shopping.nix | 49 + modules/servers/homepage/bookmarks/social.nix | 49 + .../servers/homepage/bookmarks/torrents.nix | 49 + modules/servers/homepage/layout.nix | 46 + modules/servers/homepage/service-widgets.nix | 263 ++++ modules/servers/homepage/services.nix | 39 + modules/servers/homepage/widgets.nix | 35 + modules/servers/jellyfin.nix | 117 ++ modules/servers/kavita.nix | 26 + modules/servers/lidarr.nix | 31 + modules/servers/maloja.nix | 25 + modules/servers/mealie.nix | 28 + modules/servers/metube.nix | 22 + modules/servers/microbin.nix | 20 + modules/servers/multi-scrobbler.nix | 27 + modules/servers/nextcloud.nix | 289 ++++ modules/servers/nix-serve.nix | 21 + modules/servers/ombi.nix | 11 + modules/servers/paperless.nix | 30 + modules/servers/plex-discord-bot.nix | 20 + modules/servers/plex.nix | 52 + modules/servers/portfolio.nix | 22 + modules/servers/postgres.nix | 65 + modules/servers/prowlarr.nix | 26 + modules/servers/qbittorrent.nix | 134 ++ modules/servers/radarr.nix | 14 + modules/servers/readeck.nix | 25 + modules/servers/ryot.nix | 23 + modules/servers/sabnzbd.nix | 20 + modules/servers/shiori.nix | 16 + modules/servers/sonarr.nix | 12 + modules/servers/synapse.nix | 127 ++ modules/servers/tranga.nix | 28 + modules/servers/vaultwarden.nix | 34 + modules/services/msmtp.nix | 25 + modules/services/network.nix | 50 + modules/services/nvidia.nix | 36 + modules/services/printing.nix | 26 + modules/services/sound.nix | 25 + modules/services/wireguard.nix | 53 + modules/shell/config.nix | 20 + modules/shell/exercism.nix | 17 + modules/shell/multimedia.nix | 33 + modules/shell/tools.nix | 122 ++ modules/users/nixremote.nix | 37 + patches/libpng.patch | 15 + secrets/certs.yaml | 61 + secrets/env.yaml | 58 + secrets/homepage.yaml | 43 + secrets/keys.yaml | 84 ++ secrets/secrets.yaml | 56 + secrets/ssh/ed25519_deacero.pub | 1 + secrets/ssh/ed25519_emacs.pub | 1 + secrets/ssh/ed25519_galaxy.pub | 1 + secrets/ssh/ed25519_miniserver.pub | 1 + secrets/ssh/ed25519_nixminiserver.pub | 1 + secrets/ssh/ed25519_nixserver.pub | 1 + secrets/ssh/ed25519_nixworkstation.pub | 1 + secrets/ssh/ed25519_phone.pub | 1 + secrets/ssh/ed25519_server.pub | 1 + secrets/ssh/ed25519_vps.pub | 1 + secrets/ssh/ed25519_workstation.pub | 1 + secrets/ssh/iqQCY4iAWO-ca.pem | 21 + secrets/ssh/root-private-ca.pem | 32 + secrets/wireguard.yaml | 52 + 165 files changed, 10586 insertions(+) create mode 100644 .github/workflows/weekly-build-cache.yml create mode 100644 .gitignore create mode 100644 .sops.yaml create mode 100644 config/base.nix create mode 100644 config/home-manager.nix create mode 100644 config/jawz.nix create mode 100644 config/overlay.nix create mode 100644 config/schemes.nix create mode 100644 config/stylix.nix create mode 100644 dotfiles/doom/bookmarks create mode 100755 dotfiles/doom/config.org create mode 100644 dotfiles/doom/custom.el create mode 100755 dotfiles/doom/init.el create mode 100755 dotfiles/doom/packages.el create mode 100755 dotfiles/doom/templates/default.org create mode 100644 dotfiles/doom/templates/events.org create mode 100755 dotfiles/doom/templates/programming.org create mode 100644 dotfiles/gallery-dl.nix create mode 100644 dotfiles/npmrc create mode 100644 dotfiles/pythonrc create mode 100644 dotfiles/stignore create mode 100644 dotfiles/unpackerr.conf create mode 100644 environments/cinnamon.nix create mode 100644 environments/gnome.nix create mode 100644 environments/hyprland.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 hosts/emacs/configuration.nix create mode 100644 hosts/galaxy/configuration.nix create mode 100644 hosts/miniserver/configuration.nix create mode 100644 hosts/miniserver/hardware-configuration.nix create mode 100644 hosts/miniserver/toggles.nix create mode 100644 hosts/server/configuration.nix create mode 100644 hosts/server/hardware-configuration.nix create mode 100644 hosts/server/toggles.nix create mode 100644 hosts/workstation/configuration.nix create mode 100644 hosts/workstation/hardware-configuration.nix create mode 100644 hosts/workstation/toggles.nix create mode 100644 modules/apps/art.nix create mode 100644 modules/apps/dictionaries.nix create mode 100644 modules/apps/fonts.nix create mode 100644 modules/apps/gaming.nix create mode 100644 modules/apps/internet.nix create mode 100644 modules/apps/librewolf.nix create mode 100644 modules/apps/misc.nix create mode 100644 modules/apps/multimedia.nix create mode 100644 modules/apps/music.nix create mode 100644 modules/apps/office.nix create mode 100644 modules/dev/cc.nix create mode 100644 modules/dev/docker.nix create mode 100644 modules/dev/emacs.nix create mode 100644 modules/dev/go.nix create mode 100644 modules/dev/haskell.nix create mode 100644 modules/dev/javascript.nix create mode 100644 modules/dev/julia.nix create mode 100644 modules/dev/nix.nix create mode 100644 modules/dev/python.nix create mode 100644 modules/dev/ruby.nix create mode 100644 modules/dev/rust.nix create mode 100644 modules/dev/sh.nix create mode 100644 modules/dev/zig.nix create mode 100644 modules/factories/mkscript.nix create mode 100644 modules/factories/mkserver.nix create mode 100644 modules/modules.nix create mode 100644 modules/network/firewall.nix create mode 100644 modules/network/nginx.nix create mode 100644 modules/nix/build.nix create mode 100644 modules/nix/gitea-actions-runners/nixos.nix create mode 100644 modules/nix/gitea-actions-runners/ryujinx.nix create mode 100644 modules/scripts/download.nix create mode 100644 modules/scripts/ffmpeg4discord.nix create mode 100644 modules/scripts/ffmpreg.nix create mode 100644 modules/scripts/find-dup-episode.nix create mode 100644 modules/scripts/library-report.nix create mode 100644 modules/scripts/manage-library.nix create mode 100644 modules/scripts/pika-list.nix create mode 100644 modules/scripts/run.nix create mode 100644 modules/scripts/split-dir.nix create mode 100644 modules/scripts/stream-dl.nix create mode 100644 modules/scripts/tasks.nix create mode 100644 modules/scripts/tuh-activity-logger.nix create mode 100644 modules/scripts/update-dns.nix create mode 100644 modules/scripts/update-org-agenda-cache.nix create mode 100644 modules/servers/adguardhome.nix create mode 100644 modules/servers/atticd.nix create mode 100644 modules/servers/audiobookshelf.nix create mode 100644 modules/servers/bazarr.nix create mode 100644 modules/servers/drpp.nix create mode 100644 modules/servers/firefly-iii.nix create mode 100644 modules/servers/firefox-syncserver.nix create mode 100644 modules/servers/flame.nix create mode 100644 modules/servers/gitea.nix create mode 100644 modules/servers/homepage.nix create mode 100644 modules/servers/homepage/bookmarks/art.nix create mode 100644 modules/servers/homepage/bookmarks/development.nix create mode 100644 modules/servers/homepage/bookmarks/entertainment.nix create mode 100644 modules/servers/homepage/bookmarks/secret-art.nix create mode 100644 modules/servers/homepage/bookmarks/secret-media.nix create mode 100644 modules/servers/homepage/bookmarks/secret-social.nix create mode 100644 modules/servers/homepage/bookmarks/servers.nix create mode 100644 modules/servers/homepage/bookmarks/shopping.nix create mode 100644 modules/servers/homepage/bookmarks/social.nix create mode 100644 modules/servers/homepage/bookmarks/torrents.nix create mode 100644 modules/servers/homepage/layout.nix create mode 100644 modules/servers/homepage/service-widgets.nix create mode 100644 modules/servers/homepage/services.nix create mode 100644 modules/servers/homepage/widgets.nix create mode 100644 modules/servers/jellyfin.nix create mode 100644 modules/servers/kavita.nix create mode 100644 modules/servers/lidarr.nix create mode 100644 modules/servers/maloja.nix create mode 100644 modules/servers/mealie.nix create mode 100644 modules/servers/metube.nix create mode 100644 modules/servers/microbin.nix create mode 100644 modules/servers/multi-scrobbler.nix create mode 100644 modules/servers/nextcloud.nix create mode 100644 modules/servers/nix-serve.nix create mode 100644 modules/servers/ombi.nix create mode 100644 modules/servers/paperless.nix create mode 100644 modules/servers/plex-discord-bot.nix create mode 100644 modules/servers/plex.nix create mode 100644 modules/servers/portfolio.nix create mode 100644 modules/servers/postgres.nix create mode 100644 modules/servers/prowlarr.nix create mode 100644 modules/servers/qbittorrent.nix create mode 100644 modules/servers/radarr.nix create mode 100644 modules/servers/readeck.nix create mode 100644 modules/servers/ryot.nix create mode 100644 modules/servers/sabnzbd.nix create mode 100644 modules/servers/shiori.nix create mode 100644 modules/servers/sonarr.nix create mode 100644 modules/servers/synapse.nix create mode 100644 modules/servers/tranga.nix create mode 100644 modules/servers/vaultwarden.nix create mode 100644 modules/services/msmtp.nix create mode 100644 modules/services/network.nix create mode 100644 modules/services/nvidia.nix create mode 100644 modules/services/printing.nix create mode 100644 modules/services/sound.nix create mode 100644 modules/services/wireguard.nix create mode 100644 modules/shell/config.nix create mode 100644 modules/shell/exercism.nix create mode 100644 modules/shell/multimedia.nix create mode 100644 modules/shell/tools.nix create mode 100644 modules/users/nixremote.nix create mode 100644 patches/libpng.patch create mode 100644 secrets/certs.yaml create mode 100644 secrets/env.yaml create mode 100644 secrets/homepage.yaml create mode 100644 secrets/keys.yaml create mode 100644 secrets/secrets.yaml create mode 100644 secrets/ssh/ed25519_deacero.pub create mode 100644 secrets/ssh/ed25519_emacs.pub create mode 100644 secrets/ssh/ed25519_galaxy.pub create mode 100644 secrets/ssh/ed25519_miniserver.pub create mode 100644 secrets/ssh/ed25519_nixminiserver.pub create mode 100644 secrets/ssh/ed25519_nixserver.pub create mode 100644 secrets/ssh/ed25519_nixworkstation.pub create mode 100644 secrets/ssh/ed25519_phone.pub create mode 100644 secrets/ssh/ed25519_server.pub create mode 100644 secrets/ssh/ed25519_vps.pub create mode 100644 secrets/ssh/ed25519_workstation.pub create mode 100644 secrets/ssh/iqQCY4iAWO-ca.pem create mode 100644 secrets/ssh/root-private-ca.pem create mode 100644 secrets/wireguard.yaml diff --git a/.github/workflows/weekly-build-cache.yml b/.github/workflows/weekly-build-cache.yml new file mode 100644 index 0000000..3a16a9a --- /dev/null +++ b/.github/workflows/weekly-build-cache.yml @@ -0,0 +1,99 @@ +name: Weekly NixOS Build & Cache + +on: + schedule: + - cron: "30 09 * * 1,5" + workflow_dispatch: # Allow manual trigger + +jobs: + build-and-cache: + runs-on: nixos + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure Git for automated commits + run: | + git config user.name "NixOS Builder Bot" + git config user.email "noreply@servidos.lat" + + - name: Update flake inputs + run: | + nix flake update + + - name: Check for changes + id: check_changes + run: | + if git diff --quiet flake.lock; then + echo "changes=false" >> $GITHUB_OUTPUT + echo "No changes in flake.lock" + else + echo "changes=true" >> $GITHUB_OUTPUT + echo "Changes detected in flake.lock" + fi + + - name: Configure Attic cache + if: steps.check_changes.outputs.changes == 'true' + run: | + # Configure attic client to use your cache server + attic login servidos https://cache.servidos.lat ${{ secrets.ATTIC_TOKEN }} + + - name: Build workstation configuration + if: steps.check_changes.outputs.changes == 'true' + run: | + echo "Building workstation configuration..." + nix build .#nixosConfigurations.workstation.config.system.build.toplevel --quiet + + - name: Build server configuration + if: steps.check_changes.outputs.changes == 'true' + run: | + echo "Building server configuration..." + nix build .#nixosConfigurations.server.config.system.build.toplevel --quiet + + - name: Build emacs-vm configuration + if: steps.check_changes.outputs.changes == 'true' + run: | + echo "Building emacs-vm configuration..." + nix build .#emacs-vm --quiet + + - name: Push to cache + if: steps.check_changes.outputs.changes == 'true' + run: | + echo "Pushing builds to cache..." + # Push all built derivations to cache + if ls result* 1> /dev/null 2>&1; then + attic push servidos:nixos result* + fi + + # Push the specific system derivations we just built + nix build .#nixosConfigurations.workstation.config.system.build.toplevel --print-out-paths | attic push servidos:nixos --stdin + nix build .#nixosConfigurations.server.config.system.build.toplevel --print-out-paths | attic push servidos:nixos --stdin + nix build .#emacs-vm --print-out-paths | attic push servidos:nixos --stdin + + - name: Commit updated flake.lock + if: steps.check_changes.outputs.changes == 'true' + run: | + git add flake.lock + git commit -m "Weekly flake update: $(date -u '+%Y-%m-%d %H:%M UTC')" + git push origin main + + - name: Create release tag + if: steps.check_changes.outputs.changes == 'true' + run: | + TAG_NAME="weekly-$(date -u '+%Y-%m-%d')" + git tag -a "$TAG_NAME" -m "Weekly build and cache update for $(date -u '+%Y-%m-%d')" + git push origin "$TAG_NAME" + + - name: Summary + run: | + if [[ "${{ steps.check_changes.outputs.changes }}" == "true" ]]; then + echo "✅ Weekly build completed successfully!" + echo "- Updated flake.lock" + echo "- Built workstation and server configurations" + echo "- Pushed builds to Atticd cache" + echo "- Committed changes and created release tag" + else + echo "ℹ️ No updates needed - flake.lock is already up to date" + fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b3423f2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.direnv +config.el +*.qcow2 +result diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..19beac9 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,48 @@ +keys: + - &devkey age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37 + - &workstation age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz + - &server age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5 + - &miniserver age13w4elx3x6afrte2d82lak59mwr2k25wfz3hx79tny6sfdk66lqjq989dzl +creation_rules: + - path_regex: secrets/secrets.yaml$ + key_groups: + - age: + - *devkey + - *workstation + - *server + - *miniserver + - path_regex: secrets/keys.yaml$ + key_groups: + - age: + - *devkey + - *workstation + - *server + - *miniserver + - path_regex: secrets/env.yaml$ + key_groups: + - age: + - *devkey + - *workstation + - *server + - *miniserver + - path_regex: secrets/wireguard.yaml$ + key_groups: + - age: + - *devkey + - *workstation + - *server + - *miniserver + - path_regex: secrets/homepage.yaml$ + key_groups: + - age: + - *devkey + - *workstation + - *server + - *miniserver + - path_regex: secrets/certs.yaml$ + key_groups: + - age: + - *devkey + - *workstation + - *server + - *miniserver diff --git a/config/base.nix b/config/base.nix new file mode 100644 index 0000000..ef08ea8 --- /dev/null +++ b/config/base.nix @@ -0,0 +1,189 @@ +{ + lib, + pkgs, + inputs, + outputs, + config, + ... +}: +{ + imports = [ + inputs.home-manager.nixosModules.home-manager + ./jawz.nix + ../modules/modules.nix + ]; + system.stateVersion = "23.05"; + sops = { + defaultSopsFormat = "yaml"; + defaultSopsFile = ../secrets/secrets.yaml; + age = { + sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + keyFile = "/var/lib/sops-nix/key.txt"; + generateKey = true; + }; + }; + home-manager = { + backupFileExtension = "hbckup"; + useUserPackages = true; + useGlobalPkgs = true; + extraSpecialArgs = { + inherit inputs outputs; + }; + users.jawz = import ./home-manager.nix; + }; + time = { + inherit (config.my) timeZone; + hardwareClockInLocalTime = true; + }; + i18n = { + defaultLocale = "en_CA.UTF-8"; + extraLocaleSettings = { + LC_MONETARY = "es_MX.UTF-8"; + }; + }; + console = { + font = "Lat2-Terminus16"; + keyMap = "us"; + }; + security = { + polkit.enable = true; + sudo = { + enable = true; + wheelNeedsPassword = false; + }; + pam.loginLimits = [ + { + domain = "*"; + type = "soft"; + item = "nofile"; + value = "8192"; + } + ]; + }; + users = { + mutableUsers = false; + groups = { + users.gid = 100; + piracy.gid = 985; + }; + }; + nixpkgs.config = { + allowUnfree = true; + permittedInsecurePackages = [ + "aspnetcore-runtime-wrapped-6.0.36" + "aspnetcore-runtime-6.0.36" + "dotnet-runtime-6.0.36" + "dotnet-sdk-wrapped-6.0.428" + "dotnet-sdk-6.0.428" + ]; + }; + nix = { + distributedBuilds = true; + optimise.automatic = true; + settings = { + use-xdg-base-directories = true; + auto-optimise-store = true; + trusted-users = [ + "jawz" + "root" + "nixremote" + ]; + experimental-features = [ + "nix-command" + "flakes" + "pipe-operators" + ]; + substituters = [ + "${config.my.servers.atticd.url}/nixos" + "https://nix-gaming.cachix.org" + "https://nixpkgs-python.cachix.org" + "https://devenv.cachix.org" + "https://cuda-maintainers.cachix.org" + "https://ai.cachix.org" + "https://cache.lix.systems" + "https://cosmic.cachix.org" + ]; + trusted-public-keys = [ + "nixos:kubuWhYCk9/aZp5GDJFAScYgigM66DszP8i1Pzbq0Fc=" + "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + "nixpkgs-python.cachix.org-1:hxjI7pFxTyuTHn2NkvWCrAUcNZLNS3ZAvfYNuYifcEU=" + "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" + "cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E=" + "ai.cachix.org-1:N9dzRK+alWwoKXQlnn0H6aUx0lU/mspIoz8hMvGvbbc=" + "cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o=" + "cosmic.cachix.org-1:Dya9IyXD4xdBehWjrkPv6rtxpmMdRel02smYzA85dPE=" + ]; + }; + }; + documentation.enable = false; + environment = { + systemPackages = builtins.attrValues { + inherit (pkgs) + wget + sops + ; + }; + variables = + let + XDG_DATA_HOME = "\${HOME}/.local/share"; + XDG_CONFIG_HOME = "\${HOME}/.config"; + XDG_CACHE_HOME = "\${HOME}/.cache"; + in + { + # PATH + inherit XDG_DATA_HOME XDG_CONFIG_HOME XDG_CACHE_HOME; + XDG_BIN_HOME = "\${HOME}/.local/bin"; + XDG_STATE_HOME = "\${HOME}/.local/state"; + # DEV PATH + PSQL_HISTORY = "${XDG_DATA_HOME}/psql_history"; + REDISCLI_HISTFILE = "${XDG_DATA_HOME}/redis/rediscli_history"; + WINEPREFIX = "${XDG_DATA_HOME}/wine"; + # OPTIONS + ELECTRUMDIR = "${XDG_DATA_HOME}/electrum"; + WGETRC = "${XDG_CONFIG_HOME}/wgetrc"; + XCOMPOSECACHE = "${XDG_CACHE_HOME}/X11/xcompose"; + "_JAVA_OPTIONS" = "-Djava.util.prefs.userRoot=${XDG_CONFIG_HOME}/java"; + ORG_DEVICE = "workstation"; + # WAYLAND + WLR_NO_HARDWARE_CURSORS = 1; + NIXOS_OZONE_WL = 1; + PATH = [ "\${HOME}/.local/bin" ]; + NH_USE_DOAS = 1; + }; + }; + programs = { + nh = { + enable = true; + flake = "/home/jawz/Development/NixOS"; + clean = { + enable = true; + extraArgs = "--keep-since 3d"; + }; + }; + gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + }; + services = { + udev.packages = [ pkgs.yubikey-personalization ]; + smartd.enable = true; + fstrim.enable = true; + avahi = { + enable = true; + nssmdns4 = true; + }; + openssh = { + enable = true; + openFirewall = true; + startWhenNeeded = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "prohibit-password"; + KbdInteractiveAuthentication = false; + }; + }; + }; + fonts.fontconfig.enable = true; + powerManagement.cpuFreqGovernor = lib.mkDefault "performance"; +} diff --git a/config/home-manager.nix b/config/home-manager.nix new file mode 100644 index 0000000..6227852 --- /dev/null +++ b/config/home-manager.nix @@ -0,0 +1,89 @@ +{ + inputs, + config, + pkgs, + lib, + osConfig, + ... +}: +let + inherit (pkgs) fd fzf; + inherit (inputs.jawz-scripts.packages.x86_64-linux) pokemon-colorscripts; + shellType = osConfig.my.shell.type; + commonInit = '' + ${pokemon-colorscripts}/bin/pokemon-colorscripts -r --no-title + export command_timeout=60 + ''; + commonAliases = { + cp = "cp -i"; + mv = "mv -i"; + mkdir = "mkdir -p"; + mkcd = "(){ mkdir -p \"$1\" && cd \"$1\" }"; + copy = "xclip -selection clipboard"; + cdp = "pwd | copy"; + cfp = "(){ readlink -f \"$1\" | copy }"; + ".." = "cd .."; + "..." = "cd ../.."; + ".3" = "cd ../../.."; + ".4" = "cd ../../../.."; + ".5" = "cd ../../../../.."; + c = "cat"; + sc = "systemctl --user"; + jc = "journalctl --user -xefu"; + }; +in +{ + home.stateVersion = "23.05"; + programs = { + direnv = { + enable = true; + enableBashIntegration = shellType == "bash"; + enableZshIntegration = shellType == "zsh"; + nix-direnv.enable = true; + }; + git = { + enable = true; + userName = "Danilo Reyes"; + userEmail = "CaptainJawZ@protonmail.com"; + }; + bash = lib.mkIf (shellType == "bash") { + enable = true; + historyFile = "\${XDG_STATE_HOME}/bash/history"; + shellAliases = commonAliases; + enableVteIntegration = true; + initExtra = commonInit; + historyControl = [ + "erasedups" + "ignorespace" + "ignoredups" + ]; + }; + zsh = lib.mkIf (shellType == "zsh") { + enable = true; + dotDir = ".config/zsh"; + shellAliases = commonAliases; + initContent = commonInit; + history = { + path = "\${XDG_STATE_HOME}/zsh/history"; + expireDuplicatesFirst = true; + ignoreSpace = true; + ignoreAllDups = true; + }; + }; + }; + xdg = { + enable = true; + userDirs = { + enable = true; + createDirectories = false; + desktop = "${config.home.homeDirectory}"; + documents = "${config.home.homeDirectory}/Documents"; + download = "${config.home.homeDirectory}/Downloads"; + music = "${config.home.homeDirectory}/Music"; + pictures = "${config.home.homeDirectory}/Pictures"; + templates = "${config.xdg.dataHome}/Templates"; + videos = "${config.home.homeDirectory}/Videos"; + }; + configFile.wgetrc.text = "hsts-file=\${XDG_CACHE_HOME}/wget-hsts"; + }; +} diff --git a/config/jawz.nix b/config/jawz.nix new file mode 100644 index 0000000..4246225 --- /dev/null +++ b/config/jawz.nix @@ -0,0 +1,180 @@ +{ config, lib, ... }: +let + inherit (config.networking) hostName; + nixosHosts = + lib.attrNames config.my.ips + |> lib.filter ( + name: !(lib.hasPrefix "wg-" name) && name != "vps" && name != "router" && name != hostName + ); + nixosHostsMatch = lib.concatStringsSep " " nixosHosts; +in +{ + sops.secrets = lib.mkIf config.my.secureHost ( + let + baseDir = ".ssh/ed25519"; + keyConfig = file: { + sopsFile = ../secrets/keys.yaml; + owner = config.users.users.jawz.name; + inherit (config.users.users.jawz) group; + path = "/home/jawz/${file}"; + }; + in + { + jawz-password.neededForUsers = true; + "private_keys/${hostName}" = keyConfig "${baseDir}_${hostName}"; + "git_private_keys/${hostName}" = keyConfig "${baseDir}_git"; + "syncthing_keys/${hostName}" = keyConfig ".config/syncthing/key.pem"; + "syncthing_certs/${hostName}" = keyConfig ".config/syncthing/cert.pem"; + "syncthing_password".sopsFile = ../secrets/keys.yaml; + } + ); + home-manager.users.jawz = { + home.file.".librewolf/.stignore".source = ../dotfiles/stignore; + programs.ssh = lib.mkIf config.my.secureHost { + enable = true; + matchBlocks = { + vps = { + hostname = config.my.ips.vps; + user = "fedora"; + port = 3456; + identityFile = config.sops.secrets."private_keys/${hostName}".path; + }; + "${nixosHostsMatch}" = { + user = "jawz"; + identityFile = config.sops.secrets."private_keys/${hostName}".path; + }; + "${config.my.servers.gitea.host} github.com gitlab.com bitbucket.org".identityFile = + config.sops.secrets."git_private_keys/${hostName}".path; + }; + }; + }; + services.syncthing = lib.mkIf config.my.secureHost { + enable = true; + user = "jawz"; + group = "users"; + overrideDevices = true; + overrideFolders = true; + openDefaultPorts = true; + key = config.sops.secrets."syncthing_keys/${hostName}".path; + cert = config.sops.secrets."syncthing_certs/${hostName}".path; + guiAddress = "${config.my.ips."${hostName}"}:8384"; + settings = { + options = { + natEnabled = false; + relaysEnabled = false; + globalAnnounceEnabled = false; + }; + gui = { + user = "jawz"; + password = config.sops.secrets.syncthing_password.path; + }; + devices = { + server.id = "BG6PF7S-KATABWO-7WAZFMX-6YO7IS3-WQTMR3M-VSOSV7V-HFFMNNH-BFX2EQ4"; + miniserver.id = "HDYEGIR-GFU7ONK-MOOJUFH-N3L3XHX-SXWN3FI-O23K6LD-BJENQK5-VIPV2AT"; + workstation.id = "4E4KJ6M-MSTNBVF-D7CNHDW-DUTB3VR-SXKZ4NH-ZKAOMF5-V24JECJ-4STSZAA"; + galaxy.id = "UAZ5YDV-YUFBXOY-QMS6S6R-WPIIKZI-4OPPW5L-G4OVUPO-YW5KFYY-YASRAAV"; + phone.id = "OSOX2VZ-AO2SA3C-BFB6NKF-K6CR6WX-64TDBKW-RRKEKJ4-FKZE5CV-J2RGJAJ"; + wg-friend1 = { + id = "XBIYCD4-EFKS5SK-WFF73CU-P37GXVH-OMWEIA4-6KC5F3L-U5UQWSF-SYNNRQF"; + addresses = [ "tcp://${config.my.ips.wg-friend1}:22000" ]; + introducer = false; + autoAcceptFolders = false; + paused = false; + }; + }; + folders = + let + isMainHost = hostName == "workstation"; + mkMobile = + path: + lib.mkIf isMainHost { + inherit path; + ignorePerms = false; + devices = [ + "galaxy" + "phone" + ]; + }; + in + { + cache = mkMobile "~/Downloads/cache/"; + friends = mkMobile "~/Pictures/artist/friends/"; + forme = mkMobile "~/Pictures/art for me/"; + comfy = mkMobile "~/Development/AI/ComfyUI/output/"; + gdl = { + path = "~/.config/jawz/"; + ignorePerms = false; + devices = [ + "server" + "miniserver" + "workstation" + ]; + }; + librewolf = { + path = "~/.librewolf/"; + ignorePerms = false; + copyOwnershipFromParent = true; + type = if isMainHost then "sendonly" else "receiveonly"; + devices = [ + "server" + "miniserver" + "workstation" + ]; + }; + notes = { + path = "~/Documents/Notes"; + ignorePerms = false; + devices = [ + "galaxy" + "phone" + "server" + "miniserver" + "workstation" + ]; + }; + friend_share = { + path = "~/Pictures/encrypted/friends"; + ignorePerms = false; + type = "sendreceive"; + devices = [ + "server" + "workstation" + "wg-friend1" + ]; + }; + }; + }; + }; + users.users.jawz = { + uid = 1000; + linger = true; + isNormalUser = true; + hashedPasswordFile = lib.mkIf config.my.secureHost config.sops.secrets.jawz-password.path; + hashedPassword = + lib.mkIf (!config.my.secureHost) + "$6$s4kbia4u7xVwCmyo$LCN7.Ki2n3xQOqPKnTwa5idwOWYeMNTieQYbLkiiKcMFkFmK76BjtNofJk3U7yRmLGnW3oFT433.nTRq1aoN.1"; + extraGroups = [ + "wheel" + "networkmanager" + "scanner" + "lp" + "piracy" + "kavita" + "video" + "docker" + "libvirt" + "rslsync" + "plugdev" + "bluetooth" + ]; + openssh.authorizedKeys.keyFiles = [ + ../secrets/ssh/ed25519_deacero.pub + ../secrets/ssh/ed25519_workstation.pub + ../secrets/ssh/ed25519_server.pub + ../secrets/ssh/ed25519_miniserver.pub + ../secrets/ssh/ed25519_galaxy.pub + ../secrets/ssh/ed25519_phone.pub + ../secrets/ssh/ed25519_vps.pub + ]; + }; +} diff --git a/config/overlay.nix b/config/overlay.nix new file mode 100644 index 0000000..4d6849d --- /dev/null +++ b/config/overlay.nix @@ -0,0 +1,42 @@ +{ + mkpkgs, + inputs, + ... +}: +let + pkgs = mkpkgs inputs.nixpkgs; + pkgsU = mkpkgs inputs.nixpkgs-unstable; +in +_final: prev: { + nautilus = prev.nautilus.overrideAttrs (old: { + buildInputs = + old.buildInputs + ++ builtins.attrValues { + inherit (pkgs.gst_all_1) + gst-plugins-good + gst-plugins-bad + ; + }; + }); + lutris = prev.lutris.override { + extraPkgs = + pkgs: + builtins.attrValues { + inherit (pkgs) pango winetricks; + } + ++ (with pkgs; [ + wine64Packages.stable + wineWowPackages.stable + ]); + }; + handbrake = prev.handbrake.override { useGtk = true; }; + ripgrep = prev.ripgrep.override { withPCRE2 = true; }; + discord = prev.discord.override { + withVencord = true; + withOpenASAR = true; + }; + waybar = prev.waybar.overrideAttrs (old: { + mesonFlags = old.mesonFlags ++ [ "-Dexperimental=true" ]; + }); + inherit (pkgsU) symbola mealie flaresolver; +} diff --git a/config/schemes.nix b/config/schemes.nix new file mode 100644 index 0000000..e48f93a --- /dev/null +++ b/config/schemes.nix @@ -0,0 +1,108 @@ +{ pkgs, inputs }: +let + inherit (inputs) wallpapers; + mkScheme = + { + color ? null, + name ? null, + polarity, + image, + iconPackage ? pkgs.papirus-icon-theme.override { inherit color; }, + base16Scheme ? if name != null then "${pkgs.base16-schemes}/share/themes/${name}.yaml" else null, + }: + { + inherit + color + name + polarity + image + iconPackage + base16Scheme + ; + }; +in +{ + schemes = { + vulcano = mkScheme { + name = "mocha"; + color = "brown"; + polarity = "dark"; + image = "${wallpapers}/la_fragua_de_vulcano.jpg"; + }; + who = mkScheme { + name = "catppuccin-frappe"; + polarity = "dark"; + image = "${wallpapers}/Nikolay_Kasatkin_Who.jpeg"; + iconPackage = pkgs.catppuccin-papirus-folders.override { + flavor = "frappe"; + accent = "peach"; + }; + }; + space = mkScheme { + name = "solarflare"; + color = "darkcyan"; + polarity = "dark"; + image = "${wallpapers}/space.jpg"; + }; + jesus = mkScheme { + color = "red"; + name = "equilibrium-light"; + polarity = "light"; + image = "${wallpapers}/jesus.png"; + }; + ballerinas = mkScheme { + color = "brown"; + name = "mocha"; + polarity = "dark"; + image = "${wallpapers}/Waay-Ballerinas.jpeg"; + }; + paul = mkScheme { + color = "green"; + name = "valua"; + polarity = "light"; + image = "${wallpapers}/paul1.jpg"; + base16Scheme = { + base00 = "#1a1f16"; # dark forest floor (was deep green-black) + base01 = "#23291a"; # bark shadow + base02 = "#3c422c"; # damp moss + base03 = "#50573c"; # lichen-streaked rock + base04 = "#767d5e"; # moss + sun mix + base05 = "#a9ae8a"; # dry fern or lichen dust + base06 = "#dfe1d2"; # pale sage + base07 = "#f5f7f0"; # slightly sunlit leaf white + base08 = "#4c7c4a"; # deep fern green + base09 = "#6b8f3c"; # olive bark + base0A = "#b5b938"; # lichen gold + base0B = "#7CC844"; # success green (kept from original) + base0C = "#4fbf87"; # turquoise vine + base0D = "#2aaf6f"; # jungle leaf + base0E = "#88a337"; # mossy lime + base0F = "#5c8b55"; # swamp olive + }; + }; + cheems = mkScheme { + color = "yellow"; + name = "equilibrium-light"; + polarity = "light"; + image = "${wallpapers}/cheems.png"; + base16Scheme = { + base00 = "#f5f0e9"; # very light cream + base01 = "#e8ddd4"; # light beige + base02 = "#d4c4b0"; # warm tan + base03 = "#b8a082"; # golden brown + base04 = "#9c7c5a"; # medium brown + base05 = "#7a5f3f"; # darker brown + base06 = "#5c4328"; # dark brown + base07 = "#3e2d1a"; # very dark brown + base08 = "#d2691e"; # golden orange + base09 = "#cd853f"; # peru + base0A = "#daa520"; # goldenrod + base0B = "#228b22"; # forest green + base0C = "#20b2aa"; # light sea green + base0D = "#4169e1"; # royal blue + base0E = "#8b008b"; # dark magenta + base0F = "#dc143c"; # crimson + }; + }; + }; +} diff --git a/config/stylix.nix b/config/stylix.nix new file mode 100644 index 0000000..bc237db --- /dev/null +++ b/config/stylix.nix @@ -0,0 +1,52 @@ +{ + pkgs, + lib, + config, + inputs, + ... +}: +let + schemesFile = import ./schemes.nix { + inherit pkgs inputs; + }; + scheme = schemesFile.schemes.cheems; + cfg = config.my.stylix; + gnomeEnabled = config.services.xserver.desktopManager.gnome.enable; +in +{ + options.my.stylix.enable = lib.mkEnableOption "system-wide theming with Stylix"; + config = { + stylix = { + inherit (scheme) image polarity; + enable = true; + autoEnable = cfg.enable; + targets.qt.platform = lib.mkForce "qtct"; + } + // lib.optionalAttrs (scheme ? base16Scheme) { inherit (scheme) base16Scheme; }; + home-manager.users.jawz = { + gtk = lib.mkIf (!cfg.enable && gnomeEnabled) { + enable = true; + iconTheme = { + name = "Papirus-Light"; + package = pkgs.papirus-icon-theme.override { + color = "yellow"; + }; + }; + }; + stylix = { + inherit (cfg) enable; + autoEnable = cfg.enable; + iconTheme = { + inherit (cfg) enable; + package = scheme.iconPackage; + light = "Papirus-Light"; + dark = "Papirus-Dark"; + }; + targets.librewolf = { + firefoxGnomeTheme.enable = true; + profileNames = [ "jawz" ]; + }; + }; + }; + }; +} diff --git a/dotfiles/doom/bookmarks b/dotfiles/doom/bookmarks new file mode 100644 index 0000000..97f9da7 --- /dev/null +++ b/dotfiles/doom/bookmarks @@ -0,0 +1,10 @@ +;;;; Emacs Bookmark Format Version 1;;;; -*- coding: utf-8-emacs; mode: lisp-data -*- +;;; This format is meant to be slightly human-readable; +;;; nevertheless, you probably don't want to edit it. +;;; -*- End Of Bookmark File Format Version Stamp -*- +(("org-capture-last-stored" + (filename . "~/Documents/Notes/20240518175854-egypt.org") + (front-context-string) + (rear-context-string . "\n#+title: Egypt\n") + (position . 83)) +) diff --git a/dotfiles/doom/config.org b/dotfiles/doom/config.org new file mode 100755 index 0000000..4d5d1a5 --- /dev/null +++ b/dotfiles/doom/config.org @@ -0,0 +1,1076 @@ +#+AUTHOR: Danilo Reyes (JawZ) +#+STARTUP: content +#+TITLE: JawZ's Doom Emacs config + +* ABOUT THIS CONFIG +This is my personal Doom Emacs config file, forked from DT's config file on +GitLab and modified to fit my personal preferences, plugins, extensions and +other customization settings. + +The purpose of this file, is to have an easy-to-read documentation which +explains why and how each customization works, for future editing and other +friends to use. + +** Resources ++ The following [[https://systemcrafters.net/build-a-second-brain-in-emacs/5-org-roam-hacks/][tutorial]] and [[https://shiori.danilo-reyes.com/bookmark/39/content][archived tutorial]]. ++ [[https://github.com/psamim/dotfiles][Agenda/org prettify stuff]] ++ [[https://gitlab.com/dwt1/dotfiles/-/tree/master/.config/doom][DT's original repo]] + +** Variables +Below are some variables, which effect a lot of paths on the configuration, +putting these variables on top, will make it easier to make this file modular. + +#+begin_src emacs-lisp :tangle ./config.el +(defvar my/org-device (or (getenv "ORG_DEVICE") "default")) +(defvar my/org-base-dir "~/Documents/Notes/") +(defvar my/doom-config-dir + (cond + ((string= my/org-device "galaxy") "~/.config/doom/") + ((string= my/org-device "workstation") "~/Development/NixOS/dotfiles/doom/") + (t "~/Development/NixOS/dotfiles/doom/"))) +(defvar my/doom-data-dir + (cond + ((string= my/org-device "galaxy") "~/.config/doom") + ((string= my/org-device "workstation") "~/.local/share/doom/") + (t "~/.local/share/doom/"))) +(defvar my/hugo-posts-dir + (cond + ((string= my/org-device "galaxy") "~/portfolio/content-org/") + ((string= my/org-device "workstation") "~/Development/Websites/portfolio/content-org/") + (t "~/Development/Websites/portfolio/content-org/"))) + +(defvar my/org-agenda-cache-file (expand-file-name ".cache" my/org-base-dir) + "Path to the org-agenda cache file.") +(defvar my/org-always-included-agenda-files + (list + (expand-file-name "20220823172331-chores.org" my/org-base-dir)) + "Org files to always include in the agenda, even if no TODOs are found.") +(defvar my/doom-template-dir (expand-file-name "templates/" my/doom-data-dir) + "Directory for org-roam capture templates.") +(setq! org-roam-directory my/org-base-dir + org-roam-dailies-directory (expand-file-name "daily/" my/org-base-dir)) +#+end_src + +* BIBLE +Allows me to insert bible quotes into my org notes. +=NOTE= I'm not religious just for worldbuilding purposes lol. + +#+begin_src emacs-lisp :tangle ./config.el +(use-package + insert-esv + :init + (setq insert-esv-crossway-api-key "bb1872462ecc59624c7bb8ab36c9701ce2027cd1") + (setq insert-esv-include-short-copyright 'false) + (setq insert-esv-include-headings 'true) + (setq insert-esv-include-passage-horizontal-lines 'false) + (setq insert-esv-line-length '500) + :bind ("C-x C-e" . insert-esv-passage)) +#+end_src + +* BOOKMARKS AND BUFFERS +Doom Emacs uses 'SPC b' for keybindings related to bookmarks and buffers. + +** Bookmarks +Emacs bookmarking works somewhat like registers in that they record positions +you can jump to. Unlike registers, they have long names, and they persist +automatically from one Emacs session to the next. The prototypical use of +bookmarks is to record where you were reading in bookmarked files. + +| COMMAND | DESCRIPTION | KEYBINDING | +|-----------------+----------------------------------------+------------| +| list-bookmarks | /List bookmarks/ | SPC b L | +| bookmark-set | /Set bookmark/ | SPC b m | +| bookmark-delete | /Delete bookmark/ | SPC b M | +| bookmark-save | /Save current bookmark to bookmark file/ | SPC b w | + +#+BEGIN_src emacs-lisp :tangle ./config.el +(setq bookmark-default-file (expand-file-name "bookmarks" my/doom-data-dir)) + +(map! :leader + (:prefix ("b". "buffer") + :desc "List bookmarks" "L" #'list-bookmarks + :desc "Set bookmark" "m" #'bookmark-set + :desc "Delete bookmark" "M" #'bookmark-set + :desc "Save current bookmarks to bookmark file" "w" #'bookmark-save)) +#+END_SRC + +** Buffers +Regarding /buffers/, the text you are editing in Emacs resides in an object +called a /buffer/. Each time you visit a file, a buffer holds the file’s text. +Each time you invoke Dired, a buffer holds the directory listing. /Ibuffer/ is +a program that lists all of your Emacs /buffers/, allowing you to navigate +between them and filter them. + +| COMMAND | DESCRIPTION | KEYBINDING | +|-----------------+----------------------+------------| +| ibuffer | Launch ibuffer | SPC b i | +| kill-buffer | Kill current buffer | SPC b k | +| next-buffer | Goto next buffer | SPC b n | +| previous-buffer | Goto previous buffer | SPC b p | +| save-buffer | Save current buffer | SPC b s | + +** Global Auto Revert +A buffer can get out of sync with respect to its visited file on disk if that +file changes by another program. To keep it up to date, you can enable Auto +Revert mode by typing M-x auto-revert-mode, or you can set to turn on globally +with ‘global-auto-revert-mode’. I have also turned on Global Auto Revert on +non-file buffers, which is especially useful for ‘dired’ buffers. + +#+begin_src emacs-lisp :tangle ./config.el +(global-auto-revert-mode 1) +(setq global-auto-revert-non-file-buffers t) +#+end_src + +** Keybindings within ibuffer mode +ibuffer mode, it's a more elegant way to display your opened buffers, and plus +you can manipulate them using vim keybindings. + +| COMMAND | DESCRIPTION | KEYBINDING | +|-----------------------------------+----------------------------------------+------------| +| ibuffer-mark-forward | Mark the buffer | m | +| ibuffer-unmark-forward | Unmark the buffer | u | +| ibuffer-do-kill-on-deletion-marks | Kill the marked buffers | x | +| ibuffer-filter-by-content | ibuffer filter by content | f c | +| ibuffer-filter-by-directory | ibuffer filter by directory | f d | +| ibuffer-filter-by-filename | ibuffer filter by filename (full path) | f f | +| ibuffer-filter-by-mode | ibuffer filter by mode | f m | +| ibuffer-filter-by-name | ibuffer filter by name | f n | +| ibuffer-filter-disable | Disable ibuffer filter | f x | +| ibuffer-do-kill-lines | Hide marked buffers | g h | +| ibuffer-update | Restore hidden buffers | g H | + +#+begin_src emacs-lisp :tangle ./config.el +(evil-define-key 'normal ibuffer-mode-map + (kbd "f c") 'ibuffer-filter-by-content + (kbd "f d") 'ibuffer-filter-by-directory + (kbd "f f") 'ibuffer-filter-by-filename + (kbd "f m") 'ibuffer-filter-by-mode + (kbd "f n") 'ibuffer-filter-by-name + (kbd "f x") 'ibuffer-filter-disable + (kbd "g h") 'ibuffer-do-kill-lines + (kbd "g H") 'ibuffer-update) +#+end_src + +* DASHBOARD +Emacs Dashboard is a startup screen showing you recent files, bookmarks, agenda +items and an Emacs banner. + +** Dashboard in Emacsclient +This setting ensures that emacsclient always opens on *dashboard* rather than +*scratch*. + +#+begin_src emacs-lisp :tangle ./config.el +(setq doom-fallback-buffer "*dashboard*") +#+end_src + +* DIRED +The file manager within Emacs. Below, I setup keybindings for image previews +(peep-dired). Doom Emacs does not use 'SPC d' for any of its keybindings, so +I've chosen the format of 'SPC d' plus 'key'. + +** Keybindings To Open Dired + +| COMMAND | DESCRIPTION | KEYBINDING | +|------------+------------------------------------+------------| +| dired | /Open dired file manager/ | SPC d d | +| dired-jump | /Jump to current directory in dired/ | SPC d j | + +** Basic dired commands + +| COMMAND | DESCRIPTION | KEYBINDING | +|------------------------+---------------------------------------------+------------| +| dired-view-file | /View file in dired/ | SPC d v | +| dired-up-directory | /Go up in directory tree/ | h | +| dired-find-file | /Go down in directory tree (or open if file)/ | l | +| dired-next-line | Move down to next line | j | +| dired-previous-line | Move up to previous line | k | +| dired-mark | Mark file at point | m | +| dired-unmark | Unmark file at point | u | +| dired-do-copy | Copy current file or marked files | C | +| dired-do-rename | Rename current file or marked files | R | +| dired-hide-details | Toggle detailed listings on/off | ( | +| dired-git-info-mode | Toggle git information on/off | ) | +| dired-create-directory | Create new empty directory | + | +| dired-diff | Compare file at point with another | = | +| dired-subtree-toggle | Toggle viewing subtree at point | TAB | + +** Dired commands using regex + +| COMMAND | DESCRIPTION | KEYBINDING | +|-------------------------+----------------------------+------------| +| dired-mark-files-regexp | Mark files using regex | % m | +| dired-do-copy-regexp | Copy files using regex | % C | +| dired-do-rename-regexp | Rename files using regex | % R | +| dired-mark-files-regexp | Mark all files using regex | * % | + +** File permissions and ownership + +| COMMAND | DESCRIPTION | KEYBINDING | +|-----------------+----------------------------------+------------| +| dired-do-chgrp | Change the group of marked files | g G | +| dired-do-chmod | Change the mode of marked files | M | +| dired-do-chown | Change the owner of marked files | O | +| dired-do-rename | Rename file or all marked files | R | + +#+begin_src emacs-lisp :tangle ./config.el +(map! :leader + (:prefix ("d" . "dired") + :desc "Open dired" "d" #'dired + :desc "Dired jump to current" "j" #'dired-jump) + (:after dired + (:map dired-mode-map + :desc "Peep-dired image previews" "d p" #'peep-dired + :desc "Dired view file" "d v" #'dired-view-file))) + +(evil-define-key 'normal dired-mode-map + (kbd "M-RET") 'dired-display-file + (kbd "h") 'dired-up-directory + (kbd "l") 'dired-open-file ; use dired-find-file instead of dired-open. + (kbd "m") 'dired-mark + (kbd "t") 'dired-toggle-marks + (kbd "u") 'dired-unmark + (kbd "C") 'dired-do-copy + (kbd "D") 'dired-do-delete + (kbd "J") 'dired-goto-file + (kbd "M") 'dired-do-chmod + (kbd "O") 'dired-do-chown + (kbd "P") 'dired-do-print + (kbd "R") 'dired-do-rename + (kbd "T") 'dired-do-touch + (kbd "Y") 'dired-copy-filenamecopy-filename-as-kill ; copies filename to kill ring. + (kbd "Z") 'dired-do-compress + (kbd "+") 'dired-create-directory + (kbd "-") 'dired-do-kill-lines + (kbd "% l") 'dired-downcase + (kbd "% m") 'dired-mark-files-regexp + (kbd "% u") 'dired-upcase + (kbd "* %") 'dired-mark-files-regexp + (kbd "* .") 'dired-mark-extension + (kbd "* /") 'dired-mark-directories + (kbd "; d") 'epa-dired-do-decrypt + (kbd "; e") 'epa-dired-do-encrypt) +;; (kbd "Q") 'quick-preview-at-point) ;; previews with sushi +;; Get file icons in dired +;; (add-hook 'dired-mode-hook 'all-the-icons-dired-mode) +;; With dired-open plugin, you can launch external programs for certain extensions +;; For example, I set all .png files to open in 'sxiv' and all .mp4 files to open in 'mpv' +(setq dired-open-extensions '(("gif" . "eog") + ("jpg" . "eog") + ("png" . "eog") + ("mkv" . "celluloid") + ("mp4" . "celluloid"))) +#+end_src + +** Keybindings Within Dired With Peep-Dired-Mode Enabled +With peep-dired, you will get image previews as you go up/down with 'j' +and 'k' + +| COMMAND | DESCRIPTION | KEYBINDING | +|----------------------+------------------------------------------+------------| +| peep-dired | /Toggle previews within dired/ | SPC d p | +| peep-dired-next-file | /Move to next file in peep-dired-mode/ | j | +| peep-dired-prev-file | /Move to previous file in peep-dired-mode/ | k | + +#+begin_src emacs-lisp :tangle ./config.el +(evil-define-key 'normal peep-dired-mode-map + (kbd "j") 'peep-dired-next-file + (kbd "k") 'peep-dired-prev-file) +(add-hook 'peep-dired-hook 'evil-normalize-keymaps) +#+end_src + +** Making deleted files go to trash can + +#+begin_src emacs-lisp :tangle ./config.el +(setq delete-by-moving-to-trash t + trash-directory "~/.local/share/Trash/files/") +#+end_src + +** Clean up dired buffers while navigating away + +#+begin_src emacs-lisp :tangle ./config.el +;; (diredp-toggle-find-file-reuse-dir 1) +(setq dired-kill-when-opening-new-dired-buffer 1) +#+end_src + +* DOOM THEME +Setting the theme to doom-one. To try out new themes, I set a keybinding for +counsel-load-theme with 'SPC h t'. + +#+begin_src emacs-lisp :tangle ./config.el +(unless (string= my/org-device "galaxy") + (ignore-errors + (require 'base16-stylix-theme))) + +(setq doom-theme + (cond + ((string= my/org-device "galaxy") + 'doom-opera-light) + ((featurep 'base16-stylix-theme) + 'base16-stylix) + (t 'doom-opera-light))) +#+end_src + +* EVALUATE ELISP EXPRESSIONS +Changing some keybindings from their defaults to better fit with Doom Emacs, and +to avoid conflicts with my window managers which sometimes use the control key +in their keybindings. By default, Doom Emacs does not use 'SPC e' for anything, +so I choose to use the format 'SPC e' plus 'key' for these (I also use 'SPC e' +for 'eww' keybindings). + +| COMMAND | DESCRIPTION | KEYBINDING | +|-----------------+----------------------------------------------+------------| +| eval-buffer | /Evaluate elisp in buffer/ | SPC e b | +| eval-defun | /Evaluate the defun containing or after point/ | SPC e d | +| eval-expression | /Evaluate an elisp expression/ | SPC e e | +| eval-last-sexp | /Evaluate elisp expression before point/ | SPC e l | +| eval-region | /Evaluate elisp in region/ | SPC e r | + +#+begin_src emacs-lisp :tangle ./config.el +(map! :leader + (:prefix ("e". "evaluate/EWW") + :desc "Evaluate elisp in buffer" "b" #'eval-buffer + :desc "Evaluate defun" "d" #'eval-defun + :desc "Evaluate elisp expression" "e" #'eval-expression + :desc "Evaluate last sexpression" "l" #'eval-last-sexp + :desc "Evaluate elisp in region" "r" #'eval-region)) +#+end_src + +* EWW +This is the Emacs Web Wowser, the builtin browser in Emacs. Below I set urls to +open in a specific browser (eww) with browse-url-browser-function. By default, +Doom Emacs does not use 'SPC e' for anything, so I choose to use the format 'SPC +e' plus 'key' for these (I also use 'SPC e' for 'eval' keybindings). I chose to +use 'SPC s w' for eww-search-words because Doom Emacs uses 'SPC s' for 'search' +commands. + +#+begin_src emacs-lisp :tangle ./config.el +;; (setq browse-url-browser-function 'eww-browse-url) +(map! :leader + :desc "Search web for text between BEG/END" + "s w" #'eww-search-words + (:prefix ("e" . "evaluate/EWW") + :desc "Eww web browser" "w" #'eww + :desc "Eww reload page" "R" #'eww-reload)) +#+end_src + +* FONTS +Settings related to fonts within Doom Emacs: ++ 'doom-font' -- standard monospace font that defaults for most things in Emacs. ++ 'doom-variable-pitch-font' -- variable font which is useful in some Emacs + plugins. ++ 'doom-big-font' -- used in doom-big-font-mode; useful for presentations. ++ 'font-lock-comment-face' -- for comments. ++ 'font-lock-keyword-face' -- for keywords with special significance like 'setq' + in elisp. + +#+begin_src emacs-lisp :tangle ./config.el +(setq doom-unicode-font "Symbola") +(setq doom-font (font-spec :family "ComicShannsMono Nerd Font Mono" :size 18) + doom-variable-pitch-font (font-spec :family "ComicShannsMono Nerd Font Mono" :size 18) + doom-big-font (font-spec :family "ComicShannsMono Nerd Font Mono" :size 22)) +(after! doom-themes + (setq doom-themes-enable-bold t + doom-themes-enable-italic t)) +(custom-set-faces! + '(bold :weight ultra-bold) + '(font-lock-comment-face :slant italic) + '(font-lock-keyword-face :slant italic)) +#+end_src + +* FUNCTIONS +These are a collection of functions which I've snipped from multiple sources on +the internet. Some are slightly modified for my preferences, but overall I'm +not good enough with LISP to write my own functions yet. + +** Insert date +Some custom functions to insert the date. The function 'insert-todays-date' has +three different formats: + +1) Just the keybinding without the universal argument prefix. +2) With one universal argument prefix. +3) With two universal argument prefixes. + +The universal argument prefix is 'SPC-u' in Doom Emacs (C-u in standard GNU +Emacs). The function 'insert-any-date' only outputs to one format, which is the +same format as 'insert-todays-date' without a prefix. + +| COMMAND | EXAMPLE OUTPUT | KEYBINDING | +|-----------------------+---------------------------+-----------------------| +| dt/insert-todays-date | 2021-11-19 | SPC i d t | +| dt/insert-todays-date | Friday, November 19, 2021 | SPC u SPC i d t | +| dt/insert-any-date | Friday, November 19, 2021 | SPC i d a | + +=NOTE= Made by DT + +#+begin_src emacs-lisp :tangle ./config.el +(defun my/insert-todays-date (prefix) + "Insert any DATE using the current locale." + (interactive "P") + (let ((format (cond + ((not prefix) "%Y-%m-%d") + ((equal prefix '(4)) "%A, %B %d, %Y")))) + (insert (format-time-string format)))) + +(require 'calendar) +(defun my/insert-any-date (date) + "Insert DATE using the current locale." + (interactive (list (calendar-read-date))) + (insert (calendar-date-string date))) + +(map! :leader + (:prefix ("i d" . "Insert date") + :desc "Insert any date" "a" #'func/insert-any-date + :desc "Insert todays date" "t" #'func/insert-todays-date)) +#+end_src + +** Capture a task directly into a specific project +One important thing to point out here is that we're using 'file + head + olp' in +the capture template so that we can drop the new task entry under the "Tasks" +heading. + +Works, but I'm unsure how to use it on my workflow, may be safe to delete it +later. + +=NOTE= made by SystemCrafters + +#+begin_src emacs-lisp :tangle ./config.el +(defun my/org-roam-capture-task () + "Captures an org-roam task." + (interactive) + ;; Capture the new task, creating the project file if necessary + (org-roam-capture- + :node (org-roam-node-read nil) + :templates '(("p" "project" plain "** TODO %?" + :if-new (file+head+olp "%<%Y%m%d%H%M%S>-${slug}.org" + "#+title: ${title}\n#+category: ${title}\n#+filetags: Project" + ("Tasks")))))) +(global-set-key (kbd "C-c n t") #'my/org-roam-capture-task) +#+end_src + +* FLYCHECK +Configurations to add linting support to specific languages by integrating linters with flycheck. + +#+begin_src emacs-lisp :tangle ./config.el +(use-package! flycheck + :config + (flycheck-define-checker nix-statix + "A syntax checker for Nix using Statix." + :command ("statix" "check" source) + :error-patterns + ((warning line-start (file-name) ":" line ":" column + ": " (message) line-end)) + :modes (nix-mode)) + + (add-to-list 'flycheck-checkers 'nix-statix)) +#+end_src +* GPT +Integrate most AI agents with emacs on a way that through api keys it can do +more than cursor! + +#+begin_src emacs-lisp :tangle ./config.el +(use-package! gptel + :config + (setq! gptel-api-key "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") + (gptel-make-ollama "Ollama" + :host "localhost:11434" + :stream t + :models '(mistral:latest)) + ) + +#+end_src + +* HUGO +Capture template for new hugo posts. + +#+begin_src emacs-lisp :tangle ./config.el +;; Populates only the EXPORT_FILE_NAME property in the inserted headline. +(with-eval-after-load 'org-capture + (defun org-hugo-new-subtree-post-capture-template () + "Returns `org-capture' template string for new Hugo post. + See `org-capture-templates' for more information." + (let* ((title (read-from-minibuffer "Post Title: ")) ;Prompt to enter the post title + (fname (org-hugo-slug title))) + (mapconcat #'identity + `( + ,(concat "* TODO " title) + ":PROPERTIES:" + ,(concat ":EXPORT_FILE_NAME: " (format-time-string "%Y-%m-%d-") fname) + ":END:" + "%?\n") ;Place the cursor here finally + "\n")))) +;; org capture templates +(setq org-capture-templates + '( + ("h" ;`org-capture' binding + h + "Hugo post" + entry + ;; It is assumed that below file is present in `org-directory' + ;; and that it has a "Blog Ideas" heading. It can even be a + ;; symlink pointing to the actual location of all-posts.org! + (file+olp (expand-file-name "posts.org" my/hugo-posts-dir) "blog") + (function org-hugo-new-subtree-post-capture-template)) + )) +#+end_src + +* LINE SETTINGS +I set comment-line to 'SPC TAB TAB' which is a rather comfortable keybinding for +me. The standard Emacs keybinding for comment-line is 'C-x C-;'. The other +keybindings are for commands that toggle on/off line-related settings. +Doom Emacs uses 'SPC t' for "toggle" commands, so I choose 'SPC t' plus 'key' +for those bindings. + +| COMMAND | DESCRIPTION | KEYBINDING | +|--------------------------+-------------------------------------------+-------------| +| comment-line | /Toggle commenting lines/ | SPC TAB TAB | +| hl-line-mode | /Toggle line highlighting in current frame/ | SPC t h | +| global-hl-line-mode | /Toggle line highlighting globally/ | SPC t H | +| doom/toggle-line-numbers | /Toggle line numbers/ | SPC t l | +| toggle-truncate-lines | /Toggle truncate lines/ | SPC t t | + +#+begin_src emacs-lisp :tangle ./config.el +(setq display-line-numbers-type t) +(map! :leader + :desc "Comment or uncomment lines" "TAB TAB" #'comment-line + (:prefix ("t" . "toggle") + :desc "Toggle line numbers" "l" #'doom/toggle-line-numbers + :desc "Toggle line highlight in frame" "h" #'hl-line-mode + :desc "Toggle line highlight globally" "H" #'global-hl-line-mode + :desc "Toggle truncate lines" "t" #'toggle-truncate-lines)) +#+end_src + +These are my default line display preferences. + +#+begin_src emacs-lisp :tangle ./config.el +(setq display-line-numbers-type `relative) +(global-visual-line-mode t) +#+end_src + +* LOAD-MODES +These settings make it so company modes load by default on specific file formats. + +#+begin_src emacs-lisp :tangle ./config.el +;; CONFIG +(require 'config-general-mode) + (add-to-list 'auto-mode-alist '("\\.conf$" . config-general-mode)) +#+end_src + +* MODELINE +The modeline is the bottom status bar that appears in Emacs windows. For more +information on what is available to configure in the Doom modeline, check out: +https://github.com/seagle0128/doom-modeline + +#+begin_src emacs-lisp :tangle ./config.el +(setq all-the-icons-scale-factor .8) ;; fixes the issue of rightmost characters not fitting. +(set-face-attribute 'mode-line nil :font "Iosevka Nerd Font-15") +(setq doom-modeline-height 30 ;; sets modeline height + doom-modeline-bar-width 5 ;; sets right bar width + doom-modeline-persp-name t ;; adds perspective name to modeline + doom-modeline-persp-icon t) ;; adds folder icon next to persp name +#+end_src + +* MOUSE SUPPORT +Adding mouse support in the terminal version of Emacs. + +#+begin_src emacs-lisp :tangle ./config.el +(xterm-mouse-mode 1) +#+end_src + +* OPEN SPECIFIC FILES +Keybindings to open files that I work with all the time using the find-file +command, which is the interactive file search that opens with 'C-x C-f' in GNU +Emacs or 'SPC f f' in Doom Emacs. These keybindings use find-file +non-interactively since we specify exactly what file to open. The format I use +for these bindings is 'SPC =' plus 'key' since Doom Emacs does not use 'SPC ='. + +| PATH TO FILE | DESCRIPTION | KEYBINDING | +|---------------------+-----------------------+------------| +| ../Agenda.org | /Edit agenda file/ | SPC = a | +| ../doom/config.org | /Edit doom config.org/ | SPC = c | +| ../doom/init.el | /Edit doom init.el/ | SPC = i | +| ../doom/packages.el | /Edit doom packages.el/ | SPC = p | + +#+begin_src emacs-lisp :tangle ./config.el +(map! :leader + (:prefix ("=" . "open file") + :desc "Edit agenda file" "a" + #'(lambda () (interactive) + (find-file (expand-file-name "20220819130052-agenda.org" my/org-base-dir))) + + :desc "Edit doom config.org" "c" + #'(lambda () (interactive) + (find-file (expand-file-name "config.org" my/doom-config-dir))) + + :desc "Edit doom init.el" "i" + #'(lambda () (interactive) + (find-file (expand-file-name "init.el" my/doom-config-dir))) + + :desc "Edit doom packages.el" "p" + #'(lambda () (interactive) + (find-file (expand-file-name "packages.el" my/doom-config-dir))))) +#+end_src + +* LSP +When configured properly lsp-mode's performance is on par with mainstream LSP +clients (e. g. VScode, Theia, etc). Here are steps to achieve optimal results. + +#+begin_src emacs-lisp :tangle ./config.el +(setq read-process-output-max (* 1024 1024)) ;; 1mb +(setq lsp-idle-delay 0.500) +(setq lsp-log-io nil) ; if set to true can cause a performance hit +;; c# LSP +(after! lsp-mode + (setq lsp-csharp-server-path "/usr/bin/omnisharp")) +#+end_src + +* ORG MODE +I wrapped most of this block in (after! org). Without this, my settings might +evaluate too early, which will result in my settings being overwritten by Doom's +defaults. I have also enabled org-journal, org-superstar and org-roam by adding +(+journal +pretty +roam2) to the org section of my Doom Emacs init.el. + +These are my personal settings, heavily modified from DT's original config. For +starters, I made it so org-agenda-files recursively feeds the agenda from .org +files found on my Notes directory, also made it so logs go into drawers, and +lastly customized the TODO keywords based on my personal preferences, these are +settings overwrite the original org settings, and this require to run after org, +so they can build upon the variables defined by the default configuration of +Doom Emacs. + +#+begin_src emacs-lisp :tangle ./config.el +(after! org + (setq org-directory my/org-base-dir + org-id-locations-file (expand-file-name ".orgids" my/org-base-dir) + org-attach-id-dir (expand-file-name "images" my/org-base-dir) + org-ellipsis " ▼ " + org-superstar-headline-bullets-list '("◉" "●" "○" "◆" "●" "○" "◆") + org-superstar-item-bullet-alist '((?+ . ?+) (?- . ?-)) + org-log-done 'time + org-log-into-drawer t + org-hide-emphasis-markers t + org-todo-keywords + '((sequence + "TODO(t)" ; A task that needs doing & is ready to do + "PROJ(p)" ; A project, which usually contains other tasks + "ART(a)" ; Similar to PROJ but focused on drawing + "IDEA(i)" ; Misc tasks, usually to elaborate on writing later + "HOLD(h)" ; This task on hold because I'm a lazy fuck + "|" + "DONE(d)" ; Task succesfully completed + "CANCELED(c)") ; Cancelled task + (sequence + "[ ](T)" ; A task that needs doing + "[-](S)" ; A task in progress + "[?](H)" ; A task on hold + "|" + "[X](D)")) ; A task completed + org-todo-keyword-faces + '(("[-]" . +org-todo-active) + ("[?]" . +org-todo-onhold) + ("HOLD" . +org-todo-onhold) + ("ART" . +org-todo-project) + ("IDEA" . +org-todo-project) + ("PROJ" . +org-todo-project) + ("CANCELED" . +org-todo-cancel))) + (require 'org-habit)) +#+end_src + +** Org Agenda Cache +Reads the `.cache` file in `my/org-base-dir`, which contains only Org files +with active TODOs, and sets `org-agenda-files` accordingly. Falls back to an +empty list if the cache doesn’t exist. + +#+begin_src emacs-lisp :tangle ./config.el +(defun my/update-org-agenda-cache () + "Scan Org files and cache those with TODOs, checkboxes, or timestamped entries." + (interactive) + (let* ((org-dir my/org-base-dir) + (files (directory-files-recursively org-dir "\\.org$")) + (todo-files '()) + (regex (concat + ;; Standard TODO entries and checkboxes + "\\*+[ \t]+\\(TODO\\|PROJ\\|ART\\|IDEA\\|HOLD\\|\\[ \\]\\|\\[-\\]\\|\\[\\?\\]\\)" + ;; Org scheduling keywords + "\\|SCHEDULED:" + "\\|DEADLINE:" + ;; Standalone timestamps like <2025-04-14 Mon> + "\\|<[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}"))) + (dolist (file files) + (message "Scanning: %s" file) + (condition-case err + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (when (re-search-forward regex nil t) + (message " -> Relevant entry found in: %s" file) + (push file todo-files))) + (error (message "Error reading %s: %s" file err)))) + (setq todo-files (delete-dups (append todo-files my/org-always-included-agenda-files))) + (if todo-files + (progn + (message "Writing %d agenda-relevant files to cache" (length todo-files)) + (with-temp-file my/org-agenda-cache-file + (prin1 todo-files (current-buffer)))) + (message "No relevant entries found — not writing cache.")))) + +(defun my/load-org-agenda-from-cache () + "Load org-agenda-files from the cache, or fallback to an empty list." + (interactive) + (let ((file my/org-agenda-cache-file)) + (if (and (file-readable-p file) + (> (nth 7 (file-attributes file)) 0)) ; file size > 0 + (with-temp-buffer + (insert-file-contents file) + (read (current-buffer))) + (message "Agenda cache not found or empty") + nil))) + +(after! org + (setq org-agenda-files (my/load-org-agenda-from-cache))) +#+end_src + +** Set font sizes for each header level in Org +You can set the Org heading levels to be different font sizes. So I choose to +have level 1 headings to be 140% in height, level 2 to be 130%, etc. Other +interesting things you could play with include adding :foreground color and/or +:background color if you want to override the theme colors. + +#+begin_src emacs-lisp :tangle ./config.el +(custom-set-faces + '(org-level-1 ((t (:inherit outline-1 :height 1.4)))) + '(org-level-2 ((t (:inherit outline-2 :height 1.3)))) + '(org-level-3 ((t (:inherit outline-3 :height 1.2)))) + '(org-level-4 ((t (:inherit outline-4 :height 1.1)))) + '(org-level-5 ((t (:inherit outline-5 :height 1.0)))) + '(org-document-title ((t (:inherit outline-1 :height 2.0)))) +) +#+end_src + +** Org-Alert +This change makes it so org-alert uses libnotify for system notifications as +well as update intervals. + +#+begin_src emacs-lisp :tangle ./config.el +(use-package org-alert + :ensure t) +(setq alert-default-style 'libnotify + org-alert-interval 3600) +;; Auto start org-alert when emacs/daemon load +(org-alert-enable) +#+end_src + +** Org-Auto-Tangle +Allows you to add the option #+auto_tangle: t in your Org file so that it +automatically tangles when you save the document. + +#+begin_src emacs-lisp :tangle ./config.el +(use-package org-auto-tangle + :defer t + :hook (org-mode . org-auto-tangle-mode)) +#+end_src + +** Org-Babel +Load language support on org-babel, also map out org-babel-tangle. + +#+begin_src emacs-lisp :tangle ./config.el +(map! :leader + :desc "Org babel tangle" "m B" #'org-babel-tangle) +;; (org-babel-do-load-languages +;; 'org-babel-load-languages +;; '((R . t) +;; (emacs-lisp . t) +;; (nix . t))) +#+end_src + +** Org-Inlinetask +Enables a feature native to org-mode, which after a set amount of indentations, +turns the header into a task, allowing for the insertion of TODO or PROJ without +disrupting the indentation of the lines below it. +https://github.com/amluto/org-mode/blob/master/lisp/org-inlinetask.el + +#+begin_src emacs-lisp :tangle ./config.el +(require 'org-inlinetask) +(setq org-inlinetask-min-level 9) +#+end_src + +** Org-Roam +First lines set up some preferences through variables, then it sets up some +templates for dailies, and nodes. + +| COMMAND | DESCRIPTION | KEYBINDING | +|---------------------------------+---------------------------------+-------------| +| org-roam-find-file | org roam find file | SPC n r f | +| org-roam-insert | org roam insert | SPC n r i | +| org-roam-dailies-find-date | org roam dailies find date | SPC n r d d | +| org-roam-dailies-find-today | org roam dailies find today | SPC n r d t | +| org-roam-dailies-find-tomorrow | org roam dailies find tomorrow | SPC n r d m | +| org-roam-dailies-find-yesterday | org roam dailies find yesterday | SPC n r d y | + +#+begin_src emacs-lisp :tangle ./config.el +(setq! deft-directory my/org-base-dir) +(use-package org-roam + :ensure t + :custom + (org-roam-completion-everywhere t) + (org-roam-dailies-capture-templates + '(("d" "default" entry "* %<%I:%M %p>: %?" + :if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")))) + (org-roam-capture-templates + `(("d" "default" plain + "%?" + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n") + :unnarrowed t) + ("l" "programming language" plain + (file ,(expand-file-name "programming.org" my/doom-template-dir)) + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" + "#+filetags: :programming:language:${title}:\n#+title: ${title}") + :unnarrowed t) + ("e" "political events" plain + (file ,(expand-file-name "events.org" my/doom-template-dir)) + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" + "#+filetags: :politics:conflicts:\n#+title: ${title}") + :unnarrowed t) + ("p" "project" plain + "* PROJ ${title}\n%?\n* Tasks" + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" + "#+category: ${title}\n#+filetags: :project:\n#+title: ${title}") + :unnarrowed t))) + :bind() + :bind-keymap() + :config + (org-roam-db-autosync-mode)) +(setq completion-ignore-case t) +(set-file-template! + (concat (regexp-quote my/org-base-dir) ".+\\.org$") + 'org-mode + :ignore t) +#+end_src + +** Org-Roam-UI +This is a superior (and interactive) visualizer for org-roam graph. +https://github.com/org-roam/org-roam-ui + +#+begin_src emacs-lisp :tangle ./config.el +(use-package! websocket + :after org-roam) + +(use-package! org-roam-ui + :after org-roam ;; or :after org +;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have +;; a hookable mode anymore, you're advised to pick something yourself +;; if you don't care about startup time, use + ;; :hook (after-init . org-roam-ui-mode) + :config + (setq org-roam-ui-sync-theme t + org-roam-ui-follow t + org-roam-ui-update-on-save t + org-roam-ui-open-on-start nil)) +#+end_src + +** Org-Transclusion +Org-transclusion lets you insert a copy of text content via a file link or ID +link within an Org file. It lets you have the same content present in different +buffers at the same time without copy-and-pasting it. Edit the source of the +content, and you can refresh the transcluded copies to the up-to-date state. +Org-transclusion keeps your files clear of the transcluded copies, leaving only +the links to the original content. +https://github.com/nobiot/org-transclusion + +| COMMAND | DESCRIPTION | KEYBINDING | +|-----------------------+--------------------------+------------| +| org-transclusion-add | Add transclusion block | SPC n r a | +| org-transclusion-mode | Toggle transclusion mode | SPC n r t | + + +#+begin_src emacs-lisp :tangle ./config.el +(use-package! org-transclusion + :after org + :init + (map! + :map global-map "" #'org-transclusion-add + :leader + (:prefix ("n r" . "toggle") + :desc "Org Transclussion Add" "a" #'org-transclusion-add + :desc "Org Transclusion Mode" "t" #'org-transclusion-mode))) +#+end_src + +* OTHER SETTINGS +These are some personal settings, and other fixes. + +** Disable persistent undo +Uses [[doom-package:][undo-tree]] instead of [[doom-package:][undo-fu]], which is a little less stable, but offers +branching undo history and a visualizer for navigating it. + ++ If using +tree + #+begin_src emacs-lisp :tangle ./config.el +(after! undo-tree + (setq undo-tree-auto-save-history nil)) + #+end_src + ++ Else + #+begin_src emacs-lisp :tangle ./config.el +;; (remove-hook 'undo-fu-mode-hook #'global-undo-fu-session-mode) + #+end_src + +** User information + +#+begin_src emacs-lisp :tangle ./config.el +(setq user-full-name "Danilo Reyes" + user-mail-address "CaptainJawZ@outlook.com") +#+end_src + +** Variables +Custom set variables, I should note that I don't know what git commit major mode +does, but flycheck is for minimizing errors on python scripts for long line +length. + +#+begin_src emacs-lisp :tangle ./config.el +(custom-set-variables + '(flycheck-flake8-maximum-line-length 88) + '(safe-local-variable-values '((git-commit-major-mode . git-commit-elisp-text-mode)))) +#+end_src + +* REGISTERS +Emacs registers are compartments where you can save text, rectangles and +positions for later use. Once you save text or a rectangle in a register, you +can copy it into the buffer once or multiple times; once you save a position in +a register, you can jump back to that position once or multiple times. The +default GNU Emacs keybindings for these commands (with the exception of +counsel-register) involves 'C-x r' followed by one or more other keys. I wanted +to make this a little more user friendly, and since I am using Doom Emacs, I +choose to replace the 'C-x r' part of the key chords with 'SPC r'. + +| COMMAND | DESCRIPTION | KEYBINDING | +|----------------------------------+----------------------------------+------------| +| copy-to-register | /Copy to register/ | SPC r c | +| frameset-to-register | /Frameset to register/ | SPC r f | +| insert-register | /Insert contents of register/ | SPC r i | +| jump-to-register | /Jump to register/ | SPC r j | +| list-registers | /List registers/ | SPC r l | +| number-to-register | /Number to register/ | SPC r n | +| counsel-register | /Interactively choose a register/ | SPC r r | +| view-register | /View a register/ | SPC r v | +| window-configuration-to-register | /Window configuration to register/ | SPC r w | +| increment-register | /Increment register/ | SPC r + | +| point-to-register | /Point to register/ | SPC r SPC | + +#+begin_src emacs-lisp :tangle ./config.el +(map! :leader + (:prefix ("r" . "registers") + :desc "Copy to register" "c" #'copy-to-register + :desc "Frameset to register" "f" #'frameset-to-register + :desc "Insert contents of register" "i" #'insert-register + :desc "Jump to register" "j" #'jump-to-register + :desc "List registers" "l" #'list-registers + :desc "Number to register" "n" #'number-to-register + :desc "Interactively choose a register" "r" #'counsel-register + :desc "View a register" "v" #'view-register + :desc "Window configuration to register" "w" #'window-configuration-to-register + :desc "Increment register" "+" #'increment-register + :desc "Point to register" "SPC" #'point-to-register)) +#+end_src + +* SPELL +This will disable Proselint from running inside code blocks. + +#+begin_src emacs-lisp :tangle ./config.el +(defadvice! fixed-flycheck-proselint-parse-errors-a (output checker buffer) + :override #'flycheck-proselint-parse-errors + (delq + nil (mapcar (lambda (err) + (let-alist err + (and (or (not (derived-mode-p 'org-mode)) + (save-excursion (goto-char .start) + (not (org-in-src-block-p)))) + (flycheck-error-new-at-pos + .start + (pcase .severity + (`"suggestion" 'info) + (`"warning" 'warning) + (`"error" 'error) + (_ 'error)) + .message + :id .check + :buffer buffer + :checker checker + :end-pos .end)))) + (let-alist (car (flycheck-parse-json output)) + .data.errors)))) +#+end_src + +* SPLITS +I set splits to default to opening on the right using 'prefer-horizontal-split'. +I set a keybinding for 'clone-indirect-buffer-other-window' for when I want to +have the same document in two splits. The text of the indirect buffer is always +identical to the text of its base buffer; changes made by editing either one are +visible immediately in the other. But in all other respects, the indirect +buffer and its base buffer are separate. For example, I can fold one split but +the other remains unfolded. + +#+begin_src emacs-lisp :tangle ./config.el +(defun prefer-horizontal-split () + (set-variable 'split-height-threshold nil t) + (set-variable 'split-width-threshold 40 t)) ; make this as low as needed +(add-hook 'markdown-mode-hook 'prefer-horizontal-split) +(map! :leader + :desc "Clone indirect buffer other window" "b c" #'clone-indirect-buffer-other-window) +#+end_src + +* TWITTER +Needed to login on twitter. + +#+begin_src emacs-lisp :tangle ./config.el +(setq twittering-allow-insecure-server-cert t) +#+end_src + +* WINNER MODE +Winner mode comes with GNU Emacs since version 20. This is a global minor mode +and, when activated, it allows you to “undo” (and “redo”) changes in the window +configuration with the key commands 'SCP w ' and 'SPC w '. + +#+begin_src emacs-lisp :tangle ./config.el +(map! :leader + (:prefix ("w" . "window") + :desc "Winner redo" "" #'winner-redo + :desc "Winner undo" "" #'winner-undo)) +#+end_src + +* ZAP TO CHAR +Emacs provides a 'zap-to-char' command that kills from the current point to a +character. It bounds to 'M-z' in standard GNU Emacs but since Doom Emacs uses +'SPC' as its leader key and does not have 'SPC z' binding to anything, it just +makes since to use it for 'zap-to-char'. Note that 'zap-to-char' can combine +with the universal argument 'SPC u' to modify its behaviour. Examples of +'zap-to-char' usage listed in the table below: + +| KEYBINDING | WHAT IS DOES | +|---------------------------+------------------------------------------------------------| +| SPC z e | deletes all chars to the next occurrence of 'e' | +| SPC u 2 SPC z e | deletes all chars to the second occurrence of 'e' | +| SPC u - SPC z e | deletes all chars to the previous occurrence of 'e' | +| SPC u -2 SPC z e | deletes all chars to the fourth previous occurrence of 'e' | +| SPC u 1 0 0 SPC u SPC z e | deletes all chars to the 100th occurrence of 'e' | + +=TIP= The universal argument (SPC u) can only take a single integer by default. +If you need to use a multi-digit number (like 100 in the last example in the +table above), then you must terminate the universal argument with another 'SPC +u' after typing the number. + +'zap-up-to-char' is an alternative command that does not zap the char specified. +It bounds to 'SPC Z'. It can also combine in conjunction with the universal +argument 'SPC u' in similar fashion to the 'zap-to-char' examples above. + +=NOTE= Vim (evil mode) has similar functionality builtin. You can delete to +the next occurrence of 'e' by using 'dte' in normal. To delete to the next +occurrence of 'e' including the 'e', then you would use 'dfe'. And you can +modify 'dt' and 'df' by prefixing them with numbers, so '2dte' would delete to +the second occurrence of 'e'. + +#+begin_src emacs-lisp :tangle ./config.el +(map! :leader + :desc "Zap to char" "z" #'zap-to-char + :desc "Zap up to char" "Z" #'zap-up-to-char) +#+end_src + +# LocalWords: ibuffer dired elisp setq modeline libnotify Proselint DT's SPC +# LocalWords: GitLab unmark emacsclient modeline Goto emms eww Transclusion +# LocalWords: Inlinetask LSP diff --git a/dotfiles/doom/custom.el b/dotfiles/doom/custom.el new file mode 100644 index 0000000..be0e9b7 --- /dev/null +++ b/dotfiles/doom/custom.el @@ -0,0 +1,21 @@ +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(flycheck-flake8-maximum-line-length 88) + '(safe-local-variable-values + '((org-hugo-auto-export-on-save . t) + (org-hugo-base-dir . /home/jawz/Development/Websites/portfolio/) + (git-commit-major-mode . git-commit-elisp-text-mode)))) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(org-document-title ((t (:inherit outline-1 :height 2.0)))) + '(org-level-1 ((t (:inherit outline-1 :height 1.4)))) + '(org-level-2 ((t (:inherit outline-2 :height 1.3)))) + '(org-level-3 ((t (:inherit outline-3 :height 1.2)))) + '(org-level-4 ((t (:inherit outline-4 :height 1.1)))) + '(org-level-5 ((t (:inherit outline-5 :height 1.0))))) diff --git a/dotfiles/doom/init.el b/dotfiles/doom/init.el new file mode 100755 index 0000000..33219cd --- /dev/null +++ b/dotfiles/doom/init.el @@ -0,0 +1,192 @@ +;;; init.el -*- lexical-binding: t; -*- + +;; This file controls what Doom modules are enabled and what order they load +;; in. Remember to run 'doom sync' after modifying it! + +;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's +;; documentation. There you'll find a link to Doom's Module Index where all +;; of our modules are listed, including what flags they support. + +;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or +;; 'C-c c k' for non-vim users) to view its documentation. This works on +;; flags as well (those symbols that start with a plus). +;; +;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its +;; directory (for easy access to its source code). + +(doom! :input + ;;bidi ; (tfel ot) thgir etirw uoy gnipleh + ;;chinese + ;;japanese + ;;layout ; auie,ctsrnm is the superior home row + + :completion + ;; company ; the ultimate code completion backend + (corfu +orderless) ; complete with cap(f), cape and a flying feather! + ;;helm ; the *other* search engine for love and life + ;;ido ; the other *other* search engine... + ;;(ivy +fuzzy +childframe +icons) ; a search engine for love and life + vertico ; the search engine of the future + + :ui + deft ; notational velocity for Emacs + doom ; what makes DOOM look the way it does + doom-dashboard ; a nifty splash screen for Emacs + ;;doom-quit ; DOOM quit-message prompts when you quit Emacs + ;;(emoji +unicode +github) ; 🙂 + hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW + ;;indent-guides ; highlighted indent columns + ;;(ligatures +extra +iosevka) ; ligatures and symbols to make your code pretty again + ;;minimap ; show a map of the code on the side + modeline ; snazzy, Atom-inspired modeline, plus API + ;;nav-flash ; blink cursor line after big motions + ;;neotree ; a project drawer, like NERDTree for vim + ophints ; highlight the region an operation acts on + (popup +defaults) ; tame sudden yet inevitable temporary windows + ;;tabs ; a tab bar for Emacs + (treemacs +lsp) ; a project drawer, like neotree but cooler + ;;unicode ; extended unicode support for various languages + (vc-gutter +pretty) ; vcs diff in the fringe + vi-tilde-fringe ; fringe tildes to mark beyond EOB + ;;window-select ; visually switch windows + workspaces ; tab emulation, persistence & separate workspaces + ;;zen ; distraction-free coding or writing + + :editor + (evil +everywhere); come to the dark side, we have cookies + file-templates ; auto-snippets for empty files + fold ; (nigh) universal code folding + (format +onsave) ; automated prettiness + ;;god ; run Emacs commands without modifier keys + ;;lispy ; vim for lisp, for people who don't like vim + ;;multiple-cursors ; editing in many places at once + ;;objed ; text object editing for the innocent + ;;parinfer ; turn lisp into python, sort of + rotate-text ; cycle region at point between text candidates + snippets ; my elves. They type so I don't have to + ;;word-wrap ; soft wrapping with language-aware indent + + :emacs + dired ; making dired pretty [functional] + electric ; smarter, keyword-based electric-indent + eww ; the internet is gross + ibuffer ; interactive buffer management + (undo +tree) ; persistent, smarter undo for your inevitable mistakes + vc ; version-control and Emacs, sitting in a tree + + :term + ;;eshell ; the elisp shell that works everywhere + ;;shell ; simple shell REPL for Emacs + ;;term ; basic terminal emulator for Emacs + vterm ; the best terminal emulation in Emacs + + :checkers + syntax ; tasing you for every semicolon you forget + (spell +flyspell +hunspell) ; tasing you for misspelling mispelling + grammar ; tasing grammar mistake every you make + + :tools + ;;ansible + ;;biblio ; Writes a PhD for you (citation needed) + ;;collab ; buffers with friends + ;;debugger ; FIXME stepping through code, to help you add bugs + direnv + (docker +lsp) + editorconfig ; let someone else argue about tabs vs spaces + ;;ein ; tame Jupyter notebooks with emacs + (eval +overlay) ; run code, run (also, repls) + (lookup +dictionary + offline) ; navigate your code and its documentation + (lsp +peek) ; M-x vscode + magit ; a git porcelain for Emacs + ;;make ; run make tasks from Emacs + ;;pass ; password manager for nerds + ;;pdf ; pdf enhancements + ;;prodigy ; FIXME managing external services & code builders + ;;terraform ; infrastructure as code + tmux ; an API for interacting with tmux + ;; tree-sitter ; syntax and parsing, sitting in a tree... + upload ; map local to remote projects via ssh/ftp + + :os + ;;(:if (featurep :system 'macos) macos) ; improve compatibility with macOS tty ; improve the terminal Emacs experience + + :lang + ;;agda ; types of types of types of types... + ;;beancount ; mind the GAAP + (cc +lsp) ; C > C++ == 1 + ;;clojure ; java with a lisp + ;;common-lisp ; if you've seen one lisp, you've seen them all + ;;coq ; proofs-as-programs + ;;crystal ; ruby at the speed of c + ;; (csharp +lsp) ; unity, .NET, and mono shenanigans + ;;data ; config/data formats + ;;(dart +flutter) ; paint ui and not much else + ;;dhall + ;;elixir ; erlang done right + ;;elm ; care for a cup of TEA? + emacs-lisp ; drown in parentheses + ;;erlang ; an elegant language for a more civilized age + ;;ess ; emacs speaks statistics + ;;factor + ;;faust ; dsp, but you get to keep your soul + ;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER) + ;;fsharp ; ML stands for Microsoft's Language + ;;fstar ; (dependent) types and (monadic) effects and Z3 + (gdscript +lsp) ; the language you waited for + ;;(go +lsp) ; the hipster dialect + ;;(graphql +lsp) ; Give queries a REST + (haskell +lspr) ; a language that's lazier than I am + ;;hy ; readability of scheme w/ speed of python + ;;idris ; a language you can depend on + (json +lsp) ; At least it ain't XML + ;;(java +lsp) ; the poster child for carpal tunnel syndrome + (javascript +lsp) ; all(hope(abandon(ye(who(enter(here)))))) + (julia +lsp) ; a better, faster MATLAB + ;;kotlin ; a better, slicker Java(Script) + ;;latex ; writing papers in Emacs has never been so fun + ;;lean ; for folks with too much to prove + ;;ledger ; be audit you can be + ;;lua ; one-based indices? one-based indices + ;;markdown ; writing docs for people to ignore + ;;nim ; python + lisp at the speed of c + (nix +lsp) ; I hereby declare "nix geht mehr!" + ;;ocaml ; an objective camel + (org +hugo +pretty +roam2) ; organize your plain life in plain text + ;;(php +lsp) ; perl's insecure younger brother + ;;plantuml ; diagrams for confusing people more + ;; graphviz ; diagrams for confusing yourself even more + ;;purescript ; javascript, but functional + (python +pyright +lsp) ; beautiful is better than ugly + ;;qt ; the 'cutest' gui framework ever + ;;racket ; a DSL for DSLs + ;;raku ; the artist formerly known as perl6 + ;;rest ; Emacs as a REST client + ;;rst ; ReST in peace + ;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"} + (rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap() + ;;scala ; java, but good + ;;(scheme +guile) ; a fully conniving family of lisps + (sh +lsp) ; she sells {ba,z,fi}sh shells on the C xor + ;;sml + ;;solidity ; do you need a blockchain? No. + ;;swift ; who asked for emoji variables? + ;;terra ; Earth and Moon in alignment for performance. + ;;web ; the tubes + (yaml +lsp) ; JSON, but readable + ;;zig ; C, but simpler + + :email + ;;(mu4e +org +gmail) + ;;notmuch + ;;(wanderlust +gmail) + + :app + calendar + ;;emms + everywhere ; *leave* Emacs!? You must be joking + ;;irc ; how neckbeards socialize + ;;(rss +org) ; emacs as an RSS reader + + :config + literate + (default +bindings +smartparens)) diff --git a/dotfiles/doom/packages.el b/dotfiles/doom/packages.el new file mode 100755 index 0000000..af80f4a --- /dev/null +++ b/dotfiles/doom/packages.el @@ -0,0 +1,96 @@ +;; -*- no-byte-compile: t; -*- +;;; $DOOMDIR/packages.el + +;; To install a package with Doom you must declare them here and run 'doom sync' +;; on the command line, then restart Emacs for the changes to take effect -- or +;; use 'M-x doom/reload'. + + +;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror: + ;(package! some-package) + +;; To install a package directly from a remote git repo, you must specify a +;; `:recipe'. You'll find documentation on what `:recipe' accepts here: +;; https://github.com/raxod502/straight.el#the-recipe-format + ;(package! another-package + ; :recipe (:host github :repo "username/repo")) + +;; If the package you are trying to install does not contain a PACKAGENAME.el +;; file, or is located in a subdirectory of the repo, you'll need to specify +;; `:files' in the `:recipe': + ;(package! this-package + ; :recipe (:host github :repo "username/repo" + ; :files ("some-file.el" "src/lisp/*.el"))) + +;; If you'd like to disable a package included with Doom, you can do so here +;; with the `:disable' property: + ;(package! builtin-package :disable t) + +;; You can override the recipe of a built in package without having to specify +;; all the properties for `:recipe'. These will inherit the rest of its recipe +;; from Doom or MELPA/ELPA/Emacsmirror: + ;(package! builtin-package :recipe (:nonrecursive t)) + ;(package! builtin-package-2 :recipe (:repo "myfork/package")) + +;; Specify a `:branch' to install a package from a particular branch or tag. +;; This is required for some packages whose default branch isn't 'master' (which +;; our package manager can't deal with; see raxod502/straight.el#279) + ;(package! builtin-package :recipe (:branch "develop")) + +;; Use `:pin' to specify a particular commit to install. + ;(package! builtin-package :pin "1a2b3c4d5e") + + +;; Doom's packages are pinned to a specific commit and updated from release to +;; release. The `unpin!' macro allows you to unpin single packages... + ;(unpin! pinned-package) +;; ...or multiple packages + ;(unpin! pinned-package another-pinned-package) +;; ...Or *all* packages (NOT RECOMMENDED; will likely break things) + ;(unpin! t) + +;; (package! nixos-options) ;; enable when migrating to nixos +;; (package! quick-preview) ;; preview files with sushi + + +;; (package! codeium :recipe (:host github :repo "Exafunction/codeium.el")) +(package! config-general-mode) +(package! dired-open) +(package! dired-subtree) +;; (package! doom-modeline-now-playing) +(package! ini-mode) +(package! insert-esv) ;; bible passages +(package! olivetti) ;; writing mode centering text, looks like word +(package! org-alert) +(package! org-auto-tangle) +(package! org-roam-ui) +(package! org-transclusion) +(package! peep-dired) ;; kind of cool but never could make it work +(package! php-cs-fixer) +(package! systemd) +;; (package! 2048-game) +;; (package! academic-phrases) +;; (package! caddyfile-mode) +;; (package! clippy) +;; (package! crontab-mode) ;; crontab colors +;; (package! evil-tutor) ;; vim tutorial +;; (package! ewal) ;; theme colors based on pywal +;; (package! ewal-doom-themes) +;; (package! ewal-evil-cursors) +;; (package! fish-completion) ;; what does it do??????????????????????????? +;; (package! flycheck-aspell) +;; (package! ivy-posframe) +;; (package! mw-thesaurus) +;; (package! org-appear) ;; couldn't get it to work +;; (package! org-recur) ;; works but I want to keep org vanilla +;; (package! ox-chameleon +;; :recipe (:host github :repo "tecosaur/ox-chameleon")) +;; (package! renpy) +;; (package! resize-window) +;; (package! tldr) +;; (package! typit) ;; type speed test +;; (package! vimgolf) ;; vim puzzles +;; (package! wc-mode) ;; displays character count of buffer + +(package! expand-region) +(package! gptel :recipe (:nonrecursive t)) diff --git a/dotfiles/doom/templates/default.org b/dotfiles/doom/templates/default.org new file mode 100755 index 0000000..50d062d --- /dev/null +++ b/dotfiles/doom/templates/default.org @@ -0,0 +1 @@ +%? diff --git a/dotfiles/doom/templates/events.org b/dotfiles/doom/templates/events.org new file mode 100644 index 0000000..dd15ac1 --- /dev/null +++ b/dotfiles/doom/templates/events.org @@ -0,0 +1,21 @@ +%? + +* Sources +1. + +* Belligerents +1. + +* Casualties and losses + +* Location + +* Causes + +* Events + +* Major Contention Events + +* Outcome + +* Important Notes diff --git a/dotfiles/doom/templates/programming.org b/dotfiles/doom/templates/programming.org new file mode 100755 index 0000000..5937a71 --- /dev/null +++ b/dotfiles/doom/templates/programming.org @@ -0,0 +1,13 @@ +%? + +- Influenced by +- Influenced +- Related tools + +* Hello World + +* Tips + +* Resources +- Documentation +- YouTube channels diff --git a/dotfiles/gallery-dl.nix b/dotfiles/gallery-dl.nix new file mode 100644 index 0000000..649a135 --- /dev/null +++ b/dotfiles/gallery-dl.nix @@ -0,0 +1,203 @@ +{ + extractor = { + skip = "abort:5"; + cookies = [ + "firefox" + "/home/jawz/.librewolf/jawz" + "gnomekeyring" + ]; + retries = 10; + sleep-request = 0; + directlink = { + filename = "{filename}.{extension}"; + directory = [ ]; + }; + twitter = { + skip = "abort:1"; + retweets = false; + videos = "ytdl"; + logout = true; + include = [ "media" ]; + directory = [ "{user[name]}" ]; + }; + pinterest.directory = [ + "{board[owner][username]}" + "{board[name]}" + ]; + instagram = { + browser = "firefox:linux"; + user-agent = "Mozilla/5.0 (X11; Linux x86_64; rv:138.0) Gecko/20100101 Firefox/138.0"; + sleep = "66-123"; + sleep-request = "66-123"; + parent-directory = true; + directory = [ "{username}" ]; + previews = true; + highlights = { + reverse = true; + directory = [ "{username}" ]; + }; + stories = { + reverse = true; + directory = [ "{username}" ]; + }; + tagged.directory = [ + "{username}" + "tagged" + "{tagged_username}" + ]; + }; + furaffinity = { + directory = [ + "{user}" + "{subcategory}" + ]; + include = [ + "scraps" + "gallery" + ]; + }; + patreon = { + filename = "{filename}.{num}.{extension}"; + browser = "firefox"; + directory = [ + "(Patreon) {creator[vanity]}" + "({date:%Y%m%d}) {title} ({id})" + ]; + }; + blogger = { + filename = "{filename} - {num}.{extension}"; + directory = [ + "{blog[name]}" + "{post[author]}" + "{post[title]} - [{post[id]}]" + ]; + }; + artstation = { + external = true; + directory = [ "{userinfo[username]}" ]; + }; + gfycat.format = "webm"; + reddit = { + parent-directory = true; + directory = [ "{author}" ]; + }; + redgifs = { + reverse = true; + directory = [ "{userName}" ]; + }; + imgur.mp4 = true; + fanbox = { + embeds = true; + directory = [ + "{category}" + "{creatorId}" + ]; + }; + readcomiconline = { + chapter-reverse = true; + quality = "hq"; + captcha = "wait"; + postprocessors = [ "cbz" ]; + directory = [ + "comics" + "{comic}" + "{comic} #{issue}" + ]; + }; + kissmanga = { + chapter-reverse = true; + captcha = "wait"; + postprocessors = [ "cbz" ]; + directory = [ + "manga" + "{subcategory}" + "{manga}" + "{manga} Ch.{chapter}{chapter_minor}" + ]; + }; + mangahere = { + chapter-reverse = true; + postprocessors = [ "cbz" ]; + directory = [ + "manga" + "{subcategory}" + "{manga}" + "{manga} Ch.{chapter}{chapter_minor}" + ]; + }; + mangadex = { + chapter-reverse = true; + chapter-filter = "lang == 'en'"; + postprocessors = [ "cbz" ]; + directory = [ + "manga" + "manga" + "{manga}" + "{manga} Ch.{chapter}{chapter_minor}" + ]; + }; + manganelo = { + chapter-reverse = true; + chapter-filter = "lang == 'en'"; + postprocessors = [ "cbz" ]; + directory = [ + "manga" + "{subcategory}" + "{manga}" + "{manga} Ch.{chapter}{chapter_minor}" + ]; + }; + mangareader = { + chapter-reverse = true; + postprocessors = [ "cbz" ]; + directory = [ + "manga" + "{subcategory}" + "{manga}" + "{manga} Ch.{chapter}{chapter_minor}" + ]; + }; + mangapanda = { + chapter-reverse = true; + postprocessors = [ "cbz" ]; + directory = [ + "manga" + "{subcategory}" + "{manga}" + "{manga} Ch.{chapter}{chapter_minor}" + ]; + }; + webtoons = { + chapter-reverse = true; + postprocessors = [ "cbz" ]; + directory = [ + "webtoons" + "{comic}" + "{comic} #{episode}" + ]; + }; + }; + output.mode = "auto"; + downloader = { + part = true; + part-directory = "/home/jawz/.cache/gallery-dl"; + ytdl = { + logging = true; + format = "bestvideo+bestaudio/best"; + module = "yt_dlp"; + forward-cookies = true; + }; + http = { + rate = null; + retries = 5; + timeout = 10.0; + verify = true; + }; + }; + postprocessor.cbz = { + name = "zip"; + compression = "store"; + mode = "safe"; + extension = "cbz"; + }; +} diff --git a/dotfiles/npmrc b/dotfiles/npmrc new file mode 100644 index 0000000..8932649 --- /dev/null +++ b/dotfiles/npmrc @@ -0,0 +1,7 @@ +user=0 +unsafe-perm=true +prefix=${XDG_DATA_HOME}/npm +cache=${XDG_CACHE_HOME}/npm +tmp=${XDG_RUNTIME_DIR}/npm +init-module=${XDG_CONFIG_HOME}/npm/config/npm-init.js +store-dir=${XDG_DATA_HOME}/pnpm-store diff --git a/dotfiles/pythonrc b/dotfiles/pythonrc new file mode 100644 index 0000000..f3f86a5 --- /dev/null +++ b/dotfiles/pythonrc @@ -0,0 +1,17 @@ +import os +import atexit +import readline + +history = os.path.join(os.environ['XDG_CACHE_HOME'], 'python_history') +try: + readline.read_history_file(history) +except OSError: + pass + +def write_history(): + try: + readline.write_history_file(history) + except OSError: + pass + +atexit.register(write_history) diff --git a/dotfiles/stignore b/dotfiles/stignore new file mode 100644 index 0000000..1b54b31 --- /dev/null +++ b/dotfiles/stignore @@ -0,0 +1,7 @@ +(?d)jawz/chrome/userChrome.css +(?d)jawz/chrome/userContent.css +(?d)jawz/lock +(?d)jawz/user.js +(?d)native-messaging-hosts/org.gnome.browser_connector.json +(?d)native-messaging-hosts/org.gnome.chrome_gnome_shell.json +(?d)profiles.ini diff --git a/dotfiles/unpackerr.conf b/dotfiles/unpackerr.conf new file mode 100644 index 0000000..bf92678 --- /dev/null +++ b/dotfiles/unpackerr.conf @@ -0,0 +1,222 @@ +## Unpackerr Example Configuration File ## +## The following values are application defaults. ## +## Environment Variables may override all values. ## +#################################################### + +# [true/false] Turn on debug messages in the output. Do not wrap this in quotes. +# Recommend trying this so you know what it looks like. I personally leave it on. +debug = false + +# Disable writing messages to stdout. This silences the app. You should set a log +# file below if you set this to true. Recommended when starting with systemctl. +quiet = false + +# Setting activity to true will silence all app queue log lines with only zeros. +# Set this to true when you want less log spam. +activity = false + +# The application queue data is logged on an interval. Adjust that interval with this setting. +# Default is a minute. 2m, 5m, 10m, 30m, 1h are also perfectly acceptable. +log_queues = "1m" + +# Write messages to a log file. This is the same data that is normally output to stdout. +# This setting is great for Docker users that want to export their logs to a file. +# The alternative is to use syslog to log the output of the application to a file. +# Default is no log file; this is unset. log_files=0 turns off auto-rotation. +# Default files is 10 and size(mb) is 10 Megabytes; both doubled if debug is true. +#log_file = '/downloads/unpackerr.log' +log_files = 10 +log_file_mb = 10 + +# How often to poll sonarr and radarr. +# Recommend 1m-5m. Uses Go Duration. +interval = "5m" + +# How long an item must be queued (download complete) before extraction will start. +# One minute is the historic default and works well. Set higher if your downloads +# take longer to finalize (or transfer locally). Uses Go Duration. +start_delay = "1m" + +# How long to wait before removing the history for a failed extraction. +# Once the history is deleted the item will be recognized as new and +# extraction will start again. Uses Go Duration. +retry_delay = "5m" + +# How many files may be extracted in parallel. 1 works fine. +# Do not wrap the number in quotes. Raise this only if you have fast disks and CPU. +parallel = 1 + +# Use these configurations to control the file modes used for newly extracted +# files and folders. Recommend 0644/0755 or 0666/0777. +file_mode = "0664" +dir_mode = "0775" + +[webserver] +## The web server currently only supports metrics; set this to true if you wish to use it. + metrics = false +## This may be set to a port or an ip:port to bind a specific IP. 0.0.0.0 binds ALL IPs. + listen_addr = "0.0.0.0:5656" +## Recommend setting a log file for HTTP requests. Otherwise, they go with other logs. + log_file = "" +## This app automatically rotates logs. Set these to the size and number to keep. + log_files = 10 + log_file_mb = 10 +## Set both of these to valid file paths to enable HTTPS/TLS. + ssl_cert_file = "" + ssl_key_file = "" +## Base URL from which to serve content. + urlbase = "/" +## Upstreams should be set to the IP or CIDR of your trusted upstream proxy. +## Setting this correctly allows X-Forwarded-For to be used in logs. +## In the future it may control auth proxy trust. Must be a list of strings. + upstreams = [ ] # example: upstreams = [ "127.0.0.1/32", "10.1.2.0/24" ] + +##-Notes-#######-READ THIS!!!-################################################## +## The following sections can be repeated if you have more than one Sonarr, ## +## Radarr or Lidarr, Readarr, Folder, Webhook, or Command Hook. ## +## You MUST uncomment the [[header]] and api_key at a minimum for Starr apps. ## +## ALL LINES BEGINNING WITH A HASH # ARE IGNORED ## +## REMOVE THE HASH # FROM CONFIG LINES YOU WANT TO CHANGE ## +################################################################################ + +[[sonarr]] +url = "http://localhost:8989" +api_key = "52869fe7bec4482dafb21c4053fe71e4" +## File system path where downloaded Sonarr items are located. +paths = ['/srv/pool/multimedia/downloads/torrent'] +## Default protocols is torrent. Alternative: "torrent,usenet" +protocols = "torrent" +## How long to wait for a reply from the backend. +timeout = "10s" +## How long to wait after import before deleting the extracted items. +delete_delay = "5m" +## If you use this app with NZB you may wish to delete archives after extraction. +## General recommendation is: do not enable this for torrent use. +## Setting this to true deletes the entire original download folder after import. +# delete_orig = false +## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish. +# syncthing = false + +[[radarr]] +url = "http://127.0.0.1:7878" +api_key = "a987ac45ca2c47bc88e762031ea33296" +## File system path where downloaded Radarr items are located. +paths = ['/srv/pool/multimedia/downloads/torrent'] +## Default protocols is torrents. Alternative: "torrent,usenet" +protocols = "torrent" +## How long to wait for a reply from the backend. +timeout = "10s" +## How long to wait after import before deleting the extracted items. +delete_delay = "5m" +## If you use this app with NZB you may wish to delete archives after extraction. +## General recommendation is: do not enable this for torrent use. +## Setting this to true deletes the entire original download folder after import. +# delete_orig = false +## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish. +# syncthing = false + +#[[lidarr]] +# url = "http://127.0.0.1:8686" +# api_key = "0123456789abcdef0123456789abcdef" +## File system path where downloaded Lidarr items are located. +# paths = ['/downloads'] +## Default protocols is torrent. Alternative: "torrent,usenet" +# protocols = "torrent" +## How long to wait for a reply from the backend. +# timeout = "10s" +## How long to wait after import before deleting the extracted items. +# delete_delay = "5m" +## If you use this app with NZB you may wish to delete archives after extraction. +## General recommendation is: do not enable this for torrent use. +## Setting this to true deletes the entire original download folder after import. +# delete_orig = false +## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish. +# syncthing = false + +#[[readarr]] +# url = "http://127.0.0.1:8787" +# api_key = "0123456789abcdef0123456789abc" +## File system path where downloaded Readarr items are located. +# paths = ['/downloads'] +## Default protocols is torrent. Alternative: "torrent,usenet" +# protocols = "torrent" +## How long to wait for a reply from the backend. +# timeout = "10s" +## How long to wait after import before deleting the extracted items. +# delete_delay = "5m" +## If you use this app with NZB you may wish to delete archives after extraction. +## General recommendation is: do not enable this for torrent use. +## Setting this to true deletes the entire original download folder after import. +# delete_orig = false +## If you use Syncthing, setting this to true will make unpackerr wait for syncs to finish. +# syncthing = false + + +################################################################################## +### ### STOP HERE ### STOP HERE ### STOP HERE ### STOP HERE #### STOP HERE ### # +### Only using Starr apps? The things above. The below configs are OPTIONAL. ### # +################################################################################## + +##-Folders-####################################################################### +## This application can also watch folders for things to extract. If you copy a ## +## subfolder into a watched folder (defined below) any extractable items in the ## +## folder will be decompressed. This has nothing to do with Starr applications. ## +################################################################################## +#[[folder]] +# path = '/some/folder/to/watch' +## Path to extract files to. The default (leaving this blank) is the same as `path` (above). +# extract_path = "" +## Delete extracted or original files this long after extraction. +## The default is 0. Set to 0 to disable all deletes. Uncomment it to enable deletes. Uses Go Duration. +# delete_after = "10m" +## Delete extracted files after successful extraction? true/false, no quotes. Honors delete_after. +# delete_files = false +## Delete original items after successful extraction? true/false, no quotes. Honors delete_after. +# delete_original = false +## Disable extraction log (unpackerred.txt) file creation? true/false, no quotes. +# disable_log = false +## Move extracted files into original folder? If false, files go into an _unpackerred folder. +# move_back = false +## Set this to true if you want this app to extract ISO files with .iso extension. +# extract_isos = false + + +################ +### Webhooks ### +################ +# Sends a webhook when an extraction queues, starts, finishes, and/or is deleted. +# Created to integrate with notifiarr.com. +# Also works natively with Discord.com, Telegram.org, and Slack.com webhooks. +# Can possibly be used with other services by providing a custom template_path. +###### Don't forget to uncomment [[webhook]] and url at a minimum !!!! +#[[webhook]] +# url = "https://notifiarr.com/api/v1/notification/unpackerr/api_key_from_notifiarr_com" +# name = "" # Set this to hide the URL in logs. +# silent = false # do not log success (less log spam) +# events = [0] # list of event ids to include, 0 == all. +## Advanced Optional Webhook Configuration +# nickname = "" # Used in Discord and Slack templates as bot name, in Telegram as chat_id. +# channel = "" # Also passed into templates. Used in Slack templates for destination channel. +# exclude = [] # list of apps to exclude, ie. ["radarr", "lidarr"] +# template_path = "" # Override internal webhook template for discord.com or other hooks. +# template = "" # Override automatic template detection. Values: notifiarr, discord, telegram, gotify, pushover, slack +# ignore_ssl = false # Set this to true to ignore the SSL certificate on the server. +# timeout = "10s" # You can adjust how long to wait for a server response. +# content_type = "application/json" # If your custom template uses another MIME type, set this. + + +##################### +### Command Hooks ### +##################### +# Executes a script or command when an extraction queues, starts, finishes, and/or is deleted. +# All data is passed in as environment variables. Try /usr/bin/env to see what variables are available. +###### Don't forget to uncomment [[cmdhook]] and url at a minimum !!!! +#[[cmdhook]] +# command = '/my/cool/app' # Path to command or script. +# shell = false # Runs the command inside /bin/sh ('nix) or cmd.exe (Windows). +# name = "" # Provide an optional name for logging. +# silent = false # Hides command output from logs. +# events = [0] # list of event ids to include, 0 == all. +## Optional Command Hook Configuration +# exclude = [] # list of apps to exclude, ie. ["radarr", "lidarr"] +# timeout = "10s" # You can adjust how long to wait for a server response. diff --git a/environments/cinnamon.nix b/environments/cinnamon.nix new file mode 100644 index 0000000..1cc7186 --- /dev/null +++ b/environments/cinnamon.nix @@ -0,0 +1,21 @@ +{ pkgs, ... }: +{ + services = { + libinput.enable = true; + xserver = { + enable = true; + displayManager.lightdm.enable = true; + desktopManager.cinnamon.enable = true; + }; + }; + qt = { + enable = true; + style = "adwaita"; + }; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + adw-gtk3 # theme legacy applications + papirus-icon-theme # icon theme + ; + }; +} diff --git a/environments/gnome.nix b/environments/gnome.nix new file mode 100644 index 0000000..2adf14b --- /dev/null +++ b/environments/gnome.nix @@ -0,0 +1,45 @@ +{ + pkgs, + lib, + ... +}: +{ + services = { + gvfs.enable = true; + libinput.enable = true; + xserver = { + enable = true; + displayManager.gdm.enable = true; + desktopManager = { + gnome.enable = true; + xterm.enable = lib.mkForce false; + }; + }; + }; + environment.gnome.excludePackages = builtins.attrValues { + inherit (pkgs) + baobab + cheese + epiphany + gnome-characters + gnome-connections + gnome-font-viewer + gnome-photos + # gnome-text-editor + gnome-tour + yelp + gnome-music + totem + ; + }; + qt.enable = true; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs.gnomeExtensions) + tactile # window manager + freon # hardware temperature monitor + gamemode-shell-extension # I guess I'm a gamer now? + burn-my-windows # special effects for when closing windows + pano # clipboard manager + ; + }; +} diff --git a/environments/hyprland.nix b/environments/hyprland.nix new file mode 100644 index 0000000..17c33c6 --- /dev/null +++ b/environments/hyprland.nix @@ -0,0 +1,109 @@ +{ + pkgs, + ... +}: +let + startupScript = pkgs.pkgs.writeShellScriptBin "start" '' + ${pkgs.waybar}/bin/waybar & + ${pkgs.swww}/bin/swww init & + sleep 1 + ''; +in +{ + programs.hyprland.enable = true; + services.greetd = { + enable = true; + settings.default_session = { + command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --cmd Hyprland"; + user = "greeter"; + }; + }; + xdg.portal = { + enable = true; + extraPortals = [ + pkgs.xdg-desktop-portal-hyprland + # pkgs.xdg-desktop-portal-gtk + ]; + }; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + # Wayland utilities + wl-clipboard + wf-recorder + grim + slurp + + wofi # Application launcher + mako # Notification daemon + libnotify # dependency of mako + swaylock-effects # Screen locker + # nautilus # File manager + ; + }; + home-manager.users.jawz = { + programs.kitty.enable = true; + wayland.windowManager.hyprland = { + enable = true; + settings = { + "$mainMod" = "SUPER"; + exec-once = "${startupScript}/bin/start"; + general = { + gaps_in = 5; + gaps_out = 10; + border_size = 2; + layout = "dwindle"; + }; + dwindle = { + pseudotile = true; + preserve_split = true; + force_split = 2; + }; + bind = [ + "$mainMod, return, exec, kitty" + "$mainMod, Q, killactive," + "$mainMod SHIFT, F, togglefloating," + "$mainMod, F, fullscreen," + "$mainMod, T, pin," + "$mainMod, G, togglegroup," + "$mainMod, bracketleft, changegroupactive, b" + "$mainMod, bracketright, changegroupactive, f" + "$mainMod, S, exec, wofi --show drun icons" + "$mainMod, P, pin, active" + + ",XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.4 @DEFAULT_AUDIO_SINK@ 5%+" + ",XF86AudioLowerVolume, exec, wpctl set-volume -l 1.4 @DEFAULT_AUDIO_SINK@ 5%-" + + "$mainMod, left, movefocus, l" + "$mainMod, right, movefocus, r" + "$mainMod, up, movefocus, u" + "$mainMod, down, movefocus, d" + + "$mainMod, h, movefocus, l" + "$mainMod, l, movefocus, r" + "$mainMod, k, movefocus, u" + "$mainMod, j, movefocus, d" + + "$mainMod SHIFT, h, movewindow, l" + "$mainMod SHIFT, l, movewindow, r" + "$mainMod SHIFT, k, movewindow, u" + "$mainMod SHIFT, j, movewindow, d" + ]; + binde = [ + "$mainMod SHIFT, h, moveactive, -20 0" + "$mainMod SHIFT, l, moveactive, 20 0" + "$mainMod SHIFT, k, moveactive, 0 -20" + "$mainMod SHIFT, j, moveactive, 0 20" + + "$mainMod CTRL, l, resizeactive, 30 0" + "$mainMod CTRL, h, resizeactive, -30 0" + "$mainMod CTRL, k, resizeactive, 0 -10" + "$mainMod CTRL, j, resizeactive, 0 10" + ]; + bindm = [ + "$mainMod, mouse:272, movewindow" + "$mainMod, mouse:273, resizewindow" + ]; + }; + }; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..d1db6c7 --- /dev/null +++ b/flake.lock @@ -0,0 +1,1259 @@ +{ + "nodes": { + "aquamarine": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1755946532, + "narHash": "sha256-POePremlUY5GyA1zfbtic6XLxDaQcqHN6l+bIxdT5gc=", + "owner": "hyprwm", + "repo": "aquamarine", + "rev": "81584dae2df6ac79f6b6dae0ecb7705e95129ada", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "aquamarine", + "type": "github" + } + }, + "base16": { + "inputs": { + "fromYaml": "fromYaml" + }, + "locked": { + "lastModified": 1746562888, + "narHash": "sha256-YgNJQyB5dQiwavdDFBMNKk1wyS77AtdgDk/VtU6wEaI=", + "owner": "SenchoPens", + "repo": "base16.nix", + "rev": "806a1777a5db2a1ef9d5d6f493ef2381047f2b89", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "base16.nix", + "type": "github" + } + }, + "base16-fish": { + "flake": false, + "locked": { + "lastModified": 1622559957, + "narHash": "sha256-PebymhVYbL8trDVVXxCvZgc0S5VxI7I1Hv4RMSquTpA=", + "owner": "tomyun", + "repo": "base16-fish", + "rev": "2f6dd973a9075dabccd26f1cded09508180bf5fe", + "type": "github" + }, + "original": { + "owner": "tomyun", + "repo": "base16-fish", + "type": "github" + } + }, + "base16-helix": { + "flake": false, + "locked": { + "lastModified": 1748408240, + "narHash": "sha256-9M2b1rMyMzJK0eusea0x3lyh3mu5nMeEDSc4RZkGm+g=", + "owner": "tinted-theming", + "repo": "base16-helix", + "rev": "6c711ab1a9db6f51e2f6887cc3345530b33e152e", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-helix", + "type": "github" + } + }, + "base16-vim": { + "flake": false, + "locked": { + "lastModified": 1732806396, + "narHash": "sha256-e0bpPySdJf0F68Ndanwm+KWHgQiZ0s7liLhvJSWDNsA=", + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "577fe8125d74ff456cf942c733a85d769afe58b7", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "577fe8125d74ff456cf942c733a85d769afe58b7", + "type": "github" + } + }, + "cpu-microcodes": { + "flake": false, + "locked": { + "lastModified": 1758484353, + "narHash": "sha256-zpbmZqUIhmTW01PunE5eXkYzQsMDqOOshr/KjNXeL7A=", + "owner": "platomav", + "repo": "CPUMicrocodes", + "rev": "518e82e753bbd7df44264cac38dc98e6a4ede8c6", + "type": "github" + }, + "original": { + "owner": "platomav", + "repo": "CPUMicrocodes", + "rev": "518e82e753bbd7df44264cac38dc98e6a4ede8c6", + "type": "github" + } + }, + "doom-emacs": { + "inputs": { + "doomemacs": "doomemacs", + "emacs-overlay": "emacs-overlay", + "nixpkgs": [], + "systems": "systems" + }, + "locked": { + "lastModified": 1759221805, + "narHash": "sha256-gKne7A7DWffiqdfUPdX4TK1/a4FU942LM7e6E8ORsTY=", + "owner": "marienz", + "repo": "nix-doom-emacs-unstraightened", + "rev": "5697968fa38469d12012706d9322211de10309c9", + "type": "github" + }, + "original": { + "owner": "marienz", + "repo": "nix-doom-emacs-unstraightened", + "type": "github" + } + }, + "doomemacs": { + "flake": false, + "locked": { + "lastModified": 1759180402, + "narHash": "sha256-Y67ooUjDMWjPk+/IjMRnhe+OPn19Q0wF73prtExwyiI=", + "owner": "doomemacs", + "repo": "doomemacs", + "rev": "5e7e93beb9f2b5a81768aaf4950203ceea21c4f6", + "type": "github" + }, + "original": { + "owner": "doomemacs", + "repo": "doomemacs", + "type": "github" + } + }, + "emacs-overlay": { + "inputs": { + "nixpkgs": [ + "doom-emacs" + ], + "nixpkgs-stable": [ + "doom-emacs" + ] + }, + "locked": { + "lastModified": 1759221279, + "narHash": "sha256-7EAByrl70kQ2gV0opDiNhySsk9KcJiRpnnL+BEaNOhc=", + "owner": "nix-community", + "repo": "emacs-overlay", + "rev": "6bbda1ce5dc002b22c95323b01d40518e843a00d", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "emacs-overlay", + "type": "github" + } + }, + "firefox-gnome-theme": { + "flake": false, + "locked": { + "lastModified": 1748383148, + "narHash": "sha256-pGvD/RGuuPf/4oogsfeRaeMm6ipUIznI2QSILKjKzeA=", + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "rev": "4eb2714fbed2b80e234312611a947d6cb7d70caf", + "type": "github" + }, + "original": { + "owner": "rafaelmardojai", + "repo": "firefox-gnome-theme", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1747046372, + "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1756770412, + "narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "4524271976b625a4a605beefd893f270620fd751", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": [ + "nur", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1733312601, + "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_4": { + "inputs": { + "nixpkgs-lib": [ + "stylix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1749398372, + "narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "fonts": { + "flake": false, + "locked": { + "lastModified": 1759200391, + "narHash": "sha256-S5LwvPL7sKgwKUhCyTpcuWUxCq57RFh7wbZ6rIc5AgU=", + "ref": "refs/heads/master", + "rev": "edea9d2aaf2f4e0481fbbb8e26f68a9f39248e3f", + "revCount": 2, + "type": "git", + "url": "https://git.servidos.lat/jawz/fonts.git" + }, + "original": { + "type": "git", + "url": "https://git.servidos.lat/jawz/fonts.git" + } + }, + "fromYaml": { + "flake": false, + "locked": { + "lastModified": 1731966426, + "narHash": "sha256-lq95WydhbUTWig/JpqiB7oViTcHFP8Lv41IGtayokA8=", + "owner": "SenchoPens", + "repo": "fromYaml", + "rev": "106af9e2f715e2d828df706c386a685698f3223b", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "fromYaml", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "hyprland", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gnome-shell": { + "flake": false, + "locked": { + "lastModified": 1744584021, + "narHash": "sha256-0RJ4mJzf+klKF4Fuoc8VN8dpQQtZnKksFmR2jhWE1Ew=", + "owner": "GNOME", + "repo": "gnome-shell", + "rev": "52c517c8f6c199a1d6f5118fae500ef69ea845ae", + "type": "github" + }, + "original": { + "owner": "GNOME", + "ref": "48.1", + "repo": "gnome-shell", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1758463745, + "narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-25.05", + "repo": "home-manager", + "type": "github" + } + }, + "hyprcursor": { + "inputs": { + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1753964049, + "narHash": "sha256-lIqabfBY7z/OANxHoPeIrDJrFyYy9jAM4GQLzZ2feCM=", + "owner": "hyprwm", + "repo": "hyprcursor", + "rev": "44e91d467bdad8dcf8bbd2ac7cf49972540980a5", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprcursor", + "type": "github" + } + }, + "hyprgraphics": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1758192433, + "narHash": "sha256-CR6RnqEJSTiFgA6KQY4TTLUWbZ8RBnb+hxQqesuQNzQ=", + "owner": "hyprwm", + "repo": "hyprgraphics", + "rev": "c44e749dd611521dee940d00f7c444ee0ae4cfb7", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprgraphics", + "type": "github" + } + }, + "hyprland": { + "inputs": { + "aquamarine": "aquamarine", + "hyprcursor": "hyprcursor", + "hyprgraphics": "hyprgraphics", + "hyprland-protocols": "hyprland-protocols", + "hyprland-qtutils": "hyprland-qtutils", + "hyprlang": "hyprlang", + "hyprutils": "hyprutils", + "hyprwayland-scanner": "hyprwayland-scanner", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks", + "systems": "systems_2", + "xdph": "xdph" + }, + "locked": { + "lastModified": 1759169434, + "narHash": "sha256-1u6kq88ICeE9IiJPditYa248ZoEqo00kz6iUR+jLvBQ=", + "owner": "hyprwm", + "repo": "Hyprland", + "rev": "38c1e72c9d81fcdad8f173e06102a5da18836230", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "Hyprland", + "type": "github" + } + }, + "hyprland-protocols": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1749046714, + "narHash": "sha256-kymV5FMnddYGI+UjwIw8ceDjdeg7ToDVjbHCvUlhn14=", + "owner": "hyprwm", + "repo": "hyprland-protocols", + "rev": "613878cb6f459c5e323aaafe1e6f388ac8a36330", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-protocols", + "type": "github" + } + }, + "hyprland-qt-support": { + "inputs": { + "hyprlang": [ + "hyprland", + "hyprland-qtutils", + "hyprlang" + ], + "nixpkgs": [ + "hyprland", + "hyprland-qtutils", + "nixpkgs" + ], + "systems": [ + "hyprland", + "hyprland-qtutils", + "systems" + ] + }, + "locked": { + "lastModified": 1749154592, + "narHash": "sha256-DO7z5CeT/ddSGDEnK9mAXm1qlGL47L3VAHLlLXoCjhE=", + "owner": "hyprwm", + "repo": "hyprland-qt-support", + "rev": "4c8053c3c888138a30c3a6c45c2e45f5484f2074", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-qt-support", + "type": "github" + } + }, + "hyprland-qtutils": { + "inputs": { + "hyprland-qt-support": "hyprland-qt-support", + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprland-qtutils", + "hyprlang", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1757694755, + "narHash": "sha256-j+w5QUUr2QT/jkxgVKecGYV8J7fpzXCMgzEEr6LG9ug=", + "owner": "hyprwm", + "repo": "hyprland-qtutils", + "rev": "5ffdfc13ed03df1dae5084468d935f0a3f2c9a4c", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprland-qtutils", + "type": "github" + } + }, + "hyprlang": { + "inputs": { + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1756810301, + "narHash": "sha256-wgZ3VW4VVtjK5dr0EiK9zKdJ/SOqGIBXVG85C3LVxQA=", + "owner": "hyprwm", + "repo": "hyprlang", + "rev": "3d63fb4a42c819f198deabd18c0c2c1ded1de931", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprlang", + "type": "github" + } + }, + "hyprutils": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1756117388, + "narHash": "sha256-oRDel6pNl/T2tI+nc/USU9ZP9w08dxtl7hiZxa0C/Wc=", + "owner": "hyprwm", + "repo": "hyprutils", + "rev": "b2ae3204845f5f2f79b4703b441252d8ad2ecfd0", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprutils", + "type": "github" + } + }, + "hyprwayland-scanner": { + "inputs": { + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1755184602, + "narHash": "sha256-RCBQN8xuADB0LEgaKbfRqwm6CdyopE1xIEhNc67FAbw=", + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "rev": "b3b0f1f40ae09d4447c20608e5a4faf8bf3c492d", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "hyprwayland-scanner", + "type": "github" + } + }, + "jawz-scripts": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "sudoku-solver": "sudoku-solver" + }, + "locked": { + "lastModified": 1759213850, + "narHash": "sha256-KnFUzXjSOtSG9U4U4OJonCTZaMWqJjXvHL1PQW994A4=", + "ref": "refs/heads/master", + "rev": "38959dc37b09d1cb037df02086e4d07b9ef30b80", + "revCount": 105, + "type": "git", + "url": "https://git.servidos.lat/jawz/scripts.git" + }, + "original": { + "type": "git", + "url": "https://git.servidos.lat/jawz/scripts.git" + } + }, + "nix-gaming": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1759110900, + "narHash": "sha256-fcu/r0ijvaYT2VHGkZGr0wq9uBMNFkiftVBy43/2oig=", + "owner": "fufexan", + "repo": "nix-gaming", + "rev": "2ac6a49266e9159ccb001b4c8cb1f50f67d502ae", + "type": "github" + }, + "original": { + "owner": "fufexan", + "repo": "nix-gaming", + "type": "github" + } + }, + "nixlib": { + "locked": { + "lastModified": 1736643958, + "narHash": "sha256-tmpqTSWVRJVhpvfSN9KXBvKEXplrwKnSZNAoNPf/S/s=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "1418bc28a52126761c02dd3d89b2d8ca0f521181", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixos-generators": { + "inputs": { + "nixlib": "nixlib", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1751903740, + "narHash": "sha256-PeSkNMvkpEvts+9DjFiop1iT2JuBpyknmBUs0Un0a4I=", + "owner": "nix-community", + "repo": "nixos-generators", + "rev": "032decf9db65efed428afd2fa39d80f7089085eb", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-generators", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1743576891, + "narHash": "sha256-vXiKURtntURybE6FMNFAVpRPr8+e8KoLPrYs9TGuAKc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "44a69ed688786e98a101f02b712c313f1ade37ab", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1754788789, + "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_2": { + "locked": { + "dir": "lib", + "lastModified": 1711703276, + "narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d8fe5e6c92d0d190646fb9f1056741a229980089", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-small": { + "locked": { + "lastModified": 1759250113, + "narHash": "sha256-apF3ww4pPkxHI5c424Z6VYdImge1iZSP6TOH45lIqxU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f579c51fd27e9f66c8236b26a47ed78b315f785d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1759036355, + "narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1759143472, + "narHash": "sha256-TvODmeR2W7yX/JmOCmP+lAFNkTT7hAxYcF3Kz8SZV3w=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "5ed4e25ab58fd4c028b59d5611e14ea64de51d23", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixtendo-switch": { + "inputs": { + "flake-parts": "flake-parts_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1721329381, + "narHash": "sha256-oj95wOUYXXlpx87Fjmf+Nu+wz1qrFtCf7AKDnxEB8oQ=", + "owner": "nyawox", + "repo": "nixtendo-switch", + "rev": "ba69506f44d4e154cdf11b5ba3d23534f9fb3238", + "type": "github" + }, + "original": { + "owner": "nyawox", + "repo": "nixtendo-switch", + "type": "github" + } + }, + "nur": { + "inputs": { + "flake-parts": "flake-parts_3", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1759260470, + "narHash": "sha256-7KFWm6l+qJl+b1XAx9D8isjCb2kluJEGzquZxmJPEL4=", + "owner": "nix-community", + "repo": "nur", + "rev": "2b8508603232941676978619d6d4b34fc9e0b486", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nur", + "type": "github" + } + }, + "nur_2": { + "inputs": { + "flake-parts": [ + "stylix", + "flake-parts" + ], + "nixpkgs": [ + "stylix", + "nixpkgs" + ], + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1751320053, + "narHash": "sha256-3m6RMw0FbbaUUa01PNaMLoO7D99aBClmY5ed9V3vz+0=", + "owner": "nix-community", + "repo": "NUR", + "rev": "cbde1735782f9c2bb2c63d5e05fba171a14a4670", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NUR", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": [ + "hyprland", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1758108966, + "narHash": "sha256-ytw7ROXaWZ7OfwHrQ9xvjpUWeGVm86pwnEd1QhzawIo=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "54df955a695a84cd47d4a43e08e1feaf90b1fd9b", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "doom-emacs": "doom-emacs", + "fonts": "fonts", + "home-manager": "home-manager", + "hyprland": "hyprland", + "jawz-scripts": "jawz-scripts", + "nix-gaming": "nix-gaming", + "nixos-generators": "nixos-generators", + "nixpkgs": "nixpkgs_2", + "nixpkgs-small": "nixpkgs-small", + "nixpkgs-unstable": "nixpkgs-unstable", + "nixtendo-switch": "nixtendo-switch", + "nur": "nur", + "sops-nix": "sops-nix", + "stylix": "stylix", + "ucodenix": "ucodenix", + "wallpapers": "wallpapers" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1759188042, + "narHash": "sha256-f9QC2KKiNReZDG2yyKAtDZh0rSK2Xp1wkPzKbHeQVRU=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "9fcfabe085281dd793589bdc770a2e577a3caa5d", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "stylix": { + "inputs": { + "base16": "base16", + "base16-fish": "base16-fish", + "base16-helix": "base16-helix", + "base16-vim": "base16-vim", + "firefox-gnome-theme": "firefox-gnome-theme", + "flake-parts": "flake-parts_4", + "gnome-shell": "gnome-shell", + "nixpkgs": [ + "nixpkgs" + ], + "nur": "nur_2", + "systems": "systems_4", + "tinted-foot": "tinted-foot", + "tinted-kitty": "tinted-kitty", + "tinted-schemes": "tinted-schemes", + "tinted-tmux": "tinted-tmux", + "tinted-zed": "tinted-zed" + }, + "locked": { + "lastModified": 1759050585, + "narHash": "sha256-Mj99rGy+K9jaQ85U2YWydZ9OKCIAdkxClrJlfG04GxU=", + "owner": "danth", + "repo": "stylix", + "rev": "3f71498ed14405aea347b9f5b7f56d97e64e904c", + "type": "github" + }, + "original": { + "owner": "danth", + "ref": "release-25.05", + "repo": "stylix", + "type": "github" + } + }, + "sudoku-solver": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "path": "./src/sudoku-hs", + "type": "path" + }, + "original": { + "path": "./src/sudoku-hs", + "type": "path" + }, + "parent": [ + "jawz-scripts" + ] + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "tinted-foot": { + "flake": false, + "locked": { + "lastModified": 1726913040, + "narHash": "sha256-+eDZPkw7efMNUf3/Pv0EmsidqdwNJ1TaOum6k7lngDQ=", + "owner": "tinted-theming", + "repo": "tinted-foot", + "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-foot", + "rev": "fd1b924b6c45c3e4465e8a849e67ea82933fcbe4", + "type": "github" + } + }, + "tinted-kitty": { + "flake": false, + "locked": { + "lastModified": 1735730497, + "narHash": "sha256-4KtB+FiUzIeK/4aHCKce3V9HwRvYaxX+F1edUrfgzb8=", + "owner": "tinted-theming", + "repo": "tinted-kitty", + "rev": "de6f888497f2c6b2279361bfc790f164bfd0f3fa", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-kitty", + "type": "github" + } + }, + "tinted-schemes": { + "flake": false, + "locked": { + "lastModified": 1750770351, + "narHash": "sha256-LI+BnRoFNRa2ffbe3dcuIRYAUcGklBx0+EcFxlHj0SY=", + "owner": "tinted-theming", + "repo": "schemes", + "rev": "5a775c6ffd6e6125947b393872cde95867d85a2a", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "schemes", + "type": "github" + } + }, + "tinted-tmux": { + "flake": false, + "locked": { + "lastModified": 1751159871, + "narHash": "sha256-UOHBN1fgHIEzvPmdNMHaDvdRMgLmEJh2hNmDrp3d3LE=", + "owner": "tinted-theming", + "repo": "tinted-tmux", + "rev": "bded5e24407cec9d01bd47a317d15b9223a1546c", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "tinted-tmux", + "type": "github" + } + }, + "tinted-zed": { + "flake": false, + "locked": { + "lastModified": 1751158968, + "narHash": "sha256-ksOyv7D3SRRtebpXxgpG4TK8gZSKFc4TIZpR+C98jX8=", + "owner": "tinted-theming", + "repo": "base16-zed", + "rev": "86a470d94204f7652b906ab0d378e4231a5b3384", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-zed", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "stylix", + "nur", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1733222881, + "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "49717b5af6f80172275d47a418c9719a31a78b53", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "ucodenix": { + "inputs": { + "cpu-microcodes": "cpu-microcodes" + }, + "locked": { + "lastModified": 1758553579, + "narHash": "sha256-/p9ID64/5G988NDPvfRSjgbV8GdfvJ2el9kz71nrRnU=", + "owner": "e-tho", + "repo": "ucodenix", + "rev": "ba7f0a366460e0fbea9622fc770cb982be0e4720", + "type": "github" + }, + "original": { + "owner": "e-tho", + "repo": "ucodenix", + "type": "github" + } + }, + "wallpapers": { + "flake": false, + "locked": { + "lastModified": 1759117171, + "narHash": "sha256-Oyp4MKcld+tlZISm2HvuRErgHUb2mztpOH6v3g8B9uA=", + "ref": "refs/heads/main", + "rev": "0bc27e282a4c13d43139c4794e80a5951e4787b8", + "revCount": 1, + "type": "git", + "url": "https://git.servidos.lat/jawz/wallpapers.git" + }, + "original": { + "type": "git", + "url": "https://git.servidos.lat/jawz/wallpapers.git" + } + }, + "xdph": { + "inputs": { + "hyprland-protocols": [ + "hyprland", + "hyprland-protocols" + ], + "hyprlang": [ + "hyprland", + "hyprlang" + ], + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1755354946, + "narHash": "sha256-zdov5f/GcoLQc9qYIS1dUTqtJMeDqmBmo59PAxze6e4=", + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "rev": "a10726d6a8d0ef1a0c645378f983b6278c42eaa0", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..056a480 --- /dev/null +++ b/flake.nix @@ -0,0 +1,130 @@ +{ + description = "JawZ NixOS flake setup"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.05"; + nixpkgs-small.url = "github:nixos/nixpkgs?ref=nixos-25.05-small"; + nixpkgs-unstable.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + ucodenix.url = "github:e-tho/ucodenix"; + doom-emacs = { + url = "github:marienz/nix-doom-emacs-unstraightened"; + inputs.nixpkgs.follows = ""; + }; + jawz-scripts = { + url = "git+https://git.servidos.lat/jawz/scripts.git"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + wallpapers = { + url = "git+https://git.servidos.lat/jawz/wallpapers.git"; + flake = false; + }; + fonts = { + url = "git+https://git.servidos.lat/jawz/fonts.git"; + flake = false; + }; + nur = { + url = "github:nix-community/nur"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nix-gaming = { + url = "github:fufexan/nix-gaming"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + hyprland = { + url = "github:hyprwm/Hyprland"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + home-manager = { + url = "github:nix-community/home-manager?ref=release-25.05"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + stylix = { + url = "github:danth/stylix/release-25.05"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nixtendo-switch = { + url = "github:nyawox/nixtendo-switch"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nixos-generators = { + url = "github:nix-community/nixos-generators"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + outputs = + { self, jawz-scripts, ... }@inputs: + let + inherit (self) outputs; + system = "x86_64-linux"; + mkpkgs = + repo: + import repo { + inherit system; + config.allowUnfree = true; + }; + langList = builtins.filter (name: name != "emacs") ( + builtins.map (file: builtins.replaceStrings [ ".nix" ] [ "" ] (baseNameOf file)) ( + builtins.attrNames (builtins.readDir ./modules/dev) + ) + ); + commonModules = name: [ + { + nixpkgs.overlays = [ + (import ./config/overlay.nix { inherit mkpkgs inputs; }) + inputs.doom-emacs.overlays.default + ]; + } + { + nix.registry = { + jawz.flake = self; + unstable.flake = inputs.nixpkgs-unstable; + }; + } + ./hosts/${name}/configuration.nix + inputs.nur.modules.nixos.default + inputs.sops-nix.nixosModules.sops + inputs.stylix.nixosModules.stylix + inputs.nixtendo-switch.nixosModules.nixtendo-switch + ]; + createConfig = + name: local-nixpkgs: + let + lib = local-nixpkgs.lib // inputs.home-manager.lib; + in + lib.nixosSystem { + inherit system; + specialArgs = { + inherit inputs outputs; + }; + modules = commonModules name; + }; + in + { + nixosConfigurations = { + workstation = createConfig "workstation" inputs.nixpkgs; + miniserver = createConfig "miniserver" inputs.nixpkgs-small; + server = createConfig "server" inputs.nixpkgs-small; + galaxy = createConfig "galaxy" inputs.nixpkgs-small; + emacs = createConfig "emacs" inputs.nixpkgs; + }; + packages.${system} = (jawz-scripts.packages.${system} or { }) // { + emacs-vm = inputs.nixos-generators.nixosGenerate { + inherit system; + specialArgs = { + inherit inputs outputs; + }; + modules = commonModules "emacs"; + format = "vm"; + }; + }; + devShells.${system} = builtins.listToAttrs ( + map (name: { + inherit name; + value = self.nixosConfigurations.emacs.config.devShells.${name}; + }) langList + ); + }; +} diff --git a/hosts/emacs/configuration.nix b/hosts/emacs/configuration.nix new file mode 100644 index 0000000..058a567 --- /dev/null +++ b/hosts/emacs/configuration.nix @@ -0,0 +1,49 @@ +{ + lib, + ... +}: +{ + imports = [ + ../../config/base.nix + ../../config/stylix.nix + ../../environments/hyprland.nix + ]; + virtualisation.vmVariant.virtualisation = { + memorySize = 4096; + cores = 4; + graphics = true; + resolution = { + x = 1920; + y = 1080; + }; + }; + my = { + secureHost = false; + stylix.enable = true; + emacs.enable = true; + apps.fonts.enable = true; + shell.tools.enable = true; + services.network.enable = true; + dev = { + nix.enable = true; + python.enable = true; + sh.enable = true; + rust.enable = true; + ruby.enable = true; + javascript.enable = true; + go.enable = true; + haskell.enable = true; + cc.enable = true; + julia.enable = true; + zig.enable = true; + docker.enable = true; + }; + interfaces = lib.mkMerge [ + { + emacs = "eth0"; + } + ]; + }; + networking.hostName = "emacs"; + environment.systemPackages = [ ]; +} diff --git a/hosts/galaxy/configuration.nix b/hosts/galaxy/configuration.nix new file mode 100644 index 0000000..5a93b6d --- /dev/null +++ b/hosts/galaxy/configuration.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ../../config/base.nix + ../../config/stylix.nix + ]; +} diff --git a/hosts/miniserver/configuration.nix b/hosts/miniserver/configuration.nix new file mode 100644 index 0000000..f687c50 --- /dev/null +++ b/hosts/miniserver/configuration.nix @@ -0,0 +1,52 @@ +{ config, ... }: +{ + imports = [ + ./hardware-configuration.nix + ../../config/base.nix + ../../config/stylix.nix + ]; + my = import ./toggles.nix // { + nix.cores = 3; + nix.maxJobs = 8; + users.nixremote.enable = true; + users.nixremote.authorizedKeys = [ + ../../secrets/ssh/ed25519_nixworkstation.pub + ../../secrets/ssh/ed25519_nixserver.pub + ]; + }; + nix.buildMachines = + let + buildMachine = hostName: maxJobs: speedFactor: { + inherit hostName maxJobs speedFactor; + system = "x86_64-linux"; + sshUser = "nixremote"; + supportedFeatures = config.my.nix.features; + }; + in + [ + (buildMachine "workstation" 8 40) + (buildMachine "server" 6 17) + ]; + networking = { + hostName = "miniserver"; + firewall = { + allowedTCPPorts = [ 2049 ]; + allowedUDPPorts = [ 2049 ]; + }; + }; + nixpkgs.config.permittedInsecurePackages = [ "openssl-1.1.1w" ]; + services = { + btrfs.autoScrub = { + enable = true; + fileSystems = [ "/" ]; + }; + minidlna = { + enable = false; + openFirewall = true; + settings = { + inotify = "yes"; + media_dir = [ "/srv/pool/" ]; + }; + }; + }; +} diff --git a/hosts/miniserver/hardware-configuration.nix b/hosts/miniserver/hardware-configuration.nix new file mode 100644 index 0000000..c50fdb2 --- /dev/null +++ b/hosts/miniserver/hardware-configuration.nix @@ -0,0 +1,139 @@ +{ + lib, + modulesPath, + pkgs, + ... +}: +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + powerManagement.cpuFreqGovernor = lib.mkDefault "performance"; + hardware = { + cpu.intel.updateMicrocode = lib.mkDefault true; + graphics = { + enable = true; + enable32Bit = true; + extraPackages = [ pkgs.vpl-gpu-rt ]; + }; + }; + boot = { + kernelModules = [ "kvm-intel" ]; + kernel.sysctl."vm.swappiness" = 80; + loader = { + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot/efi"; + }; + grub = { + enable = true; + device = "nodev"; + efiSupport = true; + enableCryptodisk = true; + }; + }; + extraModulePackages = [ ]; + initrd = { + secrets."/keyfile" = /etc/keyfile; + luks.devices.nvme = { + device = "/dev/disk/by-uuid/30fd7d86-9bed-42a6-8a4e-a2ddb0031233"; + keyFile = "keyfile"; + preLVM = true; + }; + availableKernelModules = [ + "xhci_pci" + "ahci" + "usbhid" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + "sdhci_pci" + ]; + kernelModules = [ "kvm-intel" ]; + }; + }; + fileSystems = + let + nfsMount = server: nfsDisk: { + device = "${server}:/${nfsDisk}"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "x-systemd.idle-timeout=600" + ]; + }; + in + { + "/" = { + device = "/dev/mapper/nvme"; + fsType = "btrfs"; + options = [ + "subvol=nix" + "ssd" + "compress=zstd:3" + "x-systemd.device-timeout=0" + "space_cache=v2" + "commit=120" + "datacow" + "noatime" + ]; + }; + "/home" = { + device = "/dev/mapper/nvme"; + fsType = "btrfs"; + options = [ + "subvol=home" + "ssd" + "compress=zstd:3" + "x-systemd.device-timeout=0" + "space_cache=v2" + "commit=120" + "datacow" + ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/bf0aeb95-94cc-4377-b6e4-1dbb4958b334"; + fsType = "ext4"; + }; + "/boot/efi" = { + device = "/dev/disk/by-uuid/0C7B-4D4C"; + fsType = "vfat"; + }; + "/var/lib/nextcloud/data" = { + device = "/srv/pool/nextcloud"; + options = [ "bind" ]; + depends = [ "/srv/pool" ]; + }; + "/export/pool" = { + device = "/srv/pool"; + options = [ "bind" ]; + depends = [ "/srv/pool" ]; + }; + "/export/jawz" = { + device = "/home/jawz"; + options = [ "bind" ]; + depends = [ "/srv/pool" ]; + }; + "/srv/server/pool" = nfsMount "server" "pool" // { }; + "/srv/server/jawz" = nfsMount "server" "jawz" // { }; + }; + services.nfs.server = { + enable = true; + exports = '' + /export workstation(rw,fsid=0,no_subtree_check) + /export/jawz workstation(rw,nohide,insecure,no_subtree_check) + /export/pool workstation(rw,nohide,insecure,no_subtree_check) + ''; + }; + swapDevices = [ + { + device = "/dev/nvme0n1p3"; + randomEncryption = { + enable = true; + cipher = "aes-xts-plain64"; + keySize = 512; + sectorSize = 4096; + }; + } + ]; +} diff --git a/hosts/miniserver/toggles.nix b/hosts/miniserver/toggles.nix new file mode 100644 index 0000000..93095f4 --- /dev/null +++ b/hosts/miniserver/toggles.nix @@ -0,0 +1,50 @@ +let + mkEnabled = name: { + inherit name; + value.enable = true; + }; + mkEnabledWithProxy = name: { + inherit name; + value = { + enable = true; + enableProxy = true; + }; + }; + enableList = func: list: list |> map func |> builtins.listToAttrs; +in +{ + emacs.enable = true; + enableProxy = true; + websites.portfolio.enableProxy = true; + apps = enableList mkEnabled [ + "dictionaries" + ]; + services = enableList mkEnabled [ + "network" + ]; + shell = enableList mkEnabled [ + "tools" + "multimedia" + ]; + dev = enableList mkEnabled [ + "nix" + "python" + "sh" + ]; + units = enableList mkEnabled [ + "download" + "stream-dl" + ]; + scripts = enableList mkEnabled [ + "split-dir" + "pika-list" + "update-dns" + ]; + servers = + enableList mkEnabled [ + "qbittorrent" + ] + // enableList mkEnabledWithProxy [ + "audiobookshelf" + ]; +} diff --git a/hosts/server/configuration.nix b/hosts/server/configuration.nix new file mode 100644 index 0000000..587f0ab --- /dev/null +++ b/hosts/server/configuration.nix @@ -0,0 +1,74 @@ +{ + pkgs, + config, + lib, + ... +}: +{ + imports = [ + ./hardware-configuration.nix + ../../config/base.nix + ../../config/stylix.nix + ]; + my = import ./toggles.nix { inherit config; } // { + nix.cores = 6; + users.nixremote.enable = true; + users.nixremote.authorizedKeys = [ + ../../secrets/ssh/ed25519_nixworkstation.pub + ../../secrets/ssh/ed25519_nixminiserver.pub + ]; + network.firewall.enabledServicePorts = true; + network.firewall.additionalPorts = [ + 2049 # idk + 8384 # syncthing gui + 22000 # syncthing relay + 3452 # sonarqube + 8448 # synapse ssl + ]; + }; + nix.buildMachines = [ + { + hostName = "workstation"; + system = "x86_64-linux"; + sshUser = "nixremote"; + maxJobs = 8; + speedFactor = 2; + supportedFeatures = config.my.nix.features; + } + ]; + sops.secrets."vps/home/private" = lib.mkIf config.my.secureHost { + sopsFile = ../../secrets/wireguard.yaml; + }; + networking = { + hostName = "server"; + firewall = { + allowedUDPPorts = config.networking.firewall.allowedTCPPorts; + interfaces.wg0.allowedTCPPorts = [ 8081 ]; + }; + wireguard.interfaces.wg0 = lib.mkIf config.my.secureHost { + ips = [ "${config.my.ips.wg-server}/32" ]; + privateKeyFile = config.sops.secrets."vps/home/private".path; + peers = [ + { + publicKey = "dFbiSekBwnZomarcS31o5+w6imHjMPNCipkfc2fZ3GY="; + endpoint = "${config.my.ips.vps}:51820"; + allowedIPs = [ + "${config.my.ips.wg-vps}/32" + "${config.my.ips.wg-friends}/24" # all friends + ]; + persistentKeepalive = 25; + } + ]; + }; + }; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) podman-compose attic-client; + }; + services.btrfs.autoScrub = { + enable = true; + fileSystems = [ + "/" + "/srv/pool" + ]; + }; +} diff --git a/hosts/server/hardware-configuration.nix b/hosts/server/hardware-configuration.nix new file mode 100644 index 0000000..3ed1f60 --- /dev/null +++ b/hosts/server/hardware-configuration.nix @@ -0,0 +1,187 @@ +{ lib, modulesPath, ... }: +let + getUUID = uuid: "/dev/disk/by-uuid/${uuid}"; +in +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + hardware.cpu.intel.updateMicrocode = lib.mkDefault true; + security.pam.loginLimits = [ + { + domain = "*"; + type = "hard"; + item = "nofile"; + value = "131072"; + } + { + domain = "*"; + type = "soft"; + item = "nofile"; + value = "131072"; + } + { + domain = "*"; + type = "hard"; + item = "nproc"; + value = "8192"; + } + { + domain = "*"; + type = "soft"; + item = "nproc"; + value = "8192"; + } + ]; + boot = { + loader = { + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot/efi"; + }; + grub = { + enable = true; + device = "nodev"; + efiSupport = true; + enableCryptodisk = true; + }; + }; + initrd = { + secrets."/keyfile" = /etc/keyfile; + luks.devices = + let + decryptLuks = uuid: { + device = getUUID uuid; + keyFile = "/keyfile"; + preLVM = true; + }; + in + { + nvme = decryptLuks "af72f45c-cf7c-4e7d-8eab-2a95ab754921"; + disk1 = decryptLuks "a9b0f346-7e38-40a6-baf6-3ad80cafc842"; + disk2 = decryptLuks "0ed12b83-4c56-4ba8-b4ea-75a9e927d771"; + disk3 = decryptLuks "8cd728f6-0d5b-4cea-8f7d-01aad11192c1"; + disk4 = decryptLuks "7fcac808-491f-4846-a4a9-a34cc77cb43d"; + disk5 = decryptLuks "1d05cf50-0f5f-427a-b41f-fab0d11e85e9"; + }; + }; + kernelModules = [ "kvm-intel" ]; + kernel.sysctl = { + "vm.swappiness" = 80; + "vm.max_map_count" = 524288; + "fs.file-max" = 131072; + }; + extraModulePackages = [ ]; + initrd = { + availableKernelModules = [ + "xhci_pci" + "ahci" + "usbhid" + "nvme" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ ]; + }; + }; + fileSystems = { + "/" = { + device = "/dev/mapper/nvme"; + fsType = "btrfs"; + options = [ + "subvol=nix" + "ssd" + "compress=zstd:3" + "x-systemd.device-timeout=0" + "space_cache=v2" + "commit=120" + "datacow" + "noatime" + ]; + }; + "/home" = { + device = "/dev/mapper/nvme"; + fsType = "btrfs"; + options = [ + "subvol=home" + "ssd" + "compress=zstd:3" + "x-systemd.device-timeout=0" + "space_cache=v2" + "commit=120" + "datacow" + ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/c574cb53-dc40-46db-beff-0fe8a4787156"; + fsType = "ext4"; + options = [ "nofail" ]; + }; + "/boot/efi" = { + device = "/dev/disk/by-uuid/CBE7-5DEB"; + fsType = "vfat"; + }; + "/srv/pool" = { + device = "/dev/disk/by-uuid/1e7cf787-e34d-4e3e-ac3c-0c07309dbd34"; + fsType = "btrfs"; + options = [ + "subvol=@data" + "compress=zstd:3" + "space_cache=v2" + "commit=120" + "datacow" + ]; + depends = [ "/boot/efi" ]; + }; + "/var/lib/nextcloud/data" = { + device = "/srv/pool/nextcloud"; + options = [ "bind" ]; + depends = [ "/srv/pool" ]; + }; + "/srv/jellyfin/media" = { + device = "/srv/pool/multimedia/media"; + options = [ + "bind" + "ro" + ]; + depends = [ "/srv/pool" ]; + }; + "/export/pool" = { + device = "/srv/pool"; + options = [ "bind" ]; + depends = [ "/srv/pool" ]; + }; + "/export/jawz" = { + device = "/home/jawz"; + options = [ "bind" ]; + depends = [ "/srv/pool" ]; + }; + "/export/backups" = { + device = "/srv/backups"; + options = [ "bind" ]; + depends = [ "/srv/pool" ]; + }; + }; + services.nfs.server = { + enable = true; + exports = '' + /export workstation(rw,fsid=0,no_subtree_check) + miniserver(rw,fsid=0,no_subtree_check) + /export/jawz workstation(rw,nohide,insecure,no_subtree_check) + miniserver(rw,nohide,insecure,no_subtree_check) + /export/pool workstation(rw,nohide,insecure,no_subtree_check) + miniserver(rw,nohide,insecure,no_subtree_check) + /export/backups workstation(rw,nohide,insecure,no_subtree_check) + miniserver(rw,nohide,insecure,no_subtree_check) + ''; + }; + swapDevices = [ + { + device = "/dev/disk/by-partuuid/cb0ad486-ebf8-4bfc-ad7c-96bdc68576ca"; + randomEncryption = { + enable = true; + cipher = "aes-xts-plain64"; + keySize = 512; + sectorSize = 4096; + }; + } + ]; +} diff --git a/hosts/server/toggles.nix b/hosts/server/toggles.nix new file mode 100644 index 0000000..62ff5bd --- /dev/null +++ b/hosts/server/toggles.nix @@ -0,0 +1,92 @@ +{ config }: +let + mkEnabled = name: { + inherit name; + value.enable = true; + }; + mkEnabledIp = name: { + inherit name; + value = { + enable = true; + ip = config.my.ips.wg-server; + }; + }; + enableList = func: list: list |> map func |> builtins.listToAttrs; +in +{ + mainServer = "server"; + emacs.enable = true; + stylix.enable = true; + enableProxy = true; + enableContainers = true; + apps.dictionaries.enable = true; + shell = enableList mkEnabled [ + "tools" + "multimedia" + ]; + services = enableList mkEnabled [ + "network" + "nvidia" + ]; + dev = enableList mkEnabled [ + "nix" + "python" + "sh" + ]; + units = enableList mkEnabled [ + "downloadManga" + "download" + "stream-dl" + ]; + scripts = enableList mkEnabled [ + "run" + "download" + "split-dir" + "ffmpreg" + "ffmpeg4discord" + "manage-library" + "library-report" + "stream-dl" + "pika-list" + "find-dup-episodes" + "tuh-activity-logger" + ]; + servers = { + nextcloud = { + enable = true; + enableCron = true; + enableProxy = true; + }; + } + // enableList mkEnabled [ + "qbittorrent" + "sabnzbd" + "unpackerr" + "postgres" + "paperless" + "bazarr" + "collabora" + "homepage" + "kavita" + "lidarr" + "maloja" + "microbin" + "multi-scrobbler" + "plex" + "prowlarr" + "radarr" + "ryot" + "sonarr" + "synapse" + "jellyfin" + "gitea" + "mealie" + "metube" + "atticd" + ] + // enableList mkEnabledIp [ + "audiobookshelf" + "vaultwarden" + "readeck" + ]; +} diff --git a/hosts/workstation/configuration.nix b/hosts/workstation/configuration.nix new file mode 100644 index 0000000..20a2c27 --- /dev/null +++ b/hosts/workstation/configuration.nix @@ -0,0 +1,173 @@ +{ + lib, + pkgs, + config, + ... +}: +let + shellType = config.my.shell.type; + krita-thumbnailer = pkgs.writeTextFile { + name = "krita-thumbnailer"; + destination = "/share/thumbnailers/kra.thumbnailer"; + text = '' + [Thumbnailer Entry] + Exec=sh -c "${pkgs.unzip}/bin/unzip -p %i preview.png > %o" + MimeType=application/x-krita; + ''; + }; +in +{ + imports = [ + ./hardware-configuration.nix + ../../config/base.nix + ../../config/stylix.nix + ]; + my = import ./toggles.nix // { + nix.cores = 8; + nix.maxJobs = 8; + users.nixremote.enable = true; + users.nixremote.authorizedKeys = [ + ../../secrets/ssh/ed25519_nixserver.pub + ../../secrets/ssh/ed25519_nixminiserver.pub + ]; + }; + home-manager.users.jawz = { + programs = { + vscode = { + enable = true; + package = pkgs.vscode; + }; + ghostty = { + enable = true; + package = pkgs.ghostty; + enableBashIntegration = shellType == "bash"; + enableZshIntegration = shellType == "zsh"; + installBatSyntax = true; + installVimSyntax = true; + }; + }; + }; + specialisation = { + gnome.configuration = { + imports = [ ../../environments/gnome.nix ]; + services.flatpak.enable = true; + }; + hyprland.configuration = { + imports = [ ../../environments/hyprland.nix ]; + services.flatpak.enable = true; + }; + }; + networking = { + hostName = "workstation"; + firewall = + let + kdeconnectPortRange = { + from = 1714; + to = 1764; + }; + ns-usbloaderPort = 6674; + syncthingPort = 8384; + openPorts = [ + ns-usbloaderPort + syncthingPort + ]; + openPortRanges = [ kdeconnectPortRange ]; + in + { + allowedTCPPorts = openPorts; + allowedUDPPorts = openPorts; + allowedTCPPortRanges = openPortRanges; + allowedUDPPortRanges = openPortRanges; + }; + }; + users.users.jawz.packages = [ + (pkgs.google-cloud-sdk.withExtraComponents [ + pkgs.google-cloud-sdk.components.gke-gcloud-auth-plugin + ]) + ] + ++ builtins.attrValues { + inherit (pkgs) + distrobox # install packages from other os + gocryptfs # encrypted filesystem! shhh!!! + vcsi # video thumbnails for torrents, can I replace it with ^? + keypunch # practice typing + google-cloud-sdk-gce + ; + }; + environment = { + pathsToLink = [ "share/thumbnailers" ]; + systemPackages = builtins.attrValues { + # thumbnail for heif files & videos + inherit krita-thumbnailer; + inherit (pkgs) + libheif + ffmpegthumbnailer + bign-handheld-thumbnailer + gnome-epub-thumbnailer + podman-compose + code-cursor + scrcpy + ; + inherit (pkgs.libheif) out; + }; + etc."wireplumber/bluetooth.lua.d/51-bluez-config.lua".text = '' + bluez_monitor.properties = { + ["bluez5.enable-sbc-xq"] = true, + ["bluez5.enable-msbc"] = true, + ["bluez5.enable-hw-volume"] = true, + ["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]" + } + ''; + }; + programs = { + kdeconnect = { + enable = true; + package = pkgs.gnomeExtensions.gsconnect; + }; + obs-studio = { + enable = true; + enableVirtualCamera = true; + plugins = builtins.attrValues { + inherit (pkgs.obs-studio-plugins) + droidcam-obs + obs-vkcapture + obs-vaapi + obs-tuna + input-overlay + ; + }; + }; + }; + security.pki.certificateFiles = [ + ../../secrets/ssh/iqQCY4iAWO-ca.pem + ../../secrets/ssh/root-private-ca.pem + ]; + services = { + flatpak.enable = lib.mkDefault false; + open-webui.enable = true; + scx = { + enable = true; + scheduler = "scx_lavd"; + }; + btrfs.autoScrub = { + enable = true; + fileSystems = [ "/" ]; + }; + protonmail-bridge = { + enable = true; + path = [ pkgs.gnome-keyring ]; + }; + ollama = { + enable = true; + acceleration = "cuda"; + models = "/srv/ai/ollama"; + }; + sunshine = { + enable = true; + autoStart = true; + capSysAdmin = true; + openFirewall = true; + }; + tailscale.enable = true; + }; +} diff --git a/hosts/workstation/hardware-configuration.nix b/hosts/workstation/hardware-configuration.nix new file mode 100644 index 0000000..965769f --- /dev/null +++ b/hosts/workstation/hardware-configuration.nix @@ -0,0 +1,144 @@ +{ + modulesPath, + config, + pkgs, + inputs, + lib, + ... +}: +let + getMapper = mapper: "/dev/mapper/${mapper}"; + getUUID = uuid: "/dev/disk/by-uuid/${uuid}"; +in +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + inputs.ucodenix.nixosModules.default + ]; + services = { + udev.extraRules = lib.mkIf config.my.apps.gaming.enable '' + SUBSYSTEM=="usb", ATTRS{idVendor}=="0cf3", ATTRS{idProduct}=="3005", TAG+="uaccess" + ''; + ucodenix = { + enable = true; + cpuModelId = "00A50F00"; + }; + }; + hardware.bluetooth = { + enable = true; + settings.General = { + Enable = "Source,Sink,Media,Socket"; + Experimental = true; + }; + }; + boot = { + plymouth.enable = true; + consoleLogLevel = 0; + loader.timeout = 5; + kernelParams = [ + "splash" + "boot.shell_on_fail" + "loglevel=3" + "rd.systemd.show_status=false" + "rd.udev.log_level=3" + "udev.log_priority=3" + "preempt=full" + "microcode.amd_sha_check=off" + ]; + kernelPackages = pkgs.linuxPackages; + kernel.sysctl = { + "vm.swappiness" = 80; + "net.ipv4.tcp_mtu_probing" = 1; + "kernel.sched_cfsbandwidth_slice_us" = lib.mkDefault 3000; + "net.ipv4.tcp_fin_timeout" = lib.mkDefault 5; + "vm.max_map_count" = lib.mkDefault 2147483642; + }; + loader = { + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot/efi"; + }; + grub = { + enable = true; + device = "nodev"; + efiSupport = true; + useOSProber = true; + enableCryptodisk = true; + }; + }; + initrd = { + verbose = false; + secrets."/keyfile" = /etc/keyfile; + availableKernelModules = [ + "xhci_pci" + "ahci" + "usbhid" + "nvme" + "usb_storage" + "sd_mod" + ]; + luks.devices.nvme = { + device = getUUID "e9618e85-a631-4374-b2a4-22c376d6e41b"; + keyFile = "/keyfile"; + preLVM = true; + }; + }; + }; + fileSystems = + let + nfsMount = server: nfsDisk: { + device = "${server}:/${nfsDisk}"; + fsType = "nfs"; + options = [ + "x-systemd.automount" + "noauto" + "x-systemd.idle-timeout=600" + ]; + }; + btrfsMount = device: subvol: extraOpts: { + inherit device; + fsType = "btrfs"; + options = extraOpts ++ [ + "subvol=${subvol}" + "ssd" + "compress=lzo" + "x-systemd.device-timeout=0" + "space_cache=v2" + "commit=120" + "datacow" + ]; + }; + trashOptions = [ + "x-gvfs-trash" + "x-gvfs-show" + ]; + in + { + "/" = btrfsMount (getMapper "nvme") "nixos" [ "noatime" ]; + "/home" = btrfsMount (getMapper "nvme") "home" [ ]; + "/srv/games" = btrfsMount (getMapper "nvme") "games" trashOptions; + "/srv/ai" = btrfsMount (getUUID "ca1671e1-e201-4960-ad30-593393f970fb") "ai" trashOptions; + "/srv/pool" = nfsMount "server" "pool"; + "/srv/server_home" = nfsMount "server" "jawz"; + "/srv/backups" = nfsMount "server" "backups"; + "/boot" = { + device = getUUID "ac6d349a-96b9-499e-9009-229efd7743a5"; + fsType = "ext4"; + }; + "/boot/efi" = { + device = getUUID "B05D-B5FB"; + fsType = "vfat"; + }; + }; + swapDevices = [ + { + device = "/dev/disk/by-partuuid/c1bd22d7-e62c-440a-88d1-6464be1aa1b0"; + randomEncryption = { + enable = true; + cipher = "aes-xts-plain64"; + keySize = 512; + sectorSize = 4096; + }; + } + ]; +} diff --git a/hosts/workstation/toggles.nix b/hosts/workstation/toggles.nix new file mode 100644 index 0000000..48d74ae --- /dev/null +++ b/hosts/workstation/toggles.nix @@ -0,0 +1,51 @@ +let + mkEnabled = name: { + inherit name; + value.enable = true; + }; + enableList = func: list: list |> map func |> builtins.listToAttrs; +in +{ + stylix.enable = true; + emacs.enable = true; + enableContainers = true; + servers.drpp.enable = true; + apps = enableList mkEnabled [ + "art" + "piano" + "dictionaries" + "fonts" + "gaming" + "switch" + "internet" + "multimedia" + "office" + "misc" + ]; + dev = enableList mkEnabled [ + "nix" + "python" + "gameDev" + "sh" + ]; + shell = enableList mkEnabled [ + "exercism" + "multimedia" + "tools" + ]; + services = enableList mkEnabled [ + "network" + "nvidia" + "printing" + "sound" + ]; + scripts = enableList mkEnabled [ + "tasks" + "run" + "split-dir" + "download" + "ffmpreg" + "ffmpeg4discord" + "update-org-agenda-cache" + ]; +} diff --git a/modules/apps/art.nix b/modules/apps/art.nix new file mode 100644 index 0000000..c92ef8f --- /dev/null +++ b/modules/apps/art.nix @@ -0,0 +1,44 @@ +{ + config, + lib, + pkgs, + ... +}: +let + # Patch to libpng so that big brushes can be loaded + patched-krita = pkgs.replaceDependency { + drv = pkgs.krita; + oldDependency = pkgs.libpng; + newDependency = pkgs.libpng.overrideAttrs (old: { + patches = (old.patches or [ ]) ++ [ ../../patches/libpng.patch ]; + }); + }; + attrValuesIf = cond: attrs: if cond then builtins.attrValues attrs else [ ]; + artPackages = attrValuesIf config.my.apps.art.enable { + inherit patched-krita; # art to your heart desire! + inherit (pkgs) + eyedropper # color picker + emulsion-palette # self explanatory + gimp # the coolest bestest art program to never exist + mypaint # not the best art program + mypaint-brushes # but it's got some + mypaint-brushes1 # nice damn brushes + blender # cgi animation and sculpting + drawpile # arty party with friends!! + pureref # create inspiration/reference boards + ; + }; + gameDevPackages = attrValuesIf config.my.dev.gameDev.enable { + inherit (pkgs) + godot_4 # game development + gdtoolkit_4 # gdscript language server + ; + }; +in +{ + options.my = { + apps.art.enable = lib.mkEnableOption "digital art and creative applications"; + dev.gameDev.enable = lib.mkEnableOption "game development tools and engines"; + }; + config.users.users.jawz.packages = artPackages ++ gameDevPackages; +} diff --git a/modules/apps/dictionaries.nix b/modules/apps/dictionaries.nix new file mode 100644 index 0000000..be742f4 --- /dev/null +++ b/modules/apps/dictionaries.nix @@ -0,0 +1,21 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.apps.dictionaries.enable = lib.mkEnableOption "dictionaries and language tools"; + config = lib.mkIf config.my.apps.dictionaries.enable { + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + hunspell + ; + inherit (pkgs.hunspellDicts) + it_IT + es_MX + en_CA-large + ; + }; + }; +} diff --git a/modules/apps/fonts.nix b/modules/apps/fonts.nix new file mode 100644 index 0000000..3e72cdf --- /dev/null +++ b/modules/apps/fonts.nix @@ -0,0 +1,44 @@ +{ + config, + lib, + pkgs, + inputs, + ... +}: +let + customFonts = pkgs.stdenvNoCC.mkDerivation { + name = "custom-fonts"; + src = inputs.fonts; + installPhase = '' + mkdir -p $out/share/fonts + find $src -type f \( \ + -name "*.ttf" -o \ + -name "*.otf" -o \ + -name "*.woff" -o \ + -name "*.woff2" \ + \) -exec cp {} $out/share/fonts/ \; + ''; + }; +in +{ + options.my.apps.fonts.enable = lib.mkEnableOption "additional fonts and typography"; + config = lib.mkIf config.my.apps.fonts.enable { + nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "corefonts" ]; + fonts.packages = builtins.attrValues { + inherit customFonts; + inherit (pkgs) + symbola + comic-neue + cascadia-code + corefonts + ; + inherit (pkgs.nerd-fonts) + caskaydia-cove + open-dyslexic + comic-shanns-mono + iosevka + agave + ; + }; + }; +} diff --git a/modules/apps/gaming.nix b/modules/apps/gaming.nix new file mode 100644 index 0000000..02177b6 --- /dev/null +++ b/modules/apps/gaming.nix @@ -0,0 +1,60 @@ +{ + inputs, + config, + lib, + pkgs, + ... +}: +{ + imports = [ inputs.nix-gaming.nixosModules.platformOptimizations ]; + options.my.apps = { + gaming.enable = lib.mkEnableOption "gaming applications and emulators"; + switch.enable = lib.mkEnableOption "Nintendo Switch homebrew tools"; + }; + config = lib.mkIf config.my.apps.gaming.enable { + # sops.secrets.switch-presence = lib.mkIf config.my.apps.gaming.switch.enable { + # sopsFile = ../../secrets/env.yaml; + # format = "dotenv"; + # owner = config.users.users.jawz.name; + # inherit (config.users.users.jawz) group; + # }; + programs = { + gamemode.enable = true; + steam = { + enable = true; + gamescopeSession.enable = true; + remotePlay.openFirewall = true; + dedicatedServer.openFirewall = true; + platformOptimizations.enable = true; + }; + }; + services = lib.mkIf config.my.apps.switch.enable { + switch-boot.enable = true; + # switch-presence = { + # enable = true; + # environmentFile = config.sops.secrets.switch-presence.path; + # }; + }; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + shipwright # zelda OoT port + mangohud # fps & stats overlay + lutris # games launcher & emulator hub + cartridges # games launcher + gamemode # optimizes linux to have better gaming performance + heroic # install epic games + protonup-qt # update proton-ge + ns-usbloader # load games into my switch + # emulators + rpcs3 # ps3 + pcsx2 # ps2 + cemu # wii u + dolphin-emu # wii + snes9x-gtk # snes + ryubing # switch + azahar # 3Ds + prismlauncher # minecraft launcher with jdk overlays + ; + }; + }; +} diff --git a/modules/apps/internet.nix b/modules/apps/internet.nix new file mode 100644 index 0000000..850e104 --- /dev/null +++ b/modules/apps/internet.nix @@ -0,0 +1,56 @@ +{ + config, + lib, + pkgs, + ... +}: +let + krisp-patcher = + pkgs.writers.writePython3Bin "krisp-patcher" + { + libraries = builtins.attrValues { + inherit (pkgs.python3Packages) + capstone + pyelftools + ; + }; + flakeIgnore = [ + "E501" # line too long (82 > 79 characters) + "F403" # 'from module import *' used; unable to detect undefined names + "F405" # name may be undefined, or defined from star imports: module + ]; + } + ( + builtins.readFile ( + pkgs.fetchurl { + url = "https://pastebin.com/raw/8tQDsMVd"; + sha256 = "sha256-IdXv0MfRG1/1pAAwHLS2+1NESFEz2uXrbSdvU9OvdJ8="; + } + ) + ); +in +{ + options.my.apps.internet.enable = lib.mkEnableOption "internet browsers and communication apps"; + config = lib.mkIf config.my.apps.internet.enable { + home-manager.users.jawz.programs.librewolf = import ./librewolf.nix; + programs.geary.enable = true; + users.users.jawz.packages = builtins.attrValues { + # inherit (inputs.zen-browser.packages.x86_64-linux) twilight; + inherit krisp-patcher; + inherit (pkgs) + # thunderbird # email client + warp # transfer files with based ppl + brave # crypto-browser that at least somewhat integrates with gtk + nextcloud-client # self-hosted google-drive alternative + fragments # beautiful torrent client + tor-browser-bundle-bin # dark web, so dark! + telegram-desktop # furry chat + nicotine-plus # remember Ares? + discord # :3 + vdhcoapp # video download helper assistant + nextcloud-talk-desktop # nextcloud talk client + fractal # matrix client + ; + }; + }; +} diff --git a/modules/apps/librewolf.nix b/modules/apps/librewolf.nix new file mode 100644 index 0000000..363833c --- /dev/null +++ b/modules/apps/librewolf.nix @@ -0,0 +1,79 @@ +{ + enable = true; + languagePacks = [ + "en-CA" + "es-MX" + "it" + ]; + policies.DisabledFirefoxAccounts = false; + profiles.jawz = { + id = 0; + name = "jawz"; + path = "jawz"; + settings = { + # Enable custom userChrome.css (for GNOME theme) + "toolkit.legacyUserProfileCustomizations.stylesheets" = true; + # Enables Firefox GNOME Theme SVG icons + "svg.context-properties.content.enabled" = true; + # GNOME theme refinements + "gnomeTheme.hideSingleTab" = true; + "gnomeTheme.bookmarksToolbarUnderTabs" = true; + "gnomeTheme.allTabsButtonOnOverflow" = true; + # Normal UI density + "browser.uidensity" = 0; + "browser.toolbars.bookmarks.visibility" = "never"; + "general.autoScroll" = true; + # Tabs + "browser.sessionstore.resume_from_crash" = true; + "browser.sessionstore.max_tabs_undo" = 50; + "browser.startup.page" = 3; + # DRM + "media.eme.enabled" = true; + # Prevents private windows from using dark theme + "browser.theme.dark-private-windows" = false; + # Enables rounded corners on the main window + "widget.gtk.rounded-bottom-corners.enabled" = true; + # General privacy & fingerprinting + "privacy.sanitize.sanitizeOnShutdown" = false; + "privacy.clearOnShutdown_v2.browsingHistoryAndDownloads" = false; + "privacy.resistFingerprinting" = false; # You explicitly disabled this + "privacy.fingerprintingProtection" = true; + "privacy.query_stripping.enabled" = true; + "privacy.query_stripping.enabled.pbmode" = true; + "privacy.trackingprotection.enabled" = true; + "privacy.trackingprotection.socialtracking.enabled" = true; + "privacy.trackingprotection.emailtracking.enabled" = true; + "privacy.bounceTrackingProtection.mode" = 1; + "privacy.clearSiteData.cookiesAndStorage" = false; + "privacy.clearSiteData.historyFormDataAndDownloads" = true; + # Do Not Track + "privacy.donottrackheader.enabled" = true; + # GPC (Global Privacy Control) + "privacy.globalprivacycontrol.was_ever_enabled" = true; + # DNS-over-HTTPS (LibreDNS with adblock) + "network.trr.mode" = 2; + "network.trr.uri" = "https://doh.libredns.gr/noads"; + # Prevent predictive browsing + "network.prefetch-next" = false; + "network.predictor.enabled" = false; + "network.http.speculative-parallel-limit" = 0; + # Referrer sanitization + "network.http.referer.disallowCrossSiteRelaxingDefault.top_navigation" = true; + # Partitioning and isolation + "network.cookie.cookieBehavior.optInPartitioning" = true; + # HTTPS-only + "dom.security.https_only_mode_ever_enabled" = true; + # Disable captive portal checks + "network.captive-portal-service.enabled" = false; + "network.connectivity-service.enabled" = false; + # Permissions tightening + "permissions.delegation.enabled" = false; + # Disable safe browsing remote lookups (relies on Google) + "browser.safebrowsing.downloads.remote.enabled" = false; + "browser.safebrowsing.downloads.remote.block_potentially_unwanted" = false; + "browser.safebrowsing.downloads.remote.block_uncommon" = false; + # Enable anti-cookie tracking + purge trackers + "privacy.annotate_channels.strict_list.enabled" = true; + }; + }; +} diff --git a/modules/apps/misc.nix b/modules/apps/misc.nix new file mode 100644 index 0000000..ae63fc9 --- /dev/null +++ b/modules/apps/misc.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.apps.misc.enable = lib.mkEnableOption "miscellaneous desktop applications"; + config = lib.mkIf config.my.apps.misc.enable { + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + collector # stores things and throws them anywhere + blanket # background noise + metadata-cleaner # remove any metadata and geolocation from files + pika-backup # backups + gnome-obfuscate # censor private information + ; + }; + }; +} diff --git a/modules/apps/multimedia.nix b/modules/apps/multimedia.nix new file mode 100644 index 0000000..b347d31 --- /dev/null +++ b/modules/apps/multimedia.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.apps.multimedia.enable = lib.mkEnableOption "multimedia applications and media players"; + config = lib.mkIf config.my.apps.multimedia.enable { + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + recordbox # libadwaita music player + pitivi # video editor + celluloid # video player + curtail # image compressor + easyeffects # equalizer + handbrake # video converter, may be unnecessary + identity # compare images or videos + mousai # poor man shazam + shortwave # listen to world radio + tagger # tag music files + ; + }; + }; +} diff --git a/modules/apps/music.nix b/modules/apps/music.nix new file mode 100644 index 0000000..da20162 --- /dev/null +++ b/modules/apps/music.nix @@ -0,0 +1,18 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.apps.piano.enable = lib.mkEnableOption "piano learning and music theory apps"; + config = lib.mkIf config.my.apps.piano.enable { + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + neothesia + linthesia + timidity + ; + }; + }; +} diff --git a/modules/apps/office.nix b/modules/apps/office.nix new file mode 100644 index 0000000..d258284 --- /dev/null +++ b/modules/apps/office.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.apps.office.enable = lib.mkEnableOption "office applications and productivity tools"; + config = lib.mkIf config.my.apps.office.enable { + environment.variables.CALIBRE_USE_SYSTEM_THEME = "1"; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + jre17_minimal # for libreoffice extensions + libreoffice # office, but based & european + calibre # ugly af eBook library manager + newsflash # feed reader, syncs with nextcloud + furtherance # I packaged this one tehee track time utility + # planify # let's pretend I will organize my tasks + ; + }; + }; +} diff --git a/modules/dev/cc.nix b/modules/dev/cc.nix new file mode 100644 index 0000000..768abec --- /dev/null +++ b/modules/dev/cc.nix @@ -0,0 +1,36 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) + clang # C/C++ compiler frontend (part of LLVM) + clang-tools # Extra LLVM tools (e.g. clang-tidy, clang-apply-replacements) + gcc # GNU Compiler Collection (C, C++, etc.) + gdb # GNU Debugger + valgrind # Memory leak detector and performance profiler + ; + }; +in +{ + options = { + my.dev.cc.enable = lib.mkEnableOption "Install C/C++ tooling globally"; + devShells.cc = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "cc-dev-shell"; + shellHook = '' + echo "🔧 C/C++ dev environment" + ''; + }; + description = "C/C++ development shell"; + }; + }; + config = lib.mkIf config.my.dev.cc.enable { + users.users.jawz = { inherit packages; }; + }; +} diff --git a/modules/dev/docker.nix b/modules/dev/docker.nix new file mode 100644 index 0000000..1621a63 --- /dev/null +++ b/modules/dev/docker.nix @@ -0,0 +1,38 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) dockfmt; # Format Dockerfiles + inherit (pkgs.nodePackages) + dockerfile-language-server-nodejs # LSP for Dockerfiles + ; + }; +in +{ + options = { + my.dev.docker.enable = lib.mkEnableOption "Install Docker tooling globally"; + devShells.docker = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "docker-dev-shell"; + shellHook = '' + echo "🐳 Docker dev environment" + ''; + }; + description = "Docker and Dockerfile tooling shell"; + }; + }; + config = lib.mkMerge [ + (lib.mkIf config.my.dev.docker.enable { + users.users.jawz = { inherit packages; }; + }) + { + environment.variables.DOCKER_CONFIG = "\${XDG_CONFIG_HOME}/docker"; + } + ]; +} diff --git a/modules/dev/emacs.nix b/modules/dev/emacs.nix new file mode 100644 index 0000000..e0c17a6 --- /dev/null +++ b/modules/dev/emacs.nix @@ -0,0 +1,73 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.emacs.enable = lib.mkEnableOption "Doom Emacs configuration"; + config = lib.mkIf config.my.emacs.enable { + home-manager.users.jawz = { + xdg.dataFile = { + "doom/templates/events.org".source = ../../dotfiles/doom/templates/events.org; + "doom/templates/default.org".source = ../../dotfiles/doom/templates/default.org; + "doom/templates/programming.org".source = ../../dotfiles/doom/templates/programming.org; + }; + services.lorri.enable = true; + programs.${config.my.shell.type}.shellAliases = { + edit = "emacsclient -t"; + e = "edit"; + }; + }; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs.xorg) xwininfo; + inherit (pkgs) + #emacs everywhere + xdotool + xclip + wl-clipboard-rs + fd # modern find, faster searches + fzf # fuzzy finder! super cool and useful + ripgrep # modern grep + tree-sitter # code parsing based on symbols and shit, I do not get it + graphviz # graphs + tetex # export pdf + languagetool # proofreader for English + # lsps + yaml-language-server + markdownlint-cli + ; + inherit (pkgs.nodePackages) + vscode-json-languageserver + prettier # multi-language linter + ; + }; + services.emacs = { + enable = true; + defaultEditor = true; + package = pkgs.emacsWithDoom { + doomDir = ../../dotfiles/doom; + doomLocalDir = "/home/jawz/.local/share/nix-doom"; + tangleArgs = "--all config.org"; + extraPackages = + epkgs: + let + inherit (config.home-manager.users.jawz.programs.emacs) + extraPackages + extraConfig + ; + extra = extraPackages epkgs; + themes = lib.optional config.my.stylix.enable [ + (epkgs.trivialBuild { + pname = "stylix-theme"; + src = pkgs.writeText "stylix-theme.el" extraConfig; + version = "0.1.0"; + packageRequires = extra; + }) + ]; + in + extra ++ themes; + }; + }; + }; +} diff --git a/modules/dev/go.nix b/modules/dev/go.nix new file mode 100644 index 0000000..3bb1f05 --- /dev/null +++ b/modules/dev/go.nix @@ -0,0 +1,44 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) + go # Go compiler and core toolchain + gocode-gomod # Code completion for Go (modern fork of gocode) + gotools # Contains godoc, gorename, goimports, etc. + gore # Go REPL + gotests # Generate Go tests from function signatures + gomodifytags # Struct tag manipulation + golangci-lint # Linter aggregation + ; + }; + GOPATH = "\${XDG_DATA_HOME}/go"; +in +{ + options = { + my.dev.go.enable = lib.mkEnableOption "Install Go tooling globally"; + devShells.go = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages GOPATH; + name = "go-dev-shell"; + shellHook = '' + echo "🐹 Go dev environment" + ''; + }; + description = "Go development shell with Emacs tooling, REPL, formatter, and linter"; + }; + }; + config = lib.mkMerge [ + { + environment.variables = { inherit GOPATH; }; + } + (lib.mkIf config.my.dev.go.enable { + users.users.jawz = { inherit packages; }; + }) + ]; +} diff --git a/modules/dev/haskell.nix b/modules/dev/haskell.nix new file mode 100644 index 0000000..f323436 --- /dev/null +++ b/modules/dev/haskell.nix @@ -0,0 +1,46 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) + haskell-language-server # LSP server for Haskell + cabal-install # Standard Haskell build tool + hlint # Linter for Haskell source code + ; + inherit (pkgs.haskellPackages) + hoogle # Haskell API search engine + ; + }; +in +{ + options = { + my.dev.haskell.enable = lib.mkEnableOption "Install Haskell tooling globally"; + devShells.haskell = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "haskell-dev-shell"; + shellHook = '' + echo "λ Haskell dev environment" + ''; + }; + description = "Haskell development shell"; + }; + }; + config = lib.mkMerge [ + (lib.mkIf config.my.dev.haskell.enable { + users.users.jawz = { inherit packages; }; + }) + { + environment.variables = { + CABAL_DIR = "\${XDG_CACHE_HOME}/cabal"; + STACK_ROOT = "\${XDG_DATA_HOME}/stack"; + GHCUP_USE_XDG_DIRS = "true"; + }; + } + ]; +} diff --git a/modules/dev/javascript.nix b/modules/dev/javascript.nix new file mode 100644 index 0000000..69f8cac --- /dev/null +++ b/modules/dev/javascript.nix @@ -0,0 +1,50 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) nodejs; # Node.js runtime + inherit (pkgs.nodePackages) pnpm; # Fast package manager alternative to npm + }; +in +{ + options = { + my.dev.javascript.enable = lib.mkEnableOption "Install JavaScript tooling globally"; + devShells.javascript = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "javascript-dev-shell"; + shellHook = '' + echo "📦 JavaScript dev environment" + ''; + }; + description = "JavaScript/Node development shell with npm/pnpm support"; + }; + }; + config = lib.mkMerge [ + (lib.mkIf config.my.dev.javascript.enable { + users.users.jawz = { inherit packages; }; + }) + { + home-manager.users.jawz.xdg.configFile = { + "npm/npmrc".source = ../../dotfiles/npmrc; + "configstore/update-notifier-npm-check.json".text = builtins.toJSON { + optOut = false; + lastUpdateCheck = 1646662583446; + }; + }; + environment.variables = { + NPM_CONFIG_USERCONFIG = "\${XDG_CONFIG_HOME}/npm/npmrc"; + PNPM_HOME = "\${XDG_DATA_HOME}/pnpm"; + PATH = [ + "\${XDG_DATA_HOME}/npm/bin" + "\${XDG_DATA_HOME}/pnpm" + ]; + }; + } + ]; +} diff --git a/modules/dev/julia.nix b/modules/dev/julia.nix new file mode 100644 index 0000000..946cd51 --- /dev/null +++ b/modules/dev/julia.nix @@ -0,0 +1,30 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) julia; # High-performance dynamic language for technical computing + }; +in +{ + options = { + my.dev.julia.enable = lib.mkEnableOption "Install Julia globally"; + devShells.julia = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "julia-dev-shell"; + shellHook = '' + echo "🔬 Julia dev environment" + ''; + }; + description = "Julia development shell"; + }; + }; + config = lib.mkIf config.my.dev.julia.enable { + users.users.jawz = { inherit packages; }; + }; +} diff --git a/modules/dev/nix.nix b/modules/dev/nix.nix new file mode 100644 index 0000000..a0365bf --- /dev/null +++ b/modules/dev/nix.nix @@ -0,0 +1,43 @@ +{ + config, + lib, + pkgs, + ... +}: +let + shellType = config.my.shell.type; + packages = builtins.attrValues { + inherit (pkgs) + nixfmt-rfc-style # formatting + cachix # binary cache management + nixd # language server for Nix + statix # linter for Nix expressions + ; + }; +in +{ + options = { + my.dev.nix.enable = lib.mkEnableOption "Install Nix tooling globally"; + devShells.nix = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "nix-dev-shell"; + shellHook = '' + echo "❄️ Nix dev environment" + ''; + }; + description = "Nix/NixOS development shell with formatter, linter, LSP, and Cachix"; + }; + }; + config = lib.mkIf config.my.dev.nix.enable { + users.users.jawz = { inherit packages; }; + home-manager.users.jawz.programs.${shellType}.shellAliases = { + nixformat = '' + nix run unstable#deadnix -- -e && \ + nix run unstable#nixfmt-tree && \ + nix run unstable#statix fix + ''; + }; + }; +} diff --git a/modules/dev/python.nix b/modules/dev/python.nix new file mode 100644 index 0000000..237900d --- /dev/null +++ b/modules/dev/python.nix @@ -0,0 +1,56 @@ +{ + config, + lib, + pkgs, + ... +}: +let + python = pkgs.python3.withPackages ( + ps: + builtins.attrValues { + inherit (ps) + black # Python code formatter + editorconfig # follow rules of contributin + flake8 # wraper for pyflakes, pycodestyle and mccabe + isort # sort Python imports + pyflakes # checks source code for errors + pylint # bug and style checker for python + pytest # tests + speedtest-cli # check internet speed from the comand line + ; + } + ); + packages = builtins.attrValues { + inherit python; + inherit (pkgs) + pipenv # python development workflow for humans + pyright # LSP + ; + }; +in +{ + options = { + my.dev.python.enable = lib.mkEnableOption "Install Python tools globally"; + devShells.python = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "python-dev-shell"; + shellHook = '' + echo "🐍 Python dev environment" + which python + ''; + description = "Python development shell"; + }; + }; + }; + config = lib.mkMerge [ + (lib.mkIf config.my.dev.python.enable { + users.users.jawz = { inherit packages; }; + }) + { + home-manager.users.jawz.xdg.configFile."python/pythonrc".source = ../../dotfiles/pythonrc; + environment.variables.PYTHONSTARTUP = "\${XDG_CONFIG_HOME}/python/pythonrc"; + } + ]; +} diff --git a/modules/dev/ruby.nix b/modules/dev/ruby.nix new file mode 100644 index 0000000..d974447 --- /dev/null +++ b/modules/dev/ruby.nix @@ -0,0 +1,40 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) ruby; # Ruby interpreter + inherit (pkgs.rubyPackages) solargraph; # LSP for Ruby + }; +in +{ + options = { + my.dev.ruby.enable = lib.mkEnableOption "Install Ruby tooling globally"; + devShells.ruby = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "ruby-dev-shell"; + shellHook = '' + echo "💎 Ruby dev environment" + ''; + }; + description = "Ruby development shell with interpreter and Solargraph LSP"; + }; + }; + config = lib.mkMerge [ + (lib.mkIf config.my.dev.ruby.enable { + users.users.jawz = { inherit packages; }; + }) + { + environment.variables = { + GEM_HOME = "\${XDG_DATA_HOME}/ruby/gems"; + GEM_PATH = "\${XDG_DATA_HOME}/ruby/gems"; + GEM_SPEC_CACHE = "\${XDG_DATA_HOME}/ruby/specs"; + }; + } + ]; +} diff --git a/modules/dev/rust.nix b/modules/dev/rust.nix new file mode 100644 index 0000000..d655957 --- /dev/null +++ b/modules/dev/rust.nix @@ -0,0 +1,41 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) + rustc # Rust compiler + cargo # Rust package manager + rust-analyzer # Language server for Rust + clippy # Linter for Rust + rustfmt # Formatter for Rust code + ; + }; +in +{ + options = { + my.dev.rust.enable = lib.mkEnableOption "Install Rust tooling globally"; + devShells.rust = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "rust-dev-shell"; + shellHook = '' + echo "🦀 Rust dev environment" + ''; + }; + description = "Rust development shell with cargo and rust-analyzer"; + }; + }; + config = lib.mkMerge [ + (lib.mkIf config.my.dev.rust.enable { + users.users.jawz = { inherit packages; }; + }) + { + environment.variables.CARGO_HOME = "\${XDG_DATA_HOME}/cargo"; + } + ]; +} diff --git a/modules/dev/sh.nix b/modules/dev/sh.nix new file mode 100644 index 0000000..e5b40d8 --- /dev/null +++ b/modules/dev/sh.nix @@ -0,0 +1,36 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) + bashdb # Debugger and completion support + shellcheck # Shell script linter + shfmt # Shell parser and formatter + ; + # LSP for Bash and sh + inherit (pkgs.nodePackages) bash-language-server; + }; +in +{ + options = { + my.dev.sh.enable = lib.mkEnableOption "Install shell scripting tools globally"; + devShells.sh = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "sh-dev-shell"; + shellHook = '' + echo "💻 Shell scripting dev environment" + ''; + }; + description = "Shell scripting dev shell"; + }; + }; + config = lib.mkIf config.my.dev.sh.enable { + users.users.jawz = { inherit packages; }; + }; +} diff --git a/modules/dev/zig.nix b/modules/dev/zig.nix new file mode 100644 index 0000000..f6ca287 --- /dev/null +++ b/modules/dev/zig.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + pkgs, + ... +}: +let + packages = builtins.attrValues { + inherit (pkgs) + zig # Zig compiler and stdlib + zls # Language server for Zig + ; + }; +in +{ + options = { + my.dev.zig.enable = lib.mkEnableOption "Install Zig tooling globally"; + devShells.zig = lib.mkOption { + type = lib.types.package; + default = pkgs.mkShell { + inherit packages; + name = "zig-dev-shell"; + shellHook = '' + echo "🦎 Zig dev environment" + ''; + }; + description = "Zig development shell with compiler and LSP"; + }; + }; + config = lib.mkIf config.my.dev.zig.enable { + users.users.jawz = { inherit packages; }; + }; +} diff --git a/modules/factories/mkscript.nix b/modules/factories/mkscript.nix new file mode 100644 index 0000000..a07647c --- /dev/null +++ b/modules/factories/mkscript.nix @@ -0,0 +1,80 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.scripts = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule { + options = { + enable = lib.mkEnableOption "Whether to enable this script"; + install = lib.mkEnableOption "Whether to install the script package"; + service = lib.mkEnableOption "Whether to enable the script service"; + name = lib.mkOption { + type = lib.types.str; + description = "Name of the script."; + }; + timer = lib.mkOption { + type = lib.types.str; + default = "*:0"; + description = "Systemd timer schedule."; + }; + description = lib.mkOption { + type = lib.types.str; + description = "Description of the service."; + }; + package = lib.mkOption { + type = lib.types.package; + description = "Package containing the executable script."; + }; + }; + } + ); + default = { }; + description = "Configuration for multiple scripts."; + }; + config = lib.mkIf (lib.any (s: s.enable) (lib.attrValues config.my.scripts)) { + users.users.jawz.packages = + config.my.scripts + |> lib.mapAttrsToList (_name: script: lib.optional (script.enable && script.install) script.package) + |> lib.flatten; + systemd.user.services = + config.my.scripts + |> lib.mapAttrs' ( + _name: script: + lib.nameValuePair "${script.name}" ( + lib.mkIf (script.enable && script.service) { + restartIfChanged = true; + inherit (script) description; + wantedBy = [ "default.target" ]; + path = [ + pkgs.nix + script.package + ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${script.package}/bin/${script.name}"; + }; + } + ) + ); + systemd.user.timers = + config.my.scripts + |> lib.mapAttrs' ( + _name: script: + lib.nameValuePair "${script.name}" ( + lib.mkIf (script.enable && script.service) { + enable = true; + inherit (script) description; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = script.timer; + }; + } + ) + ); + }; +} diff --git a/modules/factories/mkserver.nix b/modules/factories/mkserver.nix new file mode 100644 index 0000000..38f348d --- /dev/null +++ b/modules/factories/mkserver.nix @@ -0,0 +1,110 @@ +{ lib, config, ... }: +let + mkOptions = name: subdomain: port: { + enable = lib.mkEnableOption "this server service"; + enableCron = lib.mkEnableOption "enable cronjob"; + enableProxy = lib.mkEnableOption "enable reverse proxy"; + port = lib.mkOption { + type = lib.types.int; + default = port; + }; + name = lib.mkOption { + type = lib.types.str; + default = name; + }; + domain = lib.mkOption { + type = lib.types.str; + default = config.my.domain; + }; + host = lib.mkOption { + type = lib.types.str; + default = "${subdomain}.${config.my.servers.${name}.domain}"; + }; + hostName = lib.mkOption { + type = lib.types.str; + default = config.networking.hostName; + }; + url = lib.mkOption { + type = lib.types.str; + default = "https://${config.my.servers.${name}.host}"; + }; + ip = lib.mkOption { + type = lib.types.str; + default = + if config.my.servers."${name}".isLocal then + config.my.localhost + else + config.my.ips."${config.my.servers.${name}.hostName}"; + }; + local = lib.mkOption { + type = lib.types.str; + default = "http://${config.my.servers.${name}.ip}:${toString port}"; + }; + isLocal = lib.mkOption { + type = lib.types.bool; + default = "${config.my.servers.${name}.hostName}" == config.my.mainServer; + }; + enableSocket = lib.mkOption { + type = lib.types.bool; + default = false; + }; + certPath = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + }; + }; + proxy = locations: { + inherit locations; + forceSSL = true; + enableACME = true; + http2 = true; + }; + proxyReverse = + cfg: + proxy { + "/" = { + proxyPass = "http://${cfg.ip}:${toString cfg.port}/"; + proxyWebsockets = cfg.enableSocket; + }; + }; + proxyReverseFix = + cfg: + let + useLocalhost = cfg.hostName == config.networking.hostName; + localHeaders = '' + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + ''; + in + proxyReverse cfg + // { + extraConfig = '' + ${if useLocalhost then localHeaders else ""} + proxy_set_header X-Forwarded-Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $http_connection; + proxy_redirect off; + proxy_http_version 1.1; + ''; + }; + proxyReversePrivate = + cfg: + proxyReverse cfg + // { + extraConfig = '' + ssl_verify_client on; + ssl_client_certificate ${cfg.certPath}; + error_page 403 /403.html; + ''; + }; +in +{ + inherit + mkOptions + proxy + proxyReverse + proxyReverseFix + proxyReversePrivate + ; +} diff --git a/modules/modules.nix b/modules/modules.nix new file mode 100644 index 0000000..4110d8c --- /dev/null +++ b/modules/modules.nix @@ -0,0 +1,196 @@ +{ lib, config, ... }: +let + filterNames = file: file != "librewolf.nix"; + autoImport = + dir: + builtins.readDir ./${dir} + |> builtins.attrNames + |> builtins.filter (file: builtins.match ".*\\.nix" file != null && filterNames file) + |> map (file: ./${dir}/${file}); +in +{ + imports = + autoImport "apps" + ++ autoImport "dev" + ++ autoImport "scripts" + ++ autoImport "servers" + ++ autoImport "services" + ++ autoImport "shell" + ++ autoImport "network" + ++ [ + ./nix/build.nix + ./users/nixremote.nix + ]; + options.my = { + localhost = lib.mkOption { + type = lib.types.str; + default = "127.0.0.1"; + description = "The localhost address."; + }; + localhost6 = lib.mkOption { + type = lib.types.str; + default = "::1"; + description = "The localhost ipv6 address."; + }; + secureHost = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Whether this is a secure host that should use SOPS,"; + }; + domain = lib.mkOption { + type = lib.types.str; + default = "servidos.lat"; + description = "The domain name."; + }; + ips = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { + router = "192.168.100.1"; + server = "192.168.100.15"; + miniserver = "192.168.1.100"; + workstation = "192.168.100.18"; + vps = "51.222.141.104"; + wg-vps = "10.77.0.1"; + wg-server = "10.77.0.2"; + wg-friend1 = "10.8.0.2"; + wg-friends = "10.8.0.0"; + }; + description = "Set of IP's for all my computers."; + }; + interfaces = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { + server = "enp0s31f6"; + miniserver = "enp2s0"; + workstation = "enp5s0"; + }; + description = "Set of network interface names for all my computers."; + }; + mainServer = lib.mkOption { + type = lib.types.str; + default = "miniserver"; + description = "The hostname of the main server."; + }; + postgresSocket = lib.mkOption { + type = lib.types.str; + default = "/run/postgresql"; + description = "The PostgreSQL socket path."; + }; + containerSocket = lib.mkOption { + type = lib.types.str; + default = "/var/run/docker.sock"; + description = "The docker/podman socket path."; + }; + containerData = lib.mkOption { + type = lib.types.str; + default = "/var/lib/docker-configs"; + description = "The docker/podman socket path."; + }; + smtpemail = lib.mkOption { + type = lib.types.str; + default = "stunner6399@gmail.com"; + description = "localhost smtp email"; + }; + email = lib.mkOption { + type = lib.types.str; + default = "CaptainJawZ@protonmail.com"; + description = "localhost smtp email"; + }; + timeZone = lib.mkOption { + type = lib.types.str; + default = "America/Mexico_City"; + description = "Timezone"; + }; + enableContainers = lib.mkEnableOption "container services (Docker/Podman)"; + enableProxy = lib.mkEnableOption "nginx reverse proxy for services"; + }; + config = { + assertions = [ + { + assertion = config.my.servers.nextcloud.enable -> config.my.servers.postgres.enable; + message = "Nextcloud requires PostgreSQL to be enabled"; + } + { + assertion = config.my.servers.vaultwarden.enable -> config.my.servers.postgres.enable; + message = "Vaultwarden requires PostgreSQL to be enabled"; + } + { + assertion = config.my.servers.firefly-iii.enable -> config.my.servers.postgres.enable; + message = "Firefly III requires PostgreSQL to be enabled"; + } + { + assertion = config.my.servers.mealie.enable -> config.my.servers.postgres.enable; + message = "Mealie requires PostgreSQL to be enabled"; + } + { + assertion = config.my.servers.shiori.enable -> config.my.servers.postgres.enable; + message = "Shiori requires PostgreSQL to be enabled"; + } + { + assertion = config.my.servers.ryot.enable -> config.my.servers.postgres.enable; + message = "Ryot requires PostgreSQL to be enabled"; + } + { + assertion = config.my.servers.synapse.enable -> config.my.servers.postgres.enable; + message = "Matrix Synapse requires PostgreSQL to be enabled"; + } + { + assertion = config.my.servers.gitea.enable -> config.my.servers.postgres.enable; + message = "Gitea requires PostgreSQL to be enabled"; + } + { + assertion = + config.my.enableProxy + -> (builtins.any (s: s.enableProxy or false) (builtins.attrValues config.my.servers)); + message = "enableProxy is true but no services have enableProxy enabled"; + } + { + assertion = + config.my.enableContainers + || !(builtins.any (opt: opt) [ + config.my.servers.ryot.enable + config.my.servers.lidarr.enable + config.my.servers.prowlarr.enable + config.my.servers.maloja.enable + config.my.servers.multi-scrobbler.enable + config.my.servers.flame.enable + config.my.servers.flameSecret.enable + config.my.servers.metube.enable + config.my.servers.go-vod.enable + config.my.servers.tranga.enable + config.my.servers.drpp.enable + config.my.servers.plex-discord-bot.enable + ]); + message = "Container services are enabled but enableContainers is false"; + } + ]; + virtualisation = { + containers.enable = true; + oci-containers.backend = "podman"; + podman = lib.mkIf config.my.enableContainers { + enable = true; + dockerCompat = true; + dockerSocket.enable = true; + defaultNetwork.settings.dns_enabled = true; + autoPrune = { + enable = true; + flags = [ "--all" ]; + dates = "weekly"; + }; + }; + }; + security.acme = lib.mkIf config.services.nginx.enable { + acceptTerms = true; + defaults.email = config.my.email; + }; + services.nginx = { + enable = config.my.enableProxy; + clientMaxBodySize = "4096m"; + sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedProxySettings = true; + }; + }; +} diff --git a/modules/network/firewall.nix b/modules/network/firewall.nix new file mode 100644 index 0000000..48b3034 --- /dev/null +++ b/modules/network/firewall.nix @@ -0,0 +1,55 @@ +{ lib, config, ... }: +let + nativeServicesWithOpenFirewall = [ + "adguardhome" + "plex" + "nix-serve" + "radarr" + "sonarr" + "jellyfin" + "prowlarr" + "bazarr" + "ombi" + "flaresolverr" + ]; + servicesConfig = lib.listToAttrs ( + map (serviceName: { + name = serviceName; + value.openFirewall = config.my.servers.${serviceName}.enable or false; + }) nativeServicesWithOpenFirewall + ); +in +{ + options.my.network.firewall = { + enabledServicePorts = lib.mkEnableOption "auto-open ports for enabled services"; + staticPorts = lib.mkOption { + type = lib.types.listOf lib.types.int; + default = [ ]; + description = "Static ports to always open"; + }; + additionalPorts = lib.mkOption { + type = lib.types.listOf lib.types.int; + default = [ ]; + description = "Additional ports to open (like syncthing, gitea, etc.)"; + }; + }; + config = lib.mkIf config.my.network.firewall.enabledServicePorts { + services = servicesConfig; + networking.firewall.allowedTCPPorts = + config.my.network.firewall.staticPorts + ++ config.my.network.firewall.additionalPorts + ++ ( + config.my.servers + |> lib.filterAttrs ( + name: srv: + (srv.enable or false) && (srv ? port) && !(builtins.elem name nativeServicesWithOpenFirewall) + ) + |> lib.attrValues + |> map (srv: srv.port) + ) + ++ (lib.optionals config.services.nginx.enable [ + config.services.nginx.defaultHTTPListenPort + config.services.nginx.defaultSSLListenPort + ]); + }; +} diff --git a/modules/network/nginx.nix b/modules/network/nginx.nix new file mode 100644 index 0000000..40ad4ec --- /dev/null +++ b/modules/network/nginx.nix @@ -0,0 +1,60 @@ +{ lib, config, ... }: +let + setup = import ../factories/mkserver.nix { inherit lib config; }; + proxyReverseServices = [ + "firefox-syncserver" + "readeck" + "microbin" + "ryot" + "bazarr" + "shiori" + "metube" + "maloja" + "vaultwarden" + "mealie" + "kavita" + "multi-scrobbler" + "nix-serve" + "flame" + "flameSecret" + ]; + proxyReverseFixServices = [ + "audiobookshelf" + "lidarr" + "gitea" + "prowlarr" + "ombi" + "radarr" + "sonarr" + "atticd" + ]; + proxyReversePrivateServices = [ + "homepage" + ]; + mkServiceConfig = + type: services: lib.listToAttrs (map (name: lib.nameValuePair name { inherit type; }) services); + standardProxyServices = + (mkServiceConfig "proxyReverse" proxyReverseServices) + // (mkServiceConfig "proxyReverseFix" proxyReverseFixServices) + // (mkServiceConfig "proxyReversePrivate" proxyReversePrivateServices); + generateProxyConfig = + serviceName: serviceConfig: + let + cfg = config.my.servers.${serviceName}; + proxyFunc = + if serviceConfig.type == "proxyReverse" then + setup.proxyReverse + else if serviceConfig.type == "proxyReverseFix" then + setup.proxyReverseFix + else if serviceConfig.type == "proxyReversePrivate" then + setup.proxyReversePrivate + else + throw "Unknown proxy type: ${serviceConfig.type}"; + in + lib.nameValuePair cfg.host (lib.mkIf cfg.enableProxy (proxyFunc cfg)); +in +{ + config = lib.mkIf config.my.enableProxy { + services.nginx.virtualHosts = lib.mapAttrs' generateProxyConfig standardProxyServices; + }; +} diff --git a/modules/nix/build.nix b/modules/nix/build.nix new file mode 100644 index 0000000..079ae01 --- /dev/null +++ b/modules/nix/build.nix @@ -0,0 +1,47 @@ +{ lib, config, ... }: +{ + options.my.nix = { + features = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ + "nixos-test" + "benchmark" + "big-parallel" + "kvm" + "gccarch-znver3" + "gccarch-skylake" + "gccarch-alderlake" + ]; + description = "List of supported nix build features for this system"; + }; + buildMachines = lib.mkOption { + type = lib.types.listOf lib.types.attrs; + default = [ ]; + description = "List of remote build machines configuration"; + }; + cores = lib.mkOption { + type = lib.types.nullOr lib.types.int; + default = null; + description = "Number of cores to use for builds (null = auto-detect)"; + }; + maxJobs = lib.mkOption { + type = lib.types.nullOr lib.types.int; + default = null; + description = "Maximum number of parallel jobs (null = auto-detect)"; + }; + }; + config = { + nix.settings = lib.mkMerge [ + { + system-features = config.my.nix.features; + } + (lib.mkIf (config.my.nix.cores != null) { + inherit (config.my.nix) cores; + }) + (lib.mkIf (config.my.nix.maxJobs != null) { + max-jobs = config.my.nix.maxJobs; + }) + ]; + nix.buildMachines = lib.mkIf (config.my.nix.buildMachines != [ ]) config.my.nix.buildMachines; + }; +} diff --git a/modules/nix/gitea-actions-runners/nixos.nix b/modules/nix/gitea-actions-runners/nixos.nix new file mode 100644 index 0000000..436941c --- /dev/null +++ b/modules/nix/gitea-actions-runners/nixos.nix @@ -0,0 +1,32 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.servers.gitea; +in +{ + config = lib.mkIf (cfg.enable && config.my.secureHost) { + services.gitea-actions-runner.instances.nixos = { + inherit (cfg) url enable; + name = "${config.networking.hostName}-nixos"; + tokenFile = config.sops.secrets.gitea.path; + labels = [ + "nixos:host" + ]; + hostPackages = builtins.attrValues { + inherit (pkgs) + bash + coreutils + gitMinimal + nix + attic-client + nodejs # Required for GitHub Actions + openssh # Required for SSH git operations + ; + }; + }; + }; +} diff --git a/modules/nix/gitea-actions-runners/ryujinx.nix b/modules/nix/gitea-actions-runners/ryujinx.nix new file mode 100644 index 0000000..95a138c --- /dev/null +++ b/modules/nix/gitea-actions-runners/ryujinx.nix @@ -0,0 +1,59 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.servers.gitea; +in +{ + config = lib.mkIf (cfg.enable && config.my.secureHost) { + services.gitea-actions-runner.instances.ryujinx = { + inherit (cfg) url enable; + name = "${config.networking.hostName}-ryujinx"; + tokenFile = config.sops.secrets.gitea.path; + labels = [ + "ubuntu-latest:host" + "ubuntu-20.04:host" + ]; + hostPackages = + let + python3 = pkgs.python3.withPackages ( + ps: + builtins.attrValues { + inherit (ps) + pyyaml + lxml + ; + } + ); + in + builtins.attrValues { + inherit python3; + inherit (pkgs.xorg) libX11; + inherit (pkgs) + bash + coreutils + curl + gawk + gitMinimal + gnused + nodejs + wget + gnutar + gzip + dotnet-sdk_8 + openal + vulkan-loader + libGL + gtk3 + llvm_15 + rcodesign + gh + p7zip + ; + }; + }; + }; +} diff --git a/modules/scripts/download.nix b/modules/scripts/download.nix new file mode 100644 index 0000000..506fef9 --- /dev/null +++ b/modules/scripts/download.nix @@ -0,0 +1,121 @@ +{ + inputs, + pkgs, + lib, + config, + ... +}: +{ + imports = [ ../factories/mkscript.nix ]; + options.my.units = { + download.enable = lib.mkEnableOption "media download automation scripts"; + downloadManga.enable = lib.mkEnableOption "manga download automation"; + }; + config = + let + inherit (inputs.jawz-scripts.packages.x86_64-linux) download; + in + { + home-manager.users.jawz.programs.${config.my.shell.type} = { + shellAliases = { + dl = "${download}/bin/download -u jawz -i"; + comic = ''dl "$(cat "$LC" | fzf --multi --exact -i)"''; + gallery = ''dl "$(cat "$LW" | fzf --multi --exact -i)"''; + }; + } + // ( + if config.my.shell.type == "bash" then + { + initExtra = '' + list_root=$XDG_CONFIG_HOME/jawz/lists/jawz + export LW=$list_root/watch.txt + export LI=$list_root/instant.txt + export LC=$list_root/comic.txt + ''; + } + else + { + initContent = '' + list_root=$XDG_CONFIG_HOME/jawz/lists/jawz + export LW=$list_root/watch.txt + export LI=$list_root/instant.txt + export LC=$list_root/comic.txt + ''; + } + ); + systemd.user = { + services = + let + mkDownloadService = desc: execStartCmd: { + restartIfChanged = true; + description = "Downloads ${desc}"; + wantedBy = [ "default.target" ]; + path = [ + pkgs.bash + ]; + serviceConfig = { + TimeoutStartSec = 2000; + TimeoutStopSec = 2000; + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${download}/bin/download ${execStartCmd}"; + }; + }; + in + { + tuhmayto = lib.mkIf config.my.units.download.enable ( + mkDownloadService "tuhmayto stuff" '' + -u jawz -i https://x.com/tuhmayto/media \ + https://www.furaffinity.net/user/tuhmayto/ \ + https://bsky.app/profile/tumayto.bsky.social'' + ); + "download@" = lib.mkIf (config.my.units.download.enable || config.my.units.downloadManga.enable) ( + mkDownloadService "post from multiple sources" "%I" + ); + "instagram@" = lib.mkIf config.my.units.download.enable ( + mkDownloadService "post types from instagram" "instagram -u jawz -t %I" + ); + }; + timers = + let + downloadTimer = time: delay: { + enable = true; + description = "Downloads post types from different sites"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = time; + RandomizedDelaySec = delay; + Persistent = true; + }; + }; + in + { + # "instagram@stories" = lib.mkIf config.my.units.download.enable ( + # downloadTimer "*-*-* 12:34:00" 120 // { } + # ); + "download@main" = lib.mkIf config.my.units.download.enable ( + downloadTimer "*-*-* 06,18:02:00" 30 // { } + ); + "download@push" = lib.mkIf config.my.units.download.enable (downloadTimer "*:0/5" 30 // { }); + "download@manga" = lib.mkIf config.my.units.downloadManga.enable ( + downloadTimer "*-*-* 03:08:00" 30 // { } + ); + tuhmayto = lib.mkIf config.my.units.download.enable { + enable = true; + description = "Downloads tuhmayto stuff"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "*:0/10"; + }; + }; + }; + }; + my.scripts.download = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "download"; + package = download; + }; + }; +} diff --git a/modules/scripts/ffmpeg4discord.nix b/modules/scripts/ffmpeg4discord.nix new file mode 100644 index 0000000..735934f --- /dev/null +++ b/modules/scripts/ffmpeg4discord.nix @@ -0,0 +1,11 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.ffmpeg4discord = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "ffmpeg4discord"; + package = inputs.jawz-scripts.packages.x86_64-linux.ffmpeg4discord; + }; +} diff --git a/modules/scripts/ffmpreg.nix b/modules/scripts/ffmpreg.nix new file mode 100644 index 0000000..ce7f918 --- /dev/null +++ b/modules/scripts/ffmpreg.nix @@ -0,0 +1,11 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.ffmpreg = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "ffmpreg"; + package = inputs.jawz-scripts.packages.x86_64-linux.ffmpreg; + }; +} diff --git a/modules/scripts/find-dup-episode.nix b/modules/scripts/find-dup-episode.nix new file mode 100644 index 0000000..9f02e84 --- /dev/null +++ b/modules/scripts/find-dup-episode.nix @@ -0,0 +1,11 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.find-dup-episodes = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "find-dup-episodes"; + package = inputs.jawz-scripts.packages.x86_64-linux.find-dup-episodes; + }; +} diff --git a/modules/scripts/library-report.nix b/modules/scripts/library-report.nix new file mode 100644 index 0000000..fbbe1d2 --- /dev/null +++ b/modules/scripts/library-report.nix @@ -0,0 +1,11 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.library-report = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "library-report"; + package = inputs.jawz-scripts.packages.x86_64-linux.library-report; + }; +} diff --git a/modules/scripts/manage-library.nix b/modules/scripts/manage-library.nix new file mode 100644 index 0000000..0be7a47 --- /dev/null +++ b/modules/scripts/manage-library.nix @@ -0,0 +1,13 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.manage-library = { + enable = lib.mkDefault false; + install = true; + service = true; + name = "manage-library"; + timer = "00:30"; + description = "scans the library directory and sorts files"; + package = inputs.jawz-scripts.packages.x86_64-linux.manage-library; + }; +} diff --git a/modules/scripts/pika-list.nix b/modules/scripts/pika-list.nix new file mode 100644 index 0000000..804bb13 --- /dev/null +++ b/modules/scripts/pika-list.nix @@ -0,0 +1,11 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.pika-list = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "pika-list"; + package = inputs.jawz-scripts.packages.x86_64-linux.pika-list; + }; +} diff --git a/modules/scripts/run.nix b/modules/scripts/run.nix new file mode 100644 index 0000000..5effd53 --- /dev/null +++ b/modules/scripts/run.nix @@ -0,0 +1,11 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.run = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "run"; + package = inputs.jawz-scripts.packages.x86_64-linux.run; + }; +} diff --git a/modules/scripts/split-dir.nix b/modules/scripts/split-dir.nix new file mode 100644 index 0000000..c65bed2 --- /dev/null +++ b/modules/scripts/split-dir.nix @@ -0,0 +1,11 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.split-dir = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "split-dir"; + package = inputs.jawz-scripts.packages.x86_64-linux.split-dir; + }; +} diff --git a/modules/scripts/stream-dl.nix b/modules/scripts/stream-dl.nix new file mode 100644 index 0000000..c9ef465 --- /dev/null +++ b/modules/scripts/stream-dl.nix @@ -0,0 +1,60 @@ +{ + inputs, + pkgs, + lib, + config, + ... +}: +{ + imports = [ ../factories/mkscript.nix ]; + options.my.units.stream-dl.enable = lib.mkEnableOption "streaming media download service"; + config = + let + inherit (inputs.jawz-scripts.packages.x86_64-linux) stream-dl; + in + { + systemd.user = lib.mkIf config.my.units.stream-dl.enable { + services."stream@" = { + description = "monitors a stream channel for online streams."; + restartIfChanged = true; + wantedBy = [ "default.target" ]; + path = [ + pkgs.nix + stream-dl + ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${stream-dl}/bin/stream-dl %I"; + }; + }; + timers = + let + streamTimer = { + enable = true; + description = "monitors a stream channel for online streams."; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "5min"; + OnUnitActiveSec = "65min"; + RandomizedDelaySec = 30; + }; + }; + in + { + "stream@johnneal911" = streamTimer // { }; + "stream@uk2011boy" = streamTimer // { }; + "stream@tommy9x6" = streamTimer // { }; + "stream@brocollirob" = streamTimer // { }; + "stream@tomayto\\x20picarto" = streamTimer // { }; + }; + }; + my.scripts.stream-dl = { + enable = lib.mkDefault false; + install = true; + service = false; + name = "stream-dl"; + package = stream-dl; + }; + }; +} diff --git a/modules/scripts/tasks.nix b/modules/scripts/tasks.nix new file mode 100644 index 0000000..1d6c60f --- /dev/null +++ b/modules/scripts/tasks.nix @@ -0,0 +1,13 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.tasks = { + enable = lib.mkDefault false; + install = true; + service = true; + name = "tasks"; + timer = "*:0/10"; + description = "Runs a bunch of organizing tasks on selected directories"; + package = inputs.jawz-scripts.packages.x86_64-linux.tasks; + }; +} diff --git a/modules/scripts/tuh-activity-logger.nix b/modules/scripts/tuh-activity-logger.nix new file mode 100644 index 0000000..b0038d4 --- /dev/null +++ b/modules/scripts/tuh-activity-logger.nix @@ -0,0 +1,13 @@ +{ inputs, lib, ... }: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.tuh-activity-logger = { + enable = lib.mkDefault false; + install = true; + service = true; + name = "tuh-activity-logger"; + timer = "0/4:00"; + description = "Logs the online activity on a website"; + package = inputs.jawz-scripts.packages.x86_64-linux.tuh-activity-logger; + }; +} diff --git a/modules/scripts/update-dns.nix b/modules/scripts/update-dns.nix new file mode 100644 index 0000000..8b3ae29 --- /dev/null +++ b/modules/scripts/update-dns.nix @@ -0,0 +1,51 @@ +{ + inputs, + config, + pkgs, + lib, + ... +}: +{ + imports = [ ../factories/mkscript.nix ]; + config = lib.mkIf config.my.secureHost { + sops.secrets = { + cloudflare-api.sopsFile = ../../secrets/env.yaml; + dns = { + sopsFile = ../../secrets/env.yaml; + owner = config.users.users.jawz.name; + inherit (config.users.users.jawz) group; + }; + }; + services.cloudflare-dyndns = { + # inherit (config.my.scripts.update-dns) enable; + enable = false; + ipv4 = true; + ipv6 = false; + proxied = false; + domains = [ + config.my.domain + ]; + apiTokenFile = config.sops.secrets.cloudflare-api.path; + }; + my.scripts.update-dns = { + enable = lib.mkDefault false; + install = true; + service = true; + name = "update-dns"; + timer = "*:0/30"; + description = "Updates the IP of all my domains"; + package = + let + inherit (inputs.jawz-scripts.packages.x86_64-linux) update-dns; + in + pkgs.writeScriptBin "update-dns" '' + #!/usr/bin/env nix-shell + #! nix-shell -i bash -p bash curl + set -a + source ${config.sops.secrets.dns.path} + set -a + ${update-dns}/bin/update-dns + ''; + }; + }; +} diff --git a/modules/scripts/update-org-agenda-cache.nix b/modules/scripts/update-org-agenda-cache.nix new file mode 100644 index 0000000..c9ceb58 --- /dev/null +++ b/modules/scripts/update-org-agenda-cache.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + imports = [ ../factories/mkscript.nix ]; + config.my.scripts.update-org-agenda-cache = { + enable = lib.mkDefault false; + install = config.my.emacs.enable; + service = config.my.emacs.enable; + name = "update-org-agenda-cache"; + timer = "*:0/30"; + description = "runs a function which builds a cache file."; + package = pkgs.writeScriptBin "update-org-agenda-cache" '' + #!/usr/bin/env nix-shell + #! nix-shell -i bash -p bash + ${config.services.emacs.package}/bin/emacsclient --eval '(my/update-org-agenda-cache)' + ''; + }; +} diff --git a/modules/servers/adguardhome.nix b/modules/servers/adguardhome.nix new file mode 100644 index 0000000..16506c2 --- /dev/null +++ b/modules/servers/adguardhome.nix @@ -0,0 +1,13 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.adguardhome; +in +{ + options.my.servers.adguardhome.enable = lib.mkEnableOption "AdGuard Home DNS ad blocker"; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + services.adguardhome = { + inherit (cfg) enable; + mutableSettings = true; + }; + }; +} diff --git a/modules/servers/atticd.nix b/modules/servers/atticd.nix new file mode 100644 index 0000000..37d357e --- /dev/null +++ b/modules/servers/atticd.nix @@ -0,0 +1,33 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.atticd; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.atticd = setup.mkOptions "atticd" "cache" 2343; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + sops.secrets."private_cache_keys/atticd".sopsFile = ../../secrets/keys.yaml; + services.atticd = { + inherit (cfg) enable; + environmentFile = config.sops.secrets."private_cache_keys/atticd".path; + settings = { + listen = "[::]:${toString cfg.port}"; + jwt = { }; + chunking = { + nar-size-threshold = 64 * 1024; # 64 KiB + min-size = 16 * 1024; # 16 KiB + avg-size = 64 * 1024; # 64 KiB + max-size = 256 * 1024; # 256 KiB + }; + compression = { + type = "zstd"; + level = 8; + }; + garbage-collection = { + interval = "7 days"; + default-retention-period = "7 days"; + }; + }; + }; + }; +} diff --git a/modules/servers/audiobookshelf.nix b/modules/servers/audiobookshelf.nix new file mode 100644 index 0000000..cdcb04d --- /dev/null +++ b/modules/servers/audiobookshelf.nix @@ -0,0 +1,16 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.audiobookshelf; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.audiobookshelf = setup.mkOptions "audiobookshelf" "audiobooks" 5687; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + my.servers.audiobookshelf.enableSocket = true; + services.audiobookshelf = { + inherit (cfg) enable port; + host = cfg.ip; + group = "piracy"; + }; + }; +} diff --git a/modules/servers/bazarr.nix b/modules/servers/bazarr.nix new file mode 100644 index 0000000..b7617ac --- /dev/null +++ b/modules/servers/bazarr.nix @@ -0,0 +1,12 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.bazarr; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.bazarr = setup.mkOptions "bazarr" "subs" config.services.bazarr.listenPort; + config.services.bazarr = lib.mkIf cfg.enable { + inherit (cfg) enable; + group = "piracy"; + }; +} diff --git a/modules/servers/drpp.nix b/modules/servers/drpp.nix new file mode 100644 index 0000000..9481770 --- /dev/null +++ b/modules/servers/drpp.nix @@ -0,0 +1,19 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.drpp; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.drpp = setup.mkOptions "drpp" "drpp" 0; + config.virtualisation.oci-containers.containers.drpp = lib.mkIf cfg.enable { + image = "ghcr.io/phin05/discord-rich-presence-plex:latest"; + environment = { + DRPP_UID = toString config.users.users.jawz.uid; + DRPP_GID = toString config.users.groups.users.gid; + }; + volumes = [ + "${config.my.containerData}/drpp:/app/data" + "/run/user/${toString config.users.users.jawz.uid}:/run/app" + ]; + }; +} diff --git a/modules/servers/firefly-iii.nix b/modules/servers/firefly-iii.nix new file mode 100644 index 0000000..960d8e2 --- /dev/null +++ b/modules/servers/firefly-iii.nix @@ -0,0 +1,25 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.firefly-iii; +in +{ + options.my.servers.firefly-iii = { + enable = lib.mkEnableOption "Firefly III personal finance manager"; + enableProxy = lib.mkEnableOption "enableProxy"; + }; + config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable && config.my.secureHost) { + sops.secrets.firefly-iii-keyfile = { + owner = config.users.users.firefly-iii.name; + inherit (config.users.users.firefly-iii) group; + }; + services.firefly-iii = { + inherit (cfg) enable; + enableNginx = cfg.enableProxy; + settings = { + APP_KEY_FILE = config.sops.secrets.firefly-iii-keyfile.path; + DB_HOST = config.my.postgresSocket; + DB_CONNECTION = "pgsql"; + }; + }; + }; +} diff --git a/modules/servers/firefox-syncserver.nix b/modules/servers/firefox-syncserver.nix new file mode 100644 index 0000000..04e486d --- /dev/null +++ b/modules/servers/firefox-syncserver.nix @@ -0,0 +1,23 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.firefox-syncserver; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.firefox-syncserver = setup.mkOptions "firefox-syncserver" "sync" 4233; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + # sops.secrets.firefox-syncserver.sopsFile = ../../secrets/env.yaml; + services.firefox-syncserver = { + inherit (cfg) enable; + # secrets = config.sops.secrets.firefox-syncserver; + settings.port = cfg.port; + singleNode = { + enable = true; + enableTLS = true; + enableNginx = true; + hostname = config.networking.hostName; + # url = cfg.host; + }; + }; + }; +} diff --git a/modules/servers/flame.nix b/modules/servers/flame.nix new file mode 100644 index 0000000..f77c929 --- /dev/null +++ b/modules/servers/flame.nix @@ -0,0 +1,47 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.flame; + cfgS = config.my.servers.flameSecret; + enable = (cfg.enable || cfgS.enable) && config.my.secureHost; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers = { + flame = setup.mkOptions "flame" "start" 5005; + flameSecret = setup.mkOptions "flameSecret" "qampqwn4wprhqny8h8zj" 5007; + }; + config = lib.mkIf enable { + sops.secrets = { + flame.sopsFile = ../../secrets/env.yaml; + }; + virtualisation.oci-containers.containers = lib.mkIf enable { + flame = lib.mkIf cfg.enable { + autoStart = true; + image = "pawelmalak/flame"; + ports = [ "${toString cfg.port}:${toString cfg.port}" ]; + volumes = [ + "${config.my.containerData}/flame:/app/data" + "${config.my.containerSocket}:${config.my.containerSocket}" + ]; + environmentFiles = [ config.sops.secrets.flame.path ]; + environment = { + TZ = config.my.timeZone; + PUID = toString config.users.users.jawz.uid; + PGID = toString config.users.groups.users.gid; + }; + }; + flame-nsfw = lib.mkIf cfgS.enable { + autoStart = true; + image = "pawelmalak/flame"; + ports = [ "${toString cfgS.port}:${toString cfg.port}" ]; + volumes = [ "${config.my.containerData}/flame-nsfw:/app/data" ]; + environmentFiles = [ config.sops.secrets.flame.path ]; + environment = { + TZ = config.my.timeZone; + PUID = toString config.users.users.jawz.uid; + PGID = toString config.users.groups.users.gid; + }; + }; + }; + }; +} diff --git a/modules/servers/gitea.nix b/modules/servers/gitea.nix new file mode 100644 index 0000000..afdb1a1 --- /dev/null +++ b/modules/servers/gitea.nix @@ -0,0 +1,42 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.servers.gitea; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + imports = [ + ../nix/gitea-actions-runners/ryujinx.nix + ../nix/gitea-actions-runners/nixos.nix + ]; + options.my.servers.gitea = setup.mkOptions "gitea" "git" 9083; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + sops.secrets.gitea.sopsFile = ../../secrets/env.yaml; + services.gitea = { + inherit (cfg) enable; + settings = { + session.COOKIE_SECURE = true; + server = { + DOMAIN = cfg.host; + ROOT_URL = cfg.url; + HTTP_PORT = cfg.port; + }; + mailer = { + ENABLED = true; + PROTOCOL = "sendmail"; + FROM = config.my.smtpemail; + SENDMAIL_PATH = "${pkgs.msmtp}/bin/msmtp"; + }; + }; + database = { + socket = config.my.postgresSocket; + type = "postgres"; + createDatabase = false; + }; + }; + }; +} diff --git a/modules/servers/homepage.nix b/modules/servers/homepage.nix new file mode 100644 index 0000000..97a269b --- /dev/null +++ b/modules/servers/homepage.nix @@ -0,0 +1,35 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.homepage; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.homepage = setup.mkOptions "homepage" "home" 8082; + config = lib.mkIf config.my.secureHost { + sops.secrets = lib.mkIf cfg.enable { + homepage.sopsFile = ../../secrets/homepage.yaml; + "private-ca/pem" = { + sopsFile = ../../secrets/certs.yaml; + owner = "nginx"; + group = "nginx"; + }; + }; + my.servers.homepage.certPath = config.sops.secrets."private-ca/pem".path; + services.homepage-dashboard = lib.mkIf cfg.enable { + inherit (cfg) enable; + listenPort = cfg.port; + environmentFile = config.sops.secrets.homepage.path; + settings = { + providers.openweathermap = "{{HOMEPAGE_VAR_OPENWEATHERMAP_API_KEY}}"; + layout = import ./homepage/layout.nix; + }; + widgets = import ./homepage/widgets.nix; + services = import ./homepage/services.nix { inherit lib config; }; + bookmarks = + builtins.readDir ./homepage/bookmarks + |> builtins.attrNames + |> builtins.filter (file: builtins.match ".*\\.nix" file != null) + |> map (file: import ./homepage/bookmarks/${file}); + }; + }; +} diff --git a/modules/servers/homepage/bookmarks/art.nix b/modules/servers/homepage/bookmarks/art.nix new file mode 100644 index 0000000..1d92674 --- /dev/null +++ b/modules/servers/homepage/bookmarks/art.nix @@ -0,0 +1,49 @@ +{ + "art" = [ + { + deviantart = [ + { + abbr = "DA"; + href = "https://deviantart.com/"; + description = ""; + } + ]; + } + { + furaffinity = [ + { + abbr = "FA"; + href = "https://furaffinity.net/"; + description = ""; + } + ]; + } + { + patreon = [ + { + abbr = "PT"; + href = "https://patreon.com/"; + description = ""; + } + ]; + } + { + pillowfort = [ + { + abbr = "MJ"; + href = "https://www.midjourney.com"; + description = ""; + } + ]; + } + { + tumblr = [ + { + abbr = "TB"; + href = "https://tumblr.com/"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/development.nix b/modules/servers/homepage/bookmarks/development.nix new file mode 100644 index 0000000..2bfa499 --- /dev/null +++ b/modules/servers/homepage/bookmarks/development.nix @@ -0,0 +1,49 @@ +{ + "development" = [ + { + chatgpt = [ + { + abbr = "CGPT"; + href = "https://chatgpt.com/"; + description = ""; + } + ]; + } + { + protonmail = [ + { + abbr = "PM"; + href = "https://account.proton.me/mail"; + description = ""; + } + ]; + } + { + github = [ + { + abbr = "GH"; + href = "https://github.com/"; + description = ""; + } + ]; + } + { + gitlab = [ + { + abbr = "GL"; + href = "https://gitlab.com/"; + description = ""; + } + ]; + } + { + exercism = [ + { + abbr = "EX"; + href = "https://exercism.org/"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/entertainment.nix b/modules/servers/homepage/bookmarks/entertainment.nix new file mode 100644 index 0000000..55965d6 --- /dev/null +++ b/modules/servers/homepage/bookmarks/entertainment.nix @@ -0,0 +1,49 @@ +{ + "entertainment" = [ + { + epicgames = [ + { + abbr = "EG"; + href = "https://store.epicgames.com/"; + description = ""; + } + ]; + } + { + deezer = [ + { + abbr = "DZ"; + href = "https://deezer.com/us/"; + description = ""; + } + ]; + } + { + readcomiconline = [ + { + abbr = "RCO"; + href = "https://readcomiconline.li/"; + description = ""; + } + ]; + } + { + primevideo = [ + { + abbr = "PV"; + href = "https://primevideo.com/"; + description = ""; + } + ]; + } + { + youtube = [ + { + abbr = "YT"; + href = "https://youtube.com/"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/secret-art.nix b/modules/servers/homepage/bookmarks/secret-art.nix new file mode 100644 index 0000000..d21ddc7 --- /dev/null +++ b/modules/servers/homepage/bookmarks/secret-art.nix @@ -0,0 +1,67 @@ +{ + "secret art" = [ + { + "{{HOMEPAGE_VAR_NAME_1}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_1}}"; + href = "{{HOMEPAGE_VAR_URL_1}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_2}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_2}}"; + href = "{{HOMEPAGE_VAR_URL_2}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_3}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_3}}"; + href = "{{HOMEPAGE_VAR_URL_3}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_4}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_4}}"; + href = "{{HOMEPAGE_VAR_URL_4}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_5}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_5}}"; + href = "{{HOMEPAGE_VAR_URL_5}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_6}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_6}}"; + href = "{{HOMEPAGE_VAR_URL_6}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_7}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_7}}"; + href = "{{HOMEPAGE_VAR_URL_7}}"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/secret-media.nix b/modules/servers/homepage/bookmarks/secret-media.nix new file mode 100644 index 0000000..140dc2b --- /dev/null +++ b/modules/servers/homepage/bookmarks/secret-media.nix @@ -0,0 +1,67 @@ +{ + "secret media" = [ + { + "{{HOMEPAGE_VAR_NAME_8}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_8}}"; + href = "{{HOMEPAGE_VAR_URL_8}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_9}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_9}}"; + href = "{{HOMEPAGE_VAR_URL_9}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_10}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_10}}"; + href = "{{HOMEPAGE_VAR_URL_10}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_11}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_11}}"; + href = "{{HOMEPAGE_VAR_URL_11}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_12}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_12}}"; + href = "{{HOMEPAGE_VAR_URL_12}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_13}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_13}}"; + href = "{{HOMEPAGE_VAR_URL_13}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_14}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_14}}"; + href = "{{HOMEPAGE_VAR_URL_14}}"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/secret-social.nix b/modules/servers/homepage/bookmarks/secret-social.nix new file mode 100644 index 0000000..d7d7699 --- /dev/null +++ b/modules/servers/homepage/bookmarks/secret-social.nix @@ -0,0 +1,67 @@ +{ + "secret social" = [ + { + "{{HOMEPAGE_VAR_NAME_15}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_15}}"; + href = "{{HOMEPAGE_VAR_URL_15}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_16}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_16}}"; + href = "{{HOMEPAGE_VAR_URL_16}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_17}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_17}}"; + href = "{{HOMEPAGE_VAR_URL_17}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_18}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_18}}"; + href = "{{HOMEPAGE_VAR_URL_18}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_19}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_19}}"; + href = "{{HOMEPAGE_VAR_URL_19}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_20}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_20}}"; + href = "{{HOMEPAGE_VAR_URL_20}}"; + description = ""; + } + ]; + } + { + "{{HOMEPAGE_VAR_NAME_21}}" = [ + { + abbr = "{{HOMEPAGE_VAR_ABBR_21}}"; + href = "{{HOMEPAGE_VAR_URL_21}}"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/servers.nix b/modules/servers/homepage/bookmarks/servers.nix new file mode 100644 index 0000000..f3be9fd --- /dev/null +++ b/modules/servers/homepage/bookmarks/servers.nix @@ -0,0 +1,58 @@ +{ + "server bookmarks" = [ + { + readeck = [ + { + abbr = "RD"; + href = "https://laters.servidos.lat/"; + description = ""; + } + ]; + } + { + maloja = [ + { + abbr = "ML"; + href = "https://maloja.servidos.lat/"; + description = ""; + } + ]; + } + { + microbin = [ + { + abbr = "CP"; + href = "https://copy.servidos.lat/"; + description = ""; + } + ]; + } + { + multi-scrobbler = [ + { + abbr = "MS"; + href = "https://scrobble.servidos.lat/"; + description = ""; + } + ]; + } + { + ryot = [ + { + abbr = "RT"; + href = "https://tracker.servidos.lat/"; + description = ""; + } + ]; + } + { + vaultwarden = [ + { + abbr = "VW"; + href = "https://vault.servidos.lat"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/shopping.nix b/modules/servers/homepage/bookmarks/shopping.nix new file mode 100644 index 0000000..2fa6b1c --- /dev/null +++ b/modules/servers/homepage/bookmarks/shopping.nix @@ -0,0 +1,49 @@ +{ + "shopping" = [ + { + amazon = [ + { + abbr = "AM"; + href = "https://amazon.com.mx/"; + description = ""; + } + ]; + } + { + cinepolis = [ + { + abbr = "CP"; + href = "https://cinepolis.com/"; + description = ""; + } + ]; + } + { + paypal = [ + { + abbr = "PP"; + href = "https://paypal.com/"; + description = ""; + } + ]; + } + { + walmart = [ + { + abbr = "WM"; + href = "https://super.walmart.com.mx/"; + description = ""; + } + ]; + } + { + mercadolibre = [ + { + abbr = "ML"; + href = "https://mercadolibre.com.mx/"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/social.nix b/modules/servers/homepage/bookmarks/social.nix new file mode 100644 index 0000000..b6b99bd --- /dev/null +++ b/modules/servers/homepage/bookmarks/social.nix @@ -0,0 +1,49 @@ +{ + "social" = [ + { + bsky = [ + { + abbr = "BS"; + href = "https://bsky.app/"; + description = ""; + } + ]; + } + { + facebook = [ + { + abbr = "FB"; + href = "https://facebook.com/"; + description = ""; + } + ]; + } + { + instagram = [ + { + abbr = "IG"; + href = "https://instagram.com/"; + description = ""; + } + ]; + } + { + reddit = [ + { + abbr = "RD"; + href = "https://reddit.com/"; + description = ""; + } + ]; + } + { + x = [ + { + abbr = "X"; + href = "https://x.com/home"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/bookmarks/torrents.nix b/modules/servers/homepage/bookmarks/torrents.nix new file mode 100644 index 0000000..eb23179 --- /dev/null +++ b/modules/servers/homepage/bookmarks/torrents.nix @@ -0,0 +1,49 @@ +{ + "torrents" = [ + { + docspedia = [ + { + abbr = "DP"; + href = "https://docspedia.world/"; + description = ""; + } + ]; + } + { + teamos = [ + { + abbr = "TM"; + href = "https://teamos.xyz/"; + description = ""; + } + ]; + } + { + iptorrents = [ + { + abbr = "IPT"; + href = "https://iptorrents.com/"; + description = ""; + } + ]; + } + { + itatorrents = [ + { + abbr = "ITA"; + href = "https://itatorrents.xyz/"; + description = ""; + } + ]; + } + { + fearnopeer = [ + { + abbr = "FNP"; + href = "https://fearnopeer.com/"; + description = ""; + } + ]; + } + ]; +} diff --git a/modules/servers/homepage/layout.nix b/modules/servers/homepage/layout.nix new file mode 100644 index 0000000..c8932ee --- /dev/null +++ b/modules/servers/homepage/layout.nix @@ -0,0 +1,46 @@ +{ + stash = { + header = false; + tab = "secret"; + style = "row"; + }; + agenda = { + header = false; + tab = "agenda"; + style = "row"; + columns = 1; + }; + multimedia = { + header = false; + tab = "servers"; + style = "row"; + columns = 4; + }; + piracy = { + header = false; + tab = "servers"; + style = "row"; + columns = 4; + }; + main = { + header = false; + tab = "servers"; + style = "row"; + columns = 3; + }; + "server bookmarks" = { + header = false; + tab = "servers"; + style = "row"; + columns = 3; + }; + art.tab = "bookmarks"; + entertainment.tab = "bookmarks"; + torrents.tab = "bookmarks"; + shopping.tab = "bookmarks"; + social.tab = "bookmarks"; + development.tab = "bookmarks"; + "secret art".tab = "secret"; + "secret media".tab = "secret"; + "secret social".tab = "secret"; +} diff --git a/modules/servers/homepage/service-widgets.nix b/modules/servers/homepage/service-widgets.nix new file mode 100644 index 0000000..095515a --- /dev/null +++ b/modules/servers/homepage/service-widgets.nix @@ -0,0 +1,263 @@ +{ lib, config, ... }: +{ + calendar.widget = { + type = "calendar"; + view = "agenda"; + maxEvents = 10; + showTime = true; + inherit (config.my) timeZone; + integrations = + let + createIntegration = name: color: { + inherit color; + type = name; + service_group = "piracy"; + service_name = name; + params.unmonitored = true; + }; + in + [ + (createIntegration "sonarr" "teal") + (createIntegration "radarr" "amber") + (createIntegration "lidarr" "lime") + ]; + }; + audiobookshelf = + let + cfg = config.my.servers.audiobookshelf; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = cfg.local; + type = cfg.name; + key = "{{HOMEPAGE_VAR_AUDIOBOOKSHELF}}"; + }; + }; + plex = + let + cfg = config.my.servers.plex; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = cfg.local; + type = cfg.name; + key = "{{HOMEPAGE_VAR_PLEX}}"; + }; + }; + jellyfin = + let + cfg = config.my.servers.jellyfin; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = cfg.local; + type = cfg.name; + key = "{{HOMEPAGE_VAR_JELLYFIN}}"; + enableUser = true; + enableBlocks = true; + enableNowPlaying = false; + }; + }; + sonarr = + let + cfg = config.my.servers.sonarr; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = cfg.local; + type = cfg.name; + key = "{{HOMEPAGE_VAR_SONARR}}"; + enableQueue = true; + }; + }; + radarr = + let + cfg = config.my.servers.radarr; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = cfg.local; + type = cfg.name; + key = "{{HOMEPAGE_VAR_RADARR}}"; + enableQueue = true; + }; + }; + lidarr = + let + cfg = config.my.servers.lidarr; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = cfg.local; + type = cfg.name; + key = "{{HOMEPAGE_VAR_LIDARR}}"; + }; + }; + prowlarr = + let + cfg = config.my.servers.prowlarr; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + type = cfg.name; + url = cfg.local; + key = "{{HOMEPAGE_VAR_PROWLARR}}"; + }; + }; + bazarr = + let + cfg = config.my.servers.bazarr; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + type = cfg.name; + url = cfg.local; + key = "{{HOMEPAGE_VAR_BAZARR}}"; + }; + }; + kavita = + let + cfg = config.my.servers.kavita; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + type = cfg.name; + url = cfg.local; + username = "{{HOMEPAGE_VAR_KAVITA_USERNAME}}"; + password = "{{HOMEPAGE_VAR_KAVITA_PASSWORD}}"; + }; + }; + qbittorrent = + let + url = "https://${config.my.ips.server}:${toString config.my.servers.qbittorrent.port}"; + name = "qbittorrent"; + in + lib.mkIf config.my.servers.qbittorrent.enable { + icon = "${name}.png"; + href = url; + widget = { + type = name; + inherit url; + username = "{{HOMEPAGE_VAR_QBIT_USERNAME}}"; + password = "{{HOMEPAGE_VAR_QBIT_PASSWORD}}"; + }; + }; + sabnzbd = + let + name = "sabnzbd"; + url = "https://${config.my.ips.server}:${toString config.my.servers.sabnzbd.port}"; + in + { + icon = "${name}.png"; + href = url; + widget = { + type = name; + inherit url; + key = "{{HOMEPAGE_VAR_SABNZBD}}"; + }; + }; + mealie = + let + cfg = config.my.servers.mealie; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = cfg.local; + type = cfg.name; + key = "{{HOMEPAGE_VAR_MEALIE}}"; + version = 2; + }; + }; + nextcloud = + let + cfg = config.my.servers.nextcloud; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = "http://${config.my.ips.wg-server}:8081"; + type = cfg.name; + username = "{{HOMEPAGE_VAR_NEXTCLOUD_USERNAME}}"; + password = "{{HOMEPAGE_VAR_NEXTCLOUD_PASSWORD}}"; + token = "{{HOMEPAGE_VAR_NEXTCLOUD_TOKEN}}"; + fields = [ + "memoryusage" + "activeusers" + "numfiles" + "numshares" + ]; + }; + }; + paperless = + let + name = "paperlessngx"; + url = "http://${config.my.ips.server}:${toString config.services.paperless.port}"; + in + lib.mkIf config.my.servers.paperless.enable { + icon = "paperless.png"; + href = url; + widget = { + type = name; + key = "{{HOMEPAGE_VAR_PAPERLESS}}"; + inherit url; + fields = [ + "total" + "inbox" + ]; + }; + }; + gitea = + let + cfg = config.my.servers.gitea; + in + lib.mkIf (cfg.enable || cfg.enableProxy) { + icon = "${cfg.name}.png"; + href = cfg.url; + widget = { + url = cfg.local; + type = cfg.name; + key = "{{HOMEPAGE_VAR_GITEA}}"; + }; + }; + stash = + let + name = "stash"; + url = "http://${config.my.ips.server}:9999"; + in + { + icon = "${name}.png"; + href = url; + widget = { + type = name; + key = "{{HOMEPAGE_VAR_STASH}}"; + inherit url; + fields = [ + "scenes" + "images" + "playCount" + "oCount" + ]; + }; + }; +} diff --git a/modules/servers/homepage/services.nix b/modules/servers/homepage/services.nix new file mode 100644 index 0000000..c781795 --- /dev/null +++ b/modules/servers/homepage/services.nix @@ -0,0 +1,39 @@ +{ lib, config, ... }: +let + services = import ./service-widgets.nix { inherit lib config; }; +in +[ + { "stash" = [ { inherit (services) stash; } ]; } + { + agenda = [ + { inherit (services) calendar; } + ]; + } + { + multimedia = [ + { inherit (services) plex; } + { inherit (services) jellyfin; } + { inherit (services) audiobookshelf; } + { inherit (services) kavita; } + ]; + } + { + piracy = [ + { inherit (services) sonarr; } + { inherit (services) radarr; } + { inherit (services) lidarr; } + { inherit (services) bazarr; } + { inherit (services) prowlarr; } + { inherit (services) sabnzbd; } + { inherit (services) qbittorrent; } + { inherit (services) paperless; } + ]; + } + { + main = [ + { inherit (services) nextcloud; } + { inherit (services) gitea; } + { inherit (services) mealie; } + ]; + } +] diff --git a/modules/servers/homepage/widgets.nix b/modules/servers/homepage/widgets.nix new file mode 100644 index 0000000..9694188 --- /dev/null +++ b/modules/servers/homepage/widgets.nix @@ -0,0 +1,35 @@ +[ + { + resources = { + cpu = true; + cputemp = true; + units = "metric"; + disk = "/"; + memory = true; + }; + } + { + search = { + provider = [ + "brave" + "bing" + "google" + ]; + target = "_blank"; + showSearchSuggestions = true; + }; + } + { + openweathermap = { + label = "Apodaca"; + latitude = 25.760339; + longitude = -100.2190662; + units = "metric"; + provider = "openweathermap"; + cache = 5; + format = { + maximumFractionDigits = 1; + }; + }; + } +] diff --git a/modules/servers/jellyfin.nix b/modules/servers/jellyfin.nix new file mode 100644 index 0000000..3cf1469 --- /dev/null +++ b/modules/servers/jellyfin.nix @@ -0,0 +1,117 @@ +{ + inputs, + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.servers.jellyfin; + inherit (inputs.jawz-scripts.packages.x86_64-linux) sub-sync; + sub-sync-path = [ + pkgs.nix + pkgs.bash + pkgs.fd + pkgs.ripgrep + pkgs.file + pkgs.alass + pkgs.ffmpeg + pkgs.gum + sub-sync + ]; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.jellyfin = setup.mkOptions "jellyfin" "flix" 8096; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + environment.systemPackages = [ + pkgs.jellyfin-ffmpeg + ] + ++ (lib.optional cfg.enableCron [ sub-sync-path ]); + services = { + jellyfin = { + inherit (cfg) enable; + group = "piracy"; + }; + nginx = lib.mkIf cfg.enableProxy { + appendHttpConfig = '' + # JELLYFIN + proxy_cache_path /var/cache/nginx/jellyfin levels=1:2 keys_zone=jellyfin:100m max_size=15g inactive=1d use_temp_path=off; + map $request_uri $h264Level { ~(h264-level=)(.+?)& $2; } + map $request_uri $h264Profile { ~(h264-profile=)(.+?)& $2; } + ''; + virtualHosts."${cfg.host}" = { + forceSSL = true; + enableACME = true; + http2 = true; + serverAliases = [ "flix.rotehaare.art" ]; + extraConfig = '' + # use a variable to store the upstream proxy + # in this example we are using a hostname which is resolved via DNS + # (if you aren't using DNS remove the resolver line and change the variable to point to an IP address + resolver ${cfg.ip} valid=30; + location = / { + return 302 http://$host/web/; + #return 302 https://$host/web/; + } + location = /web/ { + # Proxy main Jellyfin traffic + proxy_pass ${cfg.local}/web/index.html; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Protocol $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } + ''; + locations = { + "/" = { + proxyPass = cfg.local; + proxyWebsockets = true; + }; + "/socket" = { + proxyPass = cfg.local; + extraConfig = '' + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + ''; + }; + "~ /Items/(.*)/Images" = { + proxyPass = cfg.local; + extraConfig = '' + proxy_cache jellyfin; + proxy_cache_revalidate on; + proxy_cache_lock on; + ''; + }; + }; + }; + }; + }; + systemd = lib.mkIf cfg.enableCron { + services.sub-sync = { + restartIfChanged = true; + description = "syncronizes subtitles downloaded & modified today"; + wantedBy = [ "default.target" ]; + path = sub-sync-path; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${sub-sync}/bin/sub-sync all"; + Type = "simple"; + User = "root"; + }; + }; + timers.sub-sync = { + enable = true; + description = "syncronizes subtitles downloaded & modified today"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "20:00"; + }; + }; + }; + }; +} diff --git a/modules/servers/kavita.nix b/modules/servers/kavita.nix new file mode 100644 index 0000000..c37f0cc --- /dev/null +++ b/modules/servers/kavita.nix @@ -0,0 +1,26 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.kavita; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.kavita = setup.mkOptions "kavita" "library" config.services.kavita.settings.Port; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + sops.secrets.kavita-token = { + owner = config.users.users.kavita.name; + inherit (config.users.users.kavita) group; + }; + users.users.kavita = { + isSystemUser = true; + group = "kavita"; + extraGroups = [ + "users" + "piracy" + ]; + }; + services.kavita = { + inherit (cfg) enable; + tokenKeyFile = config.sops.secrets.kavita-token.path; + }; + }; +} diff --git a/modules/servers/lidarr.nix b/modules/servers/lidarr.nix new file mode 100644 index 0000000..86204a3 --- /dev/null +++ b/modules/servers/lidarr.nix @@ -0,0 +1,31 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.lidarr; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.lidarr = setup.mkOptions "lidarr" "music" 8686; + config.virtualisation.oci-containers.containers.lidarr = lib.mkIf cfg.enable { + autoStart = true; + image = "linuxserver/lidarr:version-2.13.3.4711"; + ports = [ "${toString cfg.port}:${toString cfg.port}" ]; + environment = { + TZ = config.my.timeZone; + PUID = toString config.users.users.jawz.uid; + PGID = toString config.users.groups.piracy.gid; + }; + volumes = [ + "/srv/pool/multimedia:/data" + "/srv/pool/multimedia/media/Music:/music" + "/srv/pool/multimedia/media/MusicVideos:/music-videos" + "/srv/pool/multimedia/downloads/usenet:/usenet" + "/srv/pool/multimedia/downloads/torrent:/torrent" + "${config.my.containerData}/lidarr/files:/config" + "${config.my.containerData}/lidarr/custom-services.d:/custom-services.d" + "${config.my.containerData}/lidarr/custom-cont-init.d:/custom-cont-init.d" + ]; + extraOptions = [ + "--network=host" + ]; + }; +} diff --git a/modules/servers/maloja.nix b/modules/servers/maloja.nix new file mode 100644 index 0000000..e2e3df4 --- /dev/null +++ b/modules/servers/maloja.nix @@ -0,0 +1,25 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.maloja; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.maloja = setup.mkOptions "maloja" "maloja" 42010; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + sops.secrets.maloja.sopsFile = ../../secrets/env.yaml; + virtualisation.oci-containers.containers.maloja = { + image = "krateng/maloja:3.2.4"; + ports = [ "${toString cfg.port}:${toString cfg.port}" ]; + environmentFiles = [ config.sops.secrets.maloja.path ]; + environment = { + TZ = config.my.timeZone; + MALOJA_TIMEZONE = "-6"; + PUID = toString config.users.users.jawz.uid; + PGID = toString config.users.groups.users.gid; + MALOJA_DATA_DIRECTORY = "/mljdata"; + MALOJA_SKIP_SETUP = "true"; + }; + volumes = [ "${config.my.containerData}/maloja:/mljdata" ]; + }; + }; +} diff --git a/modules/servers/mealie.nix b/modules/servers/mealie.nix new file mode 100644 index 0000000..5187b03 --- /dev/null +++ b/modules/servers/mealie.nix @@ -0,0 +1,28 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.mealie; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.mealie = setup.mkOptions "mealie" "mealie" 9925; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + sops.secrets.mealie.sopsFile = ../../secrets/env.yaml; + services.mealie = { + inherit (cfg) enable port; + settings = { + TZ = config.my.timeZone; + DEFAULT_GROUP = "Home"; + BASE_URL = cfg.url; + API_DOCS = "false"; + ALLOW_SIGNUP = "false"; + DB_ENGINE = "postgres"; + POSTGRES_URL_OVERRIDE = "postgresql://${cfg.name}:@/${cfg.name}?host=${config.my.postgresSocket}"; + MAX_WORKERS = "1"; + WEB_CONCURRENCY = "1"; + SMTP_HOST = "smtp.gmail.com"; + SMTP_PORT = "587"; + }; + credentialsFile = config.sops.secrets.mealie.path; + }; + }; +} diff --git a/modules/servers/metube.nix b/modules/servers/metube.nix new file mode 100644 index 0000000..c9898e8 --- /dev/null +++ b/modules/servers/metube.nix @@ -0,0 +1,22 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.metube; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.metube = setup.mkOptions "metube" "bajameesta" 8881; + config.virtualisation.oci-containers.containers.metube = lib.mkIf cfg.enable { + image = "ghcr.io/alexta69/metube:latest"; + ports = [ "${toString cfg.port}:8081" ]; + volumes = [ + "${config.my.containerData}/metube:/downloads" + "/home/jawz/.librewolf/cookies.txt:/cookies.txt" + ]; + environment = { + TZ = config.my.timeZone; + YTDL_OPTIONS = ''{"cookiefile":"/cookies.txt"}''; + PUID = toString config.users.users.jawz.uid; + PGID = toString config.users.groups.piracy.gid; + }; + }; +} diff --git a/modules/servers/microbin.nix b/modules/servers/microbin.nix new file mode 100644 index 0000000..60d73cb --- /dev/null +++ b/modules/servers/microbin.nix @@ -0,0 +1,20 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.microbin; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.microbin = setup.mkOptions "microbin" "copy" 8086; + config.services.microbin = lib.mkIf (cfg.enable && config.my.secureHost) { + inherit (cfg) enable; + settings = { + MICROBIN_PORT = cfg.port; + MICROBIN_HIDE_LOGO = false; + MICROBIN_HIGHLIGHTSYNTAX = true; + MICROBIN_PRIVATE = true; + MICROBIN_QR = true; + MICROBIN_ENCRYPTION_CLIENT_SIDE = true; + MICROBIN_ENCRYPTION_SERVER_SIDE = true; + }; + }; +} diff --git a/modules/servers/multi-scrobbler.nix b/modules/servers/multi-scrobbler.nix new file mode 100644 index 0000000..5aef9b1 --- /dev/null +++ b/modules/servers/multi-scrobbler.nix @@ -0,0 +1,27 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.multi-scrobbler; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.multi-scrobbler = setup.mkOptions "multi-scrobbler" "scrobble" 9078; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + sops.secrets.multi-scrobbler.sopsFile = ../../secrets/env.yaml; + virtualisation.oci-containers.containers.multi-scrobbler = { + image = "foxxmd/multi-scrobbler:0.10.0"; + ports = [ "${toString cfg.port}:${toString cfg.port}" ]; + environmentFiles = [ config.sops.secrets.multi-scrobbler.path ]; + environment = { + TZ = config.my.timeZone; + PUID = toString config.users.users.jawz.uid; + PGID = toString config.users.groups.users.gid; + BASE_URL = cfg.url; + DEEZER_REDIRECT_URI = "http://${config.my.ips.${cfg.hostName}}:${toString cfg.port}/deezer/callback"; + MALOJA_URL = "http://192.168.100.15:42010"; + PLEX_URL = "http://192.168.100.15:32400"; + WS_ENABLE = "true"; + }; + volumes = [ "${config.my.containerData}/multi-scrobbler:/config" ]; + }; + }; +} diff --git a/modules/servers/nextcloud.nix b/modules/servers/nextcloud.nix new file mode 100644 index 0000000..9a59d27 --- /dev/null +++ b/modules/servers/nextcloud.nix @@ -0,0 +1,289 @@ +{ + inputs, + lib, + config, + pkgs, + ... +}: +let + commonProxyConfig = '' + proxy_set_header Host $host; + ''; + commonWebsocketConfig = '' + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_read_timeout 36000s; + ''; + exiftool = pkgs.perlPackages.buildPerlPackage ( + let + version = "12.70"; + in + { + pname = "Image-ExifTool"; + inherit version; + src = pkgs.fetchurl { + url = "https://exiftool.org/Image-ExifTool-${version}.tar.gz"; + hash = "sha256-TLJSJEXMPj870TkExq6uraX8Wl4kmNerrSlX3LQsr/4="; + }; + } + ); + pytensorflow = pkgs.python311.withPackages (ps: [ ps.tensorflow ]); + cfg = config.my.servers.nextcloud; + cfgC = config.my.servers.collabora; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers = { + nextcloud = setup.mkOptions "nextcloud" "cloud" 80; + collabora = setup.mkOptions "collabora" "collabora" 9980; + go-vod.enable = lib.mkEnableOption "Go-VOD video transcoding service"; + }; + config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable && config.my.secureHost) { + sops.secrets.nextcloud-adminpass = { + owner = config.users.users.nextcloud.name; + inherit (config.users.users.nextcloud) group; + }; + nixpkgs.config.permittedInsecurePackages = [ + "nodejs-14.21.3" + "openssl-1.1.1v" + ]; + users.users.nextcloud = { + isSystemUser = true; + extraGroups = [ "render" ]; + packages = builtins.attrValues { + inherit exiftool pytensorflow; + inherit (pkgs) + ffmpeg + mediainfo + nodejs + perl + ; + }; + }; + services = { + nextcloud = { + enable = true; + https = false; # vps + package = pkgs.nextcloud31; + appstoreEnable = true; + configureRedis = true; + extraAppsEnable = true; + enableImagemagick = true; + maxUploadSize = "4096M"; + hostName = cfg.host; + caching = { + redis = true; + memcached = true; + apcu = true; + }; + config = { + adminpassFile = config.sops.secrets.nextcloud-adminpass.path; + dbtype = "pgsql"; + dbhost = config.my.postgresSocket; + dbname = "nextcloud"; + }; + phpOptions = { + catch_workers_output = "yes"; + display_errors = "stderr"; + error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT"; + expose_php = "Off"; + preview_max_x = 2048; + preview_max_y = 2048; + short_open_tag = "Off"; + "opcache.enable_cli" = "1"; + "opcache.fast_shutdown" = "1"; + "opcache.interned_strings_buffer" = "16"; + "opcache.jit" = "1255"; + "opcache.jit_buffer_size" = "256M"; + "opcache.max_accelerated_files" = "10000"; + "opcache.huge_code_pages" = "1"; + "opcache.enable_file_override" = "1"; + "opcache.memory_consumption" = "256"; + "opcache.revalidate_freq" = "60"; + "opcache.save_comments" = "1"; + "opcache.validate_timestamps" = "0"; + "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; + }; + settings = { + log_type = "file"; + loglevel = 1; + trusted_proxies = [ + config.my.localhost + config.my.localhost6 + config.my.ips.router + config.my.ips.wg-vps + ]; + trusted_domains = [ + cfg.host + config.my.ips.${config.networking.hostName} + "localhost" + "cloud.rotehaare.art" + ]; + overwriteprotocol = "https"; + "overwrite.cli.url" = "${cfg.url}"; + forwarded_for_headers = [ "HTTP_X_FORWARDED_FOR" ]; + default_phone_region = "MX"; + allow_local_remote_servers = true; + mail_smtpmode = "sendmail"; + mail_sendmailmode = "pipe"; + preview_ffmpeg_path = "${pkgs.ffmpeg}/bin/ffmpeg"; + "memories.exiftool" = "${exiftool}/bin/exiftool"; + "memories.ffmpeg_path" = "${pkgs.ffmpeg}/bin/ffmpeg"; + "memories.ffprobe_path" = "${pkgs.ffmpeg}/bin/ffprobe"; + enabledPreviewProviders = [ + "OC\\Preview\\AVI" + "OC\\Preview\\BMP" + "OC\\Preview\\GIF" + "OC\\Preview\\HEIC" + "OC\\Preview\\Image" + "OC\\Preview\\JPEG" + "OC\\Preview\\Krita" + "OC\\Preview\\MKV" + "OC\\Preview\\MP3" + "OC\\Preview\\MP4" + "OC\\Preview\\MarkDown" + "OC\\Preview\\Movie" + "OC\\Preview\\OpenDocument" + "OC\\Preview\\PNG" + "OC\\Preview\\TIFF" + "OC\\Preview\\TXT" + "OC\\Preview\\XBitmap" + ]; + }; + phpExtraExtensions = all: [ + all.pdlib + all.bz2 + ]; + }; + nginx.virtualHosts = { + "${cfg.host}" = lib.mkIf cfg.enableProxy { + forceSSL = false; # vps + enableACME = false; # vps + http2 = false; # vps + # default = true; #vps + #vps + listen = [ + { + addr = config.my.ips.wg-server; + port = 8081; + } + { + addr = config.my.localhost; + port = 8081; + } + ]; + #vps + serverAliases = [ "cloud.rotehaare.art" ]; + locations = { + "/".proxyWebsockets = true; + "~ ^/nextcloud/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|oc[ms]-provider/.+|.+/richdocumentscode/proxy).php(?:$|/)" = + { }; + }; + }; + "${cfgC.host}" = lib.mkIf cfgC.enableProxy { + forceSSL = true; + enableACME = true; + http2 = true; + locations = { + # static files + "^~ /loleaflet" = { + proxyPass = cfgC.local; + extraConfig = commonProxyConfig; + }; + # WOPI discovery URL + "^~ /hosting/discovery" = { + proxyPass = cfgC.local; + extraConfig = commonProxyConfig; + }; + # Capabilities + "^~ /hosting/capabilities" = { + proxyPass = cfgC.local; + extraConfig = commonProxyConfig; + }; + # download, presentation, image upload and websocket + "~ ^/lool" = { + proxyPass = cfgC.local; + extraConfig = commonWebsocketConfig; + }; + # Admin Console websocket + "^~ /lool/adminws" = { + proxyPass = cfgC.local; + extraConfig = commonWebsocketConfig; + }; + }; + }; + }; + }; + virtualisation.oci-containers.containers = { + go-vod = lib.mkIf config.my.servers.go-vod.enable { + autoStart = true; + image = "radialapps/go-vod"; + environment = { + TZ = config.my.timeZone; + NEXTCLOUD_HOST = "https://${config.services.nextcloud.hostName}"; + NVIDIA_VISIBLE_DEVICES = "all"; + }; + volumes = [ "ncdata:/var/www/html:ro" ]; + extraOptions = [ + "--device=/dev/dri" # VA-API (omit for NVENC) + ]; + }; + collabora = lib.mkIf cfgC.enable { + autoStart = true; + image = "collabora/code"; + imageFile = pkgs.dockerTools.pullImage { + imageName = "collabora/code"; + imageDigest = "sha256:aab41379baf5652832e9237fcc06a768096a5a7fccc66cf8bd4fdb06d2cbba7f"; + sha256 = "sha256-M66lynhzaOEFnE15Sy1N6lBbGDxwNw6ap+IUJAvoCLs="; + }; + ports = [ "9980:9980" ]; + environment = { + TZ = config.my.timeZone; + domain = cfg.host; + aliasgroup1 = "${cfg.host}:443"; + aliasgroup2 = "cloud.rotehaare.art:443"; + dictionaries = "en_CA en_US es_MX es_ES fr_FR it pt_BR ru"; + extra_params = '' + --o:ssl.enable=false + --o:ssl.termination=true + ''; + }; + extraOptions = [ + "--cap-add" + "MKNOD" + ]; + }; + }; + systemd = lib.mkIf cfg.enableCron { + services = { + nextcloud-cron.path = [ pkgs.perl ]; + nextcloud-cronjob = + let + inherit (inputs.jawz-scripts.packages.x86_64-linux) nextcloud-cronjob; + in + { + description = "Runs various nextcloud-related cronjobs"; + wantedBy = [ "multi-user.target" ]; + path = [ + pkgs.bash + nextcloud-cronjob + ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${nextcloud-cronjob}/bin/nextcloud-cronjob"; + }; + }; + }; + timers.nextcloud-cronjob = { + enable = true; + description = "Runs various nextcloud-related cronjobs"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "*:0/10"; + }; + }; + }; + }; +} diff --git a/modules/servers/nix-serve.nix b/modules/servers/nix-serve.nix new file mode 100644 index 0000000..1489a75 --- /dev/null +++ b/modules/servers/nix-serve.nix @@ -0,0 +1,21 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.servers.nix-serve; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.nix-serve = setup.mkOptions "nix-serve" "cache" 5000; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + sops.secrets."private_cache_keys/miniserver".sopsFile = ../../secrets/keys.yaml; + services.nix-serve = { + inherit (cfg) enable port; + package = pkgs.nix-serve-ng; + secretKeyFile = config.sops.secrets."private_cache_keys/miniserver".path; + }; + }; +} diff --git a/modules/servers/ombi.nix b/modules/servers/ombi.nix new file mode 100644 index 0000000..24c4beb --- /dev/null +++ b/modules/servers/ombi.nix @@ -0,0 +1,11 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.ombi; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.ombi = setup.mkOptions "ombi" "requests" 3425; + config.services.ombi = lib.mkIf cfg.enable { + inherit (cfg) enable port; + }; +} diff --git a/modules/servers/paperless.nix b/modules/servers/paperless.nix new file mode 100644 index 0000000..5763677 --- /dev/null +++ b/modules/servers/paperless.nix @@ -0,0 +1,30 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.paperless; +in +{ + options.my.servers.paperless.enable = lib.mkEnableOption "Paperless-ngx document management system"; + config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable) { + networking.firewall.allowedTCPPorts = [ config.services.paperless.port ]; + services.paperless = { + inherit (cfg) enable; + address = "0.0.0.0"; + consumptionDirIsPublic = true; + consumptionDir = "/srv/pool/scans/"; + settings = { + PAPERLESS_DBENGINE = "postgress"; + PAPERLESS_DBNAME = "paperless"; + PAPERLESS_DBHOST = config.my.postgresSocket; + PAPERLESS_TIME_ZONE = config.my.timeZone; + PAPERLESS_CONSUMER_IGNORE_PATTERN = builtins.toJSON [ + ".DS_STORE/*" + "desktop.ini" + ]; + PAPERLESS_OCR_USER_ARGS = builtins.toJSON { + optimize = 1; + pdfa_image_compression = "lossless"; + }; + }; + }; + }; +} diff --git a/modules/servers/plex-discord-bot.nix b/modules/servers/plex-discord-bot.nix new file mode 100644 index 0000000..6ee478a --- /dev/null +++ b/modules/servers/plex-discord-bot.nix @@ -0,0 +1,20 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.plex-discord-bot; + setup = import ../factories/mkserver.nix { inherit lib config; }; + name = "plex-discord-bot"; +in +{ + options.my.servers.plex-discord-bot = setup.mkOptions name name 0; + config.virtualisation.oci-containers.containers.plex-discord-bot = lib.mkIf cfg.enable { + image = "ghcr.io/phin05/discord-rich-presence-plex:latest"; + environment = { + DRPP_UID = toString config.users.users.jawz.uid; + DRPP_GID = toString config.users.groups.users.gid; + }; + volumes = [ + "${config.my.containerData}/drpp:/app/data" + "/run/user/${toString config.users.users.jawz.uid}:/run/app" + ]; + }; +} diff --git a/modules/servers/plex.nix b/modules/servers/plex.nix new file mode 100644 index 0000000..0e805ea --- /dev/null +++ b/modules/servers/plex.nix @@ -0,0 +1,52 @@ +{ + lib, + config, + ... +}: +let + cfg = config.my.servers.plex; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.plex = setup.mkOptions "plex" "plex" 32400; + config.services = lib.mkIf (cfg.enable && config.my.secureHost) { + plex = { + inherit (cfg) enable; + group = "piracy"; + }; + nginx = lib.mkIf cfg.enableProxy { + virtualHosts."${cfg.host}" = { + forceSSL = true; + enableACME = true; + http2 = true; + serverAliases = [ + "plex.rotehaare.art" + ]; + extraConfig = '' + # Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause + send_timeout 100m; + # Plex headers + proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier; + proxy_set_header X-Plex-Device $http_x_plex_device; + proxy_set_header X-Plex-Device-Name $http_x_plex_device_name; + proxy_set_header X-Plex-Platform $http_x_plex_platform; + proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version; + proxy_set_header X-Plex-Product $http_x_plex_product; + proxy_set_header X-Plex-Token $http_x_plex_token; + proxy_set_header X-Plex-Version $http_x_plex_version; + proxy_set_header X-Plex-Nocache $http_x_plex_nocache; + proxy_set_header X-Plex-Provides $http_x_plex_provides; + proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor; + proxy_set_header X-Plex-Model $http_x_plex_model; + # Buffering off send to the client as soon as the data is received from Plex. + proxy_redirect off; + proxy_buffering off; + ''; + locations."/" = { + proxyPass = cfg.local; + proxyWebsockets = true; + }; + }; + }; + }; +} diff --git a/modules/servers/portfolio.nix b/modules/servers/portfolio.nix new file mode 100644 index 0000000..417be54 --- /dev/null +++ b/modules/servers/portfolio.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + ... +}: +let + cfg = config.my.websites.portfolio; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.websites.portfolio = setup.mkOptions "portfolio" "portfolio" 0; + config.services.nginx.virtualHosts."danilo-reyes.com" = lib.mkIf cfg.enableProxy { + forceSSL = true; + enableACME = true; + http2 = true; + root = "/srv/www/danilo-reyes.com"; + # index = "index.html"; + locations."/".extraConfig = '' + try_files $uri $uri/ =404; + ''; + }; +} diff --git a/modules/servers/postgres.nix b/modules/servers/postgres.nix new file mode 100644 index 0000000..32dba40 --- /dev/null +++ b/modules/servers/postgres.nix @@ -0,0 +1,65 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.my.servers.postgres; + # upgrade here first, then below. + upgrade-pg-cluster = + let + newPostgres = pkgs.postgresql_17.withPackages (_pp: [ ]); + in + pkgs.writeScriptBin "upgrade-pg-cluster" '' + set -eux + systemctl stop postgresql + export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}" + export NEWBIN="${newPostgres}/bin" + export OLDDATA="${config.services.postgresql.dataDir}" + export OLDBIN="${config.services.postgresql.package}/bin" + install -d -m 0700 -o postgres -g postgres "$NEWDATA" + cd "$NEWDATA" + sudo -u postgres $NEWBIN/initdb -D "$NEWDATA" + sudo -u postgres $NEWBIN/pg_upgrade \ + --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \ + --old-bindir $OLDBIN --new-bindir $NEWBIN \ + "$@" + ''; + dbNames = [ + "jawz" + "paperless" + "nextcloud" + "ryot" + "vaultwarden" + "shiori" + "mealie" + "firefly-iii" + "matrix-synapse" + "readeck" + "sonarqube" + "gitea" + ]; +in +{ + options.my.servers.postgres.enable = lib.mkEnableOption "PostgreSQL database server"; + config = lib.mkIf cfg.enable { + environment.systemPackages = [ upgrade-pg-cluster ]; + services.postgresql = { + inherit (cfg) enable; + enableTCPIP = true; + ensureDatabases = dbNames; + package = pkgs.postgresql_17; + ensureUsers = map (name: { + inherit name; + ensureDBOwnership = true; + }) dbNames; + authentication = pkgs.lib.mkOverride 10 '' + local all all trust + host all all ${config.my.localhost}/32 trust + host all all ::1/128 trust + host all all 10.88.0.0/16 scram-sha-256 + ''; + }; + }; +} diff --git a/modules/servers/prowlarr.nix b/modules/servers/prowlarr.nix new file mode 100644 index 0000000..8474cd0 --- /dev/null +++ b/modules/servers/prowlarr.nix @@ -0,0 +1,26 @@ +{ + lib, + config, + ... +}: +let + cfg = config.my.servers.prowlarr; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.prowlarr = setup.mkOptions "prowlarr" "indexer" 9696; + config = lib.mkIf cfg.enable { + users.users.prowlarr = { + group = "piracy"; + isSystemUser = true; + }; + services = { + prowlarr = { + inherit (cfg) enable; + }; + flaresolverr = { + inherit (cfg) enable; + }; + }; + }; +} diff --git a/modules/servers/qbittorrent.nix b/modules/servers/qbittorrent.nix new file mode 100644 index 0000000..4b8f0e7 --- /dev/null +++ b/modules/servers/qbittorrent.nix @@ -0,0 +1,134 @@ +{ + lib, + config, + pkgs, + inputs, + ... +}: +let + pkgsU = import inputs.nixpkgs-unstable { + system = "x86_64-linux"; + config.allowUnfree = true; + }; + vuetorrent = pkgs.fetchzip { + url = "https://github.com/VueTorrent/VueTorrent/releases/download/v2.25.0/vuetorrent.zip"; + sha256 = "sha256-sOaQNw6AnpwNFEextgTnsjEOfpl3/lpoOZFgFOz7Bos="; + stripRoot = true; + }; + qbit_manageEnv = pkgsU.python3.withPackages ( + ps: + builtins.attrValues { + inherit (ps) + argon2-cffi + bencode-py + croniter + fastapi + gitpython + humanize + pytimeparse2 + qbittorrent-api + requests + retrying + ruamel-yaml + slowapi + uvicorn + ; + } + ); +in +{ + options.my.servers = { + unpackerr.enable = lib.mkEnableOption "automatic archive extraction service"; + qbittorrent = { + enable = lib.mkEnableOption "qBittorrent torrent client"; + port = lib.mkOption { + type = lib.types.int; + default = 9091; + description = "The port to access qbittorrent web-ui"; + }; + }; + }; + config = lib.mkIf (config.my.servers.qbittorrent.enable && config.my.secureHost) { + home-manager.users.jawz = { + xdg = { + dataFile.vuetorrent.source = vuetorrent; + configFile."unpackerr.conf" = lib.mkIf config.my.servers.unpackerr.enable { + source = ../../dotfiles/unpackerr.conf; + }; + }; + }; + sops.secrets = + let + mkQbitSecret = file: mode: { + inherit mode; + inherit (config.users.users.jawz) group; + sopsFile = ../../secrets/keys.yaml; + owner = config.users.users.jawz.name; + path = "/home/jawz/.config/qBittorrent/ssl/${file}"; + }; + in + { + "certificates/qbit_cert" = mkQbitSecret "server.crt" "0644"; + "certificates/qbit_key" = mkQbitSecret "server.key" "0600"; + }; + systemd = { + packages = [ pkgs.qbittorrent-nox ]; + services = { + "qbittorrent-nox@jawz" = { + enable = true; + overrideStrategy = "asDropin"; + wantedBy = [ "multi-user.target" ]; + }; + }; + user = { + services = { + qbit_manage = { + restartIfChanged = true; + description = "Tidy up my torrents"; + wantedBy = [ "default.target" ]; + serviceConfig = + let + env = "/home/jawz/Development/Git/qbit_manage"; + in + { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = "${qbit_manageEnv}/bin/python ${env}/qbit_manage.py -r -c ${env}/config.yml"; + }; + }; + unpackerr = lib.mkIf config.my.servers.unpackerr.enable { + enable = true; + restartIfChanged = true; + description = "Run unpackerr"; + wantedBy = [ "default.target" ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = '' + ${pkgs.unpackerr}/bin/unpackerr \ + -c /home/jawz/.config/unpackerr.conf''; + }; + }; + }; + timers.qbit_manage = { + enable = true; + description = "Tidy up my torrents"; + wantedBy = [ "timers.target" ]; + timerConfig.OnCalendar = "*:0/10"; + }; + }; + }; + networking.firewall = + let + ports = [ + 51411 + 51412 + 51413 + ]; + in + { + allowedTCPPorts = ports ++ [ config.my.servers.qbittorrent.port ]; + allowedUDPPorts = ports; + }; + }; +} diff --git a/modules/servers/radarr.nix b/modules/servers/radarr.nix new file mode 100644 index 0000000..2f3ace1 --- /dev/null +++ b/modules/servers/radarr.nix @@ -0,0 +1,14 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.radarr; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.radarr = setup.mkOptions "radarr" "movies" 7878; + config = lib.mkIf cfg.enable { + services.radarr = { + inherit (cfg) enable; + group = "piracy"; + }; + }; +} diff --git a/modules/servers/readeck.nix b/modules/servers/readeck.nix new file mode 100644 index 0000000..1c7181b --- /dev/null +++ b/modules/servers/readeck.nix @@ -0,0 +1,25 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.readeck; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.readeck = setup.mkOptions "readeck" "laters" 9546; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + sops.secrets.readeck.sopsFile = ../../secrets/env.yaml; + services.readeck = { + inherit (cfg) enable; + environmentFile = config.sops.secrets.readeck.path; + settings = { + main = { + log_level = "warn"; + data_directory = "/var/lib/readeck"; + }; + server = { + inherit (cfg) port; + host = cfg.ip; + }; + }; + }; + }; +} diff --git a/modules/servers/ryot.nix b/modules/servers/ryot.nix new file mode 100644 index 0000000..800e760 --- /dev/null +++ b/modules/servers/ryot.nix @@ -0,0 +1,23 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.ryot; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.ryot = setup.mkOptions "ryot" "tracker" 8765; + config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable && config.my.secureHost) { + sops.secrets.ryot.sopsFile = ../../secrets/env.yaml; + virtualisation.oci-containers.containers.ryot = { + image = "ghcr.io/ignisda/ryot:v9.3.0"; + ports = [ "${toString cfg.port}:8000" ]; + environmentFiles = [ config.sops.secrets.ryot.path ]; + environment = { + RUST_LOG = "ryot=debug,sea_orm=debug"; + TZ = config.my.timeZone; + DATABASE_URL = "postgres:///ryot?host=${config.my.postgresSocket}"; + FRONTEND_INSECURE_COOKIES = "true"; + }; + volumes = [ "${config.my.postgresSocket}:${config.my.postgresSocket}" ]; + }; + }; +} diff --git a/modules/servers/sabnzbd.nix b/modules/servers/sabnzbd.nix new file mode 100644 index 0000000..c33fd0e --- /dev/null +++ b/modules/servers/sabnzbd.nix @@ -0,0 +1,20 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.sabnzbd; +in +{ + options.my.servers.sabnzbd = { + enable = lib.mkEnableOption "SABnzbd Usenet downloader"; + port = lib.mkOption { + type = lib.types.int; + default = 3399; + description = "The port to access sabnzbd web-ui"; + }; + }; + config = lib.mkIf cfg.enable { + services.sabnzbd = { + inherit (cfg) enable; + group = "piracy"; + }; + }; +} diff --git a/modules/servers/shiori.nix b/modules/servers/shiori.nix new file mode 100644 index 0000000..2b8c09a --- /dev/null +++ b/modules/servers/shiori.nix @@ -0,0 +1,16 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.shiori; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.shiori = setup.mkOptions "shiori" "bookmarks" 4368; + config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable && config.my.secureHost) { + sops.secrets.shiori.sopsFile = ../../secrets/env.yaml; + services.shiori = { + inherit (cfg) enable port; + environmentFile = config.sops.secrets.shiori.path; + databaseUrl = "postgres:///shiori?host=${config.my.postgresSocket}"; + }; + }; +} diff --git a/modules/servers/sonarr.nix b/modules/servers/sonarr.nix new file mode 100644 index 0000000..d2a0920 --- /dev/null +++ b/modules/servers/sonarr.nix @@ -0,0 +1,12 @@ +{ lib, config, ... }: +let + cfg = config.my.servers.sonarr; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.sonarr = setup.mkOptions "sonarr" "series" 8989; + config.services.sonarr = lib.mkIf cfg.enable { + inherit (cfg) enable; + group = "piracy"; + }; +} diff --git a/modules/servers/synapse.nix b/modules/servers/synapse.nix new file mode 100644 index 0000000..32a7eaf --- /dev/null +++ b/modules/servers/synapse.nix @@ -0,0 +1,127 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.servers.synapse; + cfgE = config.my.servers.element; + domain = "wedsgk5ac2qcaf9yb.click"; + setup = import ../factories/mkserver.nix { inherit lib config; }; + clientConfig."m.homeserver".base_url = cfg.url; + serverConfig."m.server" = "${cfg.host}:443"; + mkWellKnown = data: '' + default_type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${builtins.toJSON data}'; + ''; +in +{ + options.my.servers = { + synapse = setup.mkOptions "synapse" "pYLemuAfsrzNBaH77xSu" 8008; + element = setup.mkOptions "element" "55a608953f6d64c199" 5345; + }; + config = lib.mkIf (cfg.enable && config.my.secureHost) { + my.servers = { + synapse = { inherit domain; }; + element = { inherit domain; }; + }; + sops.secrets = { + synapse = { + sopsFile = ../../secrets/env.yaml; + owner = "matrix-synapse"; + group = "matrix-synapse"; + }; + "iqQCY4iAWO-ca/pem" = { + sopsFile = ../../secrets/certs.yaml; + owner = "nginx"; + group = "nginx"; + }; + "matrix/key" = { + sopsFile = ../../secrets/certs.yaml; + owner = "matrix-synapse"; + group = "matrix-synapse"; + }; + "matrix/cert" = { + sopsFile = ../../secrets/certs.yaml; + owner = "matrix-synapse"; + group = "matrix-synapse"; + }; + }; + networking.firewall.allowedTCPPorts = lib.mkIf (!cfg.isLocal) [ cfg.port ]; + services = { + matrix-synapse = { + inherit (cfg) enable; + extraConfigFiles = [ + config.sops.secrets.synapse.path + ]; + settings = { + server_name = cfg.domain; + public_baseurl = cfg.url; + federation_domain_whitelist = [ ]; + allow_public_rooms_without_auth = false; + allow_public_rooms_over_federation = false; + max_upload_size = "4096M"; + tls_private_key_path = config.sops.secrets."matrix/key".path; + tls_certificate_path = config.sops.secrets."matrix/cert".path; + listeners = [ + { + inherit (cfg) port; + bind_addresses = [ + config.my.localhost + config.my.localhost6 + config.my.ips.server + config.my.ips.wg-server + ]; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + names = [ + "client" + "media" + ]; + compress = true; + } + ]; + } + ]; + }; + }; + nginx.virtualHosts = lib.mkIf cfg.enableProxy { + "${cfgE.host}" = { + enableACME = true; + forceSSL = true; + serverAliases = [ + cfgE.host + ]; + root = pkgs.element-web; + }; + "${cfg.domain}" = { + enableACME = true; + forceSSL = true; + locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig; + locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig; + }; + "${cfg.host}" = { + enableACME = true; + forceSSL = true; + locations = { + "/".extraConfig = '' + return 404; + ''; + "/_matrix".proxyPass = "http://[${config.my.localhost6}]:${toString cfg.port}"; + "/_synapse/client".proxyPass = "http://[${config.my.localhost6}]:${toString cfg.port}"; + }; + # extraConfig = '' + # ssl_verify_client on; + # ssl_client_certificate ${config.sops.secrets."iqQCY4iAWO-ca/pem".path}; + # error_page 403 /403.html; + # ''; + }; + }; + }; + }; +} diff --git a/modules/servers/tranga.nix b/modules/servers/tranga.nix new file mode 100644 index 0000000..db92c02 --- /dev/null +++ b/modules/servers/tranga.nix @@ -0,0 +1,28 @@ +{ config, lib, ... }: +let + setup = import ../factories/mkserver.nix { inherit lib config; }; + cfg = config.my.servers.tranga; +in +{ + options.my.servers.tranga = setup.mkOptions "tranga" "tranga" 9555; + config = lib.mkIf cfg.enable { + virtualisation.oci-containers.containers = { + tranga-api = { + image = "glax/tranga-api:latest"; + user = "${toString config.users.users.jawz.uid}:${toString config.users.groups.kavita.gid}"; + environment.TZ = config.my.timeZone; + ports = [ "6531:6531" ]; + volumes = [ + "/srv/pool/multimedia/media/Library/Manga:/Manga" + "${config.my.containerData}/tranga-api:/usr/share/tranga-api" + ]; + }; + tranga-website = { + image = "glax/tranga-website:latest"; + ports = [ "${toString cfg.port}:80" ]; + dependsOn = [ "tranga-api" ]; + environment.TZ = config.my.timeZone; + }; + }; + }; +} diff --git a/modules/servers/vaultwarden.nix b/modules/servers/vaultwarden.nix new file mode 100644 index 0000000..07fdbbc --- /dev/null +++ b/modules/servers/vaultwarden.nix @@ -0,0 +1,34 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.servers.vaultwarden; + setup = import ../factories/mkserver.nix { inherit lib config; }; +in +{ + options.my.servers.vaultwarden = setup.mkOptions "vaultwarden" "vault" 8222; + config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable && config.my.secureHost) { + sops.secrets.vaultwarden.sopsFile = ../../secrets/env.yaml; + services.vaultwarden = { + inherit (cfg) enable; + dbBackend = "postgresql"; + package = pkgs.vaultwarden; + environmentFile = config.sops.secrets.vaultwarden.path; + config = { + # ROCKET_ADDRESS = "${config.my.localhost}"; # VPS + ROCKET_ADDRESS = cfg.ip; + ROCKET_PORT = cfg.port; + WEBSOCKET_PORT = 8333; + DATABASE_URL = "postgresql:///${cfg.name}?host=${config.my.postgresSocket}"; + ENABLE_DB_WAL = false; + WEBSOCKET_ENABLED = true; + SHOW_PASSWORD_HINT = false; + EXTENDED_LOGGING = true; + LOG_LEVEL = "warn"; + }; + }; + }; +} diff --git a/modules/services/msmtp.nix b/modules/services/msmtp.nix new file mode 100644 index 0000000..519978d --- /dev/null +++ b/modules/services/msmtp.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + ... +}: +let + cfg = config.my.servers; +in +{ + config = lib.mkIf (config.my.secureHost && (cfg.nextcloud.enable or cfg.gitea.enable)) { + sops.secrets.smtp-password = { }; + programs.msmtp = { + enable = true; + accounts.default = { + auth = true; + host = "smtp.gmail.com"; + port = 587; + tls = true; + from = config.my.smtpemail; + user = config.my.smtpemail; + passwordeval = "cat ${config.sops.secrets.smtp-password.path}"; + }; + }; + }; +} diff --git a/modules/services/network.nix b/modules/services/network.nix new file mode 100644 index 0000000..46ce3a0 --- /dev/null +++ b/modules/services/network.nix @@ -0,0 +1,50 @@ +{ config, lib, ... }: +{ + options.my.services.network.enable = lib.mkEnableOption "network configuration and services"; + config = lib.mkIf config.my.services.network.enable { + networking = { + enableIPv6 = true; + firewall.enable = true; + dhcpcd.extraConfig = "nohook resolv.conf"; + networkmanager = { + enable = true; + dns = "none"; + }; + hosts = config.my.ips |> lib.mapAttrs' (hostname: ip: lib.nameValuePair ip [ hostname ]); + interfaces."${config.my.interfaces.${config.networking.hostName}}".wakeOnLan.enable = true; + }; + services.dnscrypt-proxy2 = { + enable = true; + settings = { + ipv6_servers = true; + require_dnssec = true; + sources.public-resolvers = { + urls = [ + "https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md" + "https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md" + ]; + cache_file = "/var/lib/dnscrypt-proxy2/public-resolvers.md"; + minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3"; + }; + server_names = [ + "adfilter-adl" + "adfilter-adl-ipv6" + "adfilter-per" + "adfilter-per-ipv6" + "adfilter-syd" + "adfilter-syd-ipv6" + "mullvad-adblock-doh" + "mullvad-doh" + "nextdns" + "nextdns-ipv6" + "quad9-dnscrypt-ip4-filter-pri" + "quad9-dnscrypt-ip6-filter-pri" + "ibksturm" + ]; + }; + }; + systemd.services.dnscrypt-proxy2.serviceConfig = { + StateDirectory = "dnscrypt-proxy"; + }; + }; +} diff --git a/modules/services/nvidia.nix b/modules/services/nvidia.nix new file mode 100644 index 0000000..0c1a112 --- /dev/null +++ b/modules/services/nvidia.nix @@ -0,0 +1,36 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.services.nvidia.enable = lib.mkEnableOption "NVIDIA GPU drivers and CUDA"; + config = lib.mkIf config.my.services.nvidia.enable { + environment.variables.CUDA_CACHE_PATH = "\${XDG_CACHE_HOME}/nv"; + boot.kernelParams = lib.mkIf (config.networking.hostName == "workstation") [ "nvidia-drm.fbdev=1" ]; + services.xserver.videoDrivers = [ "nvidia" ]; + hardware = { + graphics = { + enable = true; + enable32Bit = true; + extraPackages = builtins.attrValues { + inherit (pkgs) + nvidia-vaapi-driver + vaapiVdpau + libvdpau-va-gl + vulkan-loader + mesa + ; + }; + }; + nvidia = { + open = config.networking.hostName == "workstation"; + package = config.boot.kernelPackages.nvidiaPackages.stable; + modesetting.enable = true; + powerManagement.enable = true; + powerManagement.finegrained = false; + }; + }; + }; +} diff --git a/modules/services/printing.nix b/modules/services/printing.nix new file mode 100644 index 0000000..abecb8f --- /dev/null +++ b/modules/services/printing.nix @@ -0,0 +1,26 @@ +{ + config, + lib, + pkgs, + ... +}: +let + printingDrivers = [ + pkgs.hplip + pkgs.hplipWithPlugin + ]; +in +{ + options.my.services.printing.enable = lib.mkEnableOption "printing services and drivers"; + config = lib.mkIf config.my.services.printing.enable { + users.users.jawz.packages = [ pkgs.simple-scan ]; + services.printing = { + enable = true; + drivers = printingDrivers; + }; + hardware.sane = { + enable = true; + extraBackends = printingDrivers; + }; + }; +} diff --git a/modules/services/sound.nix b/modules/services/sound.nix new file mode 100644 index 0000000..0e2608b --- /dev/null +++ b/modules/services/sound.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + inputs, + ... +}: +{ + imports = [ inputs.nix-gaming.nixosModules.pipewireLowLatency ]; + options.my.services.sound.enable = lib.mkEnableOption "audio system and PipeWire"; + config = lib.mkIf config.my.services.sound.enable { + services.pulseaudio.enable = false; + security.rtkit.enable = true; # make pipewire realtime-capable + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + lowLatency = { + enable = true; + quantum = 64; + rate = 48000; + }; + }; + }; +} diff --git a/modules/services/wireguard.nix b/modules/services/wireguard.nix new file mode 100644 index 0000000..505f829 --- /dev/null +++ b/modules/services/wireguard.nix @@ -0,0 +1,53 @@ +{ + config, + lib, + pkgs, + ... +}: +let + port = 51820; + interface = config.my.interfaces.${config.networking.hostName}; +in +{ + options.my.services.wireguard.enable = lib.mkEnableOption "WireGuard VPN configuration"; + config = lib.mkIf (config.my.services.wireguard.enable && config.my.secureHost) { + sops.secrets."wireguard/private".sopsFile = ../../secrets/wireguard.yaml; + networking = { + firewall.allowedUDPPorts = [ port ]; + nat = { + enable = true; + externalInterface = interface; + internalInterfaces = [ "wg0" ]; + }; + wireguard.interfaces.wg0 = { + ips = [ "10.100.0.1/24" ]; + listenPort = port; + postSetup = '' + ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o ${interface} -j MASQUERADE + ''; + postShutdown = '' + ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o ${interface} -j MASQUERADE + ''; + privateKeyFile = config.sops.secrets."wireguard/private".path; + peers = [ + { + publicKey = "ciupBjCcIpd3K5vlzNMJC8iiyNqB9xXwkSC6UXPKP3g="; + allowedIPs = [ "10.100.0.2/32" ]; + } # phone + { + publicKey = "JgeA1ElDwR7oLmyGn8RzvxiscMBhR8+L+mEjY1Cq7gk="; + allowedIPs = [ "10.100.0.3/32" ]; + } # tablet + { + publicKey = "giPVRUTLtqPGb57R4foGZMNS0tjIp2ry6lMKYtqHjn4="; + allowedIPs = [ "10.100.0.15/32" ]; + } # jeancarlos + { + publicKey = "92JdW/NExg1tUE4cEyl6Yn+0Eex+iFVA37ahPRhRnRM="; + allowedIPs = [ "10.100.0.16/32" ]; + } # gorilia + ]; + }; + }; + }; +} diff --git a/modules/shell/config.nix b/modules/shell/config.nix new file mode 100644 index 0000000..0535cb8 --- /dev/null +++ b/modules/shell/config.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.shell.type = lib.mkOption { + type = lib.types.enum [ + "bash" + "zsh" + ]; + default = "bash"; + description = "The shell to use system-wide (bash or zsh)"; + }; + config = { + users.users.jawz.shell = pkgs.${config.my.shell.type}; + programs.zsh.enable = config.my.shell.type == "zsh"; + }; +} diff --git a/modules/shell/exercism.nix b/modules/shell/exercism.nix new file mode 100644 index 0000000..158f80b --- /dev/null +++ b/modules/shell/exercism.nix @@ -0,0 +1,17 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.shell.exercism.enable = lib.mkEnableOption "Exercism coding practice platform"; + config = lib.mkIf config.my.shell.exercism.enable { + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + exercism # learn to code + bats # testing system, required by Exercism + ; + }; + }; +} diff --git a/modules/shell/multimedia.nix b/modules/shell/multimedia.nix new file mode 100644 index 0000000..ec1d29e --- /dev/null +++ b/modules/shell/multimedia.nix @@ -0,0 +1,33 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options.my.shell.multimedia.enable = lib.mkEnableOption "multimedia CLI tools and codecs"; + config = lib.mkIf config.my.shell.multimedia.enable { + home-manager.users.jawz.programs = { + yt-dlp = { + enable = true; + settings = { + embed-thumbnail = true; + embed-subs = true; + sub-langs = "all"; + cookies-from-browser = "firefox+gnomekeyring:/home/jawz/.librewolf/jawz"; + }; + }; + gallery-dl = { + enable = true; + settings = import ../../dotfiles/gallery-dl.nix; + }; + }; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + ffmpeg # not ffmpreg, the coolest video conversion tool! + imagemagick # photoshop what?? + ffpb # make ffmpeg encoding... a bit fun + ; + }; + }; +} diff --git a/modules/shell/tools.nix b/modules/shell/tools.nix new file mode 100644 index 0000000..0730553 --- /dev/null +++ b/modules/shell/tools.nix @@ -0,0 +1,122 @@ +{ + config, + lib, + pkgs, + inputs, + ... +}: +let + shellType = config.my.shell.type; +in +{ + options.my.shell.tools.enable = lib.mkEnableOption "shell tools and utilities"; + config = lib.mkIf config.my.shell.tools.enable { + home-manager.users.jawz.programs = { + hstr.enable = true; + htop = { + enable = true; + package = pkgs.htop-vim; + }; + zoxide = { + enable = true; + enableBashIntegration = shellType == "bash"; + enableZshIntegration = shellType == "zsh"; + }; + ${shellType} = { + shellAliases = { + cd = "z"; + hh = "hstr"; + ls = "eza --icons --group-directories-first"; + rm = "trash"; + b = "bat"; + f = "fzf --multi --exact -i"; + unique-extensions = '' + fd -tf | rev | cut -d. -f1 | rev | + tr '[:upper:]' '[:lower:]' | sort | + uniq --count | sort -rn''; + }; + } + // ( + if shellType == "bash" then + { + initExtra = '' + if command -v fzf-share >/dev/null; then + source "$(fzf-share)/key-bindings.bash" + source "$(fzf-share)/completion.bash" + fi + ''; + } + else + { + initContent = '' + if command -v fzf-share >/dev/null; then + source "$(fzf-share)/key-bindings.bash" + source "$(fzf-share)/completion.bash" + fi + ''; + } + ); + bat = { + enable = true; + config.pager = "less -FR"; + extraPackages = builtins.attrValues { + inherit (pkgs.bat-extras) + batman # man pages + batpipe # piping + batgrep # ripgrep + batdiff # this is getting crazy! + batwatch # probably my next best friend + prettybat # trans your sourcecode! + ; + }; + }; + password-store = { + enable = false; + package = pkgs.gopass; + settings = { + PASSWORD_STORE_AUTOCLIP = "true"; + PASSWORD_STORE_AUTOIMPORT = "false"; + PASSWORD_STORE_CLIPTIMEOUT = "45"; + PASSWORD_STORE_EXPORTKEYS = "false"; + PASSWORD_STORE_NOPAGER = "false"; + PASSWORD_STORE_NOTIFICATIONS = "false"; + PASSWORD_STORE_PARSING = "true"; + PASSWORD_STORE_PATH = "/home/jawz/.local/share/pass"; + PASSWORD_STORE_SAFECONTENT = "true"; + }; + }; + }; + programs = { + starship.enable = true; + tmux.enable = true; + fzf.fuzzyCompletion = true; + neovim = { + enable = true; + vimAlias = true; + }; + }; + users.users.jawz.packages = builtins.attrValues { + inherit (pkgs) + ripgrep # modern grep + du-dust # rusty du similar to gdu + eza # like ls but with colors + fd # modern find, faster searches + fzf # fuzzy finder! super cool and useful + gdu # disk-space utility checker, somewhat useful + tealdeer # man for retards + trash-cli # oop! did not meant to delete that + jq # json parser + yq # yaml parser + smartmontools # check hard drie health + ; + inherit (inputs.jawz-scripts.packages.x86_64-linux) + rmlint # amazing dupe finder that integrates well with BTRFS + ; + }; + environment.variables = { + HISTFILE = "\${XDG_STATE_HOME}/bash/history"; + LESSHISTFILE = "-"; + RIPGREP_CONFIG_PATH = "\${XDG_CONFIG_HOME}/ripgrep/ripgreprc"; + }; + }; +} diff --git a/modules/users/nixremote.nix b/modules/users/nixremote.nix new file mode 100644 index 0000000..4b7dda6 --- /dev/null +++ b/modules/users/nixremote.nix @@ -0,0 +1,37 @@ +{ lib, config, ... }: +{ + options.my.users.nixremote = { + enable = lib.mkEnableOption "nixremote user for distributed builds"; + authorizedKeys = lib.mkOption { + type = lib.types.listOf lib.types.path; + default = [ + ../../secrets/ssh/ed25519_nixworkstation.pub + ../../secrets/ssh/ed25519_nixserver.pub + ../../secrets/ssh/ed25519_nixminiserver.pub + ]; + description = "List of SSH public key files to authorize for nixremote user"; + }; + gid = lib.mkOption { + type = lib.types.int; + default = 555; + description = "Group ID for the nixremote group"; + }; + home = lib.mkOption { + type = lib.types.str; + default = "/var/nixremote/"; + description = "Home directory for the nixremote user"; + }; + }; + config = lib.mkIf config.my.users.nixremote.enable { + users = { + groups.nixremote.gid = config.my.users.nixremote.gid; + users.nixremote = { + inherit (config.my.users.nixremote) home; + isNormalUser = true; + createHome = true; + group = "nixremote"; + openssh.authorizedKeys.keyFiles = config.my.users.nixremote.authorizedKeys; + }; + }; + }; +} diff --git a/patches/libpng.patch b/patches/libpng.patch new file mode 100644 index 0000000..cb7724f --- /dev/null +++ b/patches/libpng.patch @@ -0,0 +1,15 @@ +diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa +index fe8e481..ecaffe7 100644 +--- a/scripts/pnglibconf.dfa ++++ b/scripts/pnglibconf.dfa +@@ -516,8 +516,8 @@ setting USER_WIDTH_MAX default 1000000 + setting USER_HEIGHT_MAX default 1000000 + + # Use 0 for unlimited +-setting USER_CHUNK_CACHE_MAX default 1000 +-setting USER_CHUNK_MALLOC_MAX default 8000000 ++setting USER_CHUNK_CACHE_MAX default 0 ++setting USER_CHUNK_MALLOC_MAX default 0 + + # If this option is enabled APIs to set the above limits at run time are added; + # without this the hardwired (compile time) limits will be used. diff --git a/secrets/certs.yaml b/secrets/certs.yaml new file mode 100644 index 0000000..8842787 --- /dev/null +++ b/secrets/certs.yaml @@ -0,0 +1,61 @@ +private-ca: + slr: ENC[AES256_GCM,data:JKqoB/9fxkJCWP9o4T3YtrthfSZ3QrMeh/4/8N5wD7k39tUbZmn7rg==,iv:Ij187yeTw0Ck+xd7YSD/GahBAupb9gw9EgAhShPLzYk=,tag:8qFevhiAhxt3Wn8rTXjomQ==,type:str] + key: ENC[AES256_GCM,data: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,iv:FsCxQpTK3pJVQAAyeEsXmQVxbRXQ5Z2a2DPbCGQx3IE=,tag:3Cba1kB4TVNrFA8sQ8pwcQ==,type:str] + pem: ENC[AES256_GCM,data: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,iv:wT9152FGxzD+kdX6FUU2nJKH4nZlX4JuCiTPSM8bU0E=,tag:t1pEGIAiQJ20v0TPUPR0/Q==,type:str] +private-client: + crt: ENC[AES256_GCM,data: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,iv:R6tI2ujDUyL7y2EXCBDQQ8t++hO+ylNv+CgwguzJn0c=,tag:bdx1gYS+8R7xKOucTBKN7w==,type:str] + csr: ENC[AES256_GCM,data:vnoM6E1kHvhyPRa+EUfBHUaE1yNU0MzFuia9NQdJx6iKwxbt4aIs+dCl8vR9O4jjvsZSDdRf5Yh0jzsJIknx7LnjNebjO1KyD9XZQMrL5Ngpz/3TBPon9tTdhKj4Rdaxngk8LbUm33j/8nRduRNv+4mfLm6UonsESTmmDDNOp+teXmrkEZDAOET1N+lucw73qdYQueaSi2BkNybcC/rqgNauxZJ71lKOhchh9DdCNwOS1csTeedTJ9mzuVQwahJPlM4vmRY3QqUpqE8aWQB/rGHp/YO/H/k7ugKRw5wtKoGO+Vf5IAxgIvsjsL7FI61pGTFQEgbmyhPBn3/iEu2xlR7+n42gj+y3gbbir8yfSdrvRSuMCi3q0K23p08UpZUHSgAxJURdlDwAtYPQAWNvobQp8VBNhtWwz4VjzisaOnVcTP9ehkPSJCErlyBrpwrRaoI6TbOsyYybwDaKnod+2klN9zqc/9QeOd3n13SuCUCeFJAqprHGpWE0m+v1Bdksr69JRFSFPWKWydEEsaSiw6Z/2q8JWO04Mg2YA3efzn6xtKwmCK2xxnEdO0gMX9T1piMl+XP+1qAzttoUBeKMjSitrSSpi73JQMpVLfGXcY/GEM54GZaDv7VeAbcO0+4dgdXgthXCB91t7fDDJVH8aWt5cHBgM7eE3BZ2P+0tAbueF0CqEL1aQ4/O6yrmt/XY61JuIR2yXeV3iPiHkbgy7GhxXogjQYU7mSKhaXuSLIaZhzyWUfKSmWV32xu073Ji3zO0ZCRCpV29f9/icSwwtWAXtNO5rkTq/wmvgtu/WPhvNsLwdMRg8q3X+lcfFiSf/pPaTSY337rtP4fAhJJk3qzaRtKq/e4xslKRzokQCXIpqXWQI3+6tvarb11JJ1w+QDrnlrXNwuARyOgJUGxIrAodzsy47zF4CEBmGCBbKNUseEM6mtVzQODWxjRy6P4johY+NgYGWmXhiNzxA82ZCJbHYAWZttk4452SG6Tgmipt2MWJVVAvmO5STY0I1/6KmdTN1hCNKcMagsUGg3UU2mc9SU1LSGL911dP9ZbYMKB42QwKFkDwTzDOTHQqDgpdirPeCCTiyCRox13tLRowawIixSlDG/sgul1Esiv1K2rCdkutPgvCAhBcezOSJTK7VQhLHPYRnnKl8HrJimDMSTFotCZhcoqPkdnKfBoe36XGigFjAZ/8VK4B6Y1Y0xCmnPhhNbHdeNfIppMZo6sN4cNun/AHQ/c4TFcHvHQNUxDkyiIBQpkYLnincvI/Sqj7K0XERwxXurDneaANDBZJ4zOEoVbpeSDke1dEJx9QPjcC,iv:x53EQc1VK4rLrPLU/sYaChFVgZ3B6kcE3a3LfcTZ9qI=,tag:w7pLj84uEFz87KRS9qd/dw==,type:str] + key: ENC[AES256_GCM,data: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,iv:Wd8fayR18YGHFCgHKdD4qfGPPHBdeqbNgg4X2EF1v2U=,tag:tdjYylDT2vQ3v+CcQVUI1Q==,type:str] +iqQCY4iAWO-ca: + slr: ENC[AES256_GCM,data:yJAwpwQhGOGO4Nc6lLmQeBt4eaKAHp3/Tcpqkq6Exv13QdGwcIFEUg==,iv:kiF4pR1HluFZJCAtIhLcEKcgivT8vJUJBg4yFj7WX1s=,tag:XnDISYAmiJcEWGbK4FoEuw==,type:str] + key: ENC[AES256_GCM,data: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,iv:QKZZ6mEwirWl2rGDk6FZjCh9voYgYOAUSx/Wr3vp2eY=,tag:80P1FZhoV4tpaqG83UuoMQ==,type:str] + pem: ENC[AES256_GCM,data:jLP+MLFPCmai9SfXNDryJ1bLhZLOhP+tC8dtH7J0i3AwCoBgdLb6Yvtig7TdqiaCkU/AJCbbIpm0zCnTE4Bp99/mlWoRk3bMIzQIY/IICxP9NFkHSyEIqGDsAERT6rvF0z55FVY2eJ+kSbk5BgLUpkClcVWqBXnLdfODtfxhunmCp832wgoxs2fepCzvMUyf97Bk+ng6E9wpL9TzkqFq8gfqKp6SNujBp9A5G/PABSfeuKnpeGgfUn+X8AuCJzyP64oTlbg+ZGnuz/j+oXDJhHVz/XiiUpLhqYR+4zQiq1WtBUyRYGqFvu1hgAt+z67TGJ1TERic6KPXod7XBsoUCaeiMzPutoEyXCxo9PbEX9Mr6q9cVmg9sddwOcAD4e6t8tgmzksErZT1lKsMEaBrX3GfeyGDWzNYELp/puwwang9nCAUPyM2G+nPLnwqJD58f3uzzij2fYy6B4ByaHvYhPY3nLMOiu/RcGX8NV9FeFeXJ++ygIOiEyfIIO/sLQBCqd+WXCWFHJ2YNyhExIBTaDrgFySaob0VbkWFsyodGk2x3/son+I6Vp4zuKCMrN2dkaHS6a/P6tdNGAsuhoCtx0WR0jReEPp9HJ0u4XGl8sALPEhVdx1RzPPgmK4Ciq7FH5lEsFg205wtrG+h7tLSPG0j7pRRdmOqkolCG7oSL/eeG0ZPgPgDnwySVxiVgr82rpycofEYoRA2rjJDWl6UWcfI0f88J317BIf9TQFSi0129r6WHdiF9zxLUZKpW44IbWjWMLyfOQ2flkicNK5pFybgTl2yrO8/lelDqpQn4//4y0IwUNuwNo82jaW+837tQcwDqEtCoSPKnrNV9XA/QfG5vEL9fqT+08KoQAKwQEuEw9AGZmr1GZiVawcXAZ3q81D8IA4+p2jjR3a1mR7Q4jFp5rUTVAFEoRrQbKsOJTf8er7ZZJZbL9fZJ9eCgLHLJU6BC81v2FJfnweZ+yYAmLCiT8ak7OFrD+7eBMkZOraNhgLsIF7GTtKaMge/IsR5+EgOK3+srw4+DgFxTaA3VvMtAvGKjoV9lY3FKoQT414GIrj1l57iadems9C4ZFXtUMU1KCmuRqn0/RWj+HY2goL1aOk6t+vmeCvNehrsgkR104OBouLU6GnutF1JEvm8AG/4GPdmINFjebjLOhYVcSNGRs2zgAykVeKwFelilY9avau5wm9mFFCQWyVRF9jBeapocmS8Rt0SLdyjL2vfPQtXQqeZLbJfU7Uf+eqFcJB32F876VwJvQK1EEYNh7/vH3bxccixf295rcsRRrK7nJFuVUQVFbT2hdBW3L/EmtsTT/wXGb4nHfbwp3io7ZVI/4DRgWLlZkEdwBtAkRCZgUZPDMXShKAzbFMyY1jde7PBQiVsl1SCWu3l6b/uUpd5KMKLwAWNA29w7Cgu98yeTyNBefFrE6gmDIA4RhwKdLVXXqHWOn5Sr4DT0EXeCTcNhzLD2VflFY8ZSiionqQwpCsZvGPGjzBKcblpE2SigQU/+nZRk8MODRfo9CZO1tmVnxMowtvMAj06uKY0jlMn0UnUwhH8z32rnTfcEUQT4NaWaQY8d+tuwfPNX3HwSmfvygM4N1hrON3vMHxvFNdIurEarnBNPeDnNfTrFtww48TWtZGTiV4mFi6HJZIG,iv:JgoU2DrXHHE9P53dc1Z6/ujh71Ai19DO6oSyzjLmP0o=,tag:jxV2lJViOC1Q1z9bt7ildQ==,type:str] +iqQCY4iAWO-client: + crt: ENC[AES256_GCM,data:Ux3aErqdgkfcfSm0KDPb5ZVCs0Fp+pasfYHSUc6sTcqDCX7kAvx1b8+ZMqJszkXUxpzQHyFsEVt7mqdu5CKGvteIyr9G1oK2WmDo/xIqD22gpFj08rOQoJGvxxoMSug4n+ubY3jq7Qu1O56EMKv5Kur4aUFFhJku7pIGOKrb0sy8gM5M+NPoBruTrgS+NEw2UqGjIbzPPtI9v3bgA09LrMiz0A/f85SCA9nmktdeVAVtvBDu+52sprn/bj+UW1IR9TiS5ViQTYOwFU6vZlP/WzH+TQpd9Tcla7U2aQosPmYRUkDbAcVcdPOgnyMZqVTNifV4XzJoBE/MvM2aQr5gazihr1v6jvSwbF7yyNIT0QVUFHCp2atVvPKna6s47qMAld0BqyJy6LQYA2cNDt4U5FP0queU/JLev6vH4wVBVj4HRL6wv4uegV0UPvVIk1PSynJAWKN3hPaU4OUrVav936+CBREl/ti4x7tp0SV4SxjxXOn4qgkrVZTKZJiDsNGVfL3mfhQnULWGrYO9l21BwyaoycWpt8u+MyaK5rBie8c/c2hPxGdS72TjOzjJn/JZE+vbJ31FoI0rZscnAWHwwQYnNN4f3646+XTNiZvIRP3BmWP87smBCt54pKl0HTviozFundDoXIwLRvfu/LDA18tKsdLMUoukxpUtkUymhBOAVed0PQh4CnB2Wh1DZ+8Bm1gkxWn7qaM3SPpXS0C4lIr9Cw0NvQxDwIGS7zIDJc69HznRE9vq10fSsBDV6kYSVpzkGSX1+LiLPad2GZflsQwYFCPQLoHWf8g1KTIhh4OqX75ML1hQCkhm8VJTOGwN527H+7AX8/6bOszzW48UKTMCJHMbcKH+XaC2jopGcqMqZOJgX54zFgCou7fzQ6crhXin3d/xQ0lHzstpj20UJOWa/KkgMy6oF5SI+WDifp6vUBzhbLgVxQTkq93W/rSbvAhu0YEBi1dGIe4FdSCNSLUJQhpNykXfT5v8dFSGglGrF9ge+OGUGcWLKtVOd7+zDDGVplMw9gFVQeI4DjjPlA/zLPCjGMf6FMSWbvWNEGad9EdEyTNrKdBgoHt/bHeElo5M9Y2XoLrp70UUuFNSFsV5i33DqFsi7WrWh27E590dGBAnWP1/hb1GMYmO9G2bYJNh63utx9mXkgX4uEpe1fQm/FDXFtZCMLoqyXZrndaU7KF0ZPcXFw8yOXK+aWEeCsH5DgQPsn4aoWw9ijjmNIlEXoWhPtAd1DgtDHuHvXhpIF/by+bcc/d69coJNlOau04PGW7AAo7Ip/pUbuM0NcJaYt9gTUulS10OrkL1ArHgoOwfjwUBCQ2eUBFs6YTfJWcY5zG/G/fQHK4Cz9BpWRbu+Sk1ufVsrZEFNmNuEfC3tFuQ5ioS6L8fU4VPFf+QGmV0BFHi29ptgX/Xxwx0EcC5776ODMfjHYaDRbfWOY1JZebFRZYK8xjbGY6ObQYxCd7+paWhlb1yFlWuvH2Zon6hDGymtHjnqWJbM6dpSZPzexEQC1zD+n8yvSMLraSmjo0W1nvY5+wwcPzfviAc4sWhqh4HewBLKRckk9O2WXDkHS+wPCFV8zacEV5UBqYIuyd9dx31zWuTJTrrT+7ms5v+cLPMfB/k,iv:DnjuDkmxK4BO18WLIYqutGp9ugSs8keaYm7Uu2QtAe4=,tag:/AgNrDicQsYvYsnTcmnDOg==,type:str] + csr: ENC[AES256_GCM,data:Vn8AFxs/G+Y8aL+8sqVSor6LsbxTgTrHcbXvnyMgEBkbS84/nE7Ze1ousxzwaJRKnjAq+KLssBW13UE8F9rcX6BOj+ZNzO6f1eCwok5E9HrHtX2R7jt1xeVXmIknswOQL5JKD8FJY0FuV+x+NQO3SLILCDZFRneHvoVLPyrPjrFn/Y0pZauDCjJf+ccC75Lg+/HNZyAGA8EWUINP++YzIeXLxwX16YlalHwejaPPJ87+Tq4AFv7ON5cBq6EuET/ga3nXi4EF5hdpxH2LCFDVGomIOEwKKdk4iRyRaRWml955dfu2cCTMOIHqrn4pSMS9VjdKAhkyKPPbrHsrA2rmzvpEoUvEq0Ih5CPMfcB5Jf2y6C948BPJbRJhGXx0Q8EDfet2IECYvd3B+5dECrxaHoGfYOXIx80nESqL8SP+S9HgUqMVYNFlWqL0qepKUJQ7aznkfM0/hBUb1pkSk++RVtC4ONEqizZCHhTVgAuC2DUFBcSLs/meTSEwEPFn6BRLk2/3sarvZRQZDCcMTAxvfOL6e03NtClwrO4EdwCculsuf/Ke24oiGBX4nHbDkZDIhMjl+mv5OsP3LS7KfQmoI3eJewapkK4AHsXRFT3iXK81VJmk8quY3iEk9ZfctjI9q9VraLOAyycXh9522dZeI5U4q8gC4GXDhhfh2QNTCx0geyZMnsJHvc9vXQhL+7Peus+Tf2jMta3Q3rkuyFB2iNEUkBMxF7Yrvf3PYUte/uCLqkl7L7NR97DffC48MCfD5+jRqQ8dHCZeUyTd/YALywPSPOohH+KXthy9AYwAYeOtZSa257aqZ/NXT7P75esfZo54rdGOwY+vERaCYrQj/jxmj2YZ8DMZ3n3PAWwsWyrILq6NVQrLUj/aJgsQ9b4Zz/bx7dlrtux69SMKF/3xViW/crUXlhFrgyc3UAFV4YqkD6eKMXAMzSLw1Vo0953hg6GzanA+6TmCZe2wNcUzAEOPks4AZgUyqvBHzqtPJGEzcTcXjploQG5E/32UY0MWQdoFRTpEyBXJgUUMb5UkXWGfDiaazSxQo3JRF1u6Any2B84a1yNl8R7adI3joDMEPFgolkeHauLE3/lK3JIaTsTEVOf72T2GV3UftJotaFn8bOg9RVIavJaMWUAMwzzELA/FXEG+iBmE0wC7CBaheD5A4B8p/5gejuBfGdog4y28VjVWFTwv7IoIHDEbcZ2Gtr4lp5zoWcZEp5IsUu7JN/oZXFNeKHNNd0L76jyMt02mbo3e/epjr8UihNDTNRSNuR15dmi57UPM+no2JgvCpgKvcb614wCORHEcI41NBkHO3oGpYYjDFWKzcvhkJsIP0g==,iv:NLCQwHHt3AavzNI388QpkzC1GCGq4mYQTkYQ8/uowg4=,tag:Bs4o/1JLLV+srLmx/bYmlg==,type:str] + key: ENC[AES256_GCM,data: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,iv:hwWSLKgxK2tL8ytrv7oW4IznMn59Rycq3z+vAtfAFkg=,tag:4pGEXi3ybsH0TMH4J+LhNw==,type:str] +matrix: + cert: ENC[AES256_GCM,data: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,iv:VQV026De34FMH4WXmS83Gt0etFrR7mDcJJ0PY3S+e0A=,tag:qT2PSukOmN2UKtMGJIwlxw==,type:str] + key: ENC[AES256_GCM,data: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,iv:bVcyvW7Xr+Av67p37zEzE4Ybc7U5qJ9vTUFdPdfRY2Y=,tag:rBqDI/jahlfT6Eo+iqqPrg==,type:str] +sops: + age: + - recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsbWtvSXZ2MVdpdldmNUhx + OXlXSkxQUEdrY2wyMXZFdDNoR0VXU3hhODFzCldQOXFpamRsSmJrMXpDSU45aE55 + QzVESG9mdWN2Z2JvdEJzbElud2hWQTAKLS0tIHQvWkxRdXJlRGp0NGhoZWFaRHE5 + N1NHa25pT1FscmJ0WUowcXluaDg2WGMKigU7SPfaPWuW0gNF6yQIVWMDkddYWK+/ + BETBlD1+yyFk8pF4IfR9iU2JgWLSCzMK5JDZXjm095eoDS5xTQHj3g== + -----END AGE ENCRYPTED FILE----- + - recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAweGpWcDczZFFoTXNDc2xV + b01BYVJiYjlvQy80NlF6K0lRTWN1Y0pYcUZrCklsbzAyMFFqNXVRK0x4NU1zc2JL + WXA1OUhPQzZMNDhxMkU5K2pvc1lCOUEKLS0tIGo1aHA0b2lSdW9HM3ZPTU92Q3VU + dVgyamc5bzJ2T1M3TXh3dEg1d2xlbVEKvEWuB9hPQXkI8AQ5oKs0AU8v9bE4PpLu + x35YD4Wvfva9l21o1d1474bk9+nQnksj1ofgQKYilvKSetH11KkuQA== + -----END AGE ENCRYPTED FILE----- + - recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmem1iZmRqSXhVcVA3djBo + SFVQemRuS211Q3kvZEZzVkIxSmIrbGdtcDE0ClFwN0NydUNYU0Vpaml5bmhXSDJN + QlNMWExNRFNUMEYwa0QrbWUyUGFtNjQKLS0tIDcwYzVHYXBOejhHN0Z4Njk3OHNL + SzJoUVArZ2xkOGpYZG5pWEpGejVyUlEK5VRrn6jp40iXOdoDDLxk4DhcprKBZd8v + yHp6GBf7mFWxkvw77fl2/q7J6krlwix2sC5TLlk26zfgSaISz/mR1w== + -----END AGE ENCRYPTED FILE----- + - recipient: age13w4elx3x6afrte2d82lak59mwr2k25wfz3hx79tny6sfdk66lqjq989dzl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQOXRFVjBENnJqY21ZNkw1 + WXIvRURMSGRJUU9WMkRtOVAycHVGQkZnZkZRCnZlYUhYLzYwaEF1UTBCck9lV2c2 + Q2pmS1hVR2xkeitGSEpGNXptdDk2cEEKLS0tIDJURXNKUjV4S2VXbXdyNVRJWVhj + Y2FnZXZYZzNrZkZubCtneGNHVlVKUHMKTasbVdxTpuK3UYmeAXWt4Gs+M9NnodWF + fGuCUVkGNrXHiLBYUjomvmtYIul22xiGzes0xHzSBE9jiZuVnu4qlA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-09-21T20:28:29Z" + mac: ENC[AES256_GCM,data:e267Kxv1Pyun/VOcLepBDBEKN6uSf8/iuY8KQ8u4xK58wsWkMdSDVcDKvO/iKF/Tj9hj+lZapkaKmp5SdeX+gjpyWiZi6QmUuKsCs0jlkV2NydLtZZt9vkmY/LCguIBRMmhDgidrNcfoghTxDDK5lng5H+2MBs0r2zLID65pHUQ=,iv:tr4YFdBltnsD4uTt+0NCam7r1QzhOmdoEbfz5/+JGPI=,tag:R2dDWTC1qrwPI9ghaf1FEw==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/secrets/env.yaml b/secrets/env.yaml new file mode 100644 index 0000000..a7512ff --- /dev/null +++ b/secrets/env.yaml @@ -0,0 +1,58 @@ +stash: + password: ENC[AES256_GCM,data:DVtKQmtOQA/jS3ZncbuPKMukJyo=,iv:FSLl4Qbq58X0WNjqz8LLOW6XpBQxE5W7L9yOTBQkBOA=,tag:Qun+5Vf193Qt8n+Yp9lBJg==,type:str] + jwt: ENC[AES256_GCM,data:C1RcyQn3j5LaCSDGPjBAm6RYsqvVn1HIFxxBP4FNx7NVCroju4VEtkV98Ve0D6Z60L3mB1yOqi8OrEgXNJv+vw==,iv:t8pmLzXwg1g9kkiL98ql9YLaSitaXoJiiLiUf3G1cWk=,tag:D3mdFIe3m3219E4V8yhmpg==,type:str] + session: ENC[AES256_GCM,data:ifUXaGIO7xKPgtTVEeERx0OyBDni2eoWo7dFxazQ4W2DBrnzQfJ7Plqt8EYLhQQRP4I6e33+oEKNzpuiG+XJCw==,iv:AOI0lMcTT02GpOCQuX74hPBKth3WdFN2W2wlqKgrKJM=,tag:1I+brf4G2oKE7o2E90q/CQ==,type:str] +gitea: ENC[AES256_GCM,data:8o+U4qFdyIhCPNlYyflQIuLHsQHtbT6G/a0OyCUeg9DtIeABXNVFhiy4iFRuIF0=,iv:AYwqDRNML1XuzwQnD4VmI4rKWYfTJjOjibrAbI5qgcA=,tag:UPL3UlETdkoFXLihEIGcSw==,type:str] +shiori: ENC[AES256_GCM,data:tV7+1GusZvcli8dM86xOD71dc2mzcyfQwMeTh//LDb0=,iv:ED9wR6QjQgwd9Ll/UC5FK3CyYK3b0RniC/D6Y0nGEOI=,tag:X/aopMc2vhnRW2iTphFflQ==,type:str] +flame: ENC[AES256_GCM,data:XsYRsA2xs+juWje2Od2Yl2xIvU0OS8xMrtwtcK/0NyyRrg==,iv:FR8lHsNQNCaOy4P+7BsIjNCz+H38i5RlwLYQ4fpB2+w=,tag:61EV7H04pcr1bSX4nSvlpw==,type:str] +ryot: ENC[AES256_GCM,data:VMWf3VqcUdyJu2Ygd3XmoqGNWY/W/VJ4213ej0FrA95kAoX+S+j0+4a4B65NtW9UheDSxD1swTXebyenJCIN/tEZwH2wj9I12akNNvSDpt/LG3d1/BZ62cvLCb5n9vyE/vcXgJVfPUqmc67pYDWLpEV/vkKjpqwNH4Y8vnapVo1ytIgsjkTuBb7VFbnRPvYs6J1M0rnaTtkVhOBoRxv+Xg3pWYCgFEXdM/Pg/WKqdHpyh+tJqR74Z91Mwv6G56ZYEDQmAp+Cn+Kk2zZ+t44UAu1SQOgYXPLep+4/PgWw/vQMuyN7GNNP6TrsX3g+ONtJtkdmGu6ArcfbRAky4vM14DxlQP4xSjYSu+FDWGJL/J4TMw6IVDuw/TDVNpMrhBmZdPujYLUW1c6GCCEchBknNfw/Wt+NyTjOzCmZLVw760jY05Fa9kcW2kz+P0iAGTviY7yJZWDctP6PrVNtG1cXc4noJqV/uJ9sQmuGWCiTzaCIIZEhwRKnvjpvZNisKPhx4tctZMWm8l9gKO/TJC/SHMIhvEazmH4v0AzCiRUzdTfnWQZGTNenDrCUetztPh/UUJbLZjhFBH3QR26w/3I5oNpUzUDhfDhcEYtfWuB7ckbkXT8nyYMfe0OR16yJTfQCdnIPBhAUi1g1ZV3jFg+OhYWxk73lPiqC1ADRNh01L1k90PMMWtLXXm6aQ28cB+iQTvvgKbDrr76U8bXoZUyEl30waOQ2HT6nDG61OBUtQHTu6/cFhfhrnU6poAD/k+L7SyqcBoMYAZJN6Us1y3SKhV/3mXVKjRwSl5XZSW+ZpcRe/Cg4bonxFBYsZyY3VjK0LC4Cj8ijh4LpYWrGWtVmWOt/gg7UQPTd81A=,iv:Oa2pvfDpfPr3pqeAg2kYIzjf8KUK9ckMfbVymM78FyE=,tag:XyjYEvWo46BliYXdDH8QrQ==,type:str] +mealie: ENC[AES256_GCM,data:RjKqDs70lWhGN0LXPp3feQfW/WtfJlR6vX++0hwGtqcA3iepEh2Ab/36YRKbsVRBkglp0u18MusTmP0LSHUpzgCn/c/5ZzzRLGL83K3aQRlg8JtdTvzvEnLQSdE=,iv:GEfa8LwpOhkqWtLk0I5F14zkHcnFjVhVaHeLSFlDkN4=,tag:lkGcFn91hVxraMHCKF7rXQ==,type:str] +maloja: ENC[AES256_GCM,data:yCwokfD4I1Boy2NOhOTLA3dWgUVOdSzWKIEdYC0klvYu41IGcM8bM65uYFmiOtk+jHgt6j3kO/pBBlC4w/iTElphTqFyFRGdBN4fNRntAhMzqOszBZII,iv:Vf9hfNwSTBkh2cXV7Y2fv4NA8kng2M1i7BtTXJvy4u4=,tag:KLc8sP6N2/Pp/9069E3aPQ==,type:str] +multi-scrobbler: ENC[AES256_GCM,data:ce3dd0PKm6eyD2AqWmw+8iex/tBHgMhG8ASoOMkT3c9k6kiZabpTTFTkcouMO+s42P+qjWQAUJcJlDdYVYJZbAqw8nnxLrtYmKoBknSbbWijlR//CpgfwuuAWIyGQAGVPliuxz+lR+1cf/G2mXM+FJIfp8Sliak3v/nGg3ry0bdjbOLVoBM4rS90Jrq98ZuBrjlFVhcJTKkEHtgDv8N56wWbPL/r3cTlS9MoEu2ulCSLvfu/snr8HqJ5yssAGQ==,iv:jOJulX6o3t+W6DrD6sU7amDH7JQP/JFGBI9IM8m/sXU=,tag:jFZoLpYFXj+xplbypf3nvw==,type:str] +vaultwarden: ENC[AES256_GCM,data:NituIOyGrYALEkuwKT0RRS1gvi3wjC6ZSAfUIejfi8xoePE6vSNztJTGsRSIh4sJnRrQIiDuKTmRKZDM6AtX/oEBsNW8MVq+lWAq/vtcO7fuTriySEungmpXhQwRZD6NsXE+9283P3s6RshpA4iipmENiW2v2/uxkIXxtTguUxfX0psWYtF6mx5/hpaoNZ523OB69m6veAxD6Pmnj+pTOAORGXHldoNrxNc35WBDdndjAZICyO873tbs22VJOWD9a66BNxtfwIPYoFkuPO6QG3nnFfyPSQ==,iv:rmDJbrP+NQ5HGdRCWSYfymP8dU9WJdMEhAg80eupgeY=,tag:kdNzgWjgeqaTCjqUCc4uWw==,type:str] +dns: ENC[AES256_GCM,data:fQN3SOm0HzOjSjTohRAD4KlXdEu5PbQc3DvK3rLC1S4G0G4HUPkgucN6vJUwVJPiY0AB+L/iLNcqCRz8OH0qNtfnikBbDicq0OfrwjnN+VzmbwmrS6AdFo6lilbxI3Jb8YwGMrQxXg0U9F2/WVLETbzICG2KpukwIER0xxQpb51OVL+2hviGV8JpWKo66S6pug628Zc+uMJXEBPSqCpz2vXHXnXWMszP6MlqVfNm/zE=,iv:DOj0e8y+2N9eRA81nlT0kS66sXWZoLSVn0NAiUkNcDY=,tag:+0Baqs6TbTAmt3lRfncE6Q==,type:str] +cloudflare-api: ENC[AES256_GCM,data:iNUMlY8rz5yHVitpK4HGaFSK7j+c8Pm7rOQMOQGmSJ3a8ASyrtouPgLbcnoPY/jalsJYAj991dSiui+Vwqs=,iv:qWONG/KLd9/F4tqrWF5T25Zxst3bk+kOYaOFBFSBAAY=,tag:gRFxar8KS8gnX8oaCD156Q==,type:str] +synapse: ENC[AES256_GCM,data:IR0pFwQBEM4O8mzzYXrPe2FjulSUGuitzLDLms2uovr6gEU82mCkRO/UCQOybNm03iOQeXX0Whz739kpYSGSInEyx69BNG/etH+bMu+GbYeMdrTEyXHSa7kcH4Ug,iv:Vn2ILYXnCj+Op/E2kWoxV+2ZtlxYJxO6XK3Ql41KW6w=,tag:9wogJFLlmfM5PRgPdwFlcw==,type:str] +readeck: ENC[AES256_GCM,data:TsIkHLji37dDHQRt78SquBhoSREHDgvgbc6+M1k2MLrgMGJ/Ejfy5AZXCIp/Qj5sXDzKP4j6Y6xFvGLswCqe02XjqGCpX13gZVCFPuKr8Nq051Xg,iv:Rc/pjYP+Vd/DvLCYsfJjDrnAlAiUlZOcNeeYzE6O3UY=,tag:OvR+CXMmrUFbsrHvduhnjA==,type:str] +sops: + age: + - recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDclRxNVVzaC9lazNQSEdp + UzNBaTRnNzhzM0dLaVk1QlBaK2ZUelhoWmcwCjAzcnNsakxONSs2UThpNjhMMGpr + TGtnY21OTnd5NXdvdlpKamNCdXNjbzAKLS0tIFVxbGNLNWhudFRoRjBOblNrdW9k + VkhOV1BScVQ0RkF2bDBabUs1a2toMTQKDAeEu3+vuVKcpm27igmQuBvFfsMd7o9H + Wbinft1NiaQhc+7KtDEx51+tS+cgaGzObkWabyQutDqWEa/2PZLZLA== + -----END AGE ENCRYPTED FILE----- + - recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4RC9Ea2VSZy95Q3JJWlhB + VFVBVGxnQit0WC9Vc29Ic0g1aDNBNWFySmxzCngyTDg3R292c3VNUkhvUWNXaThE + NjVjTVlEZHhVODlFeklKNU9peWdad2MKLS0tIFhVTHZoeHV4eVVGOWNHeml0b2JE + ZVZiemVkYmZxMFVEQmVvVkZnaU81OUUKPHdwj8s0Ju2Y0Vh31jnR83nQ3jpqjkhr + 4z5OxYJk2d0uO9f1jNaiIVLRxCdbj3h84f4fQqoQv5csrc5H9mg7Rg== + -----END AGE ENCRYPTED FILE----- + - recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlNkNLTzcxa3d0M0pJbXlp + b2V1alhBUFY1VVZIZUY3ZHYyVmFKQW5tbGdjCnJXSHpmeDdTWWtHTWt3TVlCR3BU + TXFXZDVabjF3d0JYUk5Mb1c1dkVjMTgKLS0tIDFFbHBCSXlPVlM5YUk4MUNiNWdx + bjg3aWdMbkNDMVd1cTU3NGxPU3cwVjQK4zDOWDUHhK0JVjiYTMTSmGej7yXb5X6G + SLPWPbrB8WLGyK/gdxDrZAxucxe/n/O0CsR5DQubmetfUSowk9RIIw== + -----END AGE ENCRYPTED FILE----- + - recipient: age13w4elx3x6afrte2d82lak59mwr2k25wfz3hx79tny6sfdk66lqjq989dzl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4WlF0WkxIRkpnR1RhcVJX + b05ZYzk3YU84TDI0cUpBdnRpNGxEQmFIMEVNCkxrTkdkUzBnUDdDQ1RqV3hnamYy + c0owbnVHbjFPY3JsOGIzN0xIZHp5dmsKLS0tIFJwZ1ZFbG5SSmNoMVFYYlNXNWx1 + QXRUYWtGcWZCVW11U3VYRktuUjlCbDgKsTK4WhUza/JuoDTU3uATa6fq/8eYzxtb + 9BUK1ddzx9Mghea9XBMS17YGtGmW800OsLBomb3SINnOFvejcnKf8Q== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-09-28T03:54:20Z" + mac: ENC[AES256_GCM,data:nPA5SF8fw+x0t5O1aqR7bZk2dpSjf37KKWJ976vx+TjaxWDz8DQVBUNuQmy6d3uX0TT6ysmsA8S4VqjgyRKli1vdEXWXPyULyUwPv3jtR4/NS2hnFabglOn0BhjfNrcArUkdyaQBm02Y96u2XIa0LcCyPOpJauIl5SbSSHaULQs=,iv:Qh7p70oFZbp4mAzDX87hkbPW22S4SoTY/CDzJabQQ0M=,tag:2YGmN2E3y1dcqW5M8WDvUQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/secrets/homepage.yaml b/secrets/homepage.yaml new file mode 100644 index 0000000..46f2923 --- /dev/null +++ b/secrets/homepage.yaml @@ -0,0 +1,43 @@ +homepage: ENC[AES256_GCM,data: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,iv:nWpfkmox3dtLUMZbqCpxHFRHMLW8DqsPZUt17TJXhOo=,tag:+9o5O6TpgkxN0Hen3lAtvQ==,type:str] +sops: + age: + - recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMdnhZNkx1S1IyWmwvdkVh + VGxNM1lUczd4Z0JKaHVlM3N6RWRWS1dBN0IwCmcvcHJnQ2h4WVV0S01OelA3eldE + Q0lNR0w2Z0owWnNjR3hXWGF6UzhyOTgKLS0tIFMvbW1rd1A1VDRJWW9TemJzQUl5 + d2hISHVLUnpBVlAydEd1eHo4WGxLSG8K4uAVlEvgrohFbpvLexcfom5HRXMwTYrv + ftuFhDAyNHlTNABiPH/dmjy/A86Veb1LKXF0Y1r/RPWRHaxyw5f23g== + -----END AGE ENCRYPTED FILE----- + - recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwQkFPN3owRjRuZjJ5M3JX + U3FaMk5XL2xoUmo3eFFGRXc3Q0Nwd2gyV1FjCjFjL2pUaWJyVXZIUHI2OWhPYnlt + ODdFVjVvMDhGSnRGejNTWFRUdXdleHMKLS0tIHpCZlc0TTVxYk1UUUk2NkVpcm1M + NjFnY2JqNkh0NFJkcU40NEFsNjRuTW8KMRIBZVBnxe+Drs5VqGzBLI6AsVJj2Vka + bmPFMl5ZJ97HxpdqQ1xkUqjoebp9KT5osOSglSK3CTkMRTEtyWQ11A== + -----END AGE ENCRYPTED FILE----- + - recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKQkxwV2lQRzNPRUtvclVE + Tkl5MVQyUUtxUVJpbnZmVTVNRThBd1JYZUVjCk9GSklFWUJBU2owVDVxTjdncEtI + WXp3bkRtS2NEazd1KzZTZmlMZ3Q5U1kKLS0tIFhGby9NV0tidU9MdWRnY0JNNTZ2 + enphU0dnNE84Qkc2V2hxZWRqOUg5QmcKk3qdK28b9072s7bPj+TgqeYVS2lnR8uf + R9BUS6c72aJjxPm11JqNW8UPu0ODhZrVMyyv+p+KY1J2iaCNGNdvXw== + -----END AGE ENCRYPTED FILE----- + - recipient: age13w4elx3x6afrte2d82lak59mwr2k25wfz3hx79tny6sfdk66lqjq989dzl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiTEZFalVYbUdNb2YvOW95 + M1doTEp1ZHRjUFJSNm14V1VWNE5hTWRpemdZCk1GMTdrck04N2Zydm5aYmQvTzdH + TEhrK2dES1lWVGJaOU5CUUY3a0ZtSTAKLS0tIHJXdzRGY1laZnJ2em02ejB4RUpQ + N3BtMkE1Y3d6Tk50ald2clJ5VVZaVG8K6BDcM8UAtBf0eBYosTvrRmi0Fcw05q4a + FOltP/mH09OQBHYJ466s8eaPj0TwqMl3524Byr4vTPYTy0keRN9EWQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-09-28T20:36:54Z" + mac: ENC[AES256_GCM,data:HHgsVrQwk4BAyC8VRJeGtpo5/35LdW68MQPAKKvPdV/TootUsTJOWt+Y1Wm7hHANLoe1Rzk1V693vg8p3OLmkJaJOOXw9lmw0DHh+jS1R8dw+a4Li6hrYeeYjq1hd3o9XjivgxhAOOs1ply6N8bMvZYJFpmgA+rzRa8YFrCgLHo=,iv:OxgRaIBG4sOrixLh2E6oYu1rjY0uvxveTCPuCEwmEiA=,tag:0qbwDorY7qjY0LvpnCPVzQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/secrets/keys.yaml b/secrets/keys.yaml new file mode 100644 index 0000000..d0d5e26 --- /dev/null +++ b/secrets/keys.yaml @@ -0,0 +1,84 @@ +syncthing_password: ENC[AES256_GCM,data:VNlb28ADaMyB3EREV5VMN5U46fHJH0hW6tuLz7q6HqW7MnYzWqcNgrkd/INv/P+9BJo=,iv:IZzpiJ2tAqDouxAlwula9NaxmVAz5CtofOJV80sy3wk=,tag:kDz84LuAlWOVJTEGuzncMg==,type:str] +public_keys: + age: ENC[AES256_GCM,data:zHxSM0lMbOFgxR0zV/byXg1qfZ2fz+coAEnUg64HCYTir6Fbf4lKKLJPuN7md42IsCgzBkE2aR6EXfDxRNZk59kYqZw4GZtOQV9FWmeB5JsUwGP1TapRebmR/zcjgbwQ,iv:ispmW1I50n8WKn/34V+gdicEb7396SK7OcTLQWKq4+4=,tag:8PivakR8Mo/w2j0rLt/dUA==,type:str] + workstation: ENC[AES256_GCM,data:g1qejAegE2WLQ8pW868ZOuCzxIeKAPnSTl1tfMS5WEZCI1iwFA8L5N/nEwPWpzr1AhnKAP2CxnguBes7AgR9qzaFf56fVByfA4Zc5LqYBiSyCpZ7mF/nGrcQzMiqttJq5g==,iv:58/tWUjNdLzOHrliAlyhtZSNEakA1sphYrrqcWRTIMY=,tag:1fY94k11cvNploDtbglQ/w==,type:str] + server: ENC[AES256_GCM,data:ZYYcjXp7BbniEL0uhR1YHWCCNOmf4VFpMHcJsXNdBARB3FCr7HIQmfUIaWtu8IDAwKUwPEcyeW8fdXSk/fTpBQnVV/Mlg6s3H7fXNYqlXa2AG5TpCWI89M6xsho=,iv:1RIWiWIU58W01weQw/aMfFAL9Gu8wvm2Znib4+amgfM=,tag:NN6saDGDDDRxg9HgKI3X0Q==,type:str] + miniserver: ENC[AES256_GCM,data:0aI1r2O3u5gBl1icg+pkf1hsReZgvG3aPZhljaYUJWlNtYeairmN6Vd7nUOMu8u4NoRQdLvZC/369p/4GR9WvNUyuELiWbep1TdkxP0hu/wlrFCFJSYwJsm8x0izXmwA,iv:/qmAMMy5obLbw/VZG8zyV4svCWptYfbKi3+Sc1t8O6Q=,tag:R6ylK8O3jqhMPZaBTsrgtg==,type:str] + galaxy: ENC[AES256_GCM,data:9xjiz/tVn0UlZ9qb/Oi951WWVjmk6HTDjjYzB8kULKYhPJgVdlQioGdJtn3MjKCfqH0UnBZHXoGaK0MsShtfB0xfZkW92dy35KiQ9kQTBJn9LMMNxuk6IEqpWKQ=,iv:6lPWZ1iqerbWfU0UavvpFNtnsxOLkKHGsm3A/X5xUs0=,tag:8hVDlOIcCN590jEFuJ6eSw==,type:str] + deacero: ENC[AES256_GCM,data:S0FKo5q+grXFBoe9c6ADDA2uGZ1/OMzGU2p3i2PPdhO34PT39ePa/O6yP9Z69RvpL2Ho9GfLlBOSxZa1KtrJecEUoJZBdHWZRhKtcc0EM+CsNHnX74T9a/+uz3IIeys36FPBv5nTs9a22QL/5Q==,iv:xfkLrkje8pv0sMSnTrPrM5fmkAiliiYbGplz1KYYmec=,tag:3D4bZpYUQ/Oq25vfSklZBw==,type:str] + phone: ENC[AES256_GCM,data:PvSqRnz2qGQU5kdZZpeqb3Eg2psLYrMoV/168CKMWpc1h5TZi7TeWkCQa6ktPR556NT4Ny2m6rBzADtYZkjFIKtDLXdhTYCeL2eFWB3VbSGFHsHgvxXHbae+zg==,iv:XGO9d0QZXbP7vuNDY4/Z/YhRCPKwj3RoQBx5daQO/xI=,tag:zayb0RYQj6UOi6FKJbhhRg==,type:str] + emacs: ENC[AES256_GCM,data:JBdqrtYy/1oVzea3WfvAX077R/8KECe+nziqHM7sZSMSq8nVxMeTIqXuowYsp15Dr9I1hezgedC+IfvkKyu9pCfS3Smzs91o+HEPB5T+nx5Kgn4pwNzw/4ahiA==,iv:OQfL/6UmhWcX2nbyWHZnN1+a5EP0AYAqTIdxn5KLvRE=,tag:JDL3IVYy2jAsDWOObTBFLw==,type:str] +private_keys: + age: ENC[AES256_GCM,data:YZtCasGFuxj4mVnhDtNzXgrzvdjwvHVtaBj2gDJf3dzA7dCe+n7MC5mYowHnS+oZpGFt9P0ImKw30yAYRGZgvxJqL32ACbob4oqcnwmJgswx2ZCwboz/I1PKkAb5uo1Bhc3tyhEshiA9wk99CoI7ug+TGOC5eyFw8RM145uJdxaYJjFmYdSorbjYd5JpijYi3u7p5buIVtr8VRt3tuWNUzarW18d+ZjxtCAF68W9jqICtuODdFakt3pZ9/2byKR5KG1sBKdc38DvJFkRq3wlDE0U2PwPyc/RDdlLAnYGYlZD/GsC1YSWEW/ygxO5lpkoJlxF+/02Qs+lyZVEJd7buYCMU3xkR3kGOQB2dZXa7T6F+Jrr6Ek7svTOQRaId68KhQW33piNUXN8d6YnqIRj537exrcmVCNrRwJmlJ1M8pcYN4IGj6OFICw/lwiTcN51OL4UZOOQZZ60jbgdwWj5gM9OFmxLm0PkIRt6KMQVx58jIzmXqh8SF0+mkymbQdVaoDD5JJ+ltTQgIEBaPe7sGVEK4lGH6qbgtm4F,iv:coRTCK6BSI8QFtfjTg8IAdwumSt6fuQryTxF5g+GF9k=,tag:K06p6t3Gso30DTY/Nk5EDA==,type:str] + workstation: ENC[AES256_GCM,data:QrM6MwsStFeOH9bFaAuNPtxVWB7rlXXV0PD2Em5Nswf7PIPuzYagQaqBF5nV/AteeJjwsz6KLuBceMZ3O/WlccxvyfY6i00DuRvzJBi+5gZl2rfM4OR5sHC93bzcGmyU1dQUA0nEeGFYUfd4+ZM4BFRgD5OyhpjrqaNYw5kES6WZMCYiR8NAPE2Ca8MqCX3KVQp1AAzgFq/nN0cvuWIflYVIngR4PzAqDGXjgWaPT58rmcWk/3KS2nOKRX5tQ/CgJl4FLdrjuR4VLvoupeUqv1yNeSPSljX+gEK8Sn9vONFd5k0bifLzQd+zCLWyEdJgNvSPf7bnXcuqU8RLSmjckMRAP8YVBlyqsNY++JidXuXukV23aB63dUp44yhIYEkt49/ISJb2qerj3U/Sy97VTw/1WNwY1evzHPlobrUjt3ilxWoxAdzjrqJXWultYYBEk0crmKRRvnABMzaHrZaqaSrHsSfvE4E27m+L9HNwMyq7KywlwrB0KAog52iCi17Gbnrva9aEGrn8Mne2VCvwcrKSEciV1soKpQgy,iv:2+xsS/4+vfQ0UBsHgLVCeV6GOU8giclqNpPXoi43shE=,tag:YVSiY79mHJ2LE9Ab05VE1g==,type:str] + server: ENC[AES256_GCM,data:GRHzxJBEVG995fPWDdpqSV8b80kqVZcKBUg18sObNn2Rxwm/tajQunemQN8/0qXS37YACzMKX2zCyQGbIEq3d1id1CwRsao64vBFW5pZhlBiXXikP2O1NxQGCVc3ZzaPzYjeCP2uYT/I/b1ZPfUGONtcNGNgSlZQlqgBYmsH3Qp8kYRHiRxslfvyknqYDRCbRUVmtNffRqRMTHMHJFQAGLyqggy27pq2L7MSquTA8ravwj4jMp6R31f+IVufuYD/D82sAbSWy8J39QUGCt0qLvchuryDZzMkfqk+EktIQS9Invhuzael0N4RJykiwFRziwDbs1xYPY8dMfXYw37nrLow1R7lbuus4kkOcBmMqiyk5FWH1JkShRacviAQ6kB2hV7+HHhjH8y2OMYreEDIl5xk4lU/b7yO+/Jnc2Apbx383vS11iJ4Do/i2LF/9x0ILAh02pviaXi/aRnXqDqQKnHgNdCYIq/e4IWI96NkGgi1kPGr3vGl7ijoLfW+emqU97MG8j1tTIzMckdcDRpFLIoELJlbqn2L7Z1IdCXBygVMZVOxF9F+12iwyks02rg2LktmVlnknOeigEua,iv:bsv3nRX6xl08B1wGjEU0T26DvRVimfn9Edxl5eyxFK8=,tag:dQg7HQ+2T4UuvzxInQQEvQ==,type:str] + miniserver: ENC[AES256_GCM,data:OdKoGmxZYBp/XTQIviGXcRrz8sY/Ea1KwqtwmYnDmejGZFQuotyr9IHDBy7nyC38Rq18jtRGK0DvQTs+0z/jaBrtAbnk3/aodRpy0q/82XOpUDJ+oRPIbuC1KEyN+vzzTe3jd5Auwg7dy/W7gKgAoR7vhkNeAY4TPbE2ybqsbPDIhDWmCMK43DIxKcWO8LrtYJ9/h+XR1XthGjICRXygOeMA80Ip4BWGMvXnfGcayKTIlotIWNasYGZNn5E/bfb6uH58zPvCAWavleRm113zOeMjlgbtAyl4IyM1StGvZtJq0ud9Txza4AkWmTvYLcAB0xaiph/Vm01GBlaGSWZmOqo8ybGEEQgh6JBlYzHwJ0swqg3uCW59jxeQcGOnaW0YrYPix8twd/2GQafxx2denWFgvoNk5itIdOr07BF+JYKd5FU/Kajo9P5mpV2uFR8sok8/Q68thYvfOEK4wOysWM46lHS/H/P1qeJvCbO6w0hGt+VN/1lbqm+pcVTDMVsfWOkA1Rmm0aWozoYOAPRXH/PjG1NTiqJnecsyw+vZLlnvaDNHKHWhxnWVJw51hSH2fTg7nVz+WqwC24eOmGpOG7UUCdQ4V8L3wb8qDPTmLmo=,iv:FxxpTqtde+v9c/+xDfWimYlgkhJSI5GFIOAwoSrjNsg=,tag:LcLxjKaQ/5JT3hJnBgzmqQ==,type:str] + emacs: ENC[AES256_GCM,data:jBLy+gemP+4b15WGaYBMV3fdlPJpZeZfgPSWbj6nnsN0J4b7RIOZQXl2NoDsNS6yi7aO2J6LoQ6WSJX7si05OlCXJESCu3ghmNAdOQq3lWs2taQMISBV3g0S1OlLXFdDCohBC62y55nMp0/yenL7WzfhmtTmBoFxkp1VcSjI5B+MlcEW/0BzVb7YESCXB5GVSlThecGQ9BEEMBxfhKsSwmLQXIrxdtl6nmyZh8lTselwDwRZ5E8LFXLVwccujAI1zYM5H4qYjBnaizs7f4h7fHh2qs1DeZwFaELFtjgU207IDUQ2CKfVBKDL3XES5gjUnHix4l8lj62ZCWniexGQtVUFAxRerRGS5AQRGDtovC6xPZaylF3JoXEeKgMusPygIz9nzyeB1mXq7FqT+Tv9OG0biCqVEphcQ0GEc2RVPq2ftID0iWyoony9T061nWSkY7QCGlPTmp0PVGLbLpTcd3ulVbuoXKsTLrUXJrAA+5xQe62bS22P2FdKlMP93SvRkM5JoSBI/KBEzmWssuLdxyDopNGpoHgL5thc,iv:qDLbsIvW3pBPXTvPGRDzqeXEoWhhcwgNtHBVe9/NeLA=,tag:GejDD6cBIGYhHY+ixLbVWQ==,type:str] +git_public_keys: + workstation: ENC[AES256_GCM,data:VqyW8OFJ4450Okf/CVa8peYPVLjkfW8M+ykpiteTpXhlgXLPRfHdW2QrGXTMOIfRYDZD33Fx3JqGJZ17Sn7/wToLO+uY8i8JPYyYXWrQMqI0Xf/NR9JvMCycVoAT/oWG9w==,iv:VM5cBPHe3CPpiOozy+hsQcwGokQIVB97oFbVr5o6+Vo=,tag:0w4r5zrdNdpVDNcvbJ8bdA==,type:str] + server: ENC[AES256_GCM,data:WMnUqMgIQ0j4F7G/LppKsN1C+Uoq12DRcYWIEQecTzq9v9+xxe8mAusGenV7SWqz50wrkkjGThmSiXzrdao7Ri4v/BKBX6d+Cql0Us0OOKNplSy1GQ98ML+LfHU=,iv:F/SPXw/BC5JE2u1m9x26qYWrSu/b10QzNPelQN6NBvc=,tag:0YU6dba8y349UvrpeqpbOA==,type:str] + miniserver: ENC[AES256_GCM,data:M5p2My3d4rOZMj1j4CFMUdHoM2f3BK9y0ikg3NwMs36A2PUzbN39dWzvfhdqoq6stypHbEzmaI4VtUZySPFWaGclBKPea5ujZTxkkZOdt9V6/lvDMdl9O5MUrPBmXYyc,iv:PyVj4OT6ZEqyQDH/K0OtOflGoomUarF25hx95loOgJU=,tag:xZs6wd34LqqqWvRMfUgJbg==,type:str] + emacs: ENC[AES256_GCM,data:jnCEEpEB5tZAs7Y5LT3zQeFZYRqsBcQY5ZASU6p23jRzr9F4wv9ksqezTdZEYGnY7cv8w9gC7Lc0819OTHJyWP0+A45SRZPb16Ii88Omu/Erp0f69wXQCk2rvm2QnZXzGg==,iv:zlglY4hcSdw24O+aM/0BR1/1MRXNYwTcSVZJEItQgMg=,tag:PWrT0LCzs7GBcj+CFFqfNQ==,type:str] +git_private_keys: + workstation: ENC[AES256_GCM,data:LZQq96EGcEQsu1hIq0GiPKyfbBXULCXI3umT2NgNJc8YAgYjmfedNZm985GQG+YJeGKYdwlsWnQ59BNc97jQalXGIjvPCI5RAc1bd28VqlUTXZ2ipaHz0nxprgctqMUUSyst18qhumcAdiWT7euInaZiqBhp4xBvIBjK0nMutKfHER/pNV8SYwYPeiKPxB43f6jhKVEYVjItWDsM/C4JvTmwsOvvLUoNMnXtyIKaGDsRhhGSwWcOEj13LWOML6zwB5IUgavvRjKBvnlWy83vH/hFxp1IZNXU4eiePyTAj3Ydne9bmGN1EpF3FyTWZAiWC2uGiML6ZEZUoK94B8mvc8oNwcQPGMzBf0oEBrslWMFOzwItmbNUh5qiVXGUD9a4GiBQzuhPrYX3O0OgFTjveftNcaml4s/qc9MQsiUnYJEIsBVu1959HUS1kEu49LwQzzAIVZQn1dirVaNlq/nbvCv2TYQmgz6v6c/yI7FUDcasjx6hHBUnayGP/xkb0hge6hqGD/T8cZQ8ORKQyj/+R5DvyiHqEtUDNitq,iv:zZOowKGPi7l45djp4IqGdTSf/XDOJACcwpsFGHc8hzQ=,tag:8UQAwcGf3qpDpNoQCVV61A==,type:str] + server: ENC[AES256_GCM,data:88xWCYNz+gaCUw6EV/i1PTCaPUTU+6qGme5O3r2zz+ebCfR/QXIG80W7rehZgQ0I7YfD9eFydOgq8+I21L8LjF+AalREWOUZVxjERtVyjVpABcNspogBUgJCD/7s7A8DwDk92V4fiUQF8C2Sp2adfs8V7ef4IhfLC2xhFOQA3z5YZl7y2CNhYPhl0k+tpUW6yYTSTvccJLlpqzzZCPdBSnkI5pJJ2ftpoh+PG0GIzBeta+Pq3I4YMpprzxogaVwlLGn8AtTWkwwWvJpzeELfE7WLgJ9f/X9N5o4zojjvVelxHDMQayo9oeqpIUrCE+RStdLNrYrvLmq2dGTDc7DgLBon0h3led5hqBOBoY11XqaKiGKL9xwZjWM0cDhzOBgFOY9GC3el68Zri+alSIVNccybmXoM78ZFc0rbo2zYKX3r8wO1umTi1/KvGr6q35GY7AXCkLh/qVpvDc8/4NUdiVnNwPxukZMiNTWHPaaUd71zA+sphaykhzs7ex5UMQPsiF6/unUtP3bIZ4taf0mO,iv:1nx2USITQFqiYcva2f1WOjxwK7iYVsWRpAmgU87Iqqw=,tag:GbnajMHjuZNkGjYZapaOTw==,type:str] + miniserver: ENC[AES256_GCM,data:uhnZ/QmMMT+EmtaRgWDvZEvkf8TewV99zYR639e8K16xII3FM6FfrTF4rr1XwnXrh4xmT6Cr0kgHcPFEel8tUEMWqqlaqD2Vzn7VT/NyveEzCbyZ9GdAP2iMAb/xVdg4TjKxUXKZ8l9k7cDNVKKVkNcEfFQF9eTr84YAs0ZLyX5n+NiYlOcVKq0s3EDEOD5+/x7MdnUtdxOrGG3Ob9fRMfQfTVFwVQ/eMeAQXMAzU9MEcE2xFLaoK2POfu233gMf8E4X9ctt18q7S8DB97K1uhJhEsKiAriNJEyxXsQ+LO4mg1lsKDWr85qa2WoXWnq16kHdVdi1Fw/C3dkHW8NZQ7Eem8nBb9yoNNeYP1/GKFUAv9NA2uZQRGYNdiIA63Vp6Yts3rbJ5reUGrrm+NUMwIy5rC4EoCAYL9tIbYvSlk9QNEpELZniW8wf00uCkdpREMJobgQeTBZII5R4oXNqq28AWEGbEfL8nOspiKdoG6LUKMa5mJTBpmuTBo1EvrYnptf1egjQSvy7aH2WDcQOvuxxUzFmx8bLZ+wq,iv:l7raR36S6EHsuw620ch0q8HuWiyJzJaByyWZUrCLXx8=,tag:xDdJ+LVV3KVIaEjWX1YnjQ==,type:str] + emacs: ENC[AES256_GCM,data:FgJUD7p9MxQVvsz+To0Dx2kJ1WZqyNsX/zqOLAtw7pGCAZRh/FiltTOq6t4/2qJsMuVevaNkri4hUMDMhRReZ1BrPuJZHphdSb9U9JLAywTpDWrfyHdvCwNehWiccoANMz+Hjr3xBh1z7fd9apojMVnF3pAbZj/v3EaPsJzzzyY9I32yHDERXn4yUfuwHWfV/TeodFTV2MMz9Bs2mC5UH9mJhktv6xIn9NhITKWKkKzK4/JNICF9GQfjuDteBfIHmXPNeVfsD4nTle74zBsC2eXfC2Ax1wvvpQzNfrh+B121dWgZzBh0XDOtV7ejjxsN/48HMQCJC2A4XQJXK2IJeEeCz1lZK2dyqT0SMmOaxBHSjamzj9fyo2L0r1iz1vopA7zMRwFTq32x47D7TXWwN1yTSrWhXyT/6/YHqNFWDfuvTHYHF0h51W8zl/KKIjKlJEV2rKIoMjnWzfhPmuB4GRFc967ViKV0LjngpX5ummKIM8MnGY6u4VP4MDRJ/JKh1H3XzWlFBERa4xeNjArmd5cka9eL2tZIzwmh,iv:K7z+vxjyj6IOI/mv31Ngj6iufAHY0EoQPwv9jJyWaC4=,tag:jWSFvIFBGOZfDuqYIhMgFw==,type:str] +certificates: + qbit_cert: ENC[AES256_GCM,data:RQNgCoh/kC/Bi+pamonNaAhniBLD7d5Ilc7YDe02jLnGYWgvtgQCcWflSbnxuLNgIDX1tBEmR7J8hjRyetNF6mQj7z8SmvfG+Mn53qRhiqa+RoSrhL18xtHKjWkNbgwXJtrSFa4g2dMLsqkrp8mK3Xzap2Ge+bCfi8iE17NOd7U/8NwH3ApdjFFz3nmic/gsMZwJE2CvefF4OXLiLl4COeuf+yj6k7C8/e4rP3C418lF3C2HZWwOoTU57LRmfiG3GaTg5mD3Ir1OFC28G4R2MDXh/anSuJEnGQdTgXxQMUa9R8Ec2eCANEwtK7UFvnuLtUEErlJDMuW5h7E3pMXP0iWsqwP5IJrkSDxMwm6TQHlmSx62WhP0wZVGXiIeOdIQgWTgkBPk/3EpkGML9/WH+FAtZ1mhi6YLaRPlSLcKnLd2/YM2JEgq/A52No09BHw15PEMWPrEld2HLdG03MroCazci3shqeVMLk/G/CrXQ7EKUlmvfrR7/6T8/VolyCzezAtmk8LjtWQw3bes/xg+ON+MjHEGAj7H0EkDsZcgbEJZVYEyUI1y75x4TVP+LQpOd7QynlUoj0qkw7QvvMj4j94qAMbAFkTrqk0LwYytcha5A0nwfurMFkTfPGkaAF9TktVtpMCQ/ghCfhWSKAbpuFR0Gpl9Atofs6RfOWXJ4oh0vh3mQNJc4oOQxN+2vlLPjRxVUULNhCTUpffZTaBvbU/gTAKK2XOI54od09YzNwV4oBMS0opg2fi3JA1LFzDDSyCeoA91mq2iWR1NtSwB/T5zRlsnt8dujcNfGPIoyNkjzxaK9hzDdm0Sh80ZGGt6pcibyOCCCuKNt60kgbDGXP58+//Kj0bKp5PTjZz4q1fUVssMQP8cnPte4CZCTgRCrpAlYiPxz58iGo3D0MZrTIcrj/SGaV61m+7W52OXnMPDXHZ2kJ27kdCVK/hDVeBTWqSHg3qYG8AdFG1QSkDS0HkmJ+bQJtXksh36asbDfVBo4I372mI7oYC7o+U/xUDTo3wf3TsP6fzq3jTymripJfcXdNn+3Y7ZfYJTX24eh9oCMTTnlc/HdX3IiYGugcTBpQwSIu0Vx7L1Jz6GpB6hCRzTdvutnH6u+nWOgp5r5s7E3/PTTFFKwY+wxhAauSlhWYoBQcnjnkoW0saLldTpF2rAozCPQuHai/zYvWI0YHmetUJNmYOjxMHcmy/DNohN51ecg6782p4wk5E01LT2+22thAxfAe8jA7Gt87Jxx6fVNb7/r+cPhpciWfOlpbkmLjmLX909HXSekLJa1cq4VIgjJhbGbSty9ooetY4kZSoBosSizxQx5VeNZkjPOvJ/K6QOlDfJAmC5QzJVcgOF7XHSSeeaMdcPWK/TyEGCFBkutsIrYMHefyqH+/InqOco3wUdpvGEWWB8j3DfV89HgKT+Nt95rF+tpOsvt2v2QkzPzULTJ/ZRxJ6i86qJBJZrriKx8t+ns99lmao+aoBa25he6xBAyGVuBwK3eS5fJznGBF2lDg83FOac0KxrcJgOiYNyDwucFMfeY4i1p5X+zALBfVk16XICRRiYjub2+3V2kTQOLaNdPqkQ0DZPaPwwhg2v0WGdOIuAf2iB4bm1T00f1sMPKZ6MtuoXjnYP3E4gTRP9vZAyfB35xOlXmd42fw==,iv:5xKwtvNM1MOwk24m9yl7kEQaTAmFZqHWcE6TkKhmsJI=,tag:ikVouFR7x9cMFoSy/A9c4A==,type:str] + qbit_key: ENC[AES256_GCM,data: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,iv:jTER/Q2JKTeMs33IF65J9/OufVMdMsTtBWNY+CwgigI=,tag:CTB5rasvOtpey21jXtxx3Q==,type:str] +syncthing_certs: + workstation: ENC[AES256_GCM,data:TMcf/3pFwp9fyCIDMIYFlshmDIO1xwHWmSgCBU2TC79EA7XVWXTKabFAGpPWQI43f0Obc3rOIIcIyucJ3z4HexFixhzh4fAg7kZuiIFYau5BmGShng6CVZRWnSb4p/5h0zp9LcLjB0pddReCn+mQCffp0I8rgDA0WjljF7D4ZeAmBqxsMaSKjWRimDJKkC0SXr1owG3J2P15FW/qr/E+KXPzgaz1BCU/yD9yZGfZ+aClEtFZanrWoSQQ3w9AD9aDxQtVKrhviVTNeKHTTyfK6OC004X3FQKLRArjReWGgGeOZoFEv1H2oxofhM46FtlAVK8FyAwUxyg7I+zxM9qnJCGre+mRKpmLJ5l1+zyRKy0rU+axen14MmEFKY+0mgRIgN52x5zxobaOsDebU1UKUiHI/cmp48auCHMjEIsve60wTE+OQLCellE/QiEWWSdVadIjuGqGinmsB66uILW4ACy3HSVXdoB2LMJ1DoeacYlZtBYOHmQpi6JOwpeUqbRy/fxdwkwM4cgBNwnU8vYSmSGGteLGfGUlcjq02iEHegTkHTMChY+YcOrpUczcnwGn2uyBSpmUxERrF01vlx6T7zltDv3VoBal0GzhiJmRfMJF6rWkXa4SwRN3lfR4pl5iDE/cohqVfhmwab1MKib0p6RKmUhZV4cGnUDZGgE1LHISsJZibzOrHiBkuX+O6F89U9wuNRvR3/cMlfbufGVMUq0/2v/TT/FoIgGLgkYC8QYzrRImD+8JEpGTsCOeLj6QfmQO7ik1ATpsR/syXgJ1YCRrIQ7t6QWirPJJO5Xk7w48qCHpfhPDBvTVawBl8M03jsbADYPrHPsw4VfGvmOWoZFpGsN7j4WZ4IhzXy4AF1MpgdmiJvcWJQCmeiNJ0OwxqktTVDAEKJ8Ro9Jgz586PbDZq0mITOQOffRXDc7nsuswf5YxlM1W30Rmj7YTWZ6rRKT1IcN22aEMHdZMsHrncg0DPOvl8uQoeUaCB1kL5rObEykclhoxEfwdumh8PdvMzkoGumToognofwCfo8Nm7b+0L0jG404WvHI=,iv:LWKV1iCuYeAGA3z/NT3MIvDLZnFAEv9xsH3Jme5mge8=,tag:5XE4JBDtdSw/4s8dHD+cNA==,type:str] + server: ENC[AES256_GCM,data:0EKIsh+dE55G2EealykaQnU3UHowKVar1XdrIcohO9q49PrPkikcpKQAeRiVjL6wmEa3l9U1Z4kTvT5lAbIvRDPhEzPE5Mla9lyzp/+7q2tpnyVo420EH9fMiX7yc34PMzCa5D12B6FecHaM/v0lx8SyzzN8U4JUrJlV0Txx1B6TuuDGvJ1s105YEoHsFgy/uPd9HAe/dCLgsirKmC4TFmBXlarDUHz6K6eSPUZOHGVFlWHQWKEKINQMjVnT808N/HO/X7yyUTeaecE0FJ36HaGMRb9mmZKAHSKJr2rrDCupF1oWkNAt5uc/WIraQIb1BqWEAdgdLcUdhbgWkvCd77hxaPtg/60vuoxu73LG4JYockCPzNmlkNbg8gVnevGn+Ughw/1E3FKgjD2/fI2l9m5PXzcxIkZrNigBdzoTdiWIfBMWn9QJ/6uyJO+wd18yzA8G/J/PEeDGJBUIbePHkggX3BNxZztISHvYzRPohnl6MZJw+t1A1jnxUZUprU+nhuFRIdHSZWYfW++ShMf7ygiQDpGE1E/TpmGBM3b80lOgj453nNDMr7PTXYkKt4/r/Ziz4r2P7AgxaFHQKRtRBK6/zu1s20ki1GV3e/8OXnCh2abIwkUjXb6/G2OYNPjumDUc7lAZ08IZjdLhps1ydouTUkFZwrU6kciT/F3CB/KWKaDKQSc2ADHVDQfpJFHV03TEzSW1V2RQY7PY93lUCd2Pc9nNxUOq6EzB8bICE4HdkINmU21UBZJJIMLeNIUxl2TZnulvyh68FshiJcyAaEx9pRYwecZBWidLTFnTCldD76yl995DoTjJIFnOaOtTTZ+4fvDpMNFXTYMA+g4nMOD3MWqleZ3xWFRjyVjGvBOfh19Rq7WYbs4IPWvPkTzP4DsRrCuad54AiS5m5jsoqv0eoVBupPp5AkgxpxhIvTAhmBzTNdWtWSSkID0Ggh+fZstNPOyFnq6ddk8c0NVqd/llFi5hCVavpd0LTNWrkGL4FCdve23b89hIBdpQD9/HvPBmfYT7lembHvJioMd8cEKZDkfIUzrdx5E=,iv:Jq27OW+gIDDzRTieBzVc5QIt6L/C7Z9kURRpbvJOzF4=,tag:hqb1RtYwNecY2PrxF249XQ==,type:str] + miniserver: ENC[AES256_GCM,data:hTCk/BSuh4LukLeqAUHspdPPgf/Q+HEOdq3IqIvXgYnlqiZdmUf2h0qV/bjQoZ2ON7Mfn6xV8UUNBbYDrbqMaTUgG2oDL0+/OKnsGACgmJBUYGsy8oQNlMX4hLQMLEILIpL14LPmRSVejwuvKvIj0hK7b4gSqw4C18igQ9MjEsdBIUktDzjJMpLLuZ7izI5YOd0Ui8d19fNmEi29O4FSBZL/haalVEh5Ppk4lAxlsor7BuwlsNJlxDEp2nFfSMYvP+xe8Fqy1NrxgiT89+CCfUUwvNc2tlTAiMXH7QuInm9Rqwcq9zfLaDFtvVrw1NY6g4qR0sAdyWb/Ue8Mhca2SMFJwkg7+Emoz9HWaLvzg3kqZ2gkKoiQ4m13EIzS4FC/QRqTEXs6TUaeKE244hnA4/DEDY0dvg5MnC10JNHnuk88iVxBI4+O+zfoR0hz2tpOg9vqEqvJMBtOwcHReRvIlcFw2wQVlPl1Zx+611PcHdk86ezcKgwZEjolVuSgGngASxNl8an1KlLELmOaIXsi+vzAOtbPOuCKl+e2Xf5hMOyALKoiBjtHoBxMFbx8e6E4zj3dlqOz+E8+PxwNJFr7tN0a1fgrV14BPn7aJfC4O1YO8Eox9Warb2nDmiVUOz1VJ8wQioBcIOpiexev0uy136ffAqAYYyGhMqKV1ZUE3YNu3+4NfqhXbUVRFmercfN3xAJ6HA4x5UG/pfOrtqASFclCECikerw5extUmI50MYfalrGiYGWNoyfhlalDF21iG25QEiMpDC12ZUU14BQmAUw+3dL/6rkM8FC/n11nmVHHo5BT41P0lL1amk2Z7NLyLvw9uoC8rCVyFsNrULx2kajVtxy+tfexoi3PCMVzCGAwVI+j+3RXybc04NswNpnIqEen3d5wLkwWf8t8KbOwYbxKILQZk6NXVV5tvVUKTrC5qTMt/7O5ZxfENi98y3qEjyI4PVl6AjcvUXEXHRUdfWB3hbCQ21RW7ZwAn/CyEr0GmM6X6zGjxhUtm1hpEPqS63PsMNX8zsq5EN+0vRLgUNHPAFhKdWY3kVo=,iv:G1FSlSGkCGNK40h9rWH+sIHcSdUD3xurlFIp1uVgEqo=,tag:wA1kQRReClKq32jP8Eu6Nw==,type:str] +syncthing_keys: + workstation: ENC[AES256_GCM,data:3uObZ1zMR60gJt57R1b7ikjkShwXmGS7sEhxxyqES3B5pxjNgaD/XYihNTKAyzCHoFrvppzLfvVjfsx8wfWYccvcW6p6MYROSKLlA8SnjUAeiEB+NFFMP3dtqRD3qlJwA3twhfLQJD3AJqe8z0gMhdrar9aKa/iXi5W6VE52priCjjFPGkZGf0PtZDGTrBoNcGp6il898lU5XDZ6+99ywqROAf9vY2KY24NQvScMh80FTOyYGAS4rhvUVFYeHrf2u8ZIQTxV+dPGrXF50Jucc88UBaB9MsAXp7Eis3FBIjAIEx4Q4pPRJdgvuTAB9mT4HUKqzuUCnmCa+YNaFevunfiRBbzMcX+Gea72maQwAbb28EIl21f+xFkRlM0Lkuda,iv:dsxVqh8t48nvfzvQpvZ1qqC/f4hUDsGX+LT0WmGiT5s=,tag:vAOQugrOnJoek/lP1ZGksw==,type:str] + server: ENC[AES256_GCM,data:xyPsIXDzMCDr9Vt30nHODid8RnMOuVmRGoft66/hWawJqrR18Jp7L9YInH3eTXFLKeZEeUPiZDjPpU+jyD0ROc2pdy9edHGYLcWLw1hpZHy4wD6zS9bdD9Wndej1v3JYtU3BJCD+h638az2oSZHDM6JfHuo0+J28pGday8j7s3HJ2zp1LFo1KgIvshXETrCY2dpRr5uSnct3w/82nLWuIw+EzTjt8aKD3GIat5a1gGGYGTL4FQOWXZKhzijccqUF/Db4YKf77z/20ZZVVKu2tx0yP3/WZhQtGViEQBTTof9uBzRlUIDOB7FnTu1GqXBard8riOGLn8ZrScvJE3MUJxbovLTYnl7EcVcQqDMJzJJFs1WSgyanCOU+hT6PV+11,iv:Xa0YmwjFlqVzB62hOKP3CXFmQvuxG8x9ORrA/bw7g6U=,tag:+P5OWmX0H6ZuzLFGOaqHtQ==,type:str] + miniserver: ENC[AES256_GCM,data:wYeBPfbBg9ElClhOTk7eFW/pm+Gwf6io3y/FDGwmJXqZoX+ttyFVPawdamtg6iAnR3OQ18ofZeyTGGY6N9AYNjDd1m9ND+SizfBaiDMEF9QZwSpoRTvzUYo9Cp2sSsgMEaCyC5D9eL3AYFnExCSE+/d8tqiRjH7skml1aq0dE/31Z/202WcBVcFZrvdRxDzD1VNUWrkBl6pAVaLaGMOF7MUEIambEkzEH/abdm8o23KDfjyaXury6BcP8IGfWS5W0uHSLvxJP9DqR9QLSOtatX5my6iHCwDZ54/TPJEjmNQfMpVqdfZhgl0R17pgliKEBYdBrzEGy8/lK18ndWCfx++UAthEJlsc38SkSty7bKYjNzevsa3Bx2RpmRGRWzEu,iv:KGDsNKIHeK+c+9wIoPX7gJfwjNCKQ330ZkPTdfnmIg4=,tag:wD2SLxAhoz9yIgiSwsHiKA==,type:str] +private_cache_keys: + miniserver: ENC[AES256_GCM,data:Qr7TFZodQKUK/v2IcvVtjk2hv7JlPHbztn7pEgxBHeo55Kzj/Dme+iNcF5nt/nrO2kooKPHdXkB6JpcyUh4/1Uv63VDgZ4S10VZaT9ZuretA0uODagaAo12HaKDPn/j6kVCmEKLDqBXZCoI=,iv:Dq6fpnJRRWub1CHAvBcvmtrhE2qglzuhBjsfAEgxpIM=,tag:WF4fXIqm3iVipnJk6fIzFQ==,type:str] + atticd: ENC[AES256_GCM,data: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,iv:mKZpw9Ky4O5hBIWO6VABsPtYAZsKSzcJW6tyrGJA8is=,tag:plmK1HTSxFbq7M+KOT5qKQ==,type:str] +public_cache_keys: + miniserver: ENC[AES256_GCM,data:HttfFZyf+Cs+mMlsF43Kel0Kvivw/ONH8SQukPzPMz/ehdalXS3h4YxExUO+2UYv85DoddSEn5PFRgTwlCX4,iv:9M2/NkRQZII0v1ljlpu3AEZSNRaWv+444EMiex6dums=,tag:l+zHv94Fd2VB2/+KhQ74lQ==,type:str] +sops: + age: + - recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRcXFhSU03M0U4azM5VnJV + UExReVBmRnpNaUx3WDViU2hLalpnbE4wTVFjCkkzQzhlVjcrVndaUmVRNUhmSWZT + RlByQUxSSWtNeDJiTEJMR2JhWG1MM2sKLS0tIC9mUDVhNUtQei9VN3dJdmVBK0Y2 + NDM5SFhNbWp0WWdMYVc4NC9HdHhSR2cKGj8ur7g1F5OTv+XKg5pmFiSMgAcNL3b8 + PjhyPcZqxCB4J8utMf8yxmZkVqbyd3UjZRBUUXSgzg/i1nx0GTGcDA== + -----END AGE ENCRYPTED FILE----- + - recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1V0JUSk9FOUkrSzBmZFNY + M1JlZEMxSFVEV0d3NGttZFFrK0U3MWtlb1RBCjJQbmRGSVQ0M0p0NHdGK1ZHSlNo + TkVHS3lnN3VOUUNjTVI2V1B6bzlDb1EKLS0tIFRtdko2cjkzMlZyV1hRcWFnWFlv + TWVXMlpVUWJIZEhLOVVpblhwZjJDOGsKwgqjQZ1XzQNkFPItT+/gjBNnvxiYHbQ/ + JP/cse3TR7VsC5dq0SGCFY8zPBPiZPvuU+f9Bq9wfJWDG79CintBnQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuaFFlM2M5ZHZIM3FNSEYv + bnlnbG01YWRPcFR1Z2tUNTdvSmdGZ0QrMjNZCkJPemFBYktBWldPWFdyVS9ZOVBv + ZU5zRWpqYXJ4MVVQdFdWcmQ4am5DSkkKLS0tIDNudUpUNnNJUHQyYTM3Y3pwb0FT + VUY1c0ZtWDA0THZ3ekVmUFl4ZjgvaHcKuyh3cIwboc2wxectPk0La0CLRX7VvaBR + XoBMk4PbfQLS1PuaavH+NLNAp3N7LmF9IlZBS3zFW26Dy1viqWbhFw== + -----END AGE ENCRYPTED FILE----- + - recipient: age13w4elx3x6afrte2d82lak59mwr2k25wfz3hx79tny6sfdk66lqjq989dzl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4T3krdSthSnhkVGk5RHg3 + MUVWdXVqM0o3LzZtSzFsZURiSGlLTEd6SlhNCllyaW5BcHZueDRGNlMwWTNaQTNC + bTBMRWFRSG42WVg0cU9CR1F5ZmpTQ1kKLS0tIFdDaGloemJNWUJWcCtOeUhnMmlQ + dklwODNxYVo4a2FaWDJFM0FnV1l3SlUKMnq/MAJRwR7iEri2KomPrMj0gTkMyhzH + P5E4zheU7chJTAz5jf6iecyOvKAt6q5g9Q1MU0D6dkOcv2gzWSNAAw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-09-28T06:56:31Z" + mac: ENC[AES256_GCM,data:T0JfoTOkvdQ/EmQob/Mw535qoi13t1kApYqJozm3+hhSNeQnjB48jYIRSakxyRxKuaRYD2wW4X0RB0yEjZ6qh6nVOIqa+cCYfDystTcmpIQp9MnOi/FtMu2CHpH9+eUoNz4OsSYgP7KU4RVrzQAyI9oeCHsUosE2PXQWB/oqF4I=,iv:LjFxemLlf/wJctXuQfP20i3S1xhPvwszp9jI5BTExb0=,tag:we6NuzJ1T+fbBNnaC7kO8g==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2 diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml new file mode 100644 index 0000000..d2d9ffe --- /dev/null +++ b/secrets/secrets.yaml @@ -0,0 +1,56 @@ +jawz-password: ENC[AES256_GCM,data:j5qya2z9bDESQopcBpLBktyBvIuplbq3Ql4TovdAF1BIJHcf4CAjFuCStW0axFEOST6bgJwhcZZvK4rWUyoS47eaFDp2lkiQnQ==,iv:GNEA8v0NR+PGe4yvlm4V6tTJD5NmlswRPH7JnQJUyLk=,tag:dpxDK88cAJSk+XdFF2mDww==,type:str] +smtp-password: ENC[AES256_GCM,data:KAIn6lp6JXY39SgMPGP3tQ==,iv:Mgmo9bLT3iIGXw6THqJO6+IuPV65VXo1+vE3PrmS44Y=,tag:8urcnZtccaPJSOuHiZAp5A==,type:str] +nextcloud-adminpass: ENC[AES256_GCM,data:g0bnifEbMykPBVwMF14EhT/RWGsnEzJ6sXXmxSJ6kIVDeRr8XVRbFzusxlxAOOlseVwPT6e4Ad8=,iv:Gy0LwUNCw8gnqlwk91qguSEeufIJDtaqNNLX1vZp7vA=,tag:y8H42B1rue0X7/4nG/Whsw==,type:str] +firefly-iii-keyfile: ENC[AES256_GCM,data:HTifd3/5apa9f0RiOh33aRRoVkRskgo/2FV9S01wQSEmKFLg2M9gNNFm6gv2/WCQvNc1,iv:4yLIQQkfqhLixQtAOsbQePNlKOrU2p6Dqw9aLPDoJrM=,tag:uSbAMCy4FWRMU+QhExAE2w==,type:str] +resilio: + host: ENC[AES256_GCM,data:iITbrqpJSdM52A==,iv:8sahhsUA9iIXNlJYKAkakllQDbYVOsGuwBulK9FyvTU=,tag:zKKHwrEFUkl3Fcd0RJcIjw==,type:str] + user: ENC[AES256_GCM,data:31s2ihj2cN9C5Lyr2w==,iv:2MzKiRoDosawbeQ04LUKbfbSVFUUD6uUYynB6B0WNWw=,tag:GR0lXvLZAPof6WE3Verimg==,type:str] + password: ENC[AES256_GCM,data:codFGm4O9QkI2+hbrVK3UqwFWETXyfl9y3Q5lY6UfnIRe/IqWG8Ibly1BUlh7OjKIepXm6m35e6QPioVSiUT5Ll1SIE=,iv:QWqKyKrvm2y2UM2Ir1COxjV0jgU8jTeu9ehnyeXTwCE=,tag:Xtr+r7EphaiLjGwK5gmsMQ==,type:str] +kavita-token: ENC[AES256_GCM,data:kt3bTZNf4S7sKfbxzXc4Q+9yTPFTKzvEaR+mysBhhdnht+FuN9o9i9liqy2pKvB7WQmPnjQ/aYEYkcPSPg0NC5NwE7lNY7kUJtyHzYm2wkKqkkDIc/aI+dHhtX1SBF99ZpWEhmgnIA2HtCpYXUjkl4pUTKgNi0cn+bb1NULMY0zHyF2f7faOOKTWatQEuG1ZvBpiNIbPbsMznfdrWe9VEKrdtMg8IkK138Cn+EOSu0mCHdU=,iv:NCjegkB9/O6xq3fdWqhyVJy5YetqIpcDmD0yyBh3XXQ=,tag:IiqZY0mhqyUHJ61DRNHPlw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvSTFDNHN2cm5UMDkvb3h3 + RUs3aEIrZmlhQ3JvcCtKa09WUkRpZ1o4b3pnCmtiaUJnYUVWcFdpRk9vdmNQRjJT + R1NlMUJnRHQwdGRmQWJrc1NySmhPZW8KLS0tIFhnNmE4bGFUYW5GdVprc09PTTBt + N2VpQU5aeUJuRThyQVFwaEs3QnUwSDgKdgsuwN4/dfAVzXnJ7LPwhUpD8kuh3VxO + vB9iva29YN85E+CKZ7CryGdrnCy1a1fUC0YiAakbzQejon62fK2d5Q== + -----END AGE ENCRYPTED FILE----- + - recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQRnEvNzlxT0dWMDNZOEhS + TVpRSHpGM1JvZ0JQRW4zMXpXL3Rza3NiRVVNClovaGF0Z1hPdXltY3pTaGRKUTY2 + MGJtYmFqaDQ4THRRTE1rUURhR0N1Y1UKLS0tIGtOOUxVNTdFZGZ3TS8zdUJFWWxO + MG1yLzNRaTdmVEJaSnBlbGR0SjR0TlUK7iNC+uyUN3s5T7b1PD+BZ+LvlsKdOpbM + pA2P4ZaUcBXCOEonmG4LnflEyUDXrxBoTkswkpBpG/SowF+yXe0Fwg== + -----END AGE ENCRYPTED FILE----- + - recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwcU05d2R4a3k4Z2VGVlcr + VXJWeUZtWjZuY0lDM2dBNWFxbUxyaUdPVm1RCkxkNjFNbmh6L2ZMeitlY3ZwTEw4 + MUhTVnBLdmRVblFOa09nWTlXVHNIWHcKLS0tIC91aHR5d3JlRDlBWFJtWDNsNFUw + QjhiSVNRMlgwTTAvNmE4SDdQOS8rNVUKIYVulp/SpDmewQkotisfUsSZFh0r1eNB + 59ysWy09dse8Oed9lwMVMLI7B4DBT6CRWuefOU//urI/pB9itV6jvw== + -----END AGE ENCRYPTED FILE----- + - recipient: age13w4elx3x6afrte2d82lak59mwr2k25wfz3hx79tny6sfdk66lqjq989dzl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyazBBS0xKakE0Z0hHRnZo + R0VZUk5qSVF3L2NTb2p6Z29QMnp1MkIrVHowClJVZ3VzUTc4aDVha2tBUE93R2Nw + T29nakxRQkpidzlrdFZQTFlxMXFwOEkKLS0tIGJWRkdJaVpLWXBVNnZUQ2l3dm9Q + RmRyZldlMjUwMEdUUEpDS2JSa2tDTTAKp/pT+0cNnCuKVL+Z0fEMiw1PL9PB/nSM + QWVTo0Mt8Y6X0Xt0EAi9G5AYxADZ/mmEWPxB7RFgVAiMKtor5Gy1zw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-06-29T21:27:25Z" + mac: ENC[AES256_GCM,data:ZmUuxDXxfr6eJcjoC0F2A/JnU+/33jWXjCRWvkWZfduxFayF8bRZNOLgTzXeV//TGNEY38ba/VsTDqOiu0YWRFE7VaQd8xk9uKmzeCi8Djv2fI+TAwXUorrZJ2bUJQ/WCCm7hOQ2OEE1c7icr6YsPTtYC652Itm10FF4PrF+VpI=,iv:vKC/B0cfODXMZ1l2wA0iUaxwZgDwjKPVBekmc/6lSvU=,tag:tE3dmwDjtEEBTPtNM01JQA==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/secrets/ssh/ed25519_deacero.pub b/secrets/ssh/ed25519_deacero.pub new file mode 100644 index 0000000..5e487bc --- /dev/null +++ b/secrets/ssh/ed25519_deacero.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5GaQM4N+yGAByibOFQOBVMV/6TjOfaGIP+NunMiK76 gpodeacerocdreyes@100CDREYES diff --git a/secrets/ssh/ed25519_emacs.pub b/secrets/ssh/ed25519_emacs.pub new file mode 100644 index 0000000..78467ad --- /dev/null +++ b/secrets/ssh/ed25519_emacs.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPBa1lcf7ML1YCUUkHkR5L61kBiKwdco/BJPOdzRiIgH jawz@workstation diff --git a/secrets/ssh/ed25519_galaxy.pub b/secrets/ssh/ed25519_galaxy.pub new file mode 100644 index 0000000..bf25142 --- /dev/null +++ b/secrets/ssh/ed25519_galaxy.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINBEblxSDhWPEo33crSjooeUg4W02ruENxHLmmBqCuIo jawz@galaxy diff --git a/secrets/ssh/ed25519_miniserver.pub b/secrets/ssh/ed25519_miniserver.pub new file mode 100644 index 0000000..c1872c4 --- /dev/null +++ b/secrets/ssh/ed25519_miniserver.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILgKVjMLYdE0u+96Y2RjTh5Pf8f4n0h3oMUG6728YGHw jawz@miniserver diff --git a/secrets/ssh/ed25519_nixminiserver.pub b/secrets/ssh/ed25519_nixminiserver.pub new file mode 100644 index 0000000..3872c36 --- /dev/null +++ b/secrets/ssh/ed25519_nixminiserver.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGrC7sVvDT0is2oq/H1Do99LPaQKvyGMAsrF6/fuf1aP root@miniserver diff --git a/secrets/ssh/ed25519_nixserver.pub b/secrets/ssh/ed25519_nixserver.pub new file mode 100644 index 0000000..3e538d5 --- /dev/null +++ b/secrets/ssh/ed25519_nixserver.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN6HsajaTL+nTJtSIu00M5WJwgt/7fyU59gBr2R7tbnv root@server diff --git a/secrets/ssh/ed25519_nixworkstation.pub b/secrets/ssh/ed25519_nixworkstation.pub new file mode 100644 index 0000000..8c4720c --- /dev/null +++ b/secrets/ssh/ed25519_nixworkstation.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICiyTwryzw8CblPldplDpVUkXD9C1fXVgO8LeXdE5cuR root@workstation diff --git a/secrets/ssh/ed25519_phone.pub b/secrets/ssh/ed25519_phone.pub new file mode 100644 index 0000000..0de904e --- /dev/null +++ b/secrets/ssh/ed25519_phone.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwlQNZ8qrBeesBdjj5NSlgipdp3VaZbzR5cuNtKAFAr jawz@phone diff --git a/secrets/ssh/ed25519_server.pub b/secrets/ssh/ed25519_server.pub new file mode 100644 index 0000000..45e163c --- /dev/null +++ b/secrets/ssh/ed25519_server.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMkpeIV9G26W2/e9PsjBx3sNwPGoicJ807ExRGh4KjhW jawz@server diff --git a/secrets/ssh/ed25519_vps.pub b/secrets/ssh/ed25519_vps.pub new file mode 100644 index 0000000..5295a3f --- /dev/null +++ b/secrets/ssh/ed25519_vps.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPKhVIjdLiqLTgRr/7fsgRpt88kXllrugZyPq0XYVi+z fedora@vps-4dbc770c.vps.ovh.ca diff --git a/secrets/ssh/ed25519_workstation.pub b/secrets/ssh/ed25519_workstation.pub new file mode 100644 index 0000000..7369bd6 --- /dev/null +++ b/secrets/ssh/ed25519_workstation.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICcWnaIRWgH04Rc23afXMcEZnJ7JdmgeO4MfCoKio/gA jawz@workstation diff --git a/secrets/ssh/iqQCY4iAWO-ca.pem b/secrets/ssh/iqQCY4iAWO-ca.pem new file mode 100644 index 0000000..3c806d4 --- /dev/null +++ b/secrets/ssh/iqQCY4iAWO-ca.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUX2YqyhlzNcinNSWEhMVDSKSupTYwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNTAzMDcwNDQ3NDJaFw0yNTA5 +MDMwNDQ3NDJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC4pUxEdL+mC2mmyDFXjsmrj1GVoJyRatyUxwB5dsCZ +6BN2Gr5aN/OtA9cp4ACpIB7ws/X9Yo9rG8FivOZjKEMoOeCQhullDTR9SBZv0D1n +picGUR4BvY+zLj85/Ae73R66LbcW/4o3xjI0WQUckEKfO+rKvB4BsPKqaAbS/o4E +lO6cSp1Gr85OaKzbbGxu9qNPFckcSl8v3+0h2Cspy6Ar/ce1aCA4hwUE/eGl/a8c +F0aWwrHGcJ8vEfuWNnO7iw69SatlKeHf02DBLfUlLsA49CqH2sWNrcRl9cztdPpR +4swgLad9IOpkUTuElHWwGgyAHFX+AGjt9mYL1U9HYV6dAgMBAAGjUzBRMB0GA1Ud +DgQWBBRWylAAyAkrCqEPl0Hmm+36UGAJxjAfBgNVHSMEGDAWgBRWylAAyAkrCqEP +l0Hmm+36UGAJxjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAe +2Nt+9meMDKhnYz5tW3Fr0V+05p8kp3k60gfsl20G7oZplY2ExwnbrmtzJeTbqZBY +vcHWC/80cjdJpnO55oReBBNEyIySBwovltQFoxV4bGzAyCJfi3RJX2uSIT9OaiIz +N2RfYDEMAMAazHjt0M5qBaabxk3baryusaDOnQjeCqTWQ6Xk/G3uMwsHX7Nk1iqX +FtXlvo/2e1iGhbq8m/m47U6xFUolivC+3R0oiKLJ5TQmZjCtNxMnOgYgSSitWHpm +Z74sSfIOutk7tpji8UdRxRMW4JrKN0bKEt0OeTOUsne3ItONEX+eioMhhV8KCK62 +YlSncAEzWKi6Jmg2dZ38 +-----END CERTIFICATE----- diff --git a/secrets/ssh/root-private-ca.pem b/secrets/ssh/root-private-ca.pem new file mode 100644 index 0000000..1300954 --- /dev/null +++ b/secrets/ssh/root-private-ca.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFmzCCA4OgAwIBAgIUPBgrOAnSgT+y9+zaFaCuVkwi/M4wDQYJKoZIhvcNAQEL +BQAwXTELMAkGA1UEBhMCTVgxEjAQBgNVBAgMCVNvbWVTdGF0ZTERMA8GA1UEBwwI +U29tZUNpdHkxEDAOBgNVBAoMB0phd1pEZXYxFTATBgNVBAMMDEphd1ogUm9vdCBD +QTAeFw0yNTA3MTYxOTMxMTBaFw0zNTA3MTQxOTMxMTBaMF0xCzAJBgNVBAYTAk1Y +MRIwEAYDVQQIDAlTb21lU3RhdGUxETAPBgNVBAcMCFNvbWVDaXR5MRAwDgYDVQQK +DAdKYXdaRGV2MRUwEwYDVQQDDAxKYXdaIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDwcWfnMDBzdukPZUa0pbY3tHG2ONEZMDUsxo5T5veq +KrMfsu7U9tE8AY+AVl0Qz9hpBHN+GmktXQlimPkm4tSVKJMjk0iWYgZn8tTMB+AL +i3gl/bt7qP+59U7gQbojkp6B0xCMCynPlsgcMiIcZWFmNVrG6ehh4B+wuG52gWVw +TrwhDjHhxsrc66DkgC/59Pm60JqHlBhuhv9HB/q9JM3HLQ63XUwhvTVJ29tSiJZl +WpKFr5s8nfE2FIXIHzi+o+Lo3n9wvdCzNfaRUStLWbROzF97jY4VIxIDk/loQH4T +6oXBGlRe8M+G1XL/waRDySxL26jRVG8bUEv4mh/Hd9Rs0JcUOl6lFiGndJMjMyom +ZgAlhi2Id2AzkT28utdYQqKUuaTy1SwLkrcOu9k2/dw7Uf7aK5WCraOth5ys+lw+ +mzga4gNGc3Am9soFHjI56Qxvhf+Aa5tlASwpzrjsc7PJEZJXorE40uZsB/q1PafP +AIqVsSoT+Q6h6bld0EuQ5W4i1LTipZEPUaF673tGCXuI40AeTI44SFKcGm9XG1ic +I25OxuIKyl5sCANkryOHjNKY4SkzXKSpML3PYbfSKK7xDpeFofIYKnRfJm4qmBNd +lKT+ti4Hnvr8NZDRWyxC5SIDF1fdkslNu/HoAoL8JdXPYnitlTL7A5mF5PVPHom7 +XwIDAQABo1MwUTAdBgNVHQ4EFgQUhquhsVpNS4shC+7DMxOK4/wYYEswHwYDVR0j +BBgwFoAUhquhsVpNS4shC+7DMxOK4/wYYEswDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEAU8nSV6DqCZSDxWpa8JSBmZFnO2oZIRF9Nw/1QcpMOGUR +pnWyQ03QtEgXYMwvxN/FOcGvYwg0LyYy07rzlpe5n2wRBaTrPCZ928f5j0nhADjC +GYutxhbO4WYvBKUY88qYCrJRa1Aw1B/CsGCmH5f+aND6fyxZ6Lx9CQ8O43f+QCOE +ltkbHRvjxYyVpDkgccDwetMDURKKrzkibUskeCPt0TjZbLKUq/cDspdAjSJgIJrz +a50JbniKUG5Qcav3P2aA6NluOKFJfYh+146uafC6WofUtx2Vv5lViYMlIDnqN4L0 +xUzN5hB1kwF+4v1PO9/olafKqmgZ8FD/ipMYq2aYX4u9RJHLD6hMPUJpgKPRhGfi +ul9rYv6rC+pQNIn4s287sAPru5IgIzPBBCbqXSkoue7V/mpqRuZZRX84V6CzlYDc +0knoG2TL6aEWO+vj1mROgOuagyqyb3NZvgySE7GieW4tdvZhdYJJxdXh/tBQCg9E +iVcQH0rNJ+0jsybFWPqdOIZ6sH78SvY+J4KhqZ3Il/WCxCTs/Ccb/RMkhRm+bfSX +1FxoKF20b3RJ6g9N1oOj+12oK8jwMpUbaG/oAZh0TgZf1FUKic2f6jhMZLus8fGe +nyHza9mHbN1M8d9hX7U3gkepY8RVhSNL5erNp1zsBtZ4UNmouGm53wgjYZPYkrc= +-----END CERTIFICATE----- diff --git a/secrets/wireguard.yaml b/secrets/wireguard.yaml new file mode 100644 index 0000000..602174b --- /dev/null +++ b/secrets/wireguard.yaml @@ -0,0 +1,52 @@ +wireguard: + private: ENC[AES256_GCM,data:wwggc9T88gK/EMmjPauf14DZGUnfipBpfN3FnlPhsO6FtVmK2aad/D0/Rqw=,iv:Q15iiEOFRa3bPf7NfZcEZOgEqnjIJPenYgE6c6HRYI8=,tag:x+auLhc/FDhxZxzWmcrX9Q==,type:str] + public: ENC[AES256_GCM,data:uelp1opnLR5EfvNBSA3Sk33ktMoG6+Pvj7oKYtdlCpXMZel9O8G7P4X5S2M=,iv:AQECJmnXSc2MM0pT8ZJtA51pn+tvhhyAxFDMBH/H6wA=,tag:yWsnQbHaeiXyPLbpxMZwsg==,type:str] +vps: + server: + private: ENC[AES256_GCM,data:wrP/069tuQs3ObYE8Q0MNVxe3+4vZ2HIImoIdZpj1uPgdBknboX1wmANv/k=,iv:FJL5KumHos8PoXra+BB2Uc6YedsF6MD3wWyuugXzJ+E=,tag:nVuTrW2P7JvnWnv6H1SmdQ==,type:str] + public: ENC[AES256_GCM,data:YnKOf9725v9FkzdNPDVf/iinMbY/YWn6ksqEz+mpB4KHVlOvpbV6vLSKRcs=,iv:aWQNy6mT4sxVbzaXKgRzZ9XVsiBCRsOlLORRqC+uiKE=,tag:mLWv6mr3VVfw0J5BrqByXg==,type:str] + home: + private: ENC[AES256_GCM,data:YZ0jvBzkMv8Bwc9u3LDJzwSqQvPj8wPUxTIeBFiLYVQQIBjm8aS1dTYuPvo=,iv:mXuW7TVERxOMmGIit3a7Spmbk/EgYuGkO66AWJUnMF0=,tag:xM7C3F3JCiud/A9yPD5ydQ==,type:str] + public: ENC[AES256_GCM,data:DcwAHhHjIxFqRL5h7p/0nkFnWiI/iqR8Fws6AuFaxjgUHKYd/6l3D6q/O/0=,iv:bBJ0bsKRiGQUSlRmHqeLQWkOIUNfG5VVpuV6MOtKZO0=,tag:harMG6GDIfclmSq3D36bTw==,type:str] +sops: + age: + - recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlTXplR3BHYzl1bmxuSzlW + ZVQvTlg2amFnMCtTKzRoZXNYaXBNcmRyWGhZCmpLT1NqbGRtUFpxUzlTMFdYemRJ + ZXF6c2dhOG9LbXVkczU0N1RVK1lqajAKLS0tIHFmQ0FrbVQ2QldiUS9oT2J2RkU0 + N0pFQ095Uzdid2NmZXRVZ2l6N285bFUKG52XE8nf9GfESCfNfoP6L8GxLfvrihs4 + CaZSkRzkuZUsfBND0B2BX/UlrjVHWPQCYMqqTtMpLXoRSmRsvWYCTA== + -----END AGE ENCRYPTED FILE----- + - recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPdWpKeU90cTV6blNZckt0 + a2hpWms2b1ZuKzEwZUZFbEp0bFlPellVaHdVCkF5RENObjMvalJNc2FNYXk1UUxR + anE0SUI5ZWY5ZUlteVArSVN4T01DS2MKLS0tIEpDWDkzWm1mampQZDkwRCt5STVk + RHg4UklFQUp1KzFWRnpDOEIzRVJWZ2sKyS6bXtqJ3J7FrCyTa16Ithy2JS4HdkOg + NzTn/6RL+F61PLDGvEEa7Ypk/OGIjfJYxDQ5Sd9LODja47jIK5T6Aw== + -----END AGE ENCRYPTED FILE----- + - recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBueWZlTThKV1d5UEpJUVBE + SlFDMmFYSVREWXVvaDZYWk5TYXFRdTlpeVFZCnM4K3FYNk9hZ3R1K3c3Y0lURzZx + ZXdsWFNNSSt1VUtZdmRUUFdEK3BEdUkKLS0tIHB6ckZPMUkyM0ljK0RScWJSQlIz + UzVRQ3JzS1Q3N3EzTkhpNDZwZEtPbm8K0BzKOk9ljAnc5eydHfNha/QPfq9Eltfb + X/pNFkeW/b6FgLwo+3pc+NfgOFvpOuq7/bRWUCxGSJP/4w9+9q1a6A== + -----END AGE ENCRYPTED FILE----- + - recipient: age13w4elx3x6afrte2d82lak59mwr2k25wfz3hx79tny6sfdk66lqjq989dzl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkV1Fsb3FMZGxGZ1A5dk9y + SllKMjZRby9KNzhVSUVpODh0MW1Ya1JzdzBjCjZmQUFoaCtTSS9ybE1hVjExaFVR + bWlKcFdlQmRIdEJrUE5jKzRlNFdQTVEKLS0tIEtMOW8xb2hLOGluMnVDaWxFMXQw + KzZFSWprL0l0MDdVdEVKbEV5eklZdTAK/1ZyGvElfp+LVloSR6aJUtvrgU0CrzaJ + SQtO7vc4oDedkiTz6LKySta+uyn3e17Jzdyy9nU2D/Q5X+CpKGP3cg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-09-08T00:14:52Z" + mac: ENC[AES256_GCM,data:O2herKRy4k9ZMuPzzPF5QlBC2isXdRoIsbYLJ/6X7esxtxxgNuAljx4SCR6UMT7pl3G2E33cnnBEkuAIy6SMXOaZNfOuAEJXaCwpRwCXu26lrcTf6n7UdP36GWfIRsR4utD5/vv66ch6MqmQWkW7E5zydy5dOv+BJ4XS/50OUQs=,iv:TscYNQaeI+mBxyobxI1O4wUzRtA27pvjXz27kqMJhA0=,tag:zx/xrYAWJCxYz5HRTKzYfQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.10.2