Compare commits
34 Commits
2da1278b37
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2910dcb3ef | ||
|
|
8d62cffc8e | ||
|
|
7670f2fa94 | ||
|
|
b5c7024ea4 | ||
|
|
6d29835303 | ||
|
|
67119653b5 | ||
|
|
f95cf4a546 | ||
|
|
dc94b8fc44 | ||
|
|
b46e2a6269 | ||
|
|
fc62d7ab32 | ||
|
|
e0aa2b337e | ||
|
|
4fb24672bf | ||
|
|
81318b3fb1 | ||
|
|
ae1f68b105 | ||
|
|
b7a38d7634 | ||
|
|
6cd22f0448 | ||
|
|
9c73be46ac | ||
|
|
293f0a3096 | ||
|
|
d8606ad2ed | ||
|
|
7671ec686f | ||
|
|
5ed2ece05c | ||
|
|
2b1424cfd2 | ||
|
|
661629924e | ||
|
|
d7191f7a02 | ||
|
|
480c9a2a07 | ||
|
|
5e2e2ab29b | ||
|
|
b36c452c3a | ||
|
|
95c6cefd24 | ||
|
|
a8dda9d32d | ||
|
|
7a5f577806 | ||
|
|
a7482ee146 | ||
|
|
5382bf7251 | ||
|
|
ead7e5a379 | ||
|
|
416e8a4edc |
@@ -14,3 +14,8 @@ trust_level = "trusted"
|
|||||||
[mcp_servers.nixos-mcp]
|
[mcp_servers.nixos-mcp]
|
||||||
command = "nixos-mcp"
|
command = "nixos-mcp"
|
||||||
cwd = "/home/jawz/Development/NixOS"
|
cwd = "/home/jawz/Development/NixOS"
|
||||||
|
|
||||||
|
[mcp_servers.nixos]
|
||||||
|
command = "nix"
|
||||||
|
args = ["run", "github:utensils/mcp-nixos", "--"]
|
||||||
|
startup_timeout_sec = 300
|
||||||
|
|||||||
@@ -5,20 +5,30 @@ on:
|
|||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
paths:
|
paths:
|
||||||
- 'scripts/**'
|
- 'scripts/**'
|
||||||
- 'docs/**'
|
- 'scripts/mcp-server/**'
|
||||||
|
- 'parts/packages.nix'
|
||||||
|
- 'flake.nix'
|
||||||
|
- 'flake.lock'
|
||||||
- '.gitea/workflows/mcp-tests.yml'
|
- '.gitea/workflows/mcp-tests.yml'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'scripts/**'
|
- 'scripts/**'
|
||||||
- 'docs/**'
|
- 'scripts/mcp-server/**'
|
||||||
|
- 'parts/packages.nix'
|
||||||
|
- 'flake.nix'
|
||||||
|
- 'flake.lock'
|
||||||
- '.gitea/workflows/mcp-tests.yml'
|
- '.gitea/workflows/mcp-tests.yml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
mcp-tests:
|
mcp-tests:
|
||||||
runs-on: nixos
|
runs-on: nixos
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ${{ github.workspace }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Run MCP lint/format/tests via nix-shell
|
- name: Run MCP lint/format/tests via nix-shell
|
||||||
run: ./scripts/mcp-server/run-tests.sh
|
run: |
|
||||||
|
nix run .#mcp-tests
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ keys:
|
|||||||
- &devkey age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
- &devkey age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
||||||
- &workstation age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
- &workstation age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
||||||
- &server age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
- &server age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
||||||
- &vps age1ml3smrs5mwz4ds84gk0eyss86nwsmp07qh0npxsuae7lfwwpsghssavytw
|
- &vps age1v2ahkl759cftpcdq4mla2cvmgz4jlnmgj7qtgc9732zxrfvxf3lq76zjpr
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: secrets/secrets.yaml$
|
- path_regex: secrets/secrets.yaml$
|
||||||
key_groups:
|
key_groups:
|
||||||
|
|||||||
230
README.org
230
README.org
@@ -6,198 +6,72 @@
|
|||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
This repository contains my personal NixOS configuration flake, managing
|
This repository is a NixOS configuration flake with a local MCP server
|
||||||
multiple hosts with a modular approach. Designed the configuration for a
|
(`nixos-mcp`) that helps Codex CLI work with the repo’s documentation and
|
||||||
self-hosted infrastructure with services and development environments.
|
maintenance workflows. The README focuses on how to use the MCP server and
|
||||||
|
how the repo is structured.
|
||||||
|
|
||||||
* Architecture
|
* MCP Server (nixos-mcp)
|
||||||
|
|
||||||
** Hosts
|
** What it is
|
||||||
- =workstation= :: Main development machine with GNOME desktop
|
Local-only MCP server that exposes repo documentation helpers over stdio so
|
||||||
- =server= :: Primary server with containerized services
|
Codex CLI can read the constitution, playbooks, and reference map without
|
||||||
- =miniserver= :: Secondary server for additional services
|
manual navigation.
|
||||||
- =galaxy= :: Minimal configuration host
|
|
||||||
- =emacs= :: Development VM for Emacs configuration
|
|
||||||
|
|
||||||
** Key Features
|
** Tool Catalog
|
||||||
- Modular configuration system
|
- =show-constitution= :: Open =docs/constitution.md=
|
||||||
- SOPS-based secrets management
|
- =list-playbooks= :: List =docs/playbooks/=
|
||||||
- Container orchestration with Podman
|
- =show-reference= :: Open =docs/reference/index.md=
|
||||||
- Automated builds and caching
|
- =search-docs= :: Search the docs set
|
||||||
- Multi-language development environments
|
- =list-mcp-tasks= :: Show MCP tasks from =specs/002-mcp-server/tasks.md=
|
||||||
- Self-hosted service stack
|
- =sync-docs= :: Check tool catalog vs. docs anchors
|
||||||
|
|
||||||
* Quick Start
|
** Quick Start (new users)
|
||||||
|
|
||||||
** Prerequisites
|
|
||||||
- NixOS 23.05 or later
|
|
||||||
- SOPS configured with age keys
|
|
||||||
- SSH keys for remote builds
|
|
||||||
|
|
||||||
** Initial Setup
|
|
||||||
#+BEGIN_SRC bash
|
#+BEGIN_SRC bash
|
||||||
# Clone the repository git clone <repository-url> /home/jawz/Development/NixOS
|
# Enter the MCP dev shell (includes codex + nixos-mcp)
|
||||||
cd /home/jawz/Development/NixOS
|
nix develop .#mcp
|
||||||
|
|
||||||
# Install dependencies nix flake update
|
# Run the MCP server (stdio mode)
|
||||||
|
nixos-mcp
|
||||||
# Build and switch to configuration sudo nixos-rebuild switch --flake
|
|
||||||
.#<hostname>
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
Configure Codex CLI to use a local stdio MCP endpoint and allowlist
|
||||||
|
=nixos-mcp= in =.codex/requirements.toml=. The dev shell sets
|
||||||
|
=CODEX_HOME=.codex= for a repo-local Codex config.
|
||||||
|
|
||||||
** Development Environment
|
** Reference
|
||||||
#+BEGIN_SRC bash
|
Detailed invocation notes live in =docs/reference/mcp-server.md=.
|
||||||
# Enter development shell for specific language nix develop .#<language>
|
|
||||||
|
|
||||||
# Available languages: python, rust, go, haskell, javascript, julia, zig, sh,
|
* Repository Structure
|
||||||
cc, nix
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
* Configuration Structure
|
** Docs and Guidance
|
||||||
|
- =docs/constitution.md= :: AI constitution (authoritative rules)
|
||||||
|
- =docs/reference/index.md= :: Reference map
|
||||||
|
- =docs/reference/mcp-server.md= :: MCP server reference
|
||||||
|
- =docs/playbooks/= :: Repeatable workflows
|
||||||
|
- =specs/002-mcp-server/= :: MCP feature plan + tasks
|
||||||
|
|
||||||
** Core Configuration
|
** MCP Server
|
||||||
- =config/base.nix= :: Common system configuration
|
- =scripts/mcp-server/= :: Python MCP server implementation, tests, and CLI
|
||||||
- =config/jawz.nix= :: User and SSH configuration
|
- =modules/dev/mcp.nix= :: Dev shell and optional global install
|
||||||
- =config/stylix.nix= :: Theming configuration
|
|
||||||
- =config/schemes.nix= :: Color scheme definitions
|
|
||||||
|
|
||||||
** Host Configurations
|
** Flake Parts
|
||||||
- =hosts/<hostname>/configuration.nix= :: Host-specific settings
|
- =parts/core.nix= :: Shared library + base composition
|
||||||
- =hosts/<hostname>/hardware-configuration.nix= :: Hardware-specific config
|
- =parts/hosts.nix= :: Host definitions
|
||||||
- =hosts/<hostname>/toggles.nix= :: Feature toggles
|
- =parts/packages.nix= :: Package outputs
|
||||||
|
- =parts/devshells.nix= :: Dev shells (including MCP)
|
||||||
|
|
||||||
** Modules
|
* Flake Inputs (high level)
|
||||||
- =modules/apps/= :: Application packages and configurations
|
|
||||||
- =modules/dev/= :: Development environment modules
|
|
||||||
- =modules/servers/= :: Self-hosted service configurations
|
|
||||||
- =modules/services/= :: System service configurations
|
|
||||||
- =modules/scripts/= :: Custom scripts and utilities
|
|
||||||
- =modules/shell/= :: Shell and terminal configurations
|
|
||||||
|
|
||||||
* Services
|
** Core Inputs
|
||||||
|
- =nixpkgs= (25.11) and =nixpkgs-small= (25.11-small)
|
||||||
** Core Services
|
- =nixpkgs-unstable= (rolling)
|
||||||
- PostgreSQL 17 :: Database backend
|
- =flake-parts= (structure)
|
||||||
- Nginx :: Reverse proxy and web server
|
- =home-manager= (user configs)
|
||||||
- Podman :: Container runtime
|
- =stylix= (theming)
|
||||||
- Syncthing :: File synchronization
|
- =sops-nix= (secrets integration)
|
||||||
- WireGuard :: VPN connectivity
|
- =nur=, =nix-gaming=, =hyprland= (extra packages)
|
||||||
|
- Content inputs: =wallpapers=, =fonts=, =qbit_manage=
|
||||||
** Self-Hosted Applications
|
- Repo inputs: =jawz-scripts=, =prem2resolve=, =lidarr-mb-gap=
|
||||||
- Nextcloud :: File sharing and collaboration
|
|
||||||
- Gitea :: Git repository hosting
|
|
||||||
- Jellyfin :: Media server
|
|
||||||
- Plex :: Media streaming
|
|
||||||
- Sonarr/Radarr/Lidarr :: Media management
|
|
||||||
- Vaultwarden :: Password manager
|
|
||||||
- Homepage :: Service dashboard
|
|
||||||
- And more...
|
|
||||||
|
|
||||||
* Development
|
|
||||||
|
|
||||||
** Available Development Shells
|
|
||||||
The configuration provides development shells for my favorite programming
|
|
||||||
languages:
|
|
||||||
|
|
||||||
#+BEGIN_SRC bash
|
|
||||||
# Python development nix develop .#python
|
|
||||||
|
|
||||||
# Rust development nix develop .#rust
|
|
||||||
|
|
||||||
# Go development nix develop .#go
|
|
||||||
|
|
||||||
# JavaScript/Node.js development nix develop .#javascript
|
|
||||||
|
|
||||||
# Haskell development nix develop .#haskell
|
|
||||||
|
|
||||||
# Julia development nix develop .#julia
|
|
||||||
|
|
||||||
# Zig development nix develop .#zig
|
|
||||||
|
|
||||||
# Shell scripting nix develop .#sh
|
|
||||||
|
|
||||||
# C/C++ development nix develop .#cc
|
|
||||||
|
|
||||||
# Nix development nix develop .#nix
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** Adding New Modules
|
|
||||||
1. Create module file in appropriate directory under =modules/=
|
|
||||||
2. Add module to =modules/modules.nix= if needed
|
|
||||||
3. Enable module in host configuration or toggles
|
|
||||||
|
|
||||||
** Adding New Hosts
|
|
||||||
1. Create host directory under =hosts/<hostname>/
|
|
||||||
2. Add =configuration.nix= and =hardware-configuration.nix=
|
|
||||||
3. Add host to =flake.nix= outputs
|
|
||||||
4. Create =toggles.nix= for feature management
|
|
||||||
|
|
||||||
* Secrets Management
|
|
||||||
|
|
||||||
** SOPS Configuration
|
|
||||||
Manage secrets using SOPS with age encryption:
|
|
||||||
|
|
||||||
- =secrets/secrets.yaml= :: Main secrets file
|
|
||||||
- =secrets/keys.yaml= :: SSH and encryption keys
|
|
||||||
- =secrets/env.yaml= :: Environment variables
|
|
||||||
- =secrets/wireguard.yaml= :: VPN configuration
|
|
||||||
- =secrets/certs.yaml= :: SSL certificates
|
|
||||||
|
|
||||||
** Adding New Secrets
|
|
||||||
#+BEGIN_SRC bash
|
|
||||||
# Edit secrets file sops secrets/secrets.yaml
|
|
||||||
|
|
||||||
# Add new secret sops -i -a 'new-secret: "value"' secrets/secrets.yaml
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
* CI/CD
|
|
||||||
|
|
||||||
** GitHub Actions
|
|
||||||
The repository includes automated workflows:
|
|
||||||
|
|
||||||
- =weekly-build-cache.yml= :: Weekly builds and cache updates
|
|
||||||
- =build-schemes.yml= :: Color scheme builds
|
|
||||||
|
|
||||||
** Build Cache
|
|
||||||
Builds are automatically cached using Atticd for faster rebuilds.
|
|
||||||
|
|
||||||
|
|
||||||
* Customization
|
|
||||||
|
|
||||||
** Theming
|
|
||||||
The configuration uses Stylix for theming. Define color schemes in
|
|
||||||
=config/schemes.nix= and can set them via the =config/stylix.nix= file.
|
|
||||||
|
|
||||||
** Adding New Services
|
|
||||||
1. Create service module in =modules/servers/=
|
|
||||||
2. Add service configuration
|
|
||||||
3. Enable service in host toggles
|
|
||||||
4. Add to homepage if needed
|
|
||||||
|
|
||||||
** Custom Scripts
|
|
||||||
Scripts are in =modules/scripts/= and toggle them per host.
|
|
||||||
|
|
||||||
* Troubleshooting
|
|
||||||
|
|
||||||
** Common Issues
|
|
||||||
|
|
||||||
*** Build Failures
|
|
||||||
- Check flake inputs are up to date: =nix flake update=
|
|
||||||
- Verify all required secrets are present
|
|
||||||
- Check host-specific configuration
|
|
||||||
|
|
||||||
*** Service Issues
|
|
||||||
- Check service status: =systemctl status <service>=
|
|
||||||
- View logs: =journalctl -u <service>=
|
|
||||||
- Verify firewall rules
|
|
||||||
|
|
||||||
*** Development Environment
|
|
||||||
- Rebuild development shell: =nix develop .#<language>=
|
|
||||||
- Check available packages: =nix search nixpkgs <package>=
|
|
||||||
|
|
||||||
** Getting Help
|
|
||||||
- Check NixOS documentation
|
|
||||||
- Review module documentation
|
|
||||||
- Check service-specific documentation
|
- Check service-specific documentation
|
||||||
|
|
||||||
* Maintenance
|
* Maintenance
|
||||||
|
|||||||
@@ -116,5 +116,28 @@ in
|
|||||||
base0F = "#dc143c"; # crimson
|
base0F = "#dc143c"; # crimson
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
punk = mkScheme {
|
||||||
|
color = "red";
|
||||||
|
polarity = "light";
|
||||||
|
image = "${wallpapers}/punk.jpeg";
|
||||||
|
base16Scheme = {
|
||||||
|
base00 = "#f7f3ee";
|
||||||
|
base01 = "#efe6dc";
|
||||||
|
base02 = "#e1d3c6";
|
||||||
|
base03 = "#c8b2a0";
|
||||||
|
base04 = "#a18673";
|
||||||
|
base05 = "#6e5646";
|
||||||
|
base06 = "#3f2f28";
|
||||||
|
base07 = "#1a1512";
|
||||||
|
base08 = "#c7423a";
|
||||||
|
base09 = "#d28b61";
|
||||||
|
base0A = "#c9a24c";
|
||||||
|
base0B = "#7d8b6a";
|
||||||
|
base0C = "#5f8f8a";
|
||||||
|
base0D = "#4f6a86";
|
||||||
|
base0E = "#8a5b6a";
|
||||||
|
base0F = "#8b5a3c";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ let
|
|||||||
schemesFile = import ./schemes.nix {
|
schemesFile = import ./schemes.nix {
|
||||||
inherit pkgs inputs;
|
inherit pkgs inputs;
|
||||||
};
|
};
|
||||||
scheme = schemesFile.schemes.space;
|
scheme = schemesFile.schemes.punk;
|
||||||
cfg = config.my.stylix;
|
cfg = config.my.stylix;
|
||||||
gnomeEnabled = config.services.desktopManager.gnome.enable;
|
gnomeEnabled = config.services.desktopManager.gnome.enable;
|
||||||
in
|
in
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ config.services = {
|
|||||||
- VPS enrollment flow: The vps host generates its own key on first boot, then operators enroll the public key, re-encrypt secrets, and redeploy. Follow `docs/playbooks/enroll-vps.md`.
|
- VPS enrollment flow: The vps host generates its own key on first boot, then operators enroll the public key, re-encrypt secrets, and redeploy. Follow `docs/playbooks/enroll-vps.md`.
|
||||||
|
|
||||||
## Module Categories and Active Hosts
|
## Module Categories and Active Hosts
|
||||||
- Module categories: apps, dev, scripts, servers, services, shell, websites, network, users, nix, patches. Factories sit in `modules/factories/` and are imported explicitly.
|
- Module categories: apps, dev, scripts, servers, services, shell, websites, network, users, nix. Factories sit in `modules/factories/` and are imported explicitly; patch artifacts live at the repo root in `patches/`.
|
||||||
- Active hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`. Host roles and secure status are defined in `hosts/<name>/configuration.nix` and toggles in `hosts/<name>/toggles.nix`.
|
- Active hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`, `vps`. Host roles and secure status are defined in `hosts/<name>/configuration.nix` and toggles in `hosts/<name>/toggles.nix`.
|
||||||
|
|
||||||
## Precedence and Conflict Resolution
|
## Precedence and Conflict Resolution
|
||||||
- Precedence: This constitution is authoritative for AI. Human docs must be updated to match. If conflicts are found, align human docs to the constitution and log the resolution in `specs/001-ai-docs/research.md`.
|
- Precedence: This constitution is authoritative for AI. Human docs must be updated to match. If conflicts are found, align human docs to the constitution and log the resolution in `specs/001-ai-docs/research.md`.
|
||||||
|
|||||||
25
docs/playbooks/add-wireguard-peer.md
Normal file
25
docs/playbooks/add-wireguard-peer.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Playbook: Add WireGuard Peer (Friend or Guest)
|
||||||
|
|
||||||
|
## When to use
|
||||||
|
- Adding a new WireGuard peer in the friends (10.8.0.0/24) or guests (10.9.0.0/24) subnet.
|
||||||
|
- Updating firewall rules to allow access to specific ports for that peer.
|
||||||
|
|
||||||
|
## Inputs
|
||||||
|
- Peer name (e.g., `friend5`, `guest2`)
|
||||||
|
- Peer public key (WireGuard)
|
||||||
|
- Peer IP address (e.g., `10.8.0.6` or `10.9.0.3`)
|
||||||
|
- Access scope (ports/services the peer should reach)
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
1. Add the peer IP to `my.ips` in `modules/modules.nix`.
|
||||||
|
2. Add the peer to the VPS WireGuard peers list in `modules/services/wireguard.nix`.
|
||||||
|
3. If the peer is a guest/friend, ensure `allowedIPs` includes the relevant subnets in `hosts/server/configuration.nix`.
|
||||||
|
4. Add or adjust VPS firewall rules in `hosts/vps/configuration.nix` (`networking.firewall.extraForwardRules`) to allow the requested ports.
|
||||||
|
5. Rebuild both hosts:
|
||||||
|
- `nixos-rebuild switch --flake .#vps`
|
||||||
|
- `nixos-rebuild switch --flake .#server`
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
- On VPS: `sudo wg show`
|
||||||
|
- On VPS: `sudo nft list ruleset | rg -n "<peer ip>|<port>"`
|
||||||
|
- From peer: confirm access to allowed endpoints (HTTP/TCP/ICMP as defined).
|
||||||
@@ -11,13 +11,14 @@
|
|||||||
- network → `modules/network/` (networking rules, firewall helpers)
|
- network → `modules/network/` (networking rules, firewall helpers)
|
||||||
- users → `modules/users/` (user-related options)
|
- users → `modules/users/` (user-related options)
|
||||||
- nix → `modules/nix/` (Nix configuration and helpers)
|
- nix → `modules/nix/` (Nix configuration and helpers)
|
||||||
- patches → `patches/` (patch artifacts referenced by modules)
|
|
||||||
- factories → `modules/factories/` (`mkserver.nix`, `mkscript.nix` shared helpers)
|
- factories → `modules/factories/` (`mkserver.nix`, `mkscript.nix` shared helpers)
|
||||||
|
## Root Directories
|
||||||
|
- patches → `patches/` (patch artifacts referenced by modules)
|
||||||
|
|
||||||
## Auto-Import Rules
|
## Auto-Import Rules
|
||||||
- Source: `modules/modules.nix` uses `inputs.self.lib.autoImport` to load `.nix` files from module directories.
|
- Source: `modules/modules.nix` uses `inputs.self.lib.autoImport` to load `.nix` files from module directories.
|
||||||
- Filter: Excludes `librewolf.nix`; all other `.nix` files in target dirs are loaded automatically.
|
- Filter: Excludes `librewolf.nix`; all other `.nix` files in target dirs are loaded automatically.
|
||||||
- Implication: Place new modules in the correct category directory with a `.nix` filename; no manual import wiring required unless adding a new factory.
|
- Implication: Place new modules in the correct category directory with a `.nix` filename; no manual import wiring required unless adding a new factory. Patch artifacts under `patches/` are not auto-imported.
|
||||||
|
|
||||||
## Hosts and Roles
|
## Hosts and Roles
|
||||||
- Configs: `hosts/<name>/configuration.nix` with toggles in `hosts/<name>/toggles.nix`.
|
- Configs: `hosts/<name>/configuration.nix` with toggles in `hosts/<name>/toggles.nix`.
|
||||||
@@ -61,7 +62,7 @@
|
|||||||
- MCP server reference: `docs/reference/mcp-server.md` (tool catalog, `nixos-mcp` wrapper, invocation, sync-docs)
|
- MCP server reference: `docs/reference/mcp-server.md` (tool catalog, `nixos-mcp` wrapper, invocation, sync-docs)
|
||||||
|
|
||||||
## Quick Audit Checklist
|
## Quick Audit Checklist
|
||||||
- Module coverage: All categories (apps, dev, scripts, servers, services, shell, websites, network, users, nix, patches) have corresponding entries and auto-import rules.
|
- Module coverage: All categories (apps, dev, scripts, servers, services, shell, websites, network, users, nix) have corresponding entries and auto-import rules; `patches/` is documented as a root directory.
|
||||||
- Host coverage: Active hosts listed with roles and secureHost status; `mainServer` noted.
|
- Host coverage: Active hosts listed with roles and secureHost status; `mainServer` noted.
|
||||||
- Proxy rules: `enableProxy` usage, proxy helper selection, and `my.ips` mappings documented.
|
- Proxy rules: `enableProxy` usage, proxy helper selection, and `my.ips` mappings documented.
|
||||||
- Secrets map: Every secrets file and secureHost gating captured; new secret types aligned to file purposes.
|
- Secrets map: Every secrets file and secureHost gating captured; new secret types aligned to file purposes.
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
;;neotree ; a project drawer, like NERDTree for vim
|
;;neotree ; a project drawer, like NERDTree for vim
|
||||||
ophints ; highlight the region an operation acts on
|
ophints ; highlight the region an operation acts on
|
||||||
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
||||||
|
(smooth-scroll +interpolate) ; So smooth you won't believe it's not butter
|
||||||
;;tabs ; a tab bar for Emacs
|
;;tabs ; a tab bar for Emacs
|
||||||
(treemacs +lsp) ; a project drawer, like neotree but cooler
|
(treemacs +lsp) ; a project drawer, like neotree but cooler
|
||||||
;;unicode ; extended unicode support for various languages
|
;;unicode ; extended unicode support for various languages
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
;;parinfer ; turn lisp into python, sort of
|
;;parinfer ; turn lisp into python, sort of
|
||||||
rotate-text ; cycle region at point between text candidates
|
rotate-text ; cycle region at point between text candidates
|
||||||
snippets ; my elves. They type so I don't have to
|
snippets ; my elves. They type so I don't have to
|
||||||
|
(whitespace +guess +trim) ; a butler for your whitespace
|
||||||
;;word-wrap ; soft wrapping with language-aware indent
|
;;word-wrap ; soft wrapping with language-aware indent
|
||||||
|
|
||||||
:emacs
|
:emacs
|
||||||
@@ -71,6 +73,7 @@
|
|||||||
electric ; smarter, keyword-based electric-indent
|
electric ; smarter, keyword-based electric-indent
|
||||||
eww ; the internet is gross
|
eww ; the internet is gross
|
||||||
ibuffer ; interactive buffer management
|
ibuffer ; interactive buffer management
|
||||||
|
tramp ; remote files at your arthritic fingertips
|
||||||
(undo +tree) ; persistent, smarter undo for your inevitable mistakes
|
(undo +tree) ; persistent, smarter undo for your inevitable mistakes
|
||||||
vc ; version-control and Emacs, sitting in a tree
|
vc ; version-control and Emacs, sitting in a tree
|
||||||
|
|
||||||
@@ -96,21 +99,24 @@
|
|||||||
;;ein ; tame Jupyter notebooks with emacs
|
;;ein ; tame Jupyter notebooks with emacs
|
||||||
(eval +overlay) ; run code, run (also, repls)
|
(eval +overlay) ; run code, run (also, repls)
|
||||||
(lookup +dictionary + offline) ; navigate your code and its documentation
|
(lookup +dictionary + offline) ; navigate your code and its documentation
|
||||||
|
llm ; when I said you needed friends, I didn't mean...
|
||||||
(lsp +peek) ; M-x vscode
|
(lsp +peek) ; M-x vscode
|
||||||
magit ; a git porcelain for Emacs
|
magit ; a git porcelain for Emacs
|
||||||
;;make ; run make tasks from Emacs
|
;;make ; run make tasks from Emacs
|
||||||
;;pass ; password manager for nerds
|
;;pass ; password manager for nerds
|
||||||
;;pdf ; pdf enhancements
|
;;pdf ; pdf enhancements
|
||||||
;;prodigy ; FIXME managing external services & code builders
|
;;prodigy ; FIXME managing external services & code builders
|
||||||
;;terraform ; infrastructure as code
|
(terraform +lsp) ; infrastructure as code
|
||||||
tmux ; an API for interacting with tmux
|
tmux ; an API for interacting with tmux
|
||||||
;; tree-sitter ; syntax and parsing, sitting in a tree...
|
;; tree-sitter ; syntax and parsing, sitting in a tree...
|
||||||
upload ; map local to remote projects via ssh/ftp
|
upload ; map local to remote projects via ssh/ftp
|
||||||
|
|
||||||
:os
|
:os
|
||||||
;;(:if (featurep :system 'macos) macos) ; improve compatibility with macOS tty ; improve the terminal Emacs experience
|
;;(:if (featurep :system 'macos) macos) ; improve compatibility with macOS tty ; improve the terminal Emacs experience
|
||||||
|
tty ; improve the terminal Emacs experience
|
||||||
|
|
||||||
:lang
|
:lang
|
||||||
|
;;ada ; In strong typing we (blindly) trust
|
||||||
;;agda ; types of types of types of types...
|
;;agda ; types of types of types of types...
|
||||||
;;beancount ; mind the GAAP
|
;;beancount ; mind the GAAP
|
||||||
(cc +lsp) ; C > C++ == 1
|
(cc +lsp) ; C > C++ == 1
|
||||||
@@ -139,6 +145,7 @@
|
|||||||
;;hy ; readability of scheme w/ speed of python
|
;;hy ; readability of scheme w/ speed of python
|
||||||
;;idris ; a language you can depend on
|
;;idris ; a language you can depend on
|
||||||
(json +lsp) ; At least it ain't XML
|
(json +lsp) ; At least it ain't XML
|
||||||
|
;;janet ; Fun fact: Janet is me!
|
||||||
;;(java +lsp) ; the poster child for carpal tunnel syndrome
|
;;(java +lsp) ; the poster child for carpal tunnel syndrome
|
||||||
(javascript +lsp) ; all(hope(abandon(ye(who(enter(here))))))
|
(javascript +lsp) ; all(hope(abandon(ye(who(enter(here))))))
|
||||||
(julia +lsp) ; a better, faster MATLAB
|
(julia +lsp) ; a better, faster MATLAB
|
||||||
|
|||||||
@@ -49,15 +49,9 @@
|
|||||||
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
|
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
|
||||||
;(unpin! t)
|
;(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-open)
|
||||||
(package! dired-subtree)
|
(package! dired-subtree)
|
||||||
;; (package! doom-modeline-now-playing)
|
(package! expand-region)
|
||||||
(package! ini-mode)
|
(package! ini-mode)
|
||||||
(package! insert-esv) ;; bible passages
|
(package! insert-esv) ;; bible passages
|
||||||
(package! olivetti) ;; writing mode centering text, looks like word
|
(package! olivetti) ;; writing mode centering text, looks like word
|
||||||
@@ -68,11 +62,14 @@
|
|||||||
(package! peep-dired) ;; kind of cool but never could make it work
|
(package! peep-dired) ;; kind of cool but never could make it work
|
||||||
(package! php-cs-fixer)
|
(package! php-cs-fixer)
|
||||||
(package! systemd)
|
(package! systemd)
|
||||||
|
;; :recipe (:host github :repo "tecosaur/ox-chameleon"))
|
||||||
;; (package! 2048-game)
|
;; (package! 2048-game)
|
||||||
;; (package! academic-phrases)
|
;; (package! academic-phrases)
|
||||||
;; (package! caddyfile-mode)
|
;; (package! caddyfile-mode)
|
||||||
;; (package! clippy)
|
;; (package! clippy)
|
||||||
|
;; (package! codeium :recipe (:host github :repo "Exafunction/codeium.el"))
|
||||||
;; (package! crontab-mode) ;; crontab colors
|
;; (package! crontab-mode) ;; crontab colors
|
||||||
|
;; (package! doom-modeline-now-playing)
|
||||||
;; (package! evil-tutor) ;; vim tutorial
|
;; (package! evil-tutor) ;; vim tutorial
|
||||||
;; (package! ewal) ;; theme colors based on pywal
|
;; (package! ewal) ;; theme colors based on pywal
|
||||||
;; (package! ewal-doom-themes)
|
;; (package! ewal-doom-themes)
|
||||||
@@ -81,16 +78,14 @@
|
|||||||
;; (package! flycheck-aspell)
|
;; (package! flycheck-aspell)
|
||||||
;; (package! ivy-posframe)
|
;; (package! ivy-posframe)
|
||||||
;; (package! mw-thesaurus)
|
;; (package! mw-thesaurus)
|
||||||
|
;; (package! nixos-options) ;; enable when migrating to nixos
|
||||||
;; (package! org-appear) ;; couldn't get it to work
|
;; (package! org-appear) ;; couldn't get it to work
|
||||||
;; (package! org-recur) ;; works but I want to keep org vanilla
|
;; (package! org-recur) ;; works but I want to keep org vanilla
|
||||||
;; (package! ox-chameleon
|
;; (package! ox-chameleon
|
||||||
;; :recipe (:host github :repo "tecosaur/ox-chameleon"))
|
;; (package! quick-preview) ;; preview files with sushi
|
||||||
;; (package! renpy)
|
;; (package! renpy)
|
||||||
;; (package! resize-window)
|
;; (package! resize-window)
|
||||||
;; (package! tldr)
|
;; (package! tldr)
|
||||||
;; (package! typit) ;; type speed test
|
;; (package! typit) ;; type speed test
|
||||||
;; (package! vimgolf) ;; vim puzzles
|
;; (package! vimgolf) ;; vim puzzles
|
||||||
;; (package! wc-mode) ;; displays character count of buffer
|
;; (package! wc-mode) ;; displays character count of buffer
|
||||||
|
|
||||||
(package! expand-region)
|
|
||||||
(package! gptel :recipe (:nonrecursive t))
|
|
||||||
|
|||||||
8
flake.lock
generated
8
flake.lock
generated
@@ -1331,11 +1331,11 @@
|
|||||||
"wallpapers": {
|
"wallpapers": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1759463031,
|
"lastModified": 1770517108,
|
||||||
"narHash": "sha256-9goyp+g9N4+9PA9V2QerTsxlVy9MA4LXufJaruj2MMs=",
|
"narHash": "sha256-QYvx6j7r1ItxaaKN/wI0nGB6r5aWG46zfcoXCTOgK18=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "0212af5b70347f0721cfe88c25e1efb77b645a2d",
|
"rev": "dcb86c4c592b8cf838a0fd6d139254619cbbd869",
|
||||||
"revCount": 2,
|
"revCount": 3,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.lebubu.org/jawz/wallpapers.git"
|
"url": "https://git.lebubu.org/jawz/wallpapers.git"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ in
|
|||||||
endpoint = "${config.my.ips.vps}:51820";
|
endpoint = "${config.my.ips.vps}:51820";
|
||||||
allowedIPs = [
|
allowedIPs = [
|
||||||
"${config.my.ips.wg-vps}/32"
|
"${config.my.ips.wg-vps}/32"
|
||||||
|
config.my.subnets.wg-homelab
|
||||||
config.my.subnets.wg-friends
|
config.my.subnets.wg-friends
|
||||||
config.my.subnets.wg-guests
|
config.my.subnets.wg-guests
|
||||||
];
|
];
|
||||||
@@ -121,7 +122,7 @@ in
|
|||||||
config.my.ips.vps
|
config.my.ips.vps
|
||||||
"[${config.my.ips.vps}]:3456"
|
"[${config.my.ips.vps}]:3456"
|
||||||
];
|
];
|
||||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMvtTURGBtAFXxxfzMJVoNJrtWLykOloJ5XYjxGh1OUx";
|
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPp0wAuZXk96OyA/+2YpQalokS9lZdacjJqY9zN8IScP";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ in
|
|||||||
"maloja"
|
"maloja"
|
||||||
"mealie"
|
"mealie"
|
||||||
"metube"
|
"metube"
|
||||||
"microbin"
|
|
||||||
"multi-scrobbler"
|
"multi-scrobbler"
|
||||||
"paperless"
|
"paperless"
|
||||||
"plex"
|
"plex"
|
||||||
@@ -85,7 +84,6 @@ in
|
|||||||
]
|
]
|
||||||
// enableList mkEnabledIp [
|
// enableList mkEnabledIp [
|
||||||
"audiobookshelf"
|
"audiobookshelf"
|
||||||
"isso"
|
|
||||||
"keycloak"
|
"keycloak"
|
||||||
"linkwarden"
|
"linkwarden"
|
||||||
"oauth2-proxy"
|
"oauth2-proxy"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ let
|
|||||||
homeServer = config.my.ips.wg-server;
|
homeServer = config.my.ips.wg-server;
|
||||||
wgFriend1 = config.my.ips.wg-friend1;
|
wgFriend1 = config.my.ips.wg-friend1;
|
||||||
wgGuest1 = config.my.ips.wg-guest1;
|
wgGuest1 = config.my.ips.wg-guest1;
|
||||||
|
wgGuest2 = config.my.ips.wg-guest2;
|
||||||
};
|
};
|
||||||
subnets = {
|
subnets = {
|
||||||
wgFriends = config.my.subnets.wg-friends;
|
wgFriends = config.my.subnets.wg-friends;
|
||||||
@@ -36,24 +37,32 @@ let
|
|||||||
synapseClient = toString config.my.servers.synapse.port;
|
synapseClient = toString config.my.servers.synapse.port;
|
||||||
syncplay = toString config.my.servers.syncplay.port;
|
syncplay = toString config.my.servers.syncplay.port;
|
||||||
stash = toString config.my.servers.stash.port;
|
stash = toString config.my.servers.stash.port;
|
||||||
|
jellyfin = toString config.my.servers.jellyfin.port;
|
||||||
|
audiobookshelf = toString config.my.servers.audiobookshelf.port;
|
||||||
|
kavita = toString config.my.servers.kavita.port;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
|
./nginx-nextcloud.nix
|
||||||
../../config/base.nix
|
../../config/base.nix
|
||||||
];
|
];
|
||||||
my = import ./toggles.nix { inherit config inputs; } // {
|
my =
|
||||||
secureHost = true;
|
import ./toggles.nix {
|
||||||
users.nixremote = {
|
inherit config inputs lib;
|
||||||
enable = true;
|
}
|
||||||
authorizedKeys = inputs.self.lib.getSshKeys [
|
// {
|
||||||
"nixworkstation"
|
secureHost = true;
|
||||||
"nixserver"
|
users.nixremote = {
|
||||||
"nixminiserver"
|
enable = true;
|
||||||
];
|
authorizedKeys = inputs.self.lib.getSshKeys [
|
||||||
|
"nixworkstation"
|
||||||
|
"nixserver"
|
||||||
|
"nixminiserver"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
sops.age = {
|
sops.age = {
|
||||||
generateKey = true;
|
generateKey = true;
|
||||||
keyFile = "/var/lib/sops-nix/key.txt";
|
keyFile = "/var/lib/sops-nix/key.txt";
|
||||||
@@ -101,9 +110,11 @@ in
|
|||||||
|
|
||||||
iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 icmp type echo-request accept
|
iifname "${wgInterface}" ip saddr ${subnets.wgFriends} ip daddr ${ips.homeServer}/32 icmp type echo-request accept
|
||||||
iifname "${wgInterface}" ip saddr ${ips.wgFriend1}/32 ip daddr ${ips.homeServer}/32 tcp dport ${portsStr.stash} accept
|
iifname "${wgInterface}" ip saddr ${ips.wgFriend1}/32 ip daddr ${ips.homeServer}/32 tcp dport ${portsStr.stash} accept
|
||||||
iifname "${wgInterface}" ip saddr ${ips.wgGuest1}/32 ip daddr ${ips.homeServer}/32 tcp dport ${portsStr.stash} accept
|
iifname "${wgInterface}" ip saddr ${subnets.wgGuests} ip daddr ${ips.homeServer}/32 tcp dport { ${portsStr.stash}, ${portsStr.jellyfin}, ${portsStr.audiobookshelf}, ${portsStr.kavita} } accept
|
||||||
iifname "${wgInterface}" ip saddr ${subnets.wgGuests} ip daddr ${ips.homeServer}/32 icmp type echo-request accept
|
iifname "${wgInterface}" ip saddr ${subnets.wgGuests} ip daddr ${ips.homeServer}/32 icmp type echo-request accept
|
||||||
|
|
||||||
|
iifname "${wgInterface}" ip saddr ${subnets.wgHomelab} ip daddr ${ips.homeServer}/32 accept
|
||||||
|
|
||||||
iifname "${wgInterface}" ip saddr ${subnets.wgFriends} oifname "${externalInterface}" accept
|
iifname "${wgInterface}" ip saddr ${subnets.wgFriends} oifname "${externalInterface}" accept
|
||||||
iifname "${wgInterface}" ip saddr ${subnets.wgGuests} oifname "${externalInterface}" accept
|
iifname "${wgInterface}" ip saddr ${subnets.wgGuests} oifname "${externalInterface}" accept
|
||||||
|
|
||||||
@@ -131,7 +142,7 @@ in
|
|||||||
"d /var/www/html 2775 deploy www-data -"
|
"d /var/www/html 2775 deploy www-data -"
|
||||||
"d /var/www/html/portfolio 2775 deploy www-data -"
|
"d /var/www/html/portfolio 2775 deploy www-data -"
|
||||||
"d /var/www/html/blog 2775 deploy www-data -"
|
"d /var/www/html/blog 2775 deploy www-data -"
|
||||||
"d /var/www/html/lidarr-mb-gap 2775 deploy www-data -"
|
"d /var/www/html/lidarr-mb-gap 2775 lidarr-reports lidarr-reports -"
|
||||||
];
|
];
|
||||||
services = {
|
services = {
|
||||||
smartd.enable = lib.mkForce false;
|
smartd.enable = lib.mkForce false;
|
||||||
@@ -144,7 +155,12 @@ in
|
|||||||
www-data = { };
|
www-data = { };
|
||||||
};
|
};
|
||||||
users = {
|
users = {
|
||||||
nginx.extraGroups = [ "www-data" ];
|
nginx = lib.mkIf config.my.secureHost {
|
||||||
|
extraGroups = [
|
||||||
|
"www-data"
|
||||||
|
"lidarr-reports"
|
||||||
|
];
|
||||||
|
};
|
||||||
deploy = {
|
deploy = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = "deploy";
|
group = "deploy";
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
|
config,
|
||||||
modulesPath,
|
modulesPath,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
@@ -33,13 +34,17 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
fileSystems."/" = {
|
fileSystems."/" = {
|
||||||
device = "/dev/disk/by-uuid/f222513b-ded1-49fa-b591-20ce86a2fe7f";
|
device = lib.mkForce (
|
||||||
|
if config.my.build.baseImage then
|
||||||
|
"/dev/sda"
|
||||||
|
else
|
||||||
|
"/dev/disk/by-uuid/f222513b-ded1-49fa-b591-20ce86a2fe7f"
|
||||||
|
);
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
swapDevices = [
|
swapDevices = lib.mkMerge [
|
||||||
{
|
[ { device = "/dev/disk/by-uuid/f1408ea6-59a0-11ed-bc9d-525400000001"; } ]
|
||||||
device = "/dev/disk/by-uuid/f1408ea6-59a0-11ed-bc9d-525400000001";
|
(lib.mkIf config.my.build.baseImage [ { device = "/dev/sdb"; } ])
|
||||||
}
|
|
||||||
];
|
];
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
}
|
}
|
||||||
|
|||||||
116
hosts/vps/nginx-nextcloud.nix
Normal file
116
hosts/vps/nginx-nextcloud.nix
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.my.servers.nextcloud;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = lib.mkIf (cfg.enableProxy && config.my.enableProxy && config.my.secureHost) {
|
||||||
|
services.nginx.virtualHosts.${cfg.host} = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
http2 = true;
|
||||||
|
default = true;
|
||||||
|
serverAliases = [ "cloud.rotehaare.art" ];
|
||||||
|
extraConfig = ''
|
||||||
|
index index.php index.html /index.php$request_uri;
|
||||||
|
add_header X-Content-Type-Options nosniff always;
|
||||||
|
add_header X-Robots-Tag "noindex, nofollow" always;
|
||||||
|
add_header X-Permitted-Cross-Domain-Policies none always;
|
||||||
|
add_header X-Frame-Options SAMEORIGIN always;
|
||||||
|
add_header Referrer-Policy no-referrer always;
|
||||||
|
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
|
||||||
|
'';
|
||||||
|
locations = {
|
||||||
|
"= /robots.txt" = {
|
||||||
|
priority = 100;
|
||||||
|
extraConfig = ''
|
||||||
|
allow all;
|
||||||
|
access_log off;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"= /" = {
|
||||||
|
priority = 100;
|
||||||
|
proxyPass = cfg.local;
|
||||||
|
proxyWebsockets = true;
|
||||||
|
extraConfig = ''
|
||||||
|
if ( $http_user_agent ~ ^DavClnt ) {
|
||||||
|
return 302 /remote.php/webdav/$is_args$args;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"= /.well-known/carddav" = {
|
||||||
|
priority = 210;
|
||||||
|
extraConfig = ''
|
||||||
|
return 301 /remote.php/dav/;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"= /.well-known/caldav" = {
|
||||||
|
priority = 210;
|
||||||
|
extraConfig = ''
|
||||||
|
return 301 /remote.php/dav/;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ ^/\\.well-known/(?!acme-challenge|pki-validation)" = {
|
||||||
|
priority = 210;
|
||||||
|
extraConfig = ''
|
||||||
|
return 301 /index.php$request_uri;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"^~ /.well-known" = {
|
||||||
|
priority = 210;
|
||||||
|
extraConfig = ''
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)" = {
|
||||||
|
priority = 450;
|
||||||
|
extraConfig = ''
|
||||||
|
return 404;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ ^/(?:\\.|autotest|occ|issue|indie|db_|console)" = {
|
||||||
|
priority = 450;
|
||||||
|
extraConfig = ''
|
||||||
|
return 404;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ \\.php(?:$|/)" = {
|
||||||
|
priority = 500;
|
||||||
|
proxyPass = cfg.local;
|
||||||
|
proxyWebsockets = true;
|
||||||
|
extraConfig = ''
|
||||||
|
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ \\.(?:css|js|mjs|svg|gif|ico|jpg|jpeg|png|webp|wasm|tflite|map|html|ttf|bcmap|mp4|webm|ogg|flac)$" =
|
||||||
|
{
|
||||||
|
proxyPass = cfg.local;
|
||||||
|
extraConfig = ''
|
||||||
|
expires 6M;
|
||||||
|
access_log off;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ ^\\/(?:updater|ocs-provider)(?:$|\\/)" = {
|
||||||
|
proxyPass = cfg.local;
|
||||||
|
extraConfig = ''
|
||||||
|
try_files $uri/ =404;
|
||||||
|
index index.php;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"/remote" = {
|
||||||
|
priority = 1500;
|
||||||
|
extraConfig = ''
|
||||||
|
return 301 /remote.php$request_uri;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"/" = {
|
||||||
|
priority = 1600;
|
||||||
|
proxyPass = cfg.local;
|
||||||
|
proxyWebsockets = true;
|
||||||
|
extraConfig = ''
|
||||||
|
try_files $uri $uri/ /index.php$request_uri;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,64 +1,86 @@
|
|||||||
{ config, inputs }:
|
{
|
||||||
|
config,
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
inherit (inputs.self.lib)
|
inherit (inputs.self.lib)
|
||||||
enableList
|
enableList
|
||||||
mkEnabled
|
mkEnabled
|
||||||
|
mkEnabledWithProxy
|
||||||
mkEnabledWithUsers
|
mkEnabledWithUsers
|
||||||
;
|
;
|
||||||
wgServerIp = config.my.ips.wg-server;
|
wgServerIp = config.my.ips.wg-server;
|
||||||
mkEnabledProxyIp = inputs.self.lib.mkEnabledProxyIp wgServerIp;
|
mkEnabledProxyIp = inputs.self.lib.mkEnabledProxyIp wgServerIp;
|
||||||
in
|
mkEnabledProxySocketIp = name: {
|
||||||
{
|
inherit name;
|
||||||
enableProxy = true;
|
value = {
|
||||||
enableContainers = true;
|
|
||||||
apps.dictionaries.enable = true;
|
|
||||||
apps.dictionaries.users = "jawz";
|
|
||||||
services = enableList mkEnabled [
|
|
||||||
"network"
|
|
||||||
"wireguard"
|
|
||||||
];
|
|
||||||
shell = enableList mkEnabledWithUsers [
|
|
||||||
"multimedia"
|
|
||||||
"tools"
|
|
||||||
];
|
|
||||||
dev = enableList mkEnabledWithUsers [
|
|
||||||
"nix"
|
|
||||||
"sh"
|
|
||||||
];
|
|
||||||
websites = {
|
|
||||||
portfolio.enableProxy = true;
|
|
||||||
lidarrMbReport.enableProxy = true;
|
|
||||||
};
|
|
||||||
servers = {
|
|
||||||
nextcloud = {
|
|
||||||
enableProxy = true;
|
enableProxy = true;
|
||||||
|
enableSocket = true;
|
||||||
ip = wgServerIp;
|
ip = wgServerIp;
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
// enableList mkEnabledProxyIp [
|
baseToggles = {
|
||||||
"audiobookshelf"
|
services = enableList mkEnabled [
|
||||||
"bazarr"
|
"network"
|
||||||
"collabora"
|
"wireguard"
|
||||||
"gitea"
|
];
|
||||||
"homepage"
|
shell = enableList mkEnabledWithUsers [
|
||||||
"isso"
|
"multimedia"
|
||||||
"jellyfin"
|
"tools"
|
||||||
"kavita"
|
];
|
||||||
"keycloak"
|
dev = enableList mkEnabledWithUsers [
|
||||||
"lidarr"
|
"nix"
|
||||||
"linkwarden"
|
"sh"
|
||||||
"maloja"
|
];
|
||||||
"mealie"
|
apps.dictionaries = {
|
||||||
"metube"
|
enable = true;
|
||||||
"microbin"
|
users = "jawz";
|
||||||
"multi-scrobbler"
|
};
|
||||||
"oauth2-proxy"
|
};
|
||||||
"plausible"
|
secureToggles = {
|
||||||
"plex"
|
enableProxy = true;
|
||||||
"prowlarr"
|
enableContainers = true;
|
||||||
"radarr"
|
websites = {
|
||||||
"sonarr"
|
portfolio.enableProxy = true;
|
||||||
"vaultwarden"
|
lidarrMbReport.enableProxy = true;
|
||||||
"yamtrack"
|
};
|
||||||
];
|
servers =
|
||||||
}
|
enableList mkEnabledWithProxy [
|
||||||
|
"isso"
|
||||||
|
"microbin"
|
||||||
|
]
|
||||||
|
// enableList mkEnabledProxySocketIp [
|
||||||
|
"audiobookshelf"
|
||||||
|
"collabora"
|
||||||
|
"jellyfin"
|
||||||
|
"nextcloud"
|
||||||
|
"plausible"
|
||||||
|
"plex"
|
||||||
|
]
|
||||||
|
// enableList mkEnabledProxyIp [
|
||||||
|
"atticd"
|
||||||
|
"bazarr"
|
||||||
|
"gitea"
|
||||||
|
"homepage"
|
||||||
|
"kavita"
|
||||||
|
"keycloak"
|
||||||
|
"lidarr"
|
||||||
|
"linkwarden"
|
||||||
|
"maloja"
|
||||||
|
"mealie"
|
||||||
|
"metube"
|
||||||
|
"multi-scrobbler"
|
||||||
|
"oauth2-proxy"
|
||||||
|
"prowlarr"
|
||||||
|
"radarr"
|
||||||
|
"sonarr"
|
||||||
|
"vaultwarden"
|
||||||
|
"yamtrack"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
lib.mkMerge [
|
||||||
|
baseToggles
|
||||||
|
(lib.mkIf config.my.secureHost secureToggles)
|
||||||
|
]
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ in
|
|||||||
};
|
};
|
||||||
localhost6 = lib.mkOption {
|
localhost6 = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "::1";
|
default = "[::1]";
|
||||||
description = "The localhost ipv6 address.";
|
description = "The localhost ipv6 address.";
|
||||||
};
|
};
|
||||||
secureHost = lib.mkOption {
|
secureHost = lib.mkOption {
|
||||||
@@ -53,11 +53,15 @@ in
|
|||||||
vps = "45.79.25.87";
|
vps = "45.79.25.87";
|
||||||
wg-vps = "10.77.0.1";
|
wg-vps = "10.77.0.1";
|
||||||
wg-server = "10.77.0.2";
|
wg-server = "10.77.0.2";
|
||||||
|
wg-galaxy = "10.77.0.3";
|
||||||
|
wg-phone = "10.77.0.4";
|
||||||
wg-guest1 = "10.9.0.2";
|
wg-guest1 = "10.9.0.2";
|
||||||
|
wg-guest2 = "10.9.0.3";
|
||||||
wg-friend1 = "10.8.0.2";
|
wg-friend1 = "10.8.0.2";
|
||||||
wg-friend2 = "10.8.0.3";
|
wg-friend2 = "10.8.0.3";
|
||||||
wg-friend3 = "10.8.0.4";
|
wg-friend3 = "10.8.0.4";
|
||||||
wg-friend4 = "10.8.0.5";
|
wg-friend4 = "10.8.0.5";
|
||||||
|
wg-friend5 = "10.8.0.6";
|
||||||
};
|
};
|
||||||
description = "Set of IP's for all my computers.";
|
description = "Set of IP's for all my computers.";
|
||||||
};
|
};
|
||||||
@@ -126,6 +130,11 @@ in
|
|||||||
};
|
};
|
||||||
enableContainers = lib.mkEnableOption "container services (Docker/Podman)";
|
enableContainers = lib.mkEnableOption "container services (Docker/Podman)";
|
||||||
enableProxy = lib.mkEnableOption "nginx reverse proxy for services";
|
enableProxy = lib.mkEnableOption "nginx reverse proxy for services";
|
||||||
|
build.baseImage = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to enable base image settings for this host build.";
|
||||||
|
};
|
||||||
toggleUsers = lib.mkOption {
|
toggleUsers = lib.mkOption {
|
||||||
type = lib.types.attrsOf (lib.types.either lib.types.str (lib.types.listOf lib.types.str));
|
type = lib.types.attrsOf (lib.types.either lib.types.str (lib.types.listOf lib.types.str));
|
||||||
default = {
|
default = {
|
||||||
@@ -213,7 +222,6 @@ in
|
|||||||
config.my.servers.go-vod.enable
|
config.my.servers.go-vod.enable
|
||||||
config.my.servers.tranga.enable
|
config.my.servers.tranga.enable
|
||||||
config.my.servers.drpp.enable
|
config.my.servers.drpp.enable
|
||||||
config.my.servers.plex-discord-bot.enable
|
|
||||||
]);
|
]);
|
||||||
message = "Container services are enabled but enableContainers is false";
|
message = "Container services are enabled but enableContainers is false";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ let
|
|||||||
"drpp"
|
"drpp"
|
||||||
"metube"
|
"metube"
|
||||||
"multi-scrobbler"
|
"multi-scrobbler"
|
||||||
"plex-discord-bot"
|
|
||||||
];
|
];
|
||||||
nativeServicesWithOpenFirewall = inputs.self.lib.getServicesWithNativeFirewall config firewallBlacklist;
|
nativeServicesWithOpenFirewall = inputs.self.lib.getServicesWithNativeFirewall config firewallBlacklist;
|
||||||
servicesConfig = lib.listToAttrs (
|
servicesConfig = lib.listToAttrs (
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ in
|
|||||||
virtualisation.oci-containers.containers = lib.mkIf enable {
|
virtualisation.oci-containers.containers = lib.mkIf enable {
|
||||||
flame = lib.mkIf cfg.enable {
|
flame = lib.mkIf cfg.enable {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
image = "pawelmalak/flame";
|
image = "pawelmalak/flame:latest";
|
||||||
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
|
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
|
||||||
volumes = [
|
volumes = [
|
||||||
"${config.my.containerData}/flame:/app/data"
|
"${config.my.containerData}/flame:/app/data"
|
||||||
@@ -36,7 +36,7 @@ in
|
|||||||
};
|
};
|
||||||
flame-nsfw = lib.mkIf cfgS.enable {
|
flame-nsfw = lib.mkIf cfgS.enable {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
image = "pawelmalak/flame";
|
image = "pawelmalak/flame:latest";
|
||||||
ports = [ "${toString cfgS.port}:${toString cfg.port}" ];
|
ports = [ "${toString cfgS.port}:${toString cfg.port}" ];
|
||||||
volumes = [ "${config.my.containerData}/flame-nsfw:/app/data" ];
|
volumes = [ "${config.my.containerData}/flame-nsfw:/app/data" ];
|
||||||
environmentFiles = [ config.sops.secrets.flame.path ];
|
environmentFiles = [ config.sops.secrets.flame.path ];
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ in
|
|||||||
options.my.servers.lidarr = setup.mkOptions "lidarr" "music" 8686;
|
options.my.servers.lidarr = setup.mkOptions "lidarr" "music" 8686;
|
||||||
config.virtualisation.oci-containers.containers.lidarr = lib.mkIf cfg.enable {
|
config.virtualisation.oci-containers.containers.lidarr = lib.mkIf cfg.enable {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
image = "linuxserver/lidarr:version-3.0.1.4866";
|
image = "linuxserver/lidarr:latest";
|
||||||
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
|
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
|
||||||
environment = {
|
environment = {
|
||||||
TZ = config.my.timeZone;
|
TZ = config.my.timeZone;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ in
|
|||||||
config = lib.mkIf (cfg.enable && config.my.secureHost) {
|
config = lib.mkIf (cfg.enable && config.my.secureHost) {
|
||||||
sops.secrets.maloja.sopsFile = ../../secrets/env.yaml;
|
sops.secrets.maloja.sopsFile = ../../secrets/env.yaml;
|
||||||
virtualisation.oci-containers.containers.maloja = {
|
virtualisation.oci-containers.containers.maloja = {
|
||||||
image = "krateng/maloja:3.2.4";
|
image = "krateng/maloja:latest";
|
||||||
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
|
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
|
||||||
environmentFiles = [ config.sops.secrets.maloja.path ];
|
environmentFiles = [ config.sops.secrets.maloja.path ];
|
||||||
environment = {
|
environment = {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ in
|
|||||||
{
|
{
|
||||||
options.my.servers.metube = setup.mkOptions "metube" "bajameesta" 8881;
|
options.my.servers.metube = setup.mkOptions "metube" "bajameesta" 8881;
|
||||||
config.virtualisation.oci-containers.containers.metube = lib.mkIf cfg.enable {
|
config.virtualisation.oci-containers.containers.metube = lib.mkIf cfg.enable {
|
||||||
image = "ghcr.io/alexta69/metube:2026.01.02";
|
image = "ghcr.io/alexta69/metube:latest";
|
||||||
ports = [ "${toString cfg.port}:8081" ];
|
ports = [ "${toString cfg.port}:8081" ];
|
||||||
volumes = [
|
volumes = [
|
||||||
"${config.my.containerData}/metube:/downloads"
|
"${config.my.containerData}/metube:/downloads"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ in
|
|||||||
config = lib.mkIf (cfg.enable && config.my.secureHost) {
|
config = lib.mkIf (cfg.enable && config.my.secureHost) {
|
||||||
sops.secrets.multi-scrobbler.sopsFile = ../../secrets/env.yaml;
|
sops.secrets.multi-scrobbler.sopsFile = ../../secrets/env.yaml;
|
||||||
virtualisation.oci-containers.containers.multi-scrobbler = {
|
virtualisation.oci-containers.containers.multi-scrobbler = {
|
||||||
image = "foxxmd/multi-scrobbler:0.10.0";
|
image = "foxxmd/multi-scrobbler:latest";
|
||||||
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
|
ports = [ "${toString cfg.port}:${toString cfg.port}" ];
|
||||||
environmentFiles = [ config.sops.secrets.multi-scrobbler.path ];
|
environmentFiles = [ config.sops.secrets.multi-scrobbler.path ];
|
||||||
environment = {
|
environment = {
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ in
|
|||||||
virtualisation.oci-containers.containers = {
|
virtualisation.oci-containers.containers = {
|
||||||
go-vod = lib.mkIf config.my.servers.go-vod.enable {
|
go-vod = lib.mkIf config.my.servers.go-vod.enable {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
image = "radialapps/go-vod";
|
image = "radialapps/go-vod:latest";
|
||||||
environment = {
|
environment = {
|
||||||
TZ = config.my.timeZone;
|
TZ = config.my.timeZone;
|
||||||
NEXTCLOUD_HOST = "https://${config.services.nextcloud.hostName}";
|
NEXTCLOUD_HOST = "https://${config.services.nextcloud.hostName}";
|
||||||
@@ -256,78 +256,51 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
(lib.mkIf (cfg.enableProxy && config.my.enableProxy && config.networking.hostName == "vps") {
|
(lib.mkIf (cfgC.enableProxy && config.my.enableProxy) {
|
||||||
services.nginx.virtualHosts = {
|
services.nginx.virtualHosts.${cfgC.host} = {
|
||||||
"${cfg.host}" = {
|
forceSSL = true;
|
||||||
forceSSL = true;
|
enableACME = true;
|
||||||
enableACME = true;
|
http2 = true;
|
||||||
http2 = true;
|
locations = {
|
||||||
default = true;
|
# static files
|
||||||
serverAliases = [ "cloud.rotehaare.art" ];
|
"^~ /browser" = {
|
||||||
extraConfig = ''
|
proxyPass = cfgC.local;
|
||||||
add_header X-XSS-Protection "1; mode=block" always;
|
extraConfig = commonProxyConfig;
|
||||||
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
|
|
||||||
add_header X-Content-Type-Options "nosniff" always;
|
|
||||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
||||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
|
||||||
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
'';
|
|
||||||
locations = {
|
|
||||||
"/" = {
|
|
||||||
proxyPass = cfg.local;
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
# Legacy static files (for compatibility)
|
||||||
"${cfgC.host}" = lib.mkIf cfgC.enableProxy {
|
"^~ /loleaflet" = {
|
||||||
forceSSL = true;
|
proxyPass = cfgC.local;
|
||||||
enableACME = true;
|
extraConfig = commonProxyConfig;
|
||||||
http2 = true;
|
};
|
||||||
locations = {
|
# WOPI discovery URL
|
||||||
# static files
|
"^~ /hosting/discovery" = {
|
||||||
"^~ /browser" = {
|
proxyPass = cfgC.local;
|
||||||
proxyPass = cfgC.local;
|
extraConfig = commonProxyConfig;
|
||||||
extraConfig = commonProxyConfig;
|
};
|
||||||
};
|
# Capabilities
|
||||||
# Legacy static files (for compatibility)
|
"^~ /hosting/capabilities" = {
|
||||||
"^~ /loleaflet" = {
|
proxyPass = cfgC.local;
|
||||||
proxyPass = cfgC.local;
|
extraConfig = commonProxyConfig;
|
||||||
extraConfig = commonProxyConfig;
|
};
|
||||||
};
|
# download, presentation, image upload and websocket
|
||||||
# WOPI discovery URL
|
"~ ^/cool" = {
|
||||||
"^~ /hosting/discovery" = {
|
proxyPass = cfgC.local;
|
||||||
proxyPass = cfgC.local;
|
extraConfig = commonWebsocketConfig;
|
||||||
extraConfig = commonProxyConfig;
|
};
|
||||||
};
|
# Legacy websocket (for compatibility)
|
||||||
# Capabilities
|
"~ ^/lool" = {
|
||||||
"^~ /hosting/capabilities" = {
|
proxyPass = cfgC.local;
|
||||||
proxyPass = cfgC.local;
|
extraConfig = commonWebsocketConfig;
|
||||||
extraConfig = commonProxyConfig;
|
};
|
||||||
};
|
# Admin Console websocket
|
||||||
# download, presentation, image upload and websocket
|
"^~ /cool/adminws" = {
|
||||||
"~ ^/cool" = {
|
proxyPass = cfgC.local;
|
||||||
proxyPass = cfgC.local;
|
extraConfig = commonWebsocketConfig;
|
||||||
extraConfig = commonWebsocketConfig;
|
};
|
||||||
};
|
# Legacy Admin Console websocket (for compatibility)
|
||||||
# Legacy websocket (for compatibility)
|
"^~ /lool/adminws" = {
|
||||||
"~ ^/lool" = {
|
proxyPass = cfgC.local;
|
||||||
proxyPass = cfgC.local;
|
extraConfig = commonWebsocketConfig;
|
||||||
extraConfig = commonWebsocketConfig;
|
|
||||||
};
|
|
||||||
# Admin Console websocket
|
|
||||||
"^~ /cool/adminws" = {
|
|
||||||
proxyPass = cfgC.local;
|
|
||||||
extraConfig = commonWebsocketConfig;
|
|
||||||
};
|
|
||||||
# Legacy Admin Console websocket (for compatibility)
|
|
||||||
"^~ /lool/adminws" = {
|
|
||||||
proxyPass = cfgC.local;
|
|
||||||
extraConfig = commonWebsocketConfig;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
setup = import ../factories/mkserver.nix { inherit lib config; };
|
|
||||||
cfg = config.my.servers.plex-discord-bot;
|
|
||||||
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"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -75,7 +75,6 @@ in
|
|||||||
inherit (cfg) port;
|
inherit (cfg) port;
|
||||||
bind_addresses = [
|
bind_addresses = [
|
||||||
config.my.localhost
|
config.my.localhost
|
||||||
config.my.localhost6
|
|
||||||
config.my.ips.server
|
config.my.ips.server
|
||||||
config.my.ips.wg-server
|
config.my.ips.wg-server
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ in
|
|||||||
config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable && config.my.secureHost) {
|
config = lib.mkIf (cfg.enable && config.my.servers.postgres.enable && config.my.secureHost) {
|
||||||
sops.secrets.yamtrack.sopsFile = ../../secrets/env.yaml;
|
sops.secrets.yamtrack.sopsFile = ../../secrets/env.yaml;
|
||||||
virtualisation.oci-containers.containers = {
|
virtualisation.oci-containers.containers = {
|
||||||
yamtrack-redis.image = "redis:7-alpine";
|
yamtrack-redis.image = "redis:latest";
|
||||||
yamtrack = {
|
yamtrack = {
|
||||||
image = "ghcr.io/fuzzygrim/yamtrack";
|
image = "ghcr.io/fuzzygrim/yamtrack:latest";
|
||||||
ports = [ "${toString cfg.port}:8000" ];
|
ports = [ "${toString cfg.port}:8000" ];
|
||||||
dependsOn = [ "yamtrack-redis" ];
|
dependsOn = [ "yamtrack-redis" ];
|
||||||
environmentFiles = [ config.sops.secrets.yamtrack.path ];
|
environmentFiles = [ config.sops.secrets.yamtrack.path ];
|
||||||
|
|||||||
@@ -1,10 +1,23 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
stripCidr = cidr: cidr |> lib.splitString "/" |> builtins.head;
|
||||||
|
wgListenIps = config.my.wgInterfaces |> builtins.attrValues;
|
||||||
|
wgListenAddrs = wgListenIps |> builtins.map (ip: "${stripCidr ip}:53");
|
||||||
|
in
|
||||||
{
|
{
|
||||||
options.my.services.network.enable = lib.mkEnableOption "network configuration and services";
|
options.my.services.network.enable = lib.mkEnableOption "network configuration and services";
|
||||||
config = lib.mkIf config.my.services.network.enable {
|
config = lib.mkIf config.my.services.network.enable {
|
||||||
networking = {
|
networking = {
|
||||||
enableIPv6 = true;
|
enableIPv6 = true;
|
||||||
firewall.enable = true;
|
firewall = {
|
||||||
|
enable = true;
|
||||||
|
interfaces = lib.mkIf config.my.services.wireguard.enable {
|
||||||
|
wg0 = {
|
||||||
|
allowedTCPPorts = [ 53 ];
|
||||||
|
allowedUDPPorts = [ 53 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
dhcpcd.extraConfig = "nohook resolv.conf";
|
dhcpcd.extraConfig = "nohook resolv.conf";
|
||||||
networkmanager = {
|
networkmanager = {
|
||||||
enable = true;
|
enable = true;
|
||||||
@@ -19,6 +32,16 @@
|
|||||||
settings = {
|
settings = {
|
||||||
ipv6_servers = true;
|
ipv6_servers = true;
|
||||||
require_dnssec = true;
|
require_dnssec = true;
|
||||||
|
log_level = 4;
|
||||||
|
listen_addresses = [
|
||||||
|
"${config.my.localhost}:53"
|
||||||
|
"${config.my.localhost6}:53"
|
||||||
|
]
|
||||||
|
++ lib.optionals config.my.services.wireguard.enable wgListenAddrs;
|
||||||
|
query_log = {
|
||||||
|
file = "/var/lib/dnscrypt-proxy/query.log";
|
||||||
|
format = "tsv";
|
||||||
|
};
|
||||||
sources.public-resolvers = {
|
sources.public-resolvers = {
|
||||||
urls = [
|
urls = [
|
||||||
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
|
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ in
|
|||||||
publicKey = "OUiqluRaS4hmGvLJ3csQrnIM3Zzet50gsqtTABaUkH4=";
|
publicKey = "OUiqluRaS4hmGvLJ3csQrnIM3Zzet50gsqtTABaUkH4=";
|
||||||
allowedIPs = [ "${config.my.ips.wg-server}/32" ];
|
allowedIPs = [ "${config.my.ips.wg-server}/32" ];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
publicKey = "BwN4uCkMd6eAS5Ugld0oXnA16IhgEEQF8mOJ3+vHliA=";
|
||||||
|
allowedIPs = [ "${config.my.ips.wg-galaxy}/32" ];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
publicKey = "R1xUFOuboQf/yy8ShiXqoCPaPcH3Cn0n4PAWB2rgHTs=";
|
||||||
|
allowedIPs = [ "${config.my.ips.wg-phone}/32" ];
|
||||||
|
}
|
||||||
{
|
{
|
||||||
publicKey = "rFgT6TXzRazK6GMazMNGjtOvzAAPST0LvCfN7QXsLho=";
|
publicKey = "rFgT6TXzRazK6GMazMNGjtOvzAAPST0LvCfN7QXsLho=";
|
||||||
allowedIPs = [ "${config.my.ips.wg-friend1}/32" ];
|
allowedIPs = [ "${config.my.ips.wg-friend1}/32" ];
|
||||||
@@ -43,6 +51,18 @@ in
|
|||||||
publicKey = "yg+2miZCrx89znFaUlU/le/7UIPgEAMY74fZfEwz8g4=";
|
publicKey = "yg+2miZCrx89znFaUlU/le/7UIPgEAMY74fZfEwz8g4=";
|
||||||
allowedIPs = [ "${config.my.ips.wg-friend4}/32" ];
|
allowedIPs = [ "${config.my.ips.wg-friend4}/32" ];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
publicKey = "u4/6ZYO7lUJZ9QmSlFPUaadq25gwDljjhsfgs/p2amc=";
|
||||||
|
allowedIPs = [ "${config.my.ips.wg-friend5}/32" ];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
publicKey = "GawtOvsZ75avelIri5CjGoPXd8AFpi9qlZ6dSsqUISE=";
|
||||||
|
allowedIPs = [ "${config.my.ips.wg-guest1}/32" ];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
publicKey = "NvhUnErIb0/hi+Hui/o5l5Pq4ZysFVIn1VBPsjoTeCk=";
|
||||||
|
allowedIPs = [ "${config.my.ips.wg-guest2}/32" ];
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,11 +26,36 @@
|
|||||||
exec ${mcpPython}/bin/python -m mcp_server.server
|
exec ${mcpPython}/bin/python -m mcp_server.server
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
vpsLinodeConfig = inputs.self.nixosConfigurations.vps.extendModules {
|
||||||
|
modules = [
|
||||||
|
(
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
my.secureHost = lib.mkForce false;
|
||||||
|
my.build.baseImage = true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
mcpTests = pkgs.writeShellApplication {
|
||||||
|
name = "mcp-tests";
|
||||||
|
runtimeInputs = with pkgs.python3Packages; [
|
||||||
|
black
|
||||||
|
click
|
||||||
|
mypy
|
||||||
|
pytest
|
||||||
|
ruff
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
exec bash ${inputs.self}/scripts/mcp-server/run-tests.sh "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
packages = (inputs.jawz-scripts.packages.${system} or { }) // {
|
packages = (inputs.jawz-scripts.packages.${system} or { }) // {
|
||||||
emacs-vm = inputs.self.nixosConfigurations.emacs.config.system.build.vm;
|
emacs-vm = inputs.self.nixosConfigurations.emacs.config.system.build.vm;
|
||||||
vps-linode = inputs.self.nixosConfigurations.vps.config.system.build.images.linode;
|
vps-linode = vpsLinodeConfig.config.system.build.images.linode;
|
||||||
|
mcp-tests = mcpTests;
|
||||||
nixos-mcp = nixosMcp;
|
nixos-mcp = nixosMcp;
|
||||||
nixos-mcp-server = mcpServerPkg;
|
nixos-mcp-server = mcpServerPkg;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,16 @@ set -euo pipefail
|
|||||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
cd "$here"
|
cd "$here"
|
||||||
|
|
||||||
|
cache_root="${TMPDIR:-/tmp}/mcp-tests-cache"
|
||||||
|
mkdir -p "$cache_root"
|
||||||
|
export HOME="${TMPDIR:-/tmp}/mcp-tests-home"
|
||||||
|
mkdir -p "$HOME"
|
||||||
|
export XDG_CACHE_HOME="$cache_root/xdg"
|
||||||
|
export RUFF_CACHE_DIR="$cache_root/ruff"
|
||||||
|
export MYPY_CACHE_DIR="$cache_root/mypy"
|
||||||
|
export PYTEST_ADDOPTS="${PYTEST_ADDOPTS:-} -o cache_dir=$cache_root/pytest"
|
||||||
|
export PYTHONDONTWRITEBYTECODE=1
|
||||||
|
|
||||||
fix=false
|
fix=false
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
if [ "$arg" = "--fix" ]; then
|
if [ "$arg" = "--fix" ]; then
|
||||||
|
|||||||
@@ -22,38 +22,38 @@ sops:
|
|||||||
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5VUMzYjZ5WlZtQ05LdnVt
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXdVVSeEtOTE1XQTBHVW5C
|
||||||
b3V3RmFyM0VZWmh4dC9YZFpsZkRIdC9TRzFrCnBuYnhSaUgwb3JuSUNFSWlwSmVq
|
aUVVbUltOGMrV2l6VGhRQXFnbUR1NVpnYmgwCjEzWXB5SVBtbjBzMkx4OUhkUXll
|
||||||
bEoyQ09XSjNBMks3M2ZYdlh0eDFNYjAKLS0tIERpaGhISDFYd3RCYUV6Y0lmdGNQ
|
b0FkcUl2b0d0YkEwQU9iNFZrcDJTV3MKLS0tIHNrY2JFbVEwNTFaWUdmdFJPZmJI
|
||||||
VTNibTBMN2RuN3doU3lYK1drNjVTVkkKMmRW0NtiYKBcUQ8kKjXcS6KjoPdVfN5d
|
SnhZK1h2ejhQUUNtbzFINUJmNGhiYVkKCMeBiPt80A8/ynEWy2e881y1tVnqANK+
|
||||||
6vczsKTTbUwI0n6T5xrwRdbVIFsP4HisjceQWxJIVBthR0u9dLfXGw==
|
wU9Bn+oRwoudPb1io9LAoTdu7+IQpLByt1phAju8m243nM48hAkipA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvb1ZtMjV5TjlhMVRwdWNU
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhUmQzMU9hTlpQbHBQMm9R
|
||||||
ME93Y0xhVGlxdGxmeWtXQ09EN3lORlJpV3k0CkJxdE14YXpwcytjbnZuMWpHVzZ3
|
Y0d5Z0lGTkFvYnc5MkRDbjNTMlUxWmI0U2t3CkdRQzdGTTNjbmprWEdYc0Nkckpr
|
||||||
dVVBYVE0RW1naWVVQ0JRY0NoWG9LZTQKLS0tIG1udE1GbEtTQ2o3bGl0SW9NZmtF
|
Z2xqYkhlcHlQNG0rRFVvVTFLdFQxWVUKLS0tIFNPS1o2UVZobU5xN0U2QnI4dXA5
|
||||||
OFNqTncyaHFUSzBNRzZiSTVBdkhFWVkK2v81N8c8cU1Ig9fQZOn0fltqO+Ej8Wtk
|
WWR1MWNGMVIyTGFBZXFyZlhwM09qakUK8Q26phHWY9zN5j6ZxB7+kmSgmcukfgiv
|
||||||
D0nMQv2fbWp6YlyE17VYPgmhdEY6+Zstve6PlBG86iQE3LTAfjG3Uw==
|
qAAzIGdgsvnUiFZCEJHD1D686C+ZxvakD4p9sA/zEIyeIBtKCq3lIA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJSVdUWXRUa2tHVGczelhu
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHR05GcVViZTY1Q0NaR1RG
|
||||||
UWk5RFl6azRJTkdxZGxvbWlnSDc3K3NlNlgwCjBRZEVta3RuNW1DZmo4RXJyTTNk
|
SWZzYjlxQUttS0tXc1ZDbDljbXczd1gxL25ZCkM3TVJ5NzlIdUx1dTc5d3R4U3BY
|
||||||
cnpxTDRGL0kwQXJmc29LNE0wV01hUGsKLS0tIGgyTWZrOHVNTGExRWtYMzJ1aXhp
|
RVBLazRRZ2F0anJZRXl3bFdsbXJhdVkKLS0tIFVXN21DQmtqZ2hIRi9FM2dtTTlw
|
||||||
cURNZXBtbnp2OUZDZDZKeEMrZlN0TEEKznlmLKFHYDm/hv3EPcHjT0A8r06GL7if
|
aHQvOUt5UGhhR2ZXMVFOOEtKMDRtZmcK0ZX5pF08o+HLztgL1/LocDGIcOGPKqXe
|
||||||
tbuJei8aWWg+uuvCBTZjHqmPUyNR1ixt84vxy1HlwXVu3dYHcG0Wug==
|
9bRBkUtr5QuIxQEYj6NenhkeIxRoPxK9Re/Vsqpphv4NqKpzyOujcw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ml3smrs5mwz4ds84gk0eyss86nwsmp07qh0npxsuae7lfwwpsghssavytw
|
- recipient: age1v2ahkl759cftpcdq4mla2cvmgz4jlnmgj7qtgc9732zxrfvxf3lq76zjpr
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZYnlaTkd3LzFRbldWL3RZ
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYcmxldjA2UllycEFyTnpW
|
||||||
N2ZneVIzMnRpVVNHVWRMdXJLdjQwSWFKS2pFCmlQZUZMbG03VFVuUXcxZ3NRWjVH
|
c2dIa1NXYVJSU1lwb0EvckxQQ0J4ckhSeDFBCnBTZGRYUzdSK08xeWFmaUM3SEZ3
|
||||||
SHVPYzk5NGpkeUVSU1BmQnNuaWZnZFUKLS0tIFdQZEU1YnhHZWRIajNYWTYxMEwr
|
bXJSUG1OVEU1T0Z5VGRqYUloa3k0RmsKLS0tIHdRcXE3Q2lLZTRvL3ZCSnZtSk1K
|
||||||
UVBjaDFtSWs1b29DR0R2WS9pSGh3OEkKmG34ldBy4s9nj3ng/HQr+gN0LHJCOPJ8
|
TU5Iby9qamRIcEUwc2dTdERFVmNreTAKh55E4KbM6WeFhVx3KDI/pYq+1vCNwDj6
|
||||||
EWhh7cTLSF9AmZKP0sBsj7I4hHhZlOn85bvTM9RDiRVOSz8VrObXHA==
|
6zfXWJvyD9Icn2ZgqpK30wyJ/R/DzmpTDR8AtujXHT6/Uikn7M1fig==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-09-21T20:28:29Z"
|
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]
|
mac: ENC[AES256_GCM,data:e267Kxv1Pyun/VOcLepBDBEKN6uSf8/iuY8KQ8u4xK58wsWkMdSDVcDKvO/iKF/Tj9hj+lZapkaKmp5SdeX+gjpyWiZi6QmUuKsCs0jlkV2NydLtZZt9vkmY/LCguIBRMmhDgidrNcfoghTxDDK5lng5H+2MBs0r2zLID65pHUQ=,iv:tr4YFdBltnsD4uTt+0NCam7r1QzhOmdoEbfz5/+JGPI=,tag:R2dDWTC1qrwPI9ghaf1FEw==,type:str]
|
||||||
|
|||||||
@@ -21,38 +21,38 @@ sops:
|
|||||||
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjcWpKQ3RqSVdxcDllajc2
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhV0xoZEhJYlZIUDdOSlVv
|
||||||
UzVtdmxBWmJ2QkI3SGhYRlRadGJYaDU3UVN3CkpQYkxhVm5ZQ2djbldYL2VmQWsv
|
RGlOQmdSSDROaVY4L2xHSEt3cVVpc3MrRkg0CktGQ204UDNYcXN6NDJqTXFpdmxQ
|
||||||
SEJmam0zMzlJSFpHS3JZWVorUmh5ZDgKLS0tIFdWdU44VlRDZllCYXRTQzNyajRy
|
RUYrWDNCZzlObWNyYStWQlRqQ0VJQzQKLS0tIEY4bG41R1k4NDlabGhoUEl4VitI
|
||||||
cDJqNzA3ektRWll6SkFsVnFMd1FBUEEK0j9X4lYcFaj4MnVh4jnNwrTg2Sl5TTdZ
|
YmYvaDNWRzRlMkdUdVBxM2lwd0N1bXcKp1iUENgs/0RL6PN7b/mwbBdIPuDFfWM4
|
||||||
uFvTdE4ZNtZsh3nKmj+v2J3JM8dDUtw2NSooqpoqEvCYdDqwK1kDXQ==
|
9gXuoW7FiS5MYGdUY5Ub8WlSfA6iUww+t6FB/rBhK9TDXOfIKRYmgg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGSXlITkpxcHZqR0kzMlFY
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWNEtaUndrMGszbHpuYWtx
|
||||||
TStOVitPSm0zTURZcE92NkM2ak8xcVF6OVZBCkRRbkpBNW9yek9rWFlOa1pLSk0r
|
RTRCc29YcmQwYWFKeTFtaHBpM1NjR1R1dGxjCklsTFVXSmp0OUxVUzVYeFJnSWI5
|
||||||
ViszS3pMNFhLQlcwdW83R1hhTUJLT0UKLS0tIG9NTm5tNzlidlJmejdoOUkvUE9X
|
M2hEM0pjTXowbGZsQ0tHdnJYdkxjTncKLS0tIG0zUEJ6ZnNOVmd5UWF1K013N1JT
|
||||||
RzV2MUFEMnlHVmp3UmgvNmJKSDFrWHcKQ7y2W0PFLs/I6Tb0J/M91+toDP8XmgWh
|
dk1HeEJ3bkVUWnhIakt4eEdNUi9aSkkK6Ug6dwtSEpzMpgKvozR8BO0ir1YeRBQd
|
||||||
LYuNc9lkjTs+ylIWuMTwtXdceI+kK8hJlELT47FyKl755DzuB1ufAg==
|
jDtkNhpc32P5uZtx/kv74vIXgOT7KCSb03b7mSIl13J2IeHQDZTPBg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzYXRodjgzR1hoR2VDNHd6
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWMm5NRmg5Y1NYNDA4MkpR
|
||||||
NGJ3SXpqRmJKVlY5aTI0R0hBLzFGQ0VSYmpVCi9BakFwRGlXd1ZPbWpHY2h6RUo0
|
M2RPM2JLZ2NMQm9uNURNc0lSVnJaMHE1MG1JCi9CY3U5V1pnQjhPOXl5NlN0eTJW
|
||||||
VGl0T0d1LzdaZGNOZ0pDekZxVVBWUlEKLS0tIEdtVDZlN2FrcFhEU2pTMUdiZ3NH
|
d3dXQ3hMRGNjWlBQZDAzc0ZDWWUzNm8KLS0tIHMxQWdvY0F4Mk9zaElhMlhManFu
|
||||||
d3ZSMGdkNzNaczBYOHFuZWJmcEM4MXMK6ayh37HUhOYPryv2Y2WlE1U0CX7qZF89
|
TXNGcFZRd1hPdW1wWFpPRklScGZqVXMKwHv5CDSdlaGlXqFKoK9motAWNVMzerXy
|
||||||
PzvHQZYcbZ2gsRW2f1uU2VoJp/6XnSipD7fCjma3iNovoPlu2+A0yw==
|
6K2KVn3tmlAiBzkwuEVVa4jafQjd0t3J6bPx047DP6fPZVNLMElctQ==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ml3smrs5mwz4ds84gk0eyss86nwsmp07qh0npxsuae7lfwwpsghssavytw
|
- recipient: age1v2ahkl759cftpcdq4mla2cvmgz4jlnmgj7qtgc9732zxrfvxf3lq76zjpr
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4aUk0WVhTUTZXOVRqam9O
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIaTNnYlFsdFBJeGFwdUNl
|
||||||
WkVNd1FKdDA1SWpwWndHbmVBRlNaSWI4aEVnCnJTTDNYTkRtNkR5cUl0SURVQWxh
|
MVc4OXorOVhJcDBTWDZaT3pQbTg0UFlGNkhrCnVST0IrTnliREpmS0dPMzVDZUJm
|
||||||
d0c5cEhJVTZ2YXdLdHFQRk9KN04vcW8KLS0tIGF3Rmp2Z0pwM0x1WnpKaVBiUE5x
|
aUg4SnhtNlcydFYyTkp3N0xaSzVCREEKLS0tIE9tZmZLUERnSzY0aDdkTnY0SXJz
|
||||||
MVBONDBmQjI2enNIVFFQT1hyYm45YXMK2NXWvm8G+Yrvw1NAC6AiDaxA9UftuqYe
|
UDltYm4zalM2VmxmQjJRSVQ0YWpuM3cKsYQOOppHVJT2tbQQ/jXy4NcUX6aWjQxT
|
||||||
ZB7QpfkdCT3vS52lBgcEJrM1TbaVX2868trk5kB4gjqVMPVPYxcGHg==
|
Y/I40tBrkwnzVFpVvf6COS+oC6/yRISwWJYYvia9xVfC5+kss9cFIw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-02-02T03:55:24Z"
|
lastmodified: "2026-02-02T03:55:24Z"
|
||||||
mac: ENC[AES256_GCM,data:+NN+RgkHAIox1IgUuC2ACHneRBzgn5FzsujpbPtmw1IecxeKMMXM7Wa1ZziSkWJSjjDCcBoanox57e+BoNWN5WhWuMdCed04AKcknfKlHAtHrKhoLCsi1sZnsQX7xBmTsA5qHD8788EWfIgPk4gToXkq5KkEfvEWLvalClRK7tY=,iv:kGyw9hk6vp5iu0iMHaCLgVqdcv1gNUBqBhZbRSCa4Ks=,tag:FdKL/5ZraejphDIE2ig8GQ==,type:str]
|
mac: ENC[AES256_GCM,data:+NN+RgkHAIox1IgUuC2ACHneRBzgn5FzsujpbPtmw1IecxeKMMXM7Wa1ZziSkWJSjjDCcBoanox57e+BoNWN5WhWuMdCed04AKcknfKlHAtHrKhoLCsi1sZnsQX7xBmTsA5qHD8788EWfIgPk4gToXkq5KkEfvEWLvalClRK7tY=,iv:kGyw9hk6vp5iu0iMHaCLgVqdcv1gNUBqBhZbRSCa4Ks=,tag:FdKL/5ZraejphDIE2ig8GQ==,type:str]
|
||||||
|
|||||||
@@ -5,38 +5,38 @@ sops:
|
|||||||
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4R05sUnl0UFd3T3pzRm1y
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsNWNIek9yVUJIYlhSQmVZ
|
||||||
U3piNzlpTmpZeEhkeWJxRkMzRzBWRW9LQmtBCjRHTVg5ZlozUnpsVjhIK05xYjlz
|
NENoS2dvRDVENit2bnVNQmJ3TVZGWTkwTFh3CnViekVsaTVFZ29iQXNXUTNPS2U0
|
||||||
c2dwbWVKWVNXWFhTWEtlUUFjVUw2RkkKLS0tIElaNXN2ZmROdHd4bWljM3FyMEh6
|
Z2JsWWN4T2tUckVJU0tpNWFaYXpGVTAKLS0tIFowcE1tZDdPREY0ZGVzYS8xNFFp
|
||||||
Szg3WTdrVlFmSUJ1S05xNXY5RlM1V1UK7YETep9hn49UqRUjbRv6oGFUT/8lRgXx
|
elN4TnZjZUtGOGZ1c3FiU0h4YytLTmMK9wXfpIgMcPD4FpO5CNIXnJc0wJliB35g
|
||||||
5O5eGB1X8kPCY8zXiGWSzfo6X8O5659vWIvqjoY8nZxekgvsISS/WA==
|
v4wiDb4zU4VFfWzdimSXjgZrI/ZIqB4Bx/PPi6SPhuT4oQ6LSH5sKw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpT1oraHpJb0NUQndMZW9l
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtSmsyR0N6SWMvQVl2RzRZ
|
||||||
YWZrOVBqOG1KME5PYS9YVE4zd2VQb0hRN1dJCmVqSzhkbU5DVmc4MFVnSnVYTi9V
|
TUpXbm9oTmswdXViczVBOFBLL0lhUmV4WXhvCkdqRG5pcStUVDE4S3FSL0R2TTlG
|
||||||
RUR2UDNEK3JGOEFUWVoraGtqQVFFWkUKLS0tIDVRdU8rV3diVXNUQSsrKzlBdmFN
|
Sm1aZTcrejRHdzU2dFozSUZucHFtUHcKLS0tIDJTSmU1dVhSeUxMSnd1NGlkR1RC
|
||||||
Q0x5QXdaOXRMc211TUhqTndQOXR6ODAKtJYiAeVTYPOpS+GykBDOLx1g3VloFo2P
|
cVVIcy9QRFArUkdIM05neG5aM2EyM0UKSCIv0iU/X9bVoQCRxcQXwMbr0GE7MGkb
|
||||||
fDIkOCrINnAU4y07KPhGBxCV3/2cvOPhIgsd02XqxfZPCEU/cYdCgQ==
|
pn420gXMiLFBE8OOhkHg7EEjuR3n9iB3f+pTgN5v6UkxZBmZ2Xr4yg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4dTIzeCttSGNVNmhPejdW
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlL3picmtSZE8vS0Jod1RV
|
||||||
ZFkySng2T2ZYdkRrRGRXQVpER1NJMW5XN2xVCkc0VTdsbXdLUkg5d29zZ3VmY0hH
|
aGNlK2t6b3RTZWRPUmNCZXN0KytSRnRuMHdNCkd1VjU3NEhBOE9jN3gvblM2NnZF
|
||||||
U1cybHNob3VkdzRWbGt1bFhNeW9XN0EKLS0tIDdoc2cyaEIybjBHOU5tdVRsTWFZ
|
TDRhVGh1Y21YM2J4WTZtenFHSDBBNncKLS0tIHZqcnpRbldWN2cxT1I0Qzgva3R5
|
||||||
TmdZTGNDOFovMDVPakF0WTdHaUpHeFUKl0ub1OOylE2JGJNpeReebiOaVdxbd0wv
|
a2lsbG5SUFgvZXlHWUhOc0xQS1dxaHMKDMGQujRa0s4kjrQod11mn0otxO2Zl/bv
|
||||||
nvJD7tYYXI666Pi31OHttWhsHR+xkL8TU9Dd6uDs4QxIRQfwy/VxcA==
|
kHG8ufANpJS5RfKNLMhAK4piUtr1o97471MSGA0ebZAUSK01fQBNfA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ml3smrs5mwz4ds84gk0eyss86nwsmp07qh0npxsuae7lfwwpsghssavytw
|
- recipient: age1v2ahkl759cftpcdq4mla2cvmgz4jlnmgj7qtgc9732zxrfvxf3lq76zjpr
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGUldWbldqTTEwMGF5RVFV
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4WlgxL2xMR1p4eG1Ca3FM
|
||||||
ZkZ0Y24ycU1hVDlaTnpGQW1SeFlzaXc2a1FrCmtrUkxLcjNsVHNXemd1cWJJdXI5
|
c1JOcDBhaHNlUjRNZjFhVm9CdkN6NEdqdGtnCnUwUFBtLzYvM1kvd1NVREdwL3B5
|
||||||
bDFxUThzSFptNWtXMlNqM09aeklUMTgKLS0tIHR5KzE3dStMTXlhUWhtUWUwSkY0
|
MVc1UEdaSTlhWXFadSsvbHNTaUZKcDgKLS0tIDc3RDg3ZUkvRVFvRWhBWDFHZjV1
|
||||||
ZldyVmtRVGppQ0d0SnN5Tld4cEtmQ28K1Yij+7OxQUpEsPt/GTnP+dhEErBH1HuL
|
NGlweEtoVGdqT2J3UzNGaGt2RFM5eE0KUCFvcv39dFM0Vm6uDuntsnZyMq+LHfJW
|
||||||
pBFXqHLAwpqiEiiNhYnb0KVWeQnIqDo9WUnrbPavcWSrSkmCsszgxQ==
|
Sts7AJwVIGTmOolImqoVTeKFYJZu5oeKZZNsEG+gvIZptxaR0jPtow==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-10-10T05:09:54Z"
|
lastmodified: "2025-10-10T05:09:54Z"
|
||||||
mac: ENC[AES256_GCM,data:N/BwfrwWcnot36Kn6RFZjjpUIluzq5Upy5iVVV4XSs+/0PYdlZGytjoAB+E3gXyPsLZ93UqI0A9/5KbfXBuR2oY2F7iKsu5puzgyYWa0Gl2z9YcPnyDnk1dj7Ne77xJlqR9YquGzFKF8QdqFXFA9cdE3b/1usTFhP26oxofMXs0=,iv:Iz/LzS8yeKQgDiGchYdKNymBeekhopJtBWaQGOwRZlE=,tag:hMRwxJlKR21W7otW01GmGw==,type:str]
|
mac: ENC[AES256_GCM,data:N/BwfrwWcnot36Kn6RFZjjpUIluzq5Upy5iVVV4XSs+/0PYdlZGytjoAB+E3gXyPsLZ93UqI0A9/5KbfXBuR2oY2F7iKsu5puzgyYWa0Gl2z9YcPnyDnk1dj7Ne77xJlqR9YquGzFKF8QdqFXFA9cdE3b/1usTFhP26oxofMXs0=,iv:Iz/LzS8yeKQgDiGchYdKNymBeekhopJtBWaQGOwRZlE=,tag:hMRwxJlKR21W7otW01GmGw==,type:str]
|
||||||
|
|||||||
@@ -4,38 +4,38 @@ sops:
|
|||||||
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDa3NpNG5tenhqWVQ5RFAv
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWaEZKVnhKR3ZnalQ1dWZy
|
||||||
bjhhRWJWK0NFQVk0cGVpcVJGS3BFeWlSQWc0Ci9IT05mQTVWbmk3SFFpWE9KUnh6
|
THJ1Qi9EK2NHQXUxYlg1NWZqd1VuRUY0a1FNCkg0UmphaktuWklNVE85c1RuT3FV
|
||||||
bHhCSktlbzVUQm1lOHp3cVpiSHU3MDgKLS0tIGg1UU4vVVo0SXRwMjJsVUZEZkFC
|
bUwrVzIxQ2JhZmNqdnR2SUlIcGNiazgKLS0tIEVDZk4rV2tTT0pLd3I2RXVIZ0pC
|
||||||
TC9Eb2JaVUFDSWRMYm5jR1BBa2lEamMK4V77WUVbMXcsw83FFdL2Rk30oR4cAkqQ
|
RWJCbkxHMm1DRFJKZkRhRldiRFVFd2cKQvohCMbXDJzOKzfAN72/1S4CXj5d0bbK
|
||||||
kc8Z0+5kNJFUFilFb54dnWTOh27K7KZvU1qIdhG3X9fuMIHSuPnyTw==
|
Ge+V8Ew9S4+UR39iLtQzs7lNYYCtDxNnayEm0V8LlVkgeEj2HnS0bA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDRVdYVTY3QzR2MFJPVW9j
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBheTV2MllUaFMzTWpiRnFw
|
||||||
SUtmTldMRCs0dTlJcGFoMDVnaWMyNlF4OHlnCjg0OFFrOERKRFZVMm9NREhBOGRs
|
a3hHeFhyNHZGek9tWVhySnVLUzNDVzV2VUIwCitWLzJ1ZG4rVHRwZElOdTdXMmdX
|
||||||
dTEwc0NZUk9hOEtvNVJDRXl0TDhCaTQKLS0tIE5OWm5CNzc5SW9IdGFud1N6Vm1D
|
ZG9RVktFQ0VvdDViSi92YzRIZXJYOHMKLS0tIDZkRHYrMmtyZUh6bE5KaldvMDY2
|
||||||
djhzM29HK0FIdXIvaGIrRXlOMisxaTgKVCAiniAmfqJuwwiUpcGAvoyqnUEZ9gOS
|
MitQdXpDTkNxME1pV1BML1ZRRG1NaWsKUBHmQa1io7qNp+xkEmYsn7Q6XSpQ/566
|
||||||
SyhXMzv2cbomuOb0NiALRkd2up/uX0TVuz9wuBQvYYjJhqpFuSnbRg==
|
KYVB7GMSyp5YYsJv1vA8tLHnavLDam4zMZ1t24dgk8pWOZpJ4T6T4g==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1UlM2MC90SEM5elBtNmpm
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkanhPTzY4WEhVLzFvbjhR
|
||||||
cnpTQVF0VEpLUDJPZkEyeGNuYnl0cEY4M0U0CjhOY25BcERjOThkbkVhNnJtaVpv
|
emVmVmZIRmVDelpONmM1SUhuT2Zadi84aW5ZClRaVGwrbjlGYkZiOVR0V2RuVWR3
|
||||||
N00zOUZPWnNYaEtYMzlXZk56dGVPeGsKLS0tIDVDcGY5cG1ETHk4eXRFN1hVOXhV
|
UVBlNG9RUlpUZlJ6VFhKRHQ3T1VMRVkKLS0tIGpUTzM5MVA1LzdsNW5IMGlZcitR
|
||||||
Y2xncFJuNUs5ZkhLSjJyc2pzdDZxbEkKn/8BtUXPQ0OdR35ZwiHWFB0AqaDtAlG7
|
aG9pR0RRd1NBalhweEdGNnNCVHFvb0UKIiFruo9rV/VD6XykanHIpbI6G6D3cGG/
|
||||||
N4Z7iztqiscuxn8G8VVVFdkQLBY3JcrXhxPYWK4xtJeEtpIMhegxeQ==
|
ZGSxH1HD9qIVYDQ5LpBfUy/dZxRnpTiBJ7Veg/Siemz7kmChlmVDQA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ml3smrs5mwz4ds84gk0eyss86nwsmp07qh0npxsuae7lfwwpsghssavytw
|
- recipient: age1v2ahkl759cftpcdq4mla2cvmgz4jlnmgj7qtgc9732zxrfvxf3lq76zjpr
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzd1VYanVSZTd5elNlZ2NC
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4UWRTR2x6aWJEZ1p4aE1O
|
||||||
bnd0V0VZVmtrVDhBbW5KUHJDMUkrekVZeldRCjBNY3g1SkVKUzhRL2xsbjloUERi
|
RGpSM0xVRVJpTDhVa0dhTWwwTVp1Z0NkTW1RCkxRVUhkMklZUVhDSEE0bkZHaFlu
|
||||||
UXM4T1A0a1V2eEFlQWlTQ2tDdFdaZ1kKLS0tIFFtNDZzbzYyaE5UT3R4eDJzNnU1
|
UGRvYURuMWwzOUtoTzV2V05kblRpNnMKLS0tIEgrYXBpYysvenRGMENNcTY5L0dk
|
||||||
RG9UbWM4YTVHcFpKblQwemNScDVteVEKA6fibq6Ozwrz/tg9Hrx4bH9LCadmW5fR
|
a1pWRTkzSkZGaTVtbVc4VjdHdkpneGMKq+3Pd2dOJAnC/PKEYijWbk1vQSes3ykt
|
||||||
IkFalgD7nqew8KwS0keyKFk93i2p6sTDZPy2/t+WryMXBIc/y0iQ5Q==
|
1A88VIO2o/isCLr9643SVkZQ4WbISA4xvInG+peEdbja0oZNRQNU3w==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-02-01T22:31:04Z"
|
lastmodified: "2026-02-01T22:31:04Z"
|
||||||
mac: ENC[AES256_GCM,data:gtTuLmgVd5t1Eic+ld6x3pmAlv2+SVf4OgUICu78DJ9L1YCtmJ+LsqIoHFueMdQAmubPA8c4xYsHWCDu2dbrUDUs/79BF2u4P9lbNkJx5cco8bnPdy2tmkhcLwb0HwRduVIbgcm0wzYKUMd76Y0ChxdCddkrkk+PjXkUE7OBNg8=,iv:Eqhoc6GjB1NOnIIeRIdVoQNQm51DguH3vEX4zRUgeBE=,tag:V25oIemZpdJDMRFcZkH4bA==,type:str]
|
mac: ENC[AES256_GCM,data:gtTuLmgVd5t1Eic+ld6x3pmAlv2+SVf4OgUICu78DJ9L1YCtmJ+LsqIoHFueMdQAmubPA8c4xYsHWCDu2dbrUDUs/79BF2u4P9lbNkJx5cco8bnPdy2tmkhcLwb0HwRduVIbgcm0wzYKUMd76Y0ChxdCddkrkk+PjXkUE7OBNg8=,iv:Eqhoc6GjB1NOnIIeRIdVoQNQm51DguH3vEX4zRUgeBE=,tag:V25oIemZpdJDMRFcZkH4bA==,type:str]
|
||||||
|
|||||||
@@ -51,38 +51,38 @@ sops:
|
|||||||
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWRGVscDJsU0ErZ1VBRzVq
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnVVQ3NG9lM0l0MzlYaVA4
|
||||||
dE5aNUZvcmhVRHVjYUJFT09hdDd0UzhIS3hNCkRFRlphRXBTd3VFTE81RjJRaE5w
|
dEpOajlJeUxYTmJlMXJJMlN3UnRwZHEyaHlVCmYya09LMU5UQ29pQ3JCeWJnRkI4
|
||||||
bzJSaCtsT0QwMkx2WDVyZ0FzeFphWk0KLS0tIGN5M0QyWmQ4Y3lCU0FXaU9vL0hv
|
ZEpzRk93WUhXR25QK2c0UjRlTnZld0UKLS0tIHZPUGthU0tBTVNzRmFmVUxnSkda
|
||||||
MEp1ekxTdWp2b2g4dFd3OVNkUlZBMGMKzNGSzYgQsNW6HEvzTWmo73GShAAv/g8+
|
RUVNLzM0QUZLRFRCOFpjTXY4eHprUWcKK0+r6kWEw+gC8P+afVvw31SY63PTKb1C
|
||||||
h3/6n/ObqlKsjDyVFgiOYop3LWfwPMzmOhx4S0wsOHit0UxdyoJwWA==
|
D1KCOugRHnNT+xOELiVg9jjFW5lTJc4U2OBe/IpsGBujleXrWKwpvQ==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLUGFaaHFtVWl1cG1XdlRT
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZY0JpODFjNkhQbnFHNlJU
|
||||||
TUh0MHZTa0JhdDFSTVJZOWJBd0F0SWI0N2tNCkdnaG5DcXdDT3dqRVJDcjlsZ3Fz
|
V0s0YWZSTC9OTWdXR2h3S0FkM21CN3NocURVCjM5TWNNYzhkUW5jcHVuSW40ejJs
|
||||||
ZFFaeTB4UTBQRVYzcldndm1RSjhCTzQKLS0tIDJySFIvbGpBd0l4RzYwVUd1MWpF
|
MkgydVlpejhzWFlMZHNGMzdqaEpPcFEKLS0tIHdzQ3UySDFpeWhVMDk0dmswTW9N
|
||||||
ZHhxdERrd3VNUGpTTlZUM25RYzJwSjAKG2DZUyomWm8Nxn6mPDKbBh1YsEUr642a
|
U1M3aXlqSHQwaG1DZysza25KZVRDU2sKp6kZa/6/Or9zdLTfFf/lKWcoHDz4v6p7
|
||||||
nGYxmuRVBVINbOB3gBPwgLeD+S2Vlm4vrC/u2761fTgm8KFLC+txpQ==
|
UEAA3twa1VXAk7dqmDmp0Szngu8y7iF9BE5fS1nb5n+rUa9DrwWvng==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXTnc0N3JWUGk3cWV0QXNK
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrU2Y1RC9aczBVWjZoS1Vp
|
||||||
L0ZWM0I0NVlVbTdsZmdRall2V3FUTllidlJnCjQwbFJ1TjVNQjl3NURQenBDZVhy
|
VFp4VmtkME0vNVpnZXRYQmxmdHhZb01MelY4CjhHcnpVenVFd0YxOGJmT3pOOEF0
|
||||||
QXEybkIvc0RnV1dNL1Rhem9GajhzY2cKLS0tIFk0Nm9JK2ZvenJsYVF2RUJLVzVL
|
a1VBNGpSNSttblF3b3ljRDI2NjAwbzgKLS0tIEdiYWpucEY5N0JVN215ZWNDZmkr
|
||||||
bzFWRnFjd01wbDVrQnhlb3NYampEVEkKWl3/oymEX/TdMHyxE8mOopIwu4Kots27
|
SlJJaUFzaGdwdjhwdjJUWG1TdnZIWHMKGvQWCQNr83Z0CP5jGHc2wvqOIUdGC7+2
|
||||||
teyBmo6aVTAQ1zSxGDszI6kgK6PC3Z/WqaMaoJilGI6k8vCkOT3oMw==
|
8buS4XK22o7EotL4bbKsEw5dgWQIBRXH+9XCq56RIUYR0T/T9UW0ew==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ml3smrs5mwz4ds84gk0eyss86nwsmp07qh0npxsuae7lfwwpsghssavytw
|
- recipient: age1v2ahkl759cftpcdq4mla2cvmgz4jlnmgj7qtgc9732zxrfvxf3lq76zjpr
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtaG1Ea0ZyZ1IrRGxEaUdw
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnblN2TkRudTZCN2Vvcldr
|
||||||
TzlMRE84ZDBXRTNFWHcwNE81MDZlYStTZWdFCmxLbUxORFNVVHRGYXV4bDRvV1Ra
|
UDdBNXYyaUJVdkRDL1Zlb21vK1NlTnJyV1MwClFRMWpQYmo5amRWMTRCTlYySTRY
|
||||||
Rzg0YnpkaDJ3alhxalFFck10MjF4MG8KLS0tIDgwSEhReERtZHZ3U2RWcnFaaHlI
|
YStldXhHdnR4RUcvNFpVbUZPMGpFQU0KLS0tIEV4MGZ3YUJjOVdLNDF6RFhIOGs1
|
||||||
UmQzNEJVVTVPRHFqVlAraTR2bHNOdmsKKCVCzZ10sEA7rGRCUxbpYlaR6Y2jZvho
|
bmtmNDJ5OFlQYlZTWmQ5S2FmdEZ3clEKYRQ7nuP3G63vwyhW0wLQISrkiY98F3jx
|
||||||
THbZe5MHY1a44L2XQSZe3I+1qOVBWVSL10KYTjJIBTxoeBtjlQJAVQ==
|
7c9qMd2eGVvrOQr5M2OEPcjKexBa9Qt6O5t+dABrTmXCa42B251zWg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-02-03T21:56:09Z"
|
lastmodified: "2026-02-03T21:56:09Z"
|
||||||
mac: ENC[AES256_GCM,data:Bnjo3TFYoGbtB8HF1i+ZQLlfeBMOjq14lu8oLRqcZ6Fx5Am0uuh+/PHClWZ/JX5suC0Kb81+aBHg2QTsLoB6zdUrRpaqa0CUxTDoGw8tpo8m6zLWvSggpYLAuRgTYqBZ0lVK1QxAi9+qVJQ5AIhYwSPrf2oq/Mpq4tFGUoG/tzM=,iv:8JqAeBVYnZM8A+CPAlKN+6SDty0XQ4AKEBJLGV8Q738=,tag:CQXE5QsfJMiI7UQoCfE3dQ==,type:str]
|
mac: ENC[AES256_GCM,data:Bnjo3TFYoGbtB8HF1i+ZQLlfeBMOjq14lu8oLRqcZ6Fx5Am0uuh+/PHClWZ/JX5suC0Kb81+aBHg2QTsLoB6zdUrRpaqa0CUxTDoGw8tpo8m6zLWvSggpYLAuRgTYqBZ0lVK1QxAi9+qVJQ5AIhYwSPrf2oq/Mpq4tFGUoG/tzM=,iv:8JqAeBVYnZM8A+CPAlKN+6SDty0XQ4AKEBJLGV8Q738=,tag:CQXE5QsfJMiI7UQoCfE3dQ==,type:str]
|
||||||
|
|||||||
@@ -19,38 +19,38 @@ sops:
|
|||||||
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQTUEycms3ZkdMd3hpcXJz
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCWm1RTldOekErU3pxcEpP
|
||||||
R2pZZEc5STZ3dUdYbUdsSGJaRWI5TWNMK1RRCjVxR1pzY0ZVUmcwSjJFYktteWoz
|
dWducG4vTGpuYkhlZDY2a1lLemRFaW9uNFRNCnNtRExLbVBXUVBXRjhhMW1NcjR2
|
||||||
YmlaVkFPRnZha3h5ckV1TVQyVWZKdGMKLS0tIFgvdWF5VEJwTTcwdXZ6SDRMU3BL
|
dkR1MFBPdDhPMldaYzk2V2pYQjZWeHMKLS0tIFc3RDhLVXdtaC82RUpPWnVGdjc3
|
||||||
V2x6NlhyY0pmUVBsYmZITjArdjJRbEkKvzsJxs5EHR0uumwhZ36MhKuMS+WkogXU
|
d2JyM043WFJSL0grR0FheldHdWFSTXMKxf4LZ1sKH+HKKCT4w8AmKk+DtVoSobtn
|
||||||
nSVRQoc5TClzYwShY1ltHK+LCl0DlB4xFoMiO4GWwH1TySKe/ywpUQ==
|
20acQeJsbuAng+/DIQccPSp//3+3YkfsBRfSGg90vQPNKzxxNmrY1Q==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnQytNaUs1M0hiYi8vdDUx
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmSTA4Yk5TbmIyVzJWb3h1
|
||||||
V1NtZ3VGNFVjRHRWUzliR3M3Q2Z6K3RWSHo4ClQ1RE1PeHJ4REpubVJHb0lJcGJ2
|
bEFsb0l0Uk5jVDdvL0hMdlBFUzBJdTA3bEZvCmRMRmdyM3lieDVGVDZ0bjRpSngz
|
||||||
SEFvT2YvNWhMc2lneWR5NmRYc2pzVE0KLS0tIGxkRWRRRTNtVDUzVXh2L0lEa3RK
|
c0FqNjRWN29zdzFsRnhtcEhUeEtwb1EKLS0tIEkwcVdpWmhKZEVZM052WU16aXZi
|
||||||
YjFSUDJHUjFUeVBFbUlKOS8ya1ZhMW8KssRH3/XT1iCVgV+6Sh25Axp0c96aHtVX
|
UjFxUlExazVhc1hkcmZuT0ZadG1pTmcKADLIwbz9KlPgTrs3kxeWEgKsfh9K9Qyp
|
||||||
/HXN3AwTm0GJZCQnZsVIIPtoCzhUZSza+bzGZIZODYtgtCIxtdzVSw==
|
+PSLBc8OjORDBBqqRcFJ3D9paiqppegGAPKaZ9INCXVoWke+wEOL3g==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIbkZpZFJCY21IRkJjNkRB
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSM2h6Rkp3T1c3UTJXVGEw
|
||||||
UEdEVlZhRWhRb1ZDMjJtMmpkUmpnY3ZvMGlFCnBLcHlkMWNyMy8wenYwT2pmRTZL
|
ZHJJNndrUGdtVnZNOWJobzZFb2U5d09LekJzCm5mSUd6V05BUUZpMm9US2JhRUNP
|
||||||
dWtiWFlaR1FrL21HQTFZM2N3a3BHYW8KLS0tIFlYZWVHb0VEeDU5NnRjbDk5M2po
|
YnZ4U1RBSUdMaHJnd2ZGNVFyT2hKeWMKLS0tIGpzUHlVU0JMbitmSzNjOWdaRFFI
|
||||||
K0xRRFhua09DRE04WUd6NlZuQldFbEEK2OgiawCbCtbrk8l45QdjVu8+VNWbrl4i
|
YlJoZUVoQWFHMEg4Umo3WDZHUVppQncKL8HtEF3+uI/qm8K/u7V7IlEv8Lt0QwQv
|
||||||
3U9iwek30JkQSZaWBXaCZlWLvbKNjIMpwTtxDOhxmu4DUh3Hx6In/g==
|
SPzuq89L/aT7hK3LyB88B2pvAKE2Z1Kj/3Z3depQfujIQsulpIg1lA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ml3smrs5mwz4ds84gk0eyss86nwsmp07qh0npxsuae7lfwwpsghssavytw
|
- recipient: age1v2ahkl759cftpcdq4mla2cvmgz4jlnmgj7qtgc9732zxrfvxf3lq76zjpr
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAySjBmaC9rREpUQ3BvWWNU
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiNWFNMXVsdWJKYXJaMCtM
|
||||||
MWEvM3ZGb2RXZ0dMdWxLRTJCR2VSdyt5VUhBCjBvL3MxZ3pTaFQ4aGdZVnAxUmd3
|
NHRVeVV0d0dXQjhwTk9ZbkpINUxUTkNISXpzCjI3blp0bkZiM1pVcDBYaVkwaUVQ
|
||||||
YUtoZkhEV01TU0drRUdDaFZ5M2tZLzAKLS0tIHpBL3NwV2NhN0QwcHdwbFpQWlZn
|
ZTRicDhmdXpybzI1SjZSdDAyYmR1eEUKLS0tIDdUTGdvQzFXMDBMemJUMTc3MURD
|
||||||
eUNjc2RPOUxLTGowTlRqN3lEdjRLU2cKTTEXmHyhnL/hZGDr8ONrmzdU6Or5xkKY
|
S3FxRUI2eEg3bGs3Rjh2YXhiMnQ5eGcKAHlMDXwb1uULH+lLuWW4dMxofXSbKRMt
|
||||||
GHADDt+LCg8njcZom39Aj4kpCx+f7HlV65glKwr37vZ0sL9KE+O9+w==
|
Ce/mfgDwqERw8h2yotOoSkNSFBQ2kPLu3/NeTsVAfbdSMyp/T3aJ5A==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-01-16T15:38:39Z"
|
lastmodified: "2026-01-16T15:38:39Z"
|
||||||
mac: ENC[AES256_GCM,data:4xaoGvLq1UIdozNqQ7v+pORVPDCk+FZRsCRvZ3C5AZOwSaM+UfDYZcI32AI0K80yFyhVIrrjqylykvXghbpQGAju3mv7+7Tbn5p2gqXrB/m1FuyVe/ftw7SSn8FTGL14cdHuPPkQTvV/u7z1IfX4YAOEGqtWiEfOe4YoWT3xc3A=,iv:dygbKjQ0ljgBPyk2aEIa/Mpbs/At+UzuhYy8Sndx/nk=,tag:jYbROlRxeDxqF1YqrBGL8A==,type:str]
|
mac: ENC[AES256_GCM,data:4xaoGvLq1UIdozNqQ7v+pORVPDCk+FZRsCRvZ3C5AZOwSaM+UfDYZcI32AI0K80yFyhVIrrjqylykvXghbpQGAju3mv7+7Tbn5p2gqXrB/m1FuyVe/ftw7SSn8FTGL14cdHuPPkQTvV/u7z1IfX4YAOEGqtWiEfOe4YoWT3xc3A=,iv:dygbKjQ0ljgBPyk2aEIa/Mpbs/At+UzuhYy8Sndx/nk=,tag:jYbROlRxeDxqF1YqrBGL8A==,type:str]
|
||||||
|
|||||||
@@ -14,38 +14,38 @@ sops:
|
|||||||
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
- recipient: age1lufn6t35gs4wgevyr2gud4eec7lvkn7pgnnv4tja64ww3hef7gqq8fas37
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlemJmbnAwUHZHT3ozdWxH
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXN25MZVQzTmora3o3YjJs
|
||||||
Njh1ZFUvVW8zcVV6SGxrVW1IWW9ZUFBaTEh3CnJsMnFnM0d5YnBKWE5CT2Flang0
|
aUptdGxJY2YxZU5XSjBjczFnTFVVdHVsRkM0CkNFN2JoelQva1ZucUxNNUJsVk9z
|
||||||
TkNZb0xCY2c4Qk1kdXRkRXcvOU1TSW8KLS0tIE1VdGEraW03bnV4VEc5c0ZheFJ0
|
cVZVU0MxL2Y3b2dNRnhJSzZrSVlaRWcKLS0tIG1vTHB1dHNWa0RLR1BRV0hFUVdx
|
||||||
MFJpVTlvTGJ0YXBKSnFFbXhEUEwwSmMKxOtHLbRw5e6dRW4jvqFLsl6UzKZ+mvfR
|
blY1QTNhUGpKZ3EzRHNadStxaCtLb1kKtyXKpZGLtrUo1HE26IWhv8245Bjcwcqe
|
||||||
hwKJ4KEbXuCqwtPQEWk/pF0i4vzrgUP1Cp1Y7BxGGyK9ufyV/CCQIg==
|
IR2WGv7qtnpWZoaFv76LNN7YY1JViy2k2AY+TdLmFQr0Vh2n5+tH1A==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
- recipient: age17jlsydpgl35qx5ahc3exu44jt8dfa63chymt6xqp9xx0r6dh347qpg55cz
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5cnE5VENCMUxxOVZUdC9X
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZbHVXV2hVTWZlemdCQmI0
|
||||||
QWFMRytGamhaWENZY1Q4STR5L0Jsdk90SlUwCis4ekFWYmMwN2dESXMrVFNIamFG
|
SGwwK0hDYjNkWGJMMTVuWnNMVW1Ebldsd0RRCmNoN2dZN2JiSEpzUzNwcjU3eFVv
|
||||||
RzhET2ZGdGN6b1V1ZHkyOCtDNzBWVjQKLS0tIEF1NGdoU2lqYVdIN3hwRk13SFpP
|
QmNnWERpQVByYlRqUDQrWEF4bkRPQm8KLS0tIHNOaDhQZExuOVJIVXZGQVdFeGhQ
|
||||||
RHNOeDBlSHFpays2VkRuR2RxaGpYZ1EKwxZfRZthZHVuJe3D5pamCSxYo3hyaaVc
|
QXRJRFlZWXJUVW9nVDhOaUFacjFlSzgKYSs6Woc/lAr2ECcrqoMCAwvIbXTpbtTr
|
||||||
I0UvMDMgcDRZuEzV9g1ZEYnaVXg5InyOO0dDZuCYX/HZqTLPiaOIxg==
|
J4ljY3BRCdSzHEMS9IFV2j9nGu8sUrHRsO7V/Kc8i+XmTGZP76LRJA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
- recipient: age15hx530yrqmhm80vsjmffyg9deq9gssj7hl5rsqdnsn3dwegj9qusv4sjf5
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGaUhOcHV2TkYrZWxnOCtI
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlRGwzbm9rY3hXeHZReWZW
|
||||||
TzF1RVpFY3pSa1Y2MmJjVlpKcWZnWGtOOTJ3CmRnTUpyRms2aUtvS1ZvVXFsb0ZQ
|
VngyN3ZlZDJWekExNkNBdCtLT1J6d0ZYU0hrCi9RRWNYUyt3OGh1ZVNCNWI1U3Vn
|
||||||
U0RiYXM3S0RKQjVwL2hqYllhZENUdmsKLS0tIDNTRHR2ZU1VTzdNNXRDU0xkcTRM
|
dnByZnVpYmV1RndKQUxHbUtrS0F5L3cKLS0tIDJONlcvMllKOWRxdE5ZWUZmaFEx
|
||||||
ckowd2p5bitGYVhMNU9Qc0NUeFFJV3MKPKT1/06/fKpWPOMsRaU/fpyVUf7onWGB
|
S1JCM2x1WDF0Z3c0ODZNb3FKOGNhMlUKGP8P/PUcMM1c4VzXLjLNp/zThu8JCiyQ
|
||||||
0P22NBzP1i5caqSrFnVVeyuhgYxabC4oUKVmjU5QIj1R8Rqh7gworw==
|
iHdz0LBSAha/m23b316z72yg3YD5q+/qDP8KczAv1SG+VvgHDKxpCg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ml3smrs5mwz4ds84gk0eyss86nwsmp07qh0npxsuae7lfwwpsghssavytw
|
- recipient: age1v2ahkl759cftpcdq4mla2cvmgz4jlnmgj7qtgc9732zxrfvxf3lq76zjpr
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3SHdHTDhKQzFUQVdqM0hW
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5Z3hyOGFJTlpxOWFQaWsx
|
||||||
Tm9QdVozaHViQVRuTExhV1BpdWYvY012enk0CmhjODlUN0FkNldGRG94bVFSTVBv
|
WE9oYmJaaWxURjdmRlVJMUcxaUZKWDZCS1VJCmxWV01DRloyM3lLemJYc2FxcUdH
|
||||||
QUNWZmszRStZN24vZWhnajhIcWdXVDgKLS0tIG9ueVZsT29KRE1iM2oreWtGWGVC
|
M1NZRGxjVUVEUExTWjFaazhRaDdCUXcKLS0tIFF6NW4vSGJSWjN3NHFlOXRUYXhM
|
||||||
SG40OS8wMHlKNmxQa0VScHQrU2NmT2sKt9xw/8jsgnV1cZndqYNiHvIf8VdEJYCl
|
NXZzQmlneDNEb1UvR2NGK0kyY1lsa1kK7IQmyuVxa2hmic4yTeiAcxN41RvMcIDV
|
||||||
UUJ1KPz9mvUx3ny+rK50FSD61U8PHEZm2UC0w+/qkZwRtCx21Ku6dw==
|
Pofrhu7q8VvB/Cxb7FjVs3Ed5Hdz9xQ60mXUKsnJV/rIssm9wx4cfg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-02-04T18:37:11Z"
|
lastmodified: "2026-02-04T18:37:11Z"
|
||||||
mac: ENC[AES256_GCM,data:AlrMK34dWDm5hfVwnQnzk3l8NIRbiVV6KHa6io9S9l07WvC3TYLTOJS6xOi4pkEz6sqQ7IpZU7RRdosxuQp50NmMEt2QYawTHFZIgzFYeKRbl5N5LCu9afC6yTtvG/sT7uenTMhh2qT1JBwebJiUdM9zNVUzWlW5d1SdxrHgIbs=,iv:dvqsDaC+trhY1kheYUEOEwHfCDz0Mu7N0LpfjnKko5g=,tag:tuqyK8vuwSrk1kf+Vi7MKg==,type:str]
|
mac: ENC[AES256_GCM,data:AlrMK34dWDm5hfVwnQnzk3l8NIRbiVV6KHa6io9S9l07WvC3TYLTOJS6xOi4pkEz6sqQ7IpZU7RRdosxuQp50NmMEt2QYawTHFZIgzFYeKRbl5N5LCu9afC6yTtvG/sT7uenTMhh2qT1JBwebJiUdM9zNVUzWlW5d1SdxrHgIbs=,iv:dvqsDaC+trhY1kheYUEOEwHfCDz0Mu7N0LpfjnKko5g=,tag:tuqyK8vuwSrk1kf+Vi7MKg==,type:str]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
### Reference Map
|
### Reference Map
|
||||||
- **Role**: Index mapping core concerns to repo paths for navigation and validation.
|
- **Role**: Index mapping core concerns to repo paths for navigation and validation.
|
||||||
- **Key Fields**: category (apps, dev, scripts, servers, services, shell, network, users, nix, patches), hosts list (emacs, server, workstation, miniserver, galaxy), secrets files, proxy rules, auto-import rules, stylix/schemes, audit checklist entries, navigation links to constitution/playbooks.
|
- **Key Fields**: category (apps, dev, scripts, servers, services, shell, network, users, nix), root paths (patches), hosts list (emacs, server, workstation, miniserver, galaxy, vps), secrets files, proxy rules, auto-import rules, stylix/schemes, audit checklist entries, navigation links to constitution/playbooks.
|
||||||
- **Relationships**: Anchors citations used by Constitution and Playbooks.
|
- **Relationships**: Anchors citations used by Constitution and Playbooks.
|
||||||
|
|
||||||
## Constraints and States
|
## Constraints and States
|
||||||
|
|||||||
@@ -29,3 +29,8 @@
|
|||||||
- **Decision**: Gate SOPS configuration behind `config.my.secureHost` so non-secure hosts skip secret loading.
|
- **Decision**: Gate SOPS configuration behind `config.my.secureHost` so non-secure hosts skip secret loading.
|
||||||
- **Rationale**: Aligns `config/base.nix` behavior with the constitution’s secureHost rules and avoids secret dependency on non-secure hosts.
|
- **Rationale**: Aligns `config/base.nix` behavior with the constitution’s secureHost rules and avoids secret dependency on non-secure hosts.
|
||||||
- **Alternatives considered**: (a) Leave SOPS enabled on all hosts (rejected: violates secureHost contract); (b) Duplicate SOPS logic per host (rejected: increases drift risk).
|
- **Alternatives considered**: (a) Leave SOPS enabled on all hosts (rejected: violates secureHost contract); (b) Duplicate SOPS logic per host (rejected: increases drift risk).
|
||||||
|
|
||||||
|
## Decision 7 (2026-02-07): Module categories and patches location; active hosts update
|
||||||
|
- **Decision**: Treat `patches/` as a root-level directory (not a module category) and update active hosts to include `vps`.
|
||||||
|
- **Rationale**: Repo structure places patches at the root and hosts include `vps`; documentation must reflect actual paths and host inventory.
|
||||||
|
- **Alternatives considered**: (a) Move `patches/` under `modules/` (rejected: would change repo layout); (b) Keep `vps` undocumented (rejected: causes host list drift).
|
||||||
|
|||||||
@@ -89,6 +89,6 @@ An AI or contributor can update the constitution and use-case docs when repo rul
|
|||||||
### Measurable Outcomes
|
### Measurable Outcomes
|
||||||
|
|
||||||
- **SC-001**: An AI with only these docs can describe the correct steps and file locations to add a new server module in under 2 minutes of reading time, matching existing patterns.
|
- **SC-001**: An AI with only these docs can describe the correct steps and file locations to add a new server module in under 2 minutes of reading time, matching existing patterns.
|
||||||
- **SC-002**: The constitution explicitly enumerates 100% of current module categories (apps, dev, scripts, servers, services, shell, network, users, nix, patches) and active hosts (emacs, server, workstation) with their roles.
|
- **SC-002**: The constitution explicitly enumerates 100% of current module categories (apps, dev, scripts, servers, services, shell, network, users, nix), documents the root `patches/` directory, and lists active hosts (emacs, server, workstation, miniserver, galaxy, vps) with their roles.
|
||||||
- **SC-003**: Guidance includes the full secrets file map (certs/env/gallery/homepage/keys/wireguard/secrets) and secureHost behavior with no omissions when audited against the repository.
|
- **SC-003**: Guidance includes the full secrets file map (certs/env/gallery/homepage/keys/wireguard/secrets) and secureHost behavior with no omissions when audited against the repository.
|
||||||
- **SC-004**: Playbook locations and required fields are discoverable via the documented index in ≤2 navigation steps from the top of the spec.
|
- **SC-004**: Playbook locations and required fields are discoverable via the documented index in ≤2 navigation steps from the top of the spec.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
- Apply nftables/NixOS firewall rules derived from the iptables reference
|
- Apply nftables/NixOS firewall rules derived from the iptables reference
|
||||||
- Enable wireguard on VPS and expose port
|
- Enable wireguard on VPS and expose port
|
||||||
- Add service users and admin SSH keys
|
- Add service users and admin SSH keys
|
||||||
- Update VPS public IP to `45.33.0.228` in SSH configuration
|
- Update VPS public IP to `45.79.25.87` in SSH configuration
|
||||||
- Update host server VPN client to target the new VPS
|
- Update host server VPN client to target the new VPS
|
||||||
|
|
||||||
4. Provide and review legacy proxy config snapshot:
|
4. Provide and review legacy proxy config snapshot:
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
- **T002**: verify this section exists in `/home/jawz/Development/NixOS/specs/004-vps-migration/quickstart.md`
|
- **T002**: verify this section exists in `/home/jawz/Development/NixOS/specs/004-vps-migration/quickstart.md`
|
||||||
- **T003**: `rg -n "mainServer|enableProxy" hosts/server/toggles.nix modules/modules.nix`
|
- **T003**: `rg -n "mainServer|enableProxy" hosts/server/toggles.nix modules/modules.nix`
|
||||||
- **T004**: `rg -n "wireguard|wg0|services.wireguard" modules/services/wireguard.nix hosts/vps/configuration.nix`
|
- **T004**: `rg -n "wireguard|wg0|services.wireguard" modules/services/wireguard.nix hosts/vps/configuration.nix`
|
||||||
- **T005**: `rg -n "vps|45.33.0.228|programs.ssh" config/jawz.nix modules/modules.nix`
|
- **T005**: `rg -n "vps|45.79.25.87|programs.ssh" config/jawz.nix modules/modules.nix`
|
||||||
- **T006**: `rg -n "/etc/caddy/Caddyfile.d" sudo_hist jawz_hist`
|
- **T006**: `rg -n "/etc/caddy/Caddyfile.d" sudo_hist jawz_hist`
|
||||||
- **T007**: `rg -n 'mainServer = "vps"' hosts/server/toggles.nix modules/modules.nix`
|
- **T007**: `rg -n 'mainServer = "vps"' hosts/server/toggles.nix modules/modules.nix`
|
||||||
- **T008**: `rg -n "enableProxy = true" hosts/vps/toggles.nix hosts/vps/configuration.nix hosts/server/toggles.nix`
|
- **T008**: `rg -n "enableProxy = true" hosts/vps/toggles.nix hosts/vps/configuration.nix hosts/server/toggles.nix`
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ I need you to create the service users and groups for deploy and lidarr-reports.
|
|||||||
in those, I need you to add ./secrets/ssh/ed25519_deploy.pub to authorized_keys for the user deploy
|
in those, I need you to add ./secrets/ssh/ed25519_deploy.pub to authorized_keys for the user deploy
|
||||||
and for lidarr-reports ed25519_lidarr-reports.pub
|
and for lidarr-reports ed25519_lidarr-reports.pub
|
||||||
|
|
||||||
6. similar to every other host, add ssh login authorized_keys for workstation, server, deacero, galaxy and check if Im missing one. Because this will replace the ssh vps on the ssh config, you need to replace the existing vps ip with 45.33.0.228. 7. change the configuration on the host server, so that its wireguard session, connects to this server (i think will ve done automagically when the ip changes right?) 8. Ive added sudo_hist and jawz_hist, which are a dump of the histfile of this server, just check if there is a configuration that Im missing, something I did on there that I missed, and add it to the clarification list, so when I run clarify I tell you if I want that or not, granted lots of those commands are trial and error, so I think I have everything. 9. I have setup a plausible server, write the steps necesary to migrate it, I dont know.
|
6. similar to every other host, add ssh login authorized_keys for workstation, server, deacero, galaxy and check if Im missing one. Because this will replace the ssh vps on the ssh config, you need to replace the existing vps ip with 45.79.25.87. 7. change the configuration on the host server, so that its wireguard session, connects to this server (i think will ve done automagically when the ip changes right?) 8. Ive added sudo_hist and jawz_hist, which are a dump of the histfile of this server, just check if there is a configuration that Im missing, something I did on there that I missed, and add it to the clarification list, so when I run clarify I tell you if I want that or not, granted lots of those commands are trial and error, so I think I have everything. 9. I have setup a plausible server, write the steps necesary to migrate it, I dont know.
|
||||||
|
|
||||||
10. add verification steps for every task we did, when youre done and"
|
10. add verification steps for every task we did, when youre done and"
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ Deliver MVP as User Story 1 (primary host reverse proxy + keep services on host
|
|||||||
- [x] T017 [US3] Configure sshd port and auth settings in hosts/vps/configuration.nix to match: Port 3456, PermitRootLogin no, PasswordAuthentication no
|
- [x] T017 [US3] Configure sshd port and auth settings in hosts/vps/configuration.nix to match: Port 3456, PermitRootLogin no, PasswordAuthentication no
|
||||||
- [x] T018 [US3] Harden remote rebuild access by switching to a non-root SSH user for rebuilds (nixremote) and requiring sudo for nixos-rebuild in hosts/vps/configuration.nix and modules/users/nixremote.nix
|
- [x] T018 [US3] Harden remote rebuild access by switching to a non-root SSH user for rebuilds (nixremote) and requiring sudo for nixos-rebuild in hosts/vps/configuration.nix and modules/users/nixremote.nix
|
||||||
- [x] T019 [US3] Restrict SSH access for remote rebuilds by limiting allowed users/keys for nixremote (update inputs.self.lib.getSshKeys list in hosts/vps/configuration.nix)
|
- [x] T019 [US3] Restrict SSH access for remote rebuilds by limiting allowed users/keys for nixremote (update inputs.self.lib.getSshKeys list in hosts/vps/configuration.nix)
|
||||||
- [x] T020 [US3] Update VPS IP to 45.33.0.228 in modules/modules.nix and config/jawz.nix SSH host entry
|
- [x] T020 [US3] Update VPS IP to 45.79.25.87 in modules/modules.nix and config/jawz.nix SSH host entry
|
||||||
- [x] T021 [US3] Update host server wireguard client configuration in hosts/server/configuration.nix to target the new VPS endpoint
|
- [x] T021 [US3] Update host server wireguard client configuration in hosts/server/configuration.nix to target the new VPS endpoint
|
||||||
|
|
||||||
## Phase 6: User Story 4 (P3) - Migration gaps and verification
|
## Phase 6: User Story 4 (P3) - Migration gaps and verification
|
||||||
|
|||||||
Reference in New Issue
Block a user