From ad6e658327821992d8aa55e250ef87a9fdade7b8 Mon Sep 17 00:00:00 2001 From: rldyourmnd Date: Wed, 2 Sep 2026 02:18:05 +0500 Subject: [PATCH 1/2] fix(provider): the cache claim makes the registry mirror trusted The image's daemon.json has named https://192.0.2.1:5001 as a registry mirror since the docker image was first built, and zot on every member is configured as a docker.io pull-through cache. No worker ever trusted the certificate: the mirror's cert is signed by the fleet cache CA, the same CA the cache claim already hands the runner for the artifact store, and nothing installed it where dockerd looks. Every pull logged "x509: certificate signed by unknown authority" against the mirror and fell through to docker.io; the cache on gha-runner-1 held 30 MB after a month. The claim script now installs the CA at /etc/docker/certs.d//ca.crt for each mirror daemon.json names. dockerd reads that directory per request, so the mirror is real from the job's first pull, with no daemon restart and no image change. The mirror's certificate carries the bridge address as an IP SAN, so hostname verification holds. Claude-Session: https://claude.ai/code/session_0128syXKxAGCfJGRDxUUNQXp --- .../garmproviderincus/provider/cache_delivery.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/internal/garmproviderincus/provider/cache_delivery.go b/internal/garmproviderincus/provider/cache_delivery.go index 2a2cfe2d..56828dac 100644 --- a/internal/garmproviderincus/provider/cache_delivery.go +++ b/internal/garmproviderincus/provider/cache_delivery.go @@ -258,6 +258,22 @@ trap 'rm -f -- "${ca_temp}"' EXIT jq -r '.ca_pem_b64' "${assignment}" | base64 --decode >"${ca_temp}" openssl x509 -in "${ca_temp}" -noout >/dev/null install -o runner -g runner -m 0400 "${ca_temp}" "${ca_path}" +# The same CA signs the member's registry mirror (zot on 192.0.2.1:5001, a +# docker.io pull-through cache the image's daemon.json already names). The +# daemon never trusted it: every pull logged "x509: certificate signed by +# unknown authority" against the mirror and fell through to docker.io, so +# the cache held 30 MB after a month. dockerd reads certs.d per request, so +# installing the CA there makes the mirror real from the first pull with +# no daemon restart. A standard image has no daemon.json and skips this. +if [[ -r /etc/docker/daemon.json ]]; then + while IFS= read -r mirror; do + [[ "${mirror}" == https://* ]] || continue + mirror_host="${mirror#https://}" + mirror_host="${mirror_host%%/*}" + [[ "${mirror_host}" =~ ^[A-Za-z0-9.:-]+$ ]] || continue + install -D -o root -g root -m 0644 "${ca_temp}" "/etc/docker/certs.d/${mirror_host}/ca.crt" + done < <(jq -r '."registry-mirrors"[]? // empty' /etc/docker/daemon.json) +fi bundle_temp="$(mktemp /tmp/nddev-cache-ca-bundle.XXXXXXXXXX)" trap 'rm -f -- "${ca_temp}" "${bundle_temp}"' EXIT cat /etc/ssl/certs/ca-certificates.crt "${ca_temp}" >"${bundle_temp}" From b7e4b640730f3967dff29bdb7091299907cfead9 Mon Sep 17 00:00:00 2001 From: rldyourmnd Date: Wed, 2 Sep 2026 02:20:55 +0500 Subject: [PATCH 2/2] chore(provider): release v0.1.5-nddev.110 with a trusted registry mirror Source ad6e658327821992d8aa55e250ef87a9fdade7b8, built twice with CGO_ENABLED=0 go build -trimpath -buildvcs=false -ldflags "-buildid= -s -w -X main.version=v0.1.5-nddev.110 -X main.commit="; both builds agree on b2073169e22971d08a5c0255e4f0115941df0e8d4f51b89aa370177fc27339dc. Claude-Session: https://claude.ai/code/session_0128syXKxAGCfJGRDxUUNQXp --- config/example-runner-1.yaml | 2 +- config/example-runner-2.yaml | 2 +- config/example-runner-3.yaml | 2 +- config/example-runner-4.yaml | 2 +- config/example-services.yaml | 2 +- config/provider-derivative.yaml | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/config/example-runner-1.yaml b/config/example-runner-1.yaml index 6fc73e99..c02a304c 100644 --- a/config/example-runner-1.yaml +++ b/config/example-runner-1.yaml @@ -9,7 +9,7 @@ control_plane: manager_version: v0.2.1-nddev.87 scheduling_mode: scale-set provider: incus - provider_version: v0.1.5-nddev.109 + provider_version: v0.1.5-nddev.110 provider_interface: v0.1.0 worker_kind: incus-container runner: actions/runner diff --git a/config/example-runner-2.yaml b/config/example-runner-2.yaml index a55e797f..21907b56 100644 --- a/config/example-runner-2.yaml +++ b/config/example-runner-2.yaml @@ -9,7 +9,7 @@ control_plane: manager_version: v0.2.1-nddev.87 scheduling_mode: scale-set provider: incus - provider_version: v0.1.5-nddev.109 + provider_version: v0.1.5-nddev.110 provider_interface: v0.1.0 worker_kind: incus-container runner: actions/runner diff --git a/config/example-runner-3.yaml b/config/example-runner-3.yaml index a051eaf2..a3246923 100644 --- a/config/example-runner-3.yaml +++ b/config/example-runner-3.yaml @@ -9,7 +9,7 @@ control_plane: manager_version: v0.2.1-nddev.87 scheduling_mode: scale-set provider: incus - provider_version: v0.1.5-nddev.109 + provider_version: v0.1.5-nddev.110 provider_interface: v0.1.0 worker_kind: incus-container runner: actions/runner diff --git a/config/example-runner-4.yaml b/config/example-runner-4.yaml index 02df6faf..b2fdea42 100644 --- a/config/example-runner-4.yaml +++ b/config/example-runner-4.yaml @@ -9,7 +9,7 @@ control_plane: manager_version: v0.2.1-nddev.87 scheduling_mode: scale-set provider: incus - provider_version: v0.1.5-nddev.109 + provider_version: v0.1.5-nddev.110 provider_interface: v0.1.0 worker_kind: incus-container runner: actions/runner diff --git a/config/example-services.yaml b/config/example-services.yaml index 46e2a45d..1154e7ae 100644 --- a/config/example-services.yaml +++ b/config/example-services.yaml @@ -27,7 +27,7 @@ control_plane: manager_version: v0.2.1-nddev.87 scheduling_mode: scale-set provider: incus - provider_version: v0.1.5-nddev.109 + provider_version: v0.1.5-nddev.110 provider_interface: v0.1.0 worker_kind: incus-container runner: actions/runner diff --git a/config/provider-derivative.yaml b/config/provider-derivative.yaml index cb5c2c74..c1ef1068 100644 --- a/config/provider-derivative.yaml +++ b/config/provider-derivative.yaml @@ -16,7 +16,7 @@ artifact: garm-provider-incus # state all move together, because all three derive from here. A provider change # that does not bump it ships under the previous version, which is exactly how # runner-1 and runner-2 diverged. -derivative_version: v0.1.5-nddev.109 +derivative_version: v0.1.5-nddev.110 # The external-provider protocol GARM speaks to this binary. It moves on its own # schedule -- a provider release does not imply an interface release -- so it is @@ -37,8 +37,8 @@ runtime: queue_intent_schema_version: 6 build: - source_commit: 311aebe21d709466d98e54ab7933712a664f4baa - binary_sha256: 4a928b706a2eacbc94909c8978eddb33c5043cea98a728dd1c3ef98f44ddace9 + source_commit: ad6e658327821992d8aa55e250ef87a9fdade7b8 + binary_sha256: b2073169e22971d08a5c0255e4f0115941df0e8d4f51b89aa370177fc27339dc go_version: go1.26.6 cgo_enabled: false target_os: linux