From a8f7c79934418631eac508aaca46760980749ead Mon Sep 17 00:00:00 2001 From: mr-forust Date: Wed, 23 Sep 2026 13:52:57 +0200 Subject: [PATCH] fix(adguard): sync job RBAC and idempotency - grant list+watch on adguard-deployment (rollout status hung without it, job hit activeDeadline and failed) - compare content digests only (old hash embedded filenames, so every run patched + restarted even when in sync) Keeps explicit rollout restart alongside reloader annotation: one extra restart per rotation (~60d) is accepted for determinism if reloader is down. --- adguardhome/k8s/cert-sync-rbac.yaml | 7 ++++--- adguardhome/k8s/cert-sync.yaml | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/adguardhome/k8s/cert-sync-rbac.yaml b/adguardhome/k8s/cert-sync-rbac.yaml index c82e3a5..457cd75 100644 --- a/adguardhome/k8s/cert-sync-rbac.yaml +++ b/adguardhome/k8s/cert-sync-rbac.yaml @@ -5,8 +5,9 @@ # and create pods/exec (read-only `cat` of /data/letsencrypt/acme.json). # It never writes anything in namespace traefik. # * namespace adguard: get/update/patch Secret `adguard-certs` (the only -# secret it may touch) and get/patch Deployment `adguard-deployment` -# (`kubectl rollout restart` issues a patch; `rollout status` reads). +# secret it may touch) and get/list/watch/patch Deployment +# `adguard-deployment` (`rollout restart` issues a patch, +# `rollout status` needs list+watch). apiVersion: v1 kind: ServiceAccount metadata: @@ -30,7 +31,7 @@ rules: - apiGroups: ["apps"] resources: ["deployments"] resourceNames: ["adguard-deployment"] - verbs: ["get", "patch"] + verbs: ["get", "list", "watch", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding diff --git a/adguardhome/k8s/cert-sync.yaml b/adguardhome/k8s/cert-sync.yaml index 8239707..e8eaeaa 100644 --- a/adguardhome/k8s/cert-sync.yaml +++ b/adguardhome/k8s/cert-sync.yaml @@ -114,8 +114,10 @@ spec: | base64 -d > "$TMP/live.crt" kubectl -n "$NS" get secret "$SECRET" -o jsonpath='{.data.tls\.key}' \ | base64 -d > "$TMP/live.key" - NEW_HASH="$(sha256sum "$TMP/new.crt" "$TMP/new.key" | sha256sum | cut -d' ' -f1)" - LIVE_HASH="$(sha256sum "$TMP/live.crt" "$TMP/live.key" | sha256sum | cut -d' ' -f1)" + # Compare content digests only (never filenames: identical + # content under different paths must hash equal). + NEW_HASH="$(sha256sum "$TMP/new.crt" | cut -d' ' -f1)$(sha256sum "$TMP/new.key" | cut -d' ' -f1)" + LIVE_HASH="$(sha256sum "$TMP/live.crt" | cut -d' ' -f1)$(sha256sum "$TMP/live.key" | cut -d' ' -f1)" if [ "$NEW_HASH" = "$LIVE_HASH" ]; then echo "secret ${SECRET} already holds the current ${DOMAIN} cert, nothing to do" exit 0