Compare commits

...
Author SHA1 Message Date
claude-botandClaude Opus 5.5 3aa2cf7616 feat(paperless): Syncthing UI behind the Authentik gate
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
Serve the UI at syncthing.paperless.renner.uno for Paperless Admins. That hostname was the sync LoadBalancer's DNS name, so the LoadBalancer moves to sync.paperless.renner.uno and the DNS probe follows it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 11:40:45 +01:00
security-bot 0a36c324da chore(image-automation): bump gitea.renner.uno/konairius/shelly-manager:2026-10-30-0913
Updates managed by image-automation-controller.
2026-10-30 09:24:27 +00:00
security-bot 8d3578f020 chore(image-automation): bump gitea.renner.uno/konairius/shelly-manager:2026-10-30-0728
Updates managed by image-automation-controller.
2026-10-30 07:54:27 +00:00
security-bot 10f1a88802 chore(image-automation): bump gitea.renner.uno/konairius/shelly-manager:2026-10-30-0719
Updates managed by image-automation-controller.
2026-10-30 07:24:27 +00:00
security-bot 4dd46a8e7b chore(image-automation): bump gitea.renner.uno/konairius/shelly-manager:2026-10-30-0624
Updates managed by image-automation-controller.
2026-10-30 06:54:27 +00:00
security-bot 859d1a7c65 chore(image-automation): bump lscr.io/linuxserver/lidarr:3.1.6.5079-ls46
Updates managed by image-automation-controller.
2026-10-30 06:50:46 +00:00
k.renner 0575a50d9e Merge pull request 'fix(lidarr): scan ghcr.io directly instead of lscr.io redirector' (#1528) from alert-fix/issue-1527 into main
Reviewed-on: #1528
2026-10-30 06:22:12 +00:00
security-bot 33b7b58849 chore(image-automation): bump ghcr.io/paperless-ngx/paperless-ngx:3.4.0
Updates managed by image-automation-controller.
2026-10-29 22:50:43 +00:00
hermes-bot dab7c10eca fix(lidarr): scan ghcr.io directly instead of lscr.io
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
lscr.io 302-redirects the tag-list request to ghcr.io and the
image-reflector's follow-up arrives unauthenticated (UNAUTHORIZED),
leaving ImageRepository/lidarr not Ready since 2026-10-29T18:56Z.
ghcr.io/linuxserver/lidarr is the same repository (identical digest
for 3.1.6.5079-ls46) and scans anonymously. Workload refs follow so
the imagepolicy setter keeps matching.

Closes #1527
2026-10-29 21:24:11 +00:00
security-bot 378f7e3429 chore(image-automation): bump woodpeckerci/woodpecker-agent:v3.20.1
Updates managed by image-automation-controller.
2026-10-29 20:54:22 +00:00
security-bot fdc08827fb chore(image-automation): bump woodpeckerci/woodpecker-server:v3.20.1
Updates managed by image-automation-controller.
2026-10-29 19:54:51 +00:00
security-bot 3d504c2f62 chore(image-automation): bump gitea.renner.uno/konairius/shelly-manager:2026-10-29-1803
Updates managed by image-automation-controller.
2026-10-29 18:24:26 +00:00
k.renner d56deb096e Merge pull request 'feat(shelly-manager): roll firmware out to battery devices' (#1526) from shelly-manager-sleepy-rollout into main
Reviewed-on: #1526
2026-10-29 17:57:37 +00:00
claude-botandClaude Opus 5.5 222965ba47 feat(shelly-manager): roll firmware out to battery devices
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
Firmware:SleepyRollout makes shelly-manager push a battery device's update
when it calls in; it was unset, so the rollout never took them along.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185Qb5YG28FfnVi1ujMEV5C
2026-10-29 18:54:23 +01:00
security-bot 394bf91c37 chore(image-automation): bump gitea.renner.uno/konairius/mqtt-account-controller:2026-10-29-1634
Updates managed by image-automation-controller.
2026-10-29 16:34:44 +00:00
security-bot 2f7bc33b84 chore(image-automation): bump gitea.renner.uno/konairius/shelly-manager:2026-10-29-1545
Updates managed by image-automation-controller.
2026-10-29 15:54:25 +00:00
security-bot 6c045e2e56 chore(image-automation): bump gitea.renner.uno/konairius/shelly-manager:2026-10-29-1524
Updates managed by image-automation-controller.
2026-10-29 15:35:31 +00:00
k.renner 6a39dd1f6e Merge pull request 'chore(ci): bump ci-claude image to 2.1.312' (#1524) from ci-image/claude-2.1.312 into main
Reviewed-on: #1524
2026-10-29 14:50:57 +00:00
security-bot 70a9c66902 chore(image-automation): bump gitea.renner.uno/gitea_admin/ci-backup-verify:2026-10-29
Updates managed by image-automation-controller.
2026-10-29 14:23:57 +00:00
security-bot dcf902f53a chore(image-automation): bump gitea.renner.uno/gitea_admin/kuma-sync:2026-10-29-1349
Updates managed by image-automation-controller.
2026-10-29 14:23:54 +00:00
security-bot 83235b2b07 chore(image-automation): bump gitea.renner.uno/gitea_admin/cloudflare-lb-sync:2026-10-29-1355
Updates managed by image-automation-controller.
2026-10-29 14:17:20 +00:00
security-bot b656422890 chore(image-automation): bump gitea.renner.uno/gitea_admin/review-bot:2026-10-29-1346
Updates managed by image-automation-controller.
2026-10-29 14:12:31 +00:00
security-bot 9f5acfd3a6 chore(image-automation): bump gitea.renner.uno/gitea_admin/authentik-gate-sync:2026-10-29-1349
Updates managed by image-automation-controller.
2026-10-29 14:06:57 +00:00
security-bot 30db24335e chore(image-automation): bump gitea.renner.uno/gitea_admin/secret-rotator:2026-10-29
Updates managed by image-automation-controller.
2026-10-29 13:53:53 +00:00
security-bot 0e33efa3b1 chore(image-automation): bump gitea.renner.uno/konairius/alpine-jq:2026-10-29-1348 gitea.renner.uno/konairius/cni-plugins:2026-10-29-1348
Updates managed by image-automation-controller.
2026-10-29 13:53:18 +00:00
security-bot 9fcf5259cb chore(image-automation): bump gitea.renner.uno/konairius/alpine-openssl:2026-10-29-1348
Updates managed by image-automation-controller.
2026-10-29 13:53:16 +00:00
security-bot ff6a96438d chore(image-automation): bump gitea.renner.uno/konairius/hermes:2026-10-29-1342
Updates managed by image-automation-controller.
2026-10-29 13:47:37 +00:00
claude-bot 2e3d055310 chore(ci): bump ci-claude image to 2.1.312
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
2026-10-29 13:42:08 +00:00
k.renner b741f4bdb0 Merge pull request 'fix(ntp): IPv4 A record and fd02:40::123 for ntp.srv.renner.uno' (#1523) from worktree-ntp-ipv4-record into main
ci/woodpecker/push/ci-claude-refresh Pipeline was successful
ci/woodpecker/push/deploy-infrastructure Pipeline was successful
ci/woodpecker/push/hermes-image Pipeline was successful
ci/woodpecker/push/build-ci-images Pipeline was successful
Reviewed-on: #1523
2026-10-29 13:41:13 +00:00
claude-botandClaude Opus 5.5 1efbfd1424 fix(ntp): move the IPv6 service address to fd02:40::123
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
fd40::/64 is the legacy VLAN 40 ULA; fd02:40::/64 is current. edge-1
takes RAs on enp1s0.40, so the prefix is on-link there.

The AAAA for ntp.srv.renner.uno moves into OpenTofu next to the A.
Records gain an optional name so one host can carry both types without
re-keying the existing ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:38:04 +01:00
claude-bot 9a061ff4ce Merge remote-tracking branch 'origin/main' into worktree-ntp-ipv4-record 2026-10-29 14:36:46 +01:00
claude-botandClaude Opus 5.5 a593df3bb4 fix(dns): add A for ntp.srv.renner.uno (legacy IPv4 VIP)
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ntp.srv.renner.uno carries only the AAAA fd40::123, so IPv4-only clients
behind ntp.renner.uno get no address. The keepalived IPv4 VIP 10.2.40.4
answers NTP; IoT and Server share the Internal zone, where UDP 123 is
allowed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:31:36 +01:00
security-bot cd39bf648a chore(image-automation): bump gitea.renner.uno/gitea_admin/kuma-sync:2026-10-29-1313
Updates managed by image-automation-controller.
2026-10-29 13:23:53 +00:00
k.renner e4362bbd69 Merge pull request 'feat(kuma-sync): declarative notifications via KumaNotification' (#1522) from kuma-notifications into main
ci/woodpecker/push/build-ci-images Pipeline was successful
Reviewed-on: #1522
Reviewed-by: Review Bot <review-bot@renner.uno>
2026-10-29 13:13:30 +00:00
k.renner 6dc27eb31c Merge pull request 'fix(shelly-manager): allow IPv6 HTTP egress to global device addresses' (#1521) from shelly-manager-iot-v6-world-egress into main
Reviewed-on: #1521
2026-10-29 12:33:45 +00:00
claude-botandClaude Opus 5.5 1dfdb104c5 fix(shelly-manager): allow IPv6 HTTP egress to global device addresses
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
Gen3/Gen4 Shellies advertise a global address from the delegated IoT
prefix over mDNS. Egress to it was policy-denied, so connects to it hung
until the request timeout instead of reaching the device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185Qb5YG28FfnVi1ujMEV5C
2026-10-29 13:30:57 +01:00
34 changed files with 129 additions and 58 deletions
+4 -4
View File
@@ -35,25 +35,25 @@ when:
steps:
- name: model-selection-tests
depends_on: []
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.311
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.312
commands:
- sh scripts/ci/test-model-selection.sh
- name: pr-review-mistral-tests
depends_on: []
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.311
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.312
commands:
- sh scripts/ci/test-pr-review-mistral.sh
- name: promtool-rules-guard-tests
depends_on: []
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.311
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.312
commands:
- sh scripts/ci/test-promtool-rules.sh
- name: yaml-citations-guard-tests
depends_on: []
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.311
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.312
commands:
- sh scripts/ci/test-yaml-citations.sh
+1 -1
View File
@@ -26,7 +26,7 @@ steps:
# fetch-models.sh response mapping. No cluster, no secrets, no network — the
# ci-claude image just provides sh + jq. Keeps the flag-injection regression
# test from rotting (it exercises the exact injection shapes).
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.311
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.312
commands:
- sh scripts/ci/test-model-selection.sh
+1 -1
View File
@@ -70,7 +70,7 @@ steps:
# this step is skipped — otherwise we'd fork-bomb PRs.
when:
- branch: main
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.311
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.312
environment:
CLAUDE_CODE_OAUTH_TOKEN:
from_secret: claude_code_oauth_token
+1 -1
View File
@@ -30,7 +30,7 @@ when:
steps:
- name: update-audit-agent
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.311
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.312
environment:
CLAUDE_CODE_OAUTH_TOKEN:
from_secret: claude_code_oauth_token
+1 -1
View File
@@ -8,7 +8,7 @@
# two plays over this group -- withdraw the static assignments fleet-wide, then
# hand the address to keepalived -- and both need the same value. Duplicating a
# service address across plays is exactly the sort of thing that drifts.
ntp_vip6: "fd40::123/128"
ntp_vip6: "fd02:40::123/128"
# Link-local address carried as the FIRST virtual_ipaddress of the IPv6 VRRP
# instance. RFC 5798 gives an IPv6 virtual router a link-local primary, and
+1 -1
View File
@@ -55,7 +55,7 @@ heating_can
# THIS IS NO LONGER HIGHLY AVAILABLE. The group was jupiter (MASTER, prio 100),
# saturn (90), neptune (80) and edge-1 (BACKUP, 70); the first three are gone.
# A single VRRP member takes the address regardless of its configured state, so
# fd40::123 is still served — verified answering — but by one thin client with
# the service address is still served, but by one thin client with
# no failover behind it. install-ntp-ha.yml still carries the four-host
# ntp_servers priority map, which now describes hosts that do not exist.
#
+1 -1
View File
@@ -62,7 +62,7 @@
# One node at a time. The keepalived role withdraws the statically assigned
# IPv6 service address and restarts keepalived so the address is re-taken
# under VRRP control; doing that across every NTP server at once would leave
# the whole fleet with nobody holding fd40::123 until the elections settle.
# the whole fleet with nobody holding the service address until the elections settle.
# Serialised, the remaining members keep answering throughout.
serial: 1
@@ -4,7 +4,7 @@
# Networks allowed to use this server as NTP source.
#
# BOTH families are required. IPv6 is the primary address family here -- the
# service address ntp.srv.renner.uno resolves to fd40::123 -- so an IPv4-only
# service address ntp.srv.renner.uno resolves to fd02:40::123 -- so an IPv4-only
# allow list refuses every client that uses the documented name.
#
# The hosts carried `allow fd00::/8` for a long time without it ever being in
+3 -3
View File
@@ -99,7 +99,7 @@
# quietly proceed either. install-edge-host.yml is a separate play with no
# ordering relationship to this one, so nothing guarantees it has been re-run
# to drop the [Address] block. If it has not, edge-1 would end up holding
# fd40::123 statically AND running a VRRP instance for the same address:
# the service address statically AND running a VRRP instance for the same address:
# keepalived would believe it had withdrawn the address while networkd kept it
# assigned, and the host would go on answering NTP with a clock the health
# check had already rejected.
@@ -107,9 +107,9 @@
# That is the precise failure of 2026-08-04, on the host it happened to, so it
# fails fast rather than being left to inspection.
# Matched on the bare address, not the full address/prefixlen, and anchored
# with \b so it cannot also hit a longer address sharing the prefix (fd40::1234).
# with \b so it cannot also hit a longer address sharing the prefix (fd02:40::1234).
#
# Searching for the literal "fd40::123/128" would fail open: a hand-written
# Searching for the literal "fd02:40::123/128" would fail open: a hand-written
# [Address] using any other mask -- /64, say -- would not match, the assert
# below would pass, and keepalived would be handed an address networkd is
# still assigning. Since this check is detect-only, with no delete afterwards
@@ -103,6 +103,16 @@ data:
slug: paperless-proxy
state: absent
# syncthing.paperless.renner.uno is gated by authentik-gate-sync
# (kubernetes/apps/paperless/syncthing.yaml), which admits this group.
# Members are managed in Authentik.
- model: authentik_core.group
identifiers:
name: Paperless Admins
state: present
attrs:
is_superuser: false
# vscode.home.renner.uno is gated by authentik-gate-sync
# (kubernetes/apps/home-assistant/vscode-ingress.yaml), which admits this
# group. Members are managed in Authentik.
+1 -1
View File
@@ -105,7 +105,7 @@ spec:
type: RuntimeDefault
containers:
- name: controller
image: gitea.renner.uno/gitea_admin/authentik-gate-sync:2026-10-28-0712 # {"$imagepolicy": "flux-system:authentik-gate-sync"}
image: gitea.renner.uno/gitea_admin/authentik-gate-sync:2026-10-29-1349 # {"$imagepolicy": "flux-system:authentik-gate-sync"}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
@@ -30,7 +30,7 @@ spec:
type: RuntimeDefault
containers:
- name: controller
image: gitea.renner.uno/gitea_admin/cloudflare-lb-sync:2026-10-28-0718 # {"$imagepolicy": "flux-system:cloudflare-lb-sync"}
image: gitea.renner.uno/gitea_admin/cloudflare-lb-sync:2026-10-29-1355 # {"$imagepolicy": "flux-system:cloudflare-lb-sync"}
env:
- name: CLOUDFLARE_API_TOKEN
valueFrom:
@@ -32,7 +32,7 @@ spec:
type: RuntimeDefault
containers:
- name: sync
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
command:
- /opt/hermes/.venv/bin/python
- /opt/hermes-skills/gitea-issues/scripts/sync_webhook.py
+10 -10
View File
@@ -51,7 +51,7 @@ spec:
# connects from the pod network. No env equivalent exists, so it is
# set in config.yaml on every start (idempotent).
- name: config
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
command:
- /opt/hermes/.venv/bin/hermes
- config
@@ -75,7 +75,7 @@ spec:
mountPath: /opt/data
# WebSocket keepalive ping interval in seconds (default 20).
- name: config-ws-ping
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
command:
- /opt/hermes/.venv/bin/hermes
- config
@@ -99,7 +99,7 @@ spec:
mountPath: /opt/data
# Skills from git (ConfigMap hermes-skills) beside the PVC's skills/.
- name: skills-config
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
command:
- /opt/hermes/.venv/bin/hermes
- config
@@ -130,7 +130,7 @@ spec:
# - alert-monitor: hourly; the script wakes the agent only for
# untriaged alerts.
- name: cron-jobs
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
# Non-fatal: a broken jobs.json or a changed cron CLI after an image
# bump logs a warning instead of keeping Hermes from starting.
command:
@@ -187,7 +187,7 @@ spec:
readOnly: true
# Home Assistant MCP server; token resolved from HA_TOKEN at connect, writes need approval.
- name: config-mcp-homeassistant
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
command:
- /opt/hermes/.venv/bin/hermes
- config
@@ -214,7 +214,7 @@ spec:
# skills, the Home Assistant MCP and the tea login are re-applied on
# every start. default gets the kanban toolset to hand cards to them.
- name: experts
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
# Non-fatal like cron-jobs: a broken expert logs a warning.
command:
- sh
@@ -305,7 +305,7 @@ spec:
# Gitea issues -> kanban (skills/gitea-issues): route script, webhook route on default,
# completion shell hook plus its allowlist entry on every profile.
- name: gitea-issues
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
# Non-fatal like cron-jobs: a failure logs a warning.
command:
- sh
@@ -368,7 +368,7 @@ spec:
readOnly: true
# Multiplexed default reads platform credentials only from .env (rationale: commit message).
- name: default-env
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
# Fatal on a writer failure: without these Matrix and the API server stay down.
command:
- /opt/hermes/.venv/bin/python
@@ -428,7 +428,7 @@ spec:
# tea login hermes-bot, written from the mounted token into an
# emptyDir at the agent's ~/.config/tea.
- name: tea-login
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
command:
- sh
- -ec
@@ -457,7 +457,7 @@ spec:
readOnly: true
containers:
- name: hermes
image: gitea.renner.uno/konairius/hermes:2026-10-28-0704 # {"$imagepolicy": "flux-system:hermes"}
image: gitea.renner.uno/konairius/hermes:2026-10-29-1342 # {"$imagepolicy": "flux-system:hermes"}
args: ["gateway", "run"]
env:
- name: HERMES_DASHBOARD
@@ -64,7 +64,7 @@ spec:
type: RuntimeDefault
containers:
- name: shelly-manager
image: gitea.renner.uno/konairius/shelly-manager:2026-10-29-0949 # {"$imagepolicy": "flux-system:shelly-manager"}
image: gitea.renner.uno/konairius/shelly-manager:2026-10-30-0913 # {"$imagepolicy": "flux-system:shelly-manager"}
imagePullPolicy: IfNotPresent
ports:
- name: http
@@ -106,6 +106,9 @@ spec:
# The URL devices download firmware from: Service shelly-manager-firmware.
- name: Firmware__PublicBaseUrl
value: http://firmware.shelly-manager.renner.uno
# Battery devices get their update when they call in.
- name: Firmware__SleepyRollout
value: "true"
- name: ShellyManager__DnsSuffix
value: iot.renner.uno
# BLE radios: ESP32 esphome bluetooth_proxy nodes (e.g. the M5 Atom
@@ -223,7 +223,7 @@ spec:
type: RuntimeDefault
containers:
- name: controller
image: gitea.renner.uno/konairius/mqtt-account-controller:2026-10-28-0657 # {"$imagepolicy": "flux-system:mqtt-account-controller"}
image: gitea.renner.uno/konairius/mqtt-account-controller:2026-10-29-1634 # {"$imagepolicy": "flux-system:mqtt-account-controller"}
env:
- name: BROKER_URL
value: ssl://mosquitto.home-assistant.svc.cluster.local:8884
@@ -66,7 +66,7 @@ spec:
# (machine.registries.mirrors, applied by bootstrap.sh), and containerd
# keeps the repository path when it falls through — so the path has to
# exist on both registries. Steady state still pulls from Gitea.
image: gitea.renner.uno/konairius/alpine-jq:2026-10-28-0711 # {"$imagepolicy": "flux-system:alpine-jq"}
image: gitea.renner.uno/konairius/alpine-jq:2026-10-29-1348 # {"$imagepolicy": "flux-system:alpine-jq"}
command:
- sh
- -c
+1 -1
View File
@@ -30,7 +30,7 @@ spec:
type: RuntimeDefault
containers:
- name: controller
image: gitea.renner.uno/gitea_admin/kuma-sync:2026-10-28-0712 # {"$imagepolicy": "flux-system:kuma-sync"}
image: gitea.renner.uno/gitea_admin/kuma-sync:2026-10-29-1349 # {"$imagepolicy": "flux-system:kuma-sync"}
env:
- name: KUMA_URL
value: https://kuma.renner.uno
@@ -142,4 +142,4 @@ spec:
- "[fd02:47::1]:53"
- "10.2.47.1:53"
labels:
dns_name: syncthing.paperless.renner.uno
dns_name: sync.paperless.renner.uno
@@ -136,7 +136,7 @@ spec:
prober: dns
timeout: 5s
dns:
query_name: syncthing.paperless.renner.uno
query_name: sync.paperless.renner.uno
query_type: A
valid_rcodes: [NOERROR]
validate_answer_rrs:
@@ -138,3 +138,25 @@ spec:
expiryNotification: true
keyword:
keyword: "<title>authentik</title>"
---
apiVersion: uptime.renner.uno/v1alpha1
kind: KumaMonitor
metadata:
name: syncthing-ui-gate
namespace: paperless
spec:
type: keyword
displayName: Syncthing Login
parentRef:
name: docs
interval: 60
retryInterval: 60
maxRetries: 1
timeout: 20
http:
# behind the Authentik gate; asserts the login page the redirect chain ends on
url: https://syncthing.paperless.renner.uno/
acceptedStatusCodes: ["200-299"]
expiryNotification: true
keyword:
keyword: "<title>authentik</title>"
+2 -2
View File
@@ -155,7 +155,7 @@ spec:
# exist on both registries — hence konairius/, which matches the ghcr
# namespace. Steady state still pulls from Gitea and never leaves the
# network.
image: gitea.renner.uno/konairius/alpine-openssl:2026-10-28-0711 # {"$imagepolicy": "flux-system:alpine-openssl"}
image: gitea.renner.uno/konairius/alpine-openssl:2026-10-29-1348 # {"$imagepolicy": "flux-system:alpine-openssl"}
command:
- sh
- -c
@@ -182,7 +182,7 @@ spec:
drop: ["ALL"]
containers:
- name: paperless
image: ghcr.io/paperless-ngx/paperless-ngx:3.3.4 # {"$imagepolicy": "flux-system:paperless-ngx"}
image: ghcr.io/paperless-ngx/paperless-ngx:3.4.0 # {"$imagepolicy": "flux-system:paperless-ngx"}
ports:
- name: http
containerPort: 8000
+33 -10
View File
@@ -52,11 +52,8 @@ spec:
- name: syncthing
image: syncthing/syncthing:2.1.7@sha256:2b71da7c0d0a91a6ae5285ad079226fecc0a365d08b27720e1f7037b018f7546
env:
# UI bind: any-interface so the ClusterIP Service can reach
# it. Network exposure is gated by the absence of an Ingress
# and the namespace default-deny CNP — set a UI password in
# the Syncthing UI on first port-forward access before
# publishing it.
# UI bind: any-interface so the ClusterIP Service can reach it.
# External access goes through the syncthing-ui Ingress only.
- name: STGUIADDRESS
value: "0.0.0.0:8384"
- name: PUID
@@ -115,10 +112,6 @@ spec:
persistentVolumeClaim:
claimName: paperless-consume
---
# UI Service — ClusterIP only. Access via `kubectl -n paperless
# port-forward svc/syncthing-ui 8384:8384` for first-time setup
# (set admin password). Future Ingress + Authentik gate is a
# separate change once auth is configured.
apiVersion: v1
kind: Service
metadata:
@@ -132,6 +125,36 @@ spec:
port: 8384
targetPort: ui
---
# LAN-only UI: Paperless Admins through the Authentik gate.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: syncthing-ui
namespace: paperless
labels:
dns.renner.uno/internal: "true"
annotations:
traefik.ingress.kubernetes.io/router.middlewares: authentik-gate@kubernetescrd
cert-manager.io/cluster-issuer: letsencrypt-cluster
auth.renner.uno/group: Paperless Admins
spec:
ingressClassName: traefik
rules:
- host: syncthing.paperless.renner.uno
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: syncthing-ui
port:
number: 8384
tls:
- secretName: syncthing-ui-tls
hosts:
- syncthing.paperless.renner.uno
---
# Sync ports — LAN-reachable LoadBalancer. Peers (phones, laptops)
# connect here for the dropbox sync. external-dns publishes the
# hostname into UniFi DNS only (no cloudflare label); off-LAN peers
@@ -146,7 +169,7 @@ metadata:
dns.renner.uno/internal: "true"
annotations:
io.cilium/lb-ipam-ips: "10.2.99.85,fd99::85"
external-dns.kubernetes.io/hostname: syncthing.paperless.renner.uno
external-dns.kubernetes.io/hostname: sync.paperless.renner.uno
spec:
type: LoadBalancer
externalTrafficPolicy: Local
+1 -1
View File
@@ -32,7 +32,7 @@ spec:
type: RuntimeDefault
containers:
- name: review-bot
image: gitea.renner.uno/gitea_admin/review-bot:2026-10-28-0709 # {"$imagepolicy": "flux-system:review-bot"}
image: gitea.renner.uno/gitea_admin/review-bot:2026-10-29-1346 # {"$imagepolicy": "flux-system:review-bot"}
env:
- name: GITEA_URL
value: https://gitea.renner.uno
+1 -1
View File
@@ -184,7 +184,7 @@ spec:
# (machine.registries.mirrors, applied by bootstrap.sh), and containerd
# keeps the repository path, so it has to exist on both registries.
# Steady state still pulls from Gitea.
image: gitea.renner.uno/konairius/alpine-jq:2026-10-28-0711 # {"$imagepolicy": "flux-system:alpine-jq"}
image: gitea.renner.uno/konairius/alpine-jq:2026-10-29-1348 # {"$imagepolicy": "flux-system:alpine-jq"}
command:
- sh
- -c
+1 -1
View File
@@ -34,7 +34,7 @@ spec:
# Image automation, range 3.x (see image-automation/woodpecker.yaml).
# MUST stay version-matched with woodpecker-server (gRPC parity) — both
# track the same range/filter so they bump together on each release.
image: woodpeckerci/woodpecker-agent:v3.20.0 # {"$imagepolicy": "flux-system:woodpecker-agent"}
image: woodpeckerci/woodpecker-agent:v3.20.1 # {"$imagepolicy": "flux-system:woodpecker-agent"}
env:
- name: WOODPECKER_SERVER
value: woodpecker.woodpecker.svc.cluster.local:9000 # in-cluster gRPC, replaces LXC :9000
+1 -1
View File
@@ -40,7 +40,7 @@ spec:
# minor + patch auto-update within 3.x; only the 4.0 major is held for
# a reviewed bump. Safe now the DB is postgres (the old sqlite-surprise
# -bump hazard is gone). Stays in lockstep with the agent.
image: woodpeckerci/woodpecker-server:v3.20.0 # {"$imagepolicy": "flux-system:woodpecker-server"}
image: woodpeckerci/woodpecker-server:v3.20.1 # {"$imagepolicy": "flux-system:woodpecker-server"}
env:
- name: WOODPECKER_HOST
value: https://ci.renner.uno
@@ -4,7 +4,7 @@ metadata:
name: lidarr
namespace: flux-system
spec:
image: lscr.io/linuxserver/lidarr
image: ghcr.io/linuxserver/lidarr
interval: 1h
---
# Tags are <maj>.<min>.<patch>.<build>-ls<n>. Two numbers move, and BOTH
@@ -73,7 +73,7 @@ spec:
# No imagePullSecret: the ghcr namespace is private and its credential
# is in machine.registries too, because a Secret would have to come
# from OpenBao, which needs Ceph, which needs these binaries.
image: gitea.renner.uno/konairius/cni-plugins:2026-10-28-0711 # {"$imagepolicy": "flux-system:cni-plugins"}
image: gitea.renner.uno/konairius/cni-plugins:2026-10-29-1348 # {"$imagepolicy": "flux-system:cni-plugins"}
command:
- sh
- -c
@@ -401,6 +401,13 @@ spec:
- ports:
- port: "80"
protocol: TCP
# v30iot global addresses: the delegated prefix is not fixed.
- toCIDR:
- ::/0
toPorts:
- ports:
- port: "80"
protocol: TCP
- toCIDR:
- 224.0.0.251/32
toPorts:
@@ -145,8 +145,8 @@ spec:
# Allow Syncthing peer-to-peer sync from the LAN/world.
# - 22000 TCP+QUIC: actual sync traffic between peers.
# - 21027 UDP: local-discovery broadcast packets from peers on the LAN.
# UI (8384) is intentionally NOT listed — accessed via port-forward
# until an Ingress + Authentik gate is added.
# UI (8384) is intentionally NOT listed — authentik-gate-sync generates the
# CNP syncthing-ui-gate that admits traefik.
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
@@ -71,7 +71,7 @@ spec:
type: RuntimeDefault
containers:
- name: rotate
image: gitea.renner.uno/gitea_admin/secret-rotator:2026-10-28 # {"$imagepolicy": "flux-system:secret-rotator"}
image: gitea.renner.uno/gitea_admin/secret-rotator:2026-10-29 # {"$imagepolicy": "flux-system:secret-rotator"}
args: ["ha-token"]
securityContext:
allowPrivilegeEscalation: false
@@ -133,7 +133,7 @@ spec:
type: RuntimeDefault
containers:
- name: rotate
image: gitea.renner.uno/gitea_admin/secret-rotator:2026-10-28 # {"$imagepolicy": "flux-system:secret-rotator"}
image: gitea.renner.uno/gitea_admin/secret-rotator:2026-10-29 # {"$imagepolicy": "flux-system:secret-rotator"}
args: ["ha-token"]
securityContext:
allowPrivilegeEscalation: false
@@ -195,7 +195,7 @@ spec:
type: RuntimeDefault
containers:
- name: rotate
image: gitea.renner.uno/gitea_admin/secret-rotator:2026-10-28 # {"$imagepolicy": "flux-system:secret-rotator"}
image: gitea.renner.uno/gitea_admin/secret-rotator:2026-10-29 # {"$imagepolicy": "flux-system:secret-rotator"}
args: ["ha-token"]
securityContext:
allowPrivilegeEscalation: false
@@ -32,7 +32,7 @@ spec:
type: RuntimeDefault
containers:
- name: backup-verify
image: gitea.renner.uno/gitea_admin/ci-backup-verify:2026-10-28 # {"$imagepolicy": "flux-system:backup-verify"}
image: gitea.renner.uno/gitea_admin/ci-backup-verify:2026-10-29 # {"$imagepolicy": "flux-system:backup-verify"}
command: ["bash", "/script/backup-verify.sh"]
env:
- name: HOME
+7 -1
View File
@@ -25,6 +25,12 @@ locals {
# Talos K8s control-plane VIP (etcd-elected, see kubernetes/talos/patches/k8s-{1,2,3}.yaml)
"k8s" = { type = "A", value = "10.2.40.60" }
# NTP VIPs held by keepalived (ansible/roles/keepalived-ntp): IPv4
# keepalived_ntp_vip, IPv6 ntp_vip6 (group_vars/ntp_cluster.yml).
# IPv4-only clients (Shelly Gen1) need the A.
"ntp.srv" = { type = "A", value = "10.2.40.4" }
"ntp.srv/AAAA" = { name = "ntp.srv", type = "AAAA", value = "fd02:40::123" }
# AAAA Records
# UniFi auto-creates only the A record for the UDM's own hostname
# (udm -> 192.168.8.1). Pin the AAAA to the UDM's management ULA
@@ -43,7 +49,7 @@ locals {
resource "unifi_dns_record" "renner_uno" {
for_each = local.renner_uno_records
name = each.key == "@" ? "renner.uno" : "${each.key}.renner.uno"
name = each.key == "@" ? "renner.uno" : "${try(each.value.name, each.key)}.renner.uno"
record_type = each.value.type
value = each.value.value
enabled = true