From 10846d108203022953fe59f82424828a98dbf4eb Mon Sep 17 00:00:00 2001 From: k3s kubernetes Date: Fri, 4 Sep 2026 12:05:43 +0100 Subject: [PATCH] fix: root-cause Flux Setters silent no-op - namespace mismatch ImageUpdateAutomation only lists ImagePolicy objects in its own namespace (image-automation-controller's getPolicies() scopes the List() to obj.Namespace, confirmed by reading v1.2.4 source) - the $imagepolicy marker's namespace:name is only used to match against that pre-filtered list, not to broaden the search. Our ImageUpdateAutomation lived in flux-system while its ImagePolicy lived in hello-app, so the policy was invisible and Setters always found zero markers to update ("repository up-to-date" forever), regardless of correct marker syntax/RBAC/policy resolution. Moved ImageUpdateAutomation into the hello-app namespace (alongside its ImagePolicy), keeping a cross-namespace sourceRef back to the flux-system GitRepository. Also fixed the commit messageTemplate, which used the removed .Updated field (v1.2.4 requires .Changed). Verified live: Flux pushed commit 0273f15 updating deployment.yaml's tag on its own, and the cluster rolled out that image without any CI involvement. Removed the update-deployment-tag CI workaround job accordingly - it's redundant now and would otherwise race with Flux's own commits. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01GJNvvV3RrvX6TRZGAKEUeY --- .forgejo/workflows/build-hello-app.yml | 32 -------------------------- apps/hello-app/image-automation.yaml | 19 +++++++++++++-- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/.forgejo/workflows/build-hello-app.yml b/.forgejo/workflows/build-hello-app.yml index af2827b..14ccc5a 100644 --- a/.forgejo/workflows/build-hello-app.yml +++ b/.forgejo/workflows/build-hello-app.yml @@ -15,8 +15,6 @@ jobs: container: image: gcr.io/kaniko-project/executor:debug options: --entrypoint "" - outputs: - tag: ${{ steps.build.outputs.tag }} steps: # actions/checkout@v4 needs a Node.js runtime, which this minimal # kaniko image doesn't have (no package manager to add it either) - @@ -45,40 +43,10 @@ jobs: sed -i "s/__GIT_SHA__/$SHORT_SHA/; s/__BUILD_TIME__/$BUILD_TIME/" apps/hello-app/src/index.html - name: Build and push - id: build run: | TAG="main-${GITHUB_SHA::7}-$(date +%s)" - echo "tag=$TAG" >> "$GITHUB_OUTPUT" /kaniko/executor \ --context="${{ github.workspace }}/apps/hello-app/src" \ --dockerfile="${{ github.workspace }}/apps/hello-app/src/Dockerfile" \ --destination="git.boglabob.com/${{ vars.FORGEJO_ORG }}/hello-app:$TAG" \ --destination="git.boglabob.com/${{ vars.FORGEJO_ORG }}/hello-app:latest" - - # Flux's ImageUpdateAutomation (image-automation.yaml) should be doing this - # commit-back step instead - its $imagepolicy Setters marker in - # deployment.yaml is correctly formatted and verified against Flux's own - # docs, ImagePolicy correctly resolves each new tag, and every other part - # of the chain works, but it never actually commits (always reports - # "repository up-to-date" with nothing to change) for reasons that - # resisted a lengthy investigation - even a from-scratch Flux bootstrap - # against a fresh controller instance didn't change the behavior. - # ImageRepository/ImagePolicy are kept for visibility into what tag is - # available; this job does the actual commit as a working substitute. - update-deployment-tag: - needs: build-and-push - runs-on: docker - container: - image: alpine/git - steps: - - name: Commit new image tag to deployment.yaml - run: | - git config --global user.email "flux@boglabob.com" - git config --global user.name "fluxcdbot" - git clone "https://${{ vars.FORGEJO_USER }}:${{ secrets.FORGEJO_TOKEN }}@git.boglabob.com/${{ github.repository }}.git" repo - cd repo - TAG="${{ needs.build-and-push.outputs.tag }}" - sed -i "s|\(image: git.boglabob.com/${{ vars.FORGEJO_ORG }}/hello-app:\)[^ ]*|\1$TAG|" apps/hello-app/deployment.yaml - git add apps/hello-app/deployment.yaml - git diff --cached --quiet || git commit -m "chore(hello-app): auto-update image to $TAG" - git push diff --git a/apps/hello-app/image-automation.yaml b/apps/hello-app/image-automation.yaml index e73c8ad..4d4ffdd 100644 --- a/apps/hello-app/image-automation.yaml +++ b/apps/hello-app/image-automation.yaml @@ -2,6 +2,15 @@ # tags, and rewrites deployment.yaml's image tag + commits back to this repo # when one shows up. Requires clusters/homelab/flux-system to have write # access to the Forgejo repo (flux bootstrap sets this up). +# +# ImageUpdateAutomation must live in the SAME namespace as the ImagePolicy +# it targets - the controller only ever lists ImagePolicy objects from its +# own namespace (internal/controller/imageupdateautomation_controller.go's +# getPolicies() scopes the List() call to obj.Namespace), so a +# cross-namespace $imagepolicy marker silently matches nothing and every +# reconcile reports "repository up-to-date" with no commit, regardless of +# how correct the marker/RBAC/policy resolution otherwise are. GitRepository +# itself can still be referenced cross-namespace via sourceRef.namespace. apiVersion: image.toolkit.fluxcd.io/v1 kind: ImageRepository @@ -34,12 +43,13 @@ apiVersion: image.toolkit.fluxcd.io/v1 kind: ImageUpdateAutomation metadata: name: hello-app - namespace: flux-system + namespace: hello-app spec: interval: 1m sourceRef: kind: GitRepository name: flux-system + namespace: flux-system git: checkout: ref: @@ -49,7 +59,12 @@ spec: email: flux@boglabob.com name: fluxcdbot messageTemplate: | - chore(hello-app): auto-update image to {{range .Updated.Images}}{{println .}}{{end}} + chore(hello-app): auto-update image + {{ range $resource, $changes := .Changed.Objects -}} + {{ range $_, $change := $changes -}} + {{ $change.NewValue }} + {{ end -}} + {{ end -}} push: branch: main update: