Design for replacing the monthly Velero restore-test: an in-cluster
CronJob creates a throwaway VM in fsn1, which runs kopia snapshot verify
(100% of files, read-only) against every latest DataUpload snapshot and
checks sizes against DataUpload totalBytes. No restored data is written
to the Ceph OSDs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The event is derived by the pipeline from the report's severity sections:
Blocking -> REQUEST_CHANGES; none of Blocking/Suggestions/Unverified on a
non-empty diff -> APPROVE; otherwise COMMENT.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Drop the complexity triage (it downgraded most PRs to a small model) and pick
the model via scripts/ci/pick-model.sh from the live /v1/models catalog,
steered to the strongest and newest. Falls back to the CLI default.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Move the review logic out of .woodpecker/pr-review.yml into
ci/agents/pr-review/run.sh; the per-repo file becomes a logic-free stub that
clones homelab@master and runs it, so the four copies cannot drift.
Prompt: unverified suspicions must be checked (checkout + docs) and are never
blocking. Review agent gets WebFetch/WebSearch.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Gitea 1.27 deprecates [webhook] ALLOWED_HOST_LIST (fallback removed in
v28.0.0). The on-PVC app.ini had it set to `*`. Track the replacement
in git and narrow it to the hosts the configured webhooks call:
- ci.renner.uno (Woodpecker, 10 repo hooks)
- paperclip-api.renner.uno (6 repo hooks)
- wiki.ai.svc.cluster.local (1 repo hook)
- openproject.renner.uno (OpenProject GitHub-style webhook, REN-1363)
Hostname entries match before any IP check (modules/hostmatcher), so
the private Traefik VIP behind these names does not need `private`.
The deprecated [webhook] ALLOWED_HOST_LIST and the admin-panel-managed
[picture] DISABLE_GRAVATAR / ENABLE_FEDERATED_AVATAR keys were removed
from the on-PVC app.ini by hand, and the same [security] value written
there, since environment-to-ini can only add keys.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Authentik gets an OpenProject confidential OAuth2 provider, application and
OpenProject Users group in the blueprint; the client secret is read from
OpenBao apps/openproject through an ExternalSecret and !Env. OpenProject
seeds the matching provider from env, and its egress policy allows
Authentik via Traefik.
Refs: REN-1363
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The udm_cef regex expected UNIFIhost immediately after the CEF header and
UNIFIdeviceName/-Model/-Ip/-Mac/-Version before msg. The UDM emits
UNIFIcategory first and the extension keys differ per event type, so no line
matched and no labels were promoted.
Anchor on the header, UNIFIcategory, UNIFIhost and the trailing msg, and
promote vendor, product, signature_id, event_name and category.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Upstream wait-for-db boots Rails via `rails runner`, and the
06-pending_migrations_check initializer aborts boot while migrations are
pending. Ahead of the seeder it can never pass on a fresh database: the
pod crashlooped in Init:Error with 154 pending migrations.
The seeder runs docker/prod/migrate (structure load on an empty DB, else
db:migrate) under rake, which skips that check; the kubelet retries it
until op-pg accepts connections.
Refs: REN-1363
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OpenProject reads Gitea webhooks only from 1.22 on. 1.27.3 is the last
1.x release; 28.x changes the egress host lists and follows separately.
Adds a startupProbe so the liveness probe cannot kill Gitea while the
first start runs the database migrations.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Point-in-time copy of data-gitea-0 before 1.21.4 -> 1.27.3. The new
version migrates the SQLite database; a restore from this snapshot is the
way back. Restore steps are in the file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New openproject namespace and Flux KS: web + worker pod (17.9.1-slim,
digest-pinned), op-pg CNPG 17 with Barman to Hetzner, attachments PVC
with a Velero schedule, ESO-generated SECRET_KEY_BASE and admin password,
public Ingress on openproject.renner.uno via the NetBird edge, default-deny
CNP, op-pg PodMonitor and a blackbox health probe.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sandbox pods got 403 Route not allowed on /api/agents/me/secrets*.
Adds the five /api/agents/me secret routes to the callback bridge
allowlist; company-wide secret routes stay denied.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SML power-meter reader was retired by owner decision on 2026-09-19:
grid data comes from the E380 on the CAN bus (wiki
sml-to-e380-grid-meter-migration). Its reader has been unplugged since then.
- register: edge-1 loses write sml2mqtt/# (live, no broker restart)
- bridge templates: no sml2mqtt topic, no legacy sml2mqtt bridge
- remove role power-meter-sml, play install-power-meter.yml, inventory
group power_meter and the vault indirection
- edge-mqtt-bridge play: pre_tasks stop and remove the leftover compose
project on edge-1 on the next pipeline run (idempotent)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The register account `edge-1` replaces the legacy password users open3e
and sml2mqtt for edge-1's local mosquitto bridge. Controller main-cb96b1a
(REN-1308) delivers the password to edge-mqtt-cred over HTTPS with its
client certificate and pins edge-1's server certificate on first contact.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
edge-1's bridge password moves out of ansible-vault. A small receiver,
edge-mqtt-cred, speaks the controller's esp32 API over HTTPS with mTLS
(only CN mqtt-account-controller from the MQTT CA) and writes one bridge
`edge-1` for open3e and sml2mqtt. Until the first push the two
vault-password bridges stay in bridge.d/legacy.conf, so nothing changes
on the cluster side yet.
A Woodpecker pipeline runs the role-only play on merge, so no manual play
run is needed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mqtt-account-controller (REN-1284) now pushes the CA and the client
certificate of the register account home-assistant into HA's MQTT config
entry via HA's reconfigure flow, only when tls.crt changed and only inside
02:00-05:00 Europe/Berlin. Mounts mqtt-home-assistant-tls and the HA token
(OpenBao apps/home-assistant/mqtt-cert-sync-token, service user MQTT Cert
Sync), sets the HA env and adds Secret mqtt-ha-cert-sync to the Role.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Step 2 of adopt-then-prune. #1196 put the Secret in the home-assistant
Flux inventory (Ready at 67bc773a). Removing the manifest lets prune
delete it. Nothing reads it since #1191.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Step 1 of adopt-then-prune. The removed shellies bootstrap Job created
this Secret outside Git; nothing reads it. An empty manifest with the
same name and type puts it in the Flux inventory; the follow-up PR
removes the file so prune deletes the Secret.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>