Commit Graph
4354 Commits
Author SHA1 Message Date
k.rennerandClaude Fable 5 42a5cdc275 ansible: add edge-host role — bare-metal Arch N100 replaces k8s-edge VM
ci/woodpecker/push/deploy-infrastructure Pipeline was successful
Replaces the k8s-edge Talos VM (vm_153) with a dedicated Arch host
running the hardware-bound services: zwave-js-ui and sml2mqtt via
docker compose (configs ported 1:1 from the k8s manifests), plus the
new open3e CAN bridge (SocketCAN via systemd-networkd, venv + systemd
unit, read-only datapoint set).

Driver for leaving k8s here: stock Talos ships CONFIG_CAN unset
(siderolabs/talos#7686), so the Vitocal/VX3 CAN adapter cannot work in
any pod without a custom kernel per release.

Base-install procedure, secret bootstrap (vault.yml from cluster
secrets) and per-service cutover checklist in roles/edge-host/README.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 12:03:14 +02:00
k.renner 7c7a36cb4b Merge pull request 'mosquitto: add dedicated open3e broker user' (#94) from mosquitto-open3e-user into master
Reviewed-on: gitea_admin/homelab#94
2026-07-02 11:32:27 +02:00
k.rennerandClaude Fable 5 38901fe72a mosquitto: add dedicated open3e broker user
Fifth broker user for the Viessmann E3 CAN bridge (open3e, Vitocal
250-A + Vitocharge VX3). Same in-cluster bootstrap-Job pattern as the
other users; ACL scoped to open3e/#.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 11:29:58 +02:00
k.rennerandClaude Fable 5 8eca54577d fix(netbird-watchdog): probe home+immich, require all domains down
status.renner.uno will move off-cluster, so it's a bad canary. Probe two
permanently cluster-hosted domains instead and count a round as failed
only when EVERY domain fails: one dead backend 502s on its own domain,
while the dead-route state kills all domains at once — this keeps single
app outages from restarting the proxy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 09:25:46 +02:00
k.rennerandClaude Fable 5 edf5362015 feat(netbird): reverse-proxy watchdog (self-heal dead-route 502s)
ci/woodpecker/push/deploy-netbird-server Pipeline was successful
The proxy's embedded client pins each proxied domain's route to a
routing-peer identity. netbird-ingress rollouts mint fresh identities by
design, and upstream's dns-interceptor never rebinds a route whose owning
peer is gone ('already routed by peer [...]. HA routing disabled') — the
proxy then serves only 502/timeouts until restarted (2026-07-02 outage).

Add a shared role deploying a systemd timer (1min) on both cluster
members (VPS-1, proxy-1): probe status.renner.uno through the local
proxy, restart the container after 3 consecutive 502/000 results, with a
10min cooldown against restart loops. Every probe outcome is journaled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 07:07:43 +02:00
security-bot 5dffafee51 chore(image-automation): bump netbirdio/netbird:v0.74.0-rootless
Updates managed by image-automation-controller.
2026-07-01 20:52:13 +00:00
security-bot 4a8b6bdaec chore(image-automation): bump ghcr.io/music-assistant/server:2.9.5
Updates managed by image-automation-controller.
2026-07-01 18:58:34 +00:00
security-bot 129cc6bde8 chore(image-automation): bump ghcr.io/home-assistant/home-assistant:2026.7.0
Updates managed by image-automation-controller.
2026-07-01 18:12:26 +00:00
k.renner 758bdaf057 Merge pull request 'config-sync: include all of www/ (two-way merge handles HACS drift)' (#92) from feat-config-sync-include-www into master
Reviewed-on: gitea_admin/homelab#92
2026-06-30 07:24:20 +02:00
k.rennerandClaude Opus 4.8 6cf50f14a3 feat(home-assistant): include all of www/ in config-sync (two-way merges it)
www/ was excluded (except the bespoke heizungsanlage card) because the old
one-way force-overwrite fought HACS's runtime rewrites. With two-way sync that
no longer applies: HACS drift is committed to `live`, PR'd, and merges cleanly.
Widen PATHS from www/heizungsanlage-card.js to the whole www/ directory.

Bonus: this also removes the merge-refusal edge case — www changes are now
committed before the merge step, so there's no uncommitted www drift left to
block a merge.

First run captures the current HACS drift (~6 frontend files: kiosk-mode,
xiaomi-vacuum-map-card) as one small live PR, then stays current.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgbyKgrN1yYWrkAA32rJE5
2026-06-30 00:13:50 +02:00
k.renner 72dba58390 Merge pull request 'HA config-sync: two-way (push live /config changes back as a PR)' (#91) from feat-config-sync-two-way into master
Reviewed-on: gitea_admin/homelab#91
2026-06-30 00:02:53 +02:00
k.rennerandClaude Opus 4.8 b6cf090aca feat(home-assistant): make config-sync two-way (push live changes back via PR)
The sidecar was one-way and git-authoritative: it force-overwrote local edits to
the synced config paths, so changes made inside HA (code-server, the UI
automation/script editors) were reverted on the next tick.

Now it is two-way:
- PUSH: changes to the tracked config paths are committed (bot identity) onto a
  dedicated `live` branch, pushed, and a PR `live -> main` is kept open (via the
  gitea token already in the remote URL). Live edits stay live AND are captured
  for review.
- PULL: when `main` advances (merged PR / external push) the commits are merged
  back into `live`/the working tree and HA reloads.

Conflicts are left to git: a conflicting merge is ABORTED (never written into the
live files, which would break HA) and logged to resolve in the PR. Reloads fire
only on changes pulled from main (local edits are already applied by HA).

Also fixes the reload race: reload_all now retries until HA is serving, instead
of failing once right after a pod start. Scope unchanged (config paths only; rest
of www/ and untracked runtime state untouched); auto-gc still disabled.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgbyKgrN1yYWrkAA32rJE5
2026-06-29 23:59:02 +02:00
k.renner 2469fcdbdb Merge pull request 'feat(home-assistant): sync bespoke heizungsanlage card via config-sync' (#90) from feat/ha-config-sync-heizschema into master
Reviewed-on: gitea_admin/homelab#90
2026-06-29 22:35:50 +02:00
k.rennerandClaude Opus 4.8 2985c98d7b feat(home-assistant): sync bespoke heizungsanlage card via config-sync
The config-sync sidecar intentionally leaves www/ to HACS, but
www/heizungsanlage-card.js is a bespoke, non-HACS custom card committed to the
HA config repo (k.renner/homeassistant). Add that exact path to PATHS so the
sidecar force-syncs just that one file into /config/www; the rest of www/ stays
HACS-managed.

Note: extra_module_url is read only at HA startup, so a one-time full restart is
still needed to load the card after the file first lands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 22:34:29 +02:00
k.renner 185cffc7e2 Merge pull request 'Fix: config-sync sidecar logging (stderr + idle heartbeat)' (#89) from fix-config-sync-logging into master
Reviewed-on: gitea_admin/homelab#89
2026-06-29 22:21:49 +02:00
k.rennerandClaude Opus 4.8 987db9eb0b fix(home-assistant): make config-sync logs reliable + observable
Only the "starting" line surfaced in `kubectl logs`: busybox sh block-buffers
stdout when it's a pipe, so subsequent lines could sit unflushed for the life of
the loop. Log to stderr instead (unbuffered; still captured in the container
log). Also emit a one-time "initial check: config in sync" line so an idle loop
is observably alive even when there's nothing to sync.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgbyKgrN1yYWrkAA32rJE5
2026-06-29 22:06:42 +02:00
k.renner 35d584090b Merge pull request 'Fix: config-sync sidecar OOMKill (disable git auto-gc + raise limit)' (#88) from fix-config-sync-oom into master
Reviewed-on: gitea_admin/homelab#88
2026-06-29 21:47:51 +02:00
k.rennerandClaude Opus 4.8 8d7ecdda11 fix(home-assistant): stop config-sync sidecar OOM (disable git auto-gc, raise limit)
The config-sync sidecar OOMKilled (exit 137) at the 64Mi limit and crashlooped,
so it never synced. Root cause: this repo's .git is ~1.1 GB (a 1 GB backup tar
lives in history), and git auto-gc tried to repack that whole pack inside the
tiny sidecar on first fetch.

- Disable gc.auto in the sync script and cap pack window / delta caches, so
  fetch/checkout only ever touch the small config blobs and never repack.
- Raise the sidecar memory limit 64Mi -> 256Mi for index-pack headroom on the
  first fetch.

Follow-up (not here): purge the 1 GB backup tar from the homeassistant repo
history and .gitignore backups/ — it bloats every clone and the config PVC.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgbyKgrN1yYWrkAA32rJE5
2026-06-29 21:46:00 +02:00
k.renner d636266bd1 Merge pull request 'HA: git config-sync sidecar (auto-deploy /config from main)' (#87) from worktree-ha-config-sync-sidecar into master
Reviewed-on: gitea_admin/homelab#87
2026-06-29 21:37:47 +02:00
k.rennerandClaude Opus 4.8 12169bf753 fix(home-assistant): config-sync reloads HA only when synced paths actually change
The previous loop reloaded on any advance of origin/main, including commits that
touch only unsynced paths (www/, shelly_scripts/, docs). Now the reload trigger
is `git diff --quiet <remote> -- <config paths>`: HA is reloaded only when the
synced config paths differ. Non-config commits just advance the branch ref with
no reload. As a side effect the loop now also reverts local drift on synced
paths continuously (reloading only when something actually changed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgbyKgrN1yYWrkAA32rJE5
2026-06-29 21:35:45 +02:00
k.rennerandClaude Opus 4.8 07a441b060 feat(home-assistant): add git config-sync sidecar to keep /config live with main
HA's /config is an RWO PVC that is a git checkout of the homeassistant repo,
edited via the code-server sidecar. There was no automated path from a merge to
the running instance, so merged config (e.g. the notification-queue work) sat
undeployed until a manual pull+reload.

Adds a `config-sync` sidecar (alpine/git) sharing the config PVC. Every 30s it
fetches origin/main and, on change, force-syncs ONLY the HA YAML config paths
(automations(.yaml+dir), packages/, scripts.yaml, templates.yaml,
configuration.yaml, notify.yaml, groups.yaml, powercalc.yaml, blueprints) into
the working tree, advances the branch ref without touching the working tree, and
calls homeassistant.reload_all so the change goes live with no restart.

Deliberately left untouched: www/ (HACS rewrites those tracked files at runtime)
and untracked runtime state (.storage/, *.db, secrets.yaml). git auth reuses the
PAT already embedded in the PVC's remote URL; reload auth uses a dedicated
long-lived token in a sops secret.

Consequence (git becomes source of truth): uncommitted edits to a synced path
made directly in code-server OR via HA's UI automation editor are reverted on the
next sync. Commit + push to persist.

NOTE: the reload token currently reuses the existing HA long-lived token; rotate
it to a dedicated `config-sync` token (revocable independently) — see PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgbyKgrN1yYWrkAA32rJE5
2026-06-29 21:22:55 +02:00
security-bot 77add2c404 chore(image-automation): bump rhasspy/wyoming-whisper:3.3.1
Updates managed by image-automation-controller.
2026-06-29 18:58:01 +00:00
k.renner d8eaa7d4a5 Merge pull request 'fix(velero): bump data-mover timeouts 4h→8h (immich-library hits 4h cap)' (#86) from velero-bump-item-operation-timeout-8h into master
Reviewed-on: gitea_admin/homelab#86
2026-06-28 11:17:31 +02:00
k.rennerandClaude Opus 4.8 e50c622da3 fix(velero): bump data-mover timeouts 4h→8h (immich-library hits 4h cap)
The immich-library DataUpload (~250 GiB, millions of small files) now
runs ~3h50m–4h+ and was intermittently Canceled at exactly the 4h
`defaultItemOperationTimeout`. A canceled upload writes no kopia
snapshot, so the daily backup ends PartiallyFailed; the weekly
restore-test then selects that backup and fails restoring immich-library
with "Unable to load snapshot: snapshot not found", firing KubeJobFailed.

Observed cancellations:
  2026-06-26  immich-library DataUpload  Canceled  4h00m09s
  2026-06-27  immich-library DataUpload  Canceled  4h00m12s
  2026-06-28  immich-library DataUpload  Completed 3h50m18s

Raise both dataMoverPrepareTimeout and defaultItemOperationTimeout to 8h
for headroom as the library keeps growing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 11:14:52 +02:00
k.renner 6600db98f6 Merge pull request 'Evict Home Assistant from k8s-edge (read meter via MQTT, drop privileged)' (#85) from worktree-ha-meter-mqtt-bridge into master
Reviewed-on: gitea_admin/homelab#85
2026-06-27 23:08:09 +02:00
k.rennerandClaude Opus 4.8 f059cbb62c feat(home-assistant): evict HA from edge — read meter via MQTT, drop privileged
Home Assistant was pinned to k8s-edge solely for the USB power meter it
read via edl21. edl21 is now replaced by the sml2mqtt bridge (publishes to
Mosquitto), so HA:
- drops nodeSelector zone=edge + the workload-class=pinned toleration →
  the heavy 8Gi pod schedules on the general cluster pool, off the
  soon-to-be-tiny edge box;
- drops the /dev/stromzaehler USB hostPath mount + volume (bridge owns the
  device now);
- drops securityContext.privileged — the USB device was its only
  justification.

This also frees the serial fd the running HA process still held after
edl21's removal (HA recreates without the device), giving the sml2mqtt
bridge exclusive access to the meter.

Meter data in HA resumes once the MQTT sensors (reusing the old
sensor.smart_meter_* entity_ids for history continuity) land in the
homeassistant repo — brief expected gap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 23:07:14 +02:00
k.renner 5d1764562e Merge pull request 'Activate sml2mqtt bridge (privileged USB access, stdout logging, replicas 1)' (#84) from worktree-ha-meter-mqtt-bridge into master
Reviewed-on: gitea_admin/homelab#84
2026-06-27 22:59:41 +02:00
k.rennerandClaude Opus 4.8 0ad25fbe1a feat(home-assistant): activate sml2mqtt bridge (privileged, stdout, replicas 1)
edl21 has been disabled in HA, freeing the meter's serial port, so the
bridge is activated for the cutover.

Three fixes from bring-up testing:
- logging.file: stdout (was ''). Empty string made sml2mqtt try to open
  the /sml2mqtt config dir as a log file (IsADirectoryError crash loop).
  'stdout' routes logs to the container console for kubectl/Loki.
- securityContext.privileged: true (with runAsUser 0). The meter device
  is root:root 0600, AND the device cgroup blocks a hostPath-mounted char
  device for non-privileged containers even as root. There is no
  device-plugin in the cluster; the existing USB pods (zwave-js, HA) use
  the same privileged pattern. User-approved.
- replicas: 0 -> 1 (port is now free; no edl21 contention).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 22:58:36 +02:00
k.renner 38001465cb Merge pull request 'Add dormant sml2mqtt power-meter bridge (phase 1 of moving HA off edge)' (#83) from worktree-ha-meter-mqtt-bridge into master
Reviewed-on: gitea_admin/homelab#83
2026-06-27 22:46:35 +02:00
k.rennerandClaude Opus 4.8 dbe1218c06 feat(home-assistant): add dormant sml2mqtt power-meter bridge (phase 1)
First phase of moving the resource-hungry Home Assistant pod off k8s-edge.
HA is pinned to edge solely by the USB power meter (FTDI FT230X) it reads
via the built-in edl21 integration. This adds an sml2mqtt bridge that will
read the meter and publish to the in-cluster Mosquitto broker, so HA can
read it over MQTT and stop needing the USB device / the edge node.

Shipped DORMANT (replicas: 0): the meter's serial port is a single
stream, so sml2mqtt and HA's edl21 cannot both read it. Merging this
changes nothing at runtime. The cutover (separate steps) is: disable
edl21 -> scale this to 1 -> add HA MQTT sensors reusing the existing
entity_ids (preserves long-term-statistics history) -> evict HA from edge.

Contents:
- sml2mqtt-deployment.yaml: edge-pinned, replicas:0, runs
  spacemanspiff2007/sml2mqtt:3.6.0 as root (meter dev is root:root 0600;
  no privileged needed), USB hostPath mount, init container renders the
  broker password into config.yml from a Secret.
- sml2mqtt-config.yaml: v3 config; Wh kept (not kWh) to match edl21 so
  history is continuous; publishes to mosquitto:1883 as user sml2mqtt.
- mosquitto: 4th broker user `sml2mqtt` (publish-only sml2mqtt/#) via a
  new bootstrap Job + passwd/ACL/env entries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 22:45:09 +02:00
k.renner b8b83baadb Merge pull request 'Unpin matter-server, otbr, music-assistant from k8s-edge (shrink edge to USB-only)' (#82) from worktree-edge-unpin-nonusb into master
Reviewed-on: gitea_admin/homelab#82
2026-06-27 18:44:29 +02:00
k.rennerandClaude Opus 4.8 e8448f6605 fix(home-automation): unpin matter-server, otbr, music-assistant from k8s-edge
These three only need v30iot L2 presence, which exists on every node
(eth1 is the v30iot interface on k8s-1/2/3 and k8s-edge alike), not the
edge node's USB devices. Removing their topology.kubernetes.io/zone=edge
nodeSelector and workload-class=pinned toleration lets the edge
NoSchedule taint keep them off the (soon-to-be dedicated, tiny N100) edge
box, reserving it for the only genuinely USB-bound workloads:
home-assistant (FTDI power meter) and zwave-js (ZWA-2 radio).

- matter-server / otbr: macvlan NAD already uses master: eth1, which
  resolves to v30iot on all nodes (verified live on k8s-1/2/3) — no NAD
  change needed.
- music-assistant: hostNetwork gets v30iot L2 on any node; it is the
  heaviest of the three (2Gi limit), so this is the main capacity win.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:41:37 +02:00
k.renner 0a3e4f90e3 Merge pull request 'traefik: real client-IP visibility via X-Forwarded-For (CrowdSec prereq #1)' (#81) from traefik-client-ip-visibility into master
Reviewed-on: gitea_admin/homelab#81
2026-06-27 17:48:01 +02:00
k.rennerandClaude Opus 4.8 ea7e861512 traefik: real client-IP visibility via X-Forwarded-For (CrowdSec prereq #1)
The netbird-ingress rootless routing peer re-originates every mesh + WAN-via-proxy connection from its own pod IP (e.g. fd10:244::2de1 = netbird-ingress-qxxc5), so Traefik's TCP peer for all that traffic is one shared pod IP — which is what let a single CrowdSec ban 403 every IPv6 client (2026-06-27 outage). The NetBird reverse-proxy (HTTP mode) already sets X-Forwarded-For with the real WAN client IP; Traefik just wasn't reading it.

Set ports.websecure.forwardedHeaders.trustedIPs to the pod CIDRs (10.244.0.0/16, fd10:244::/56 — the re-originators), so Traefik resolves the real client IP from XFF. Mirror it in the (still-inert) crowdsec-bouncer Middleware via forwardedHeadersTrustedIPs so it's ready when enforcement is re-enabled. Safe no-op where no XFF exists (direct LAN/mesh keep their RemoteAddr). Enforcement stays OFF — re-enabling still needs the internal allowlist (prereq #2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 16:42:07 +02:00
k.renner 8fe22ccca5 Merge pull request 'e2e: prune stale migration-era checks' (#79) from prune-stale-e2e-checks into master
Reviewed-on: gitea_admin/homelab#79
2026-06-27 16:27:31 +02:00
k.renner 9b837ecb9f Merge pull request 'traefik: disable global CrowdSec enforcement (caused v6 ingress outage)' (#80) from traefik-disable-crowdsec-enforcement into master
Reviewed-on: gitea_admin/homelab#80
2026-06-27 16:27:19 +02:00
k.rennerandClaude Opus 4.8 5073eed8e5 traefik: disable global CrowdSec enforcement (caused v6 ingress outage)
The global bouncer middleware banned all IPv6 ingress: Traefik sees one shared/SNAT'd v6 source, so a single http-admin-interface-probing hit (the e2e scan) 403'd every v6 client. Remove the global entrypoint-middleware attachment; keep the plugin + Middleware CRD inert so re-enabling is one line after fixing client-IP visibility + adding an internal whitelist. Detection (agents) stays on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 16:10:59 +02:00
k.rennerandClaude Opus 4.8 f5075dfe7f e2e: prune stale migration-era checks
These checks probed resources retired during the PVE->K8s migration and have been failing since e2e could run again (the fetch-kubeconfig path was broken ~45h). Verified each against live cluster + repo before removing:

- migration-bucket OBC Bound (authentik/paperless/audiobookshelf): no such OBCs exist in the cluster or repo (kubectl get obc -A is empty).
- Ceph RGW S3 round-trip: mounts the migration-bucket Secret/ConfigMap that the (gone) OBC generated; can't run. (The CephObjectStore rook-ceph/migration is itself now vestigial — separate cleanup.)
- TLS for auth.k.renner.uno: retired hostname, no Traefik router (serves the default cert / 404). Kept dash.k/audiobooks.k.renner.uno, which are real.
- authentik OIDC well-known: paperless: paperless uses an Authentik proxy outpost, not OIDC, so it has no /application/o/paperless provider (404). Kept audiobookshelf + grafana, which are real OIDC apps (200).

Left intact: loki/prometheus/alertmanager/paperless-docs and all storage/velero/cert/db checks — those are valid and merely flaked transiently during the recent cluster churn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 14:51:27 +02:00
k.renner 76f8191658 Merge pull request 'fix(traefik): bouncer middleware attachment used a schema-invalid key' (#78) from fix-traefik-middleware-schema into master
ci/woodpecker/manual/e2e Pipeline failed
Reviewed-on: gitea_admin/homelab#78
2026-06-27 13:11:54 +02:00
k.rennerandClaude Opus 4.8 3084bf0551 traefik: fix bouncer middleware attachment (schema-invalid key)
PR #77 used ports.websecure.middlewares, which chart 40.x's values schema rejects ('additional properties middlewares not allowed'), so the whole Helm upgrade failed and degraded the infrastructure kustomization. Attach the entrypoint default middleware via additionalArguments CLI flag instead (schema-free). experimental.plugins was fine and is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 13:09:42 +02:00
k.renner 5aa5e158b7 Merge pull request 'traefik: add CrowdSec bouncer plugin + global fail-open middleware' (#77) from traefik-crowdsec-bouncer into master
ci/woodpecker/manual/deploy-infrastructure Pipeline was successful
Reviewed-on: gitea_admin/homelab#77
2026-06-27 13:06:15 +02:00
k.rennerandClaude Opus 4.8 b43e641f64 traefik: add CrowdSec bouncer plugin + global fail-open middleware
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 13:04:24 +02:00
k.renner cde4b58bad Merge pull request 'crowdsec: repoint agent log acquisition from ingress-nginx to Traefik' (#76) from crowdsec-acquisition-traefik into master
Reviewed-on: gitea_admin/homelab#76
2026-06-27 13:02:10 +02:00
k.rennerandClaude Opus 4.8 6810dba05a crowdsec: repoint agent log acquisition from ingress-nginx to Traefik
The agent's acquisition still targeted podName ingress-nginx-controller-*
in the ingress namespace — a selector that has matched no pod since
ingress-nginx was retired (2026-05-17), so the agents have been parsing
nothing and no decisions were being generated.

Repoint to the Traefik controller (podName traefik-*, program traefik)
and swap the nginx collection/parser for crowdsecurity/traefik (which
bundles its own log parser). This restores attack detection. Enforcement
(a Traefik bouncer acting on the decisions) is a separate change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 12:46:02 +02:00
k.renner 65233120a2 Merge pull request 'opentofu: decommission stopped pre-k8s guests (migration rollback net)' (#75) from decommission-pre-k8s-guests into master
ci/woodpecker/push/deploy-infrastructure Pipeline was successful
Reviewed-on: gitea_admin/homelab#75
2026-06-27 12:38:09 +02:00
k.renner 41ba8f9f72 Merge pull request 'ha/matter: remove completed HAOS migration-seed init containers' (#74) from drop-haos-migration-seeds into master
Reviewed-on: gitea_admin/homelab#74
2026-06-27 12:37:58 +02:00
k.renner e875e672b4 Merge pull request 'ci: decommission migration-only rebuild-k8s; point access tooling at Hetzner' (#73) from decouple-garage-decomm-rebuild into master
Reviewed-on: gitea_admin/homelab#73
2026-06-27 12:37:45 +02:00
k.renner 7ce80e80a6 Merge pull request 'netbird-server: drop vestigial reverse-SSH tunnel' (#72) from netbird-drop-vestigial-tunnel into master
ci/woodpecker/push/deploy-netbird-server Pipeline failed
Reviewed-on: gitea_admin/homelab#72
2026-06-27 12:37:34 +02:00
k.renner 0a1da6695b Merge pull request 'cleanup(ansible): remove dead Caddy plays + Grafana dashboard' (#71) from cleanup-caddy-ansible-residue into master
Reviewed-on: gitea_admin/homelab#71
2026-06-27 12:37:20 +02:00
k.rennerandClaude Opus 4.8 3360f6ca83 opentofu: decommission stopped pre-k8s guests (migration rollback net)
ci/woodpecker/push/deploy-infrastructure Pipeline was successful
All 13 services run in k8s and were verified healthy/Running before
removal (audiobookshelf, immich, loki, prometheus, ical-proxy,
music-assistant, authentik full stack, home-assistant, influxdb [in
cluster as influxdb-influxdb2], grafana [kube-prometheus-stack]). These
stopped Proxmox guests were the PVE->K8s migration rollback net; with the
replacements serving 1-7 weeks, retire them.

Removed tofu modules (destroys the stopped guests + their stale DNS):
- vm_103_homeassistant, vm_108_influxdb, vm_109_grafana
- lxc_121_ical_proxy, lxc_212_audiobookshelf, lxc_225_immich,
  lxc_226_loki, lxc_227_prometheus, lxc_229_music_assistant
- lxc_authentik_ha (130/131/132/133) + its stale authentik-db.renner.uno
  -> 10.2.40.135 (dead keepalived VIP) DNS record
- backup_jobs.tf: drop VMIDs 103/108/109/121/130/131/132/133/212/225/226/227/229

Kept: fortress VM (102, not a migrated service) and paperless VM (111).

IRREVERSIBLE: applying destroys these guests and wipes their disks.
Review the plan before apply.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 12:34:46 +02:00