From 8d928bfc15b5b9e11c453250a2b6b4f7421efe4e Mon Sep 17 00:00:00 2001 From: Mukul Sharma Date: Thu, 3 Sep 2026 09:42:50 +0530 Subject: [PATCH] Fix push auth: drop harbor-robot-dockerconfig mount, use admin login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirror push failed "unauthorized to access repository: base-images/ golang, action: push" — harbor-robot-dockerconfig is scoped only to the homelab project's robot account, nothing on base-images. Making base-images public only grants anonymous pull, never push. Removed the read-only docker-config secret mount (it would have blocked `docker login` from writing new credentials anyway) and switched to logging in interactively with Harbor admin credentials instead, since this whole mirror is a rarely-run manual task, not worth provisioning a dedicated robot account for. --- README.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d67b2c5..e87f0f8 100644 --- a/README.md +++ b/README.md @@ -93,9 +93,6 @@ spec: volumeMounts: - name: mirror mountPath: /mirror - - name: docker-config - mountPath: /root/.docker - readOnly: true volumes: - name: docker-graph-storage emptyDir: {} @@ -103,17 +100,29 @@ spec: configMap: name: base-images-mirror defaultMode: 0755 - - name: docker-config - secret: - secretName: harbor-robot-dockerconfig - items: - - key: .dockerconfigjson - path: config.json EOF +``` +**No `harbor-robot-dockerconfig` mount here on purpose** — that robot +account is scoped only to the `homelab` project (push+pull there +specifically); it has no grant on `base-images` at all, and making +`base-images` public only grants anonymous *pull*, never push. Push +always needs real credentials scoped to that project regardless. For a +one-off manual task like this, simplest is just logging in with your +Harbor admin account directly inside the pod, rather than provisioning +a whole new robot account for something run this rarely: + +``` kubectl wait --for=condition=Ready pod/base-images-mirror -n jenkins --timeout=120s -kubectl exec -n jenkins base-images-mirror -c docker-cli -- sh -c ' +kubectl exec -it -n jenkins base-images-mirror -c docker-cli -- sh -c ' for i in $(seq 1 30); do docker info >/dev/null 2>&1 && break; sleep 2; done + docker login harbor.192.168.1.7.nip.io +' +``` +(enter your Harbor admin username/password when prompted) + +``` +kubectl exec -n jenkins base-images-mirror -c docker-cli -- sh -c ' cd /mirror && sh mirror.sh ' kubectl delete pod base-images-mirror -n jenkins