Commit Graph
7 Commits
Author SHA1 Message Date
darmanandClaude Opus 5 b0e7e67c90 relay: copy X-Gitea-Event into X-GitHub-Event, fix deploy ordering
The relay was forwarding X-Gitea-Event and re-signing the body into the
deprecated generic-V1 X-Webhook-Signature header. Neither is something
Hermes acts on, which left the PR's core premise — "Hermes owns event
selection" — impossible to reach:

  - Hermes reads the event name only from X-GitHub-Event/X-GitLab-Event,
    then payload event_type/type, then falls back to the literal string
    "unknown" (gateway/platforms/webhook.py). Gitea sends X-Gitea-Event and
    no such payload key, so every delivery arrived as "unknown" and
    `hermes webhook subscribe --events ...` could never select anything.
  - Gitea's addDefaultHeaders() already signs every webhook type with
    X-Hub-Signature-256 in GitHub's exact format, and Hermes accepts that
    header on any route with no per-route provider gating. Re-signing into
    V1 was both redundant and on a deprecated path.

So the relay now verifies the signature (accepting either X-Hub-Signature-256
or X-Gitea-Signature), forwards body and signature byte-for-byte, and copies
the one header Hermes actually needs. Authentication alone never justified
this service; that header copy does, and the module comment now says so.

Also fixed:
  - gitea-hermes-webhook-provision had no API readiness wait, unlike both
    sibling units in the same file. After=gitea.service does not mean gitea
    is serving HTTP, so under `set -e` a Type=oneshot with no Restart= would
    fail on first boot and stay failed, leaving the webhook unregistered.
  - podman-hermes-agent added to the secret's restartUnits. The secret
    reaches the container only via sops.templates, whose rendered path never
    changes, so systemd would not restart the container when the secret was
    first added — hermes-agent-webhook-route then read an empty value back
    out of it and subscribed with an empty secret.
  - Webhook provisioning passes the request body to curl on stdin rather
    than in argv, keeping the shared secret out of /proc/<pid>/cmdline.
  - Missing Content-Length now returns 411 rather than 413; dropped the
    unreachable non-2xx branch (urlopen raises on non-2xx); env-var secret
    fallback is stripped to match the credential-file path.

Adds gitea-hermes-webhook-relay-test.py, which drives the real relay over
real HTTP against a stub Hermes and covers the header copy as a regression
test. Both nixosConfigurations still evaluate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S94o42aQ8VkBmEWvDem5xa
2026-08-23 05:02:55 +02:00
luna 806cec77e8 mars: add generic Gitea webhook relay 2026-08-23 01:45:18 +00:00
darmanandClaude Sonnet 5 3c1f3e5fc3 mars: give L.U.N.A. direct git+tea access to the homelab repo
Provisions a dedicated PR-tier gitea account (luna) with branch protection
restricting master push/merge/approve to darman only, then wires git and
tea directly into the hermes-agent container (mounted from the host's Nix
store, credential-store + tea login set up by a host-side prepare oneshot,
repo cloned inside Hermes's own writable sandbox root at
/opt/data/workspace/homelab). Replaces an earlier standalone MCP-server
approach, scrapped in favor of direct CLI access for simplicity.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FHr5ug9pu8q4XPrRkFnzJ
2026-08-22 20:50:35 +02:00
darmanandClaude Sonnet 5 dc83e8c156 add node_exporter host vitals + quickshell HUD
Prometheus node_exporter enabled on every host, plus a quickshell widget
(SUPER+CTRL+V on terra) to view live CPU/mem/disk/net/uptime without a
separate dashboard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FHr5ug9pu8q4XPrRkFnzJ
2026-08-22 20:50:16 +02:00
darmanandClaude Sonnet 5 a1cd6ae6f1 mars: add hermes CLI shell alias
darman's own podman is rootless while the container runs under root's
(system) podman, so plain `podman exec` couldn't see it. Alias runs it
with sudo against the right socket.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Du1WQRk1F8DenrPhf8TofF
2026-08-22 05:03:30 +02:00
darmanandClaude Sonnet 5 99501ce7d2 mars: drop idle-timeout on the /mnt/jupiter cifs mount
podman-hermes-agent.service RequiresMountsFor /mnt/jupiter, but the mount
option copied from terra's (read-only, nothing depends on it) browsing
mount included x-systemd.idle-timeout=60 — confirmed on real hardware,
this killed the container ~60-70s after every start with no crash or
error, just an idle auto-unmount taking the dependent service down with
it. Keep the lazy x-systemd.automount (so boot doesn't stall if jupiter's
down) but drop the timeout now that something needs the mount to persist.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FHr5ug9pu8q4XPrRkFnzJ
2026-08-22 03:09:21 +02:00
darmanandClaude Sonnet 5 7d63ba95df add mars host, move Hermes Agent there from jupiter
New on-site host mars runs Hermes Agent as its sole service: joins the
tailnet, mounts jupiter's samba share at /mnt/jupiter (doubling as
Hermes's shared dropbox), and hosts state locally under /var/lib/hermes.
Same Authentik OIDC app/Telegram bot as before, just relocated — neptun's
hermes.mgaction.town vhost now points at mars.orbit.sol instead of jupiter.

hosts/jupiter/hermes-agent.nix and its three sops secrets are removed;
jupiter's Caddy vhost for it is gone too. Also refreshes tailscale_authkey
across all hosts and fixes two stale "erik@laptop" keys in flake.nix's
kexec/installer-iso images (leftover from a previous laptop, already
swapped out of common.nix back in 2fd5752) to darman@terra.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011FHr5ug9pu8q4XPrRkFnzJ
2026-08-22 03:00:24 +02:00