Files
homelab/hosts/mars/configuration.nix
T
darmanandClaude Opus 5 2a1a1628e1 relay: remove it; gitea already speaks Hermes's protocol
The relay existed on the premise that Gitea sends no header Hermes can read
an event name from, so something had to copy X-Gitea-Event into
X-GitHub-Event. That premise was wrong. Gitea's addDefaultHeaders sets

  req.Header["X-GitHub-Delivery"]   = []string{t.UUID}
  req.Header["X-GitHub-Event"]      = []string{event}
  req.Header["X-GitHub-Event-Type"] = []string{eventType}

unconditionally, for every webhook type, alongside X-Hub-Signature-256 in
GitHub's exact format. (Direct map assignment rather than .Add() specifically
to keep the "GitHub" casing that canonicalisation would destroy.) Hermes
validates that signature on any route without provider gating and reads the
event name from that header, so gitea and hermes already speak the same
protocol and the translation layer was translating nothing.

Gitea now posts straight at http://mars.orbit.sol:8644/webhooks/gitea-pr-comments.
The URL path is the Hermes route name, so a second subscription is a second
hook and nothing else -- the route-in-path indirection the relay grew was a
reimplementation of something Hermes already had.

Removes the module, the 200-line relay, its test, the mars import, the 8645
listener, and the stale gitea-hermes-webhook-relay.service entry left in the
secret's restartUnits. hermes-agent-webhook-route moves to
hosts/mars/hermes-agent.nix, next to the container and the read-only prompt
and filter mounts it depends on.

Also makes that unit refuse to subscribe when GITEA_HERMES_WEBHOOK_SECRET is
unset in the container, matching the existing empty-prompt check. An empty
secret silently fails every delivery signature check afterwards while the
unit still reports success -- the worst possible failure shape, and one this
setup can actually produce on a first deploy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S94o42aQ8VkBmEWvDem5xa
2026-08-23 08:09:01 +02:00

55 lines
2.2 KiB
Nix

{ config, pkgs, ... }:
# mars — on-site x86_64 box, single-purpose: runs Hermes Agent only.
# See hermes-agent.nix for what that is and why it moved here from jupiter.
{
imports = [
./hardware-configuration.nix
./disk-config.nix # disko: OS-disk partitions + filesystems
./secrets.nix # sops-nix: samba/tailscale/hermes secrets
./hermes-agent.nix
../../common.nix # shared base: user / ssh / nix / firewall
../../services/containers.nix
../../services/vpn/tailscale.nix
../../services/monitoring/node-exporter.nix
];
networking.hostName = "mars";
networking.networkmanager.enable = true; # DHCP on-site, same as jupiter
users.users.darman.extraGroups = [ "docker" ]; # merges with common.nix; podman debug access
# ---- Boot (UEFI, confirmed) ----
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# jupiter's samba share (services/network/samba.nix) — mounted on demand so
# mars doesn't stall boot/login when jupiter is off or unreachable. This is
# also where Hermes's shared dropbox lives now (hermes-agent.nix). Modes are
# tighter than terra's equivalent mount (0770 not 0755, gid=hermes not
# gid=users) since the hermes-agent container (uid 986, gid 983 — no podman
# userns remapping, see services/network/pihole.nix) needs group write into
# it, not just darman.
fileSystems."/mnt/jupiter" = {
device = "//jupiter/data";
fsType = "cifs";
options = [
"credentials=${config.sops.templates."jupiter-smb.credentials".path}"
"uid=1000"
"gid=983"
"file_mode=0770"
"dir_mode=0770"
"nofail"
"x-systemd.automount" # lazy-mount so boot doesn't stall if jupiter's down
# NO idle-timeout here (unlike terra's equivalent mount): hermes-agent's
# podman-hermes-agent.service RequiresMountsFor this path, so an idle
# auto-unmount tears the container down with it — confirmed the hard
# way, it killed the service ~60-70s after every start with no crash
# or error, just "Unmounting /mnt/jupiter" right before the stop.
"x-systemd.mount-timeout=10s"
"_netdev"
];
};
system.stateVersion = "26.05"; # set at install time; do NOT bump on upgrades
}