build(ci): add z2m-seed runtime image (alpine + jq) #442

Merged
k.renner merged 2 commits from z2m-seed-drop-apk into master 2026-07-30 07:11:38 +00:00
2 changed files with 61 additions and 0 deletions
+40
View File
@@ -130,3 +130,43 @@ steps:
--dockerfile Containerfile \
--destination gitea.renner.uno/gitea_admin/secret-rotator:$TAG \
--destination gitea.renner.uno/gitea_admin/secret-rotator:latest
# Runtime image, not CI tooling: alpine + jq, the base for the zigbee2mqtt
# `seed-data` init container. Replaces an `apk add --no-cache jq` that ran on
# every pod start — tools belong in the image, not installed at runtime.
# Consumers pin it by DIGEST (as the secret-rotator CronJobs do), so this must
# be built and pushed before the Deployment can reference it.
- name: build-z2m-seed
image: gcr.io/kaniko-project/executor:v1.23.2-debug
directory: ci/images/z2m-seed
depends_on: []
when:
- event: manual
- event: push
path: ["ci/images/z2m-seed/**", ".woodpecker/build-ci-images.yml"]
environment:
GITEA_USER: gitea_admin
GITEA_TOKEN:
from_secret: ci_images_token
commands:
- mkdir -p /kaniko/.docker
- AUTH=$(printf '%s:%s' "$GITEA_USER" "$GITEA_TOKEN" | base64 | tr -d '\n')
- printf '{"auths":{"gitea.renner.uno":{"auth":"%s"}}}' "$AUTH" > /kaniko/.docker/config.json
- TAG=$(date +%Y-%m-%d)
- |
/kaniko/executor \
--context . \
--dockerfile Containerfile \
--destination gitea.renner.uno/gitea_admin/z2m-seed:$TAG \
--destination gitea.renner.uno/gitea_admin/z2m-seed:latest \
--image-name-with-digest-file /kaniko/z2m-seed.digest
# Print the digest-pinned reference so the follow-up commit that pins the
# Deployment can copy it straight from this build log, with no separate
# registry query.
#
# kaniko writes ONE LINE PER --destination to that file, so it holds two
# entries (:$TAG and :latest) carrying the same digest. Reduce to the bare
# digest and dedupe, so exactly one unambiguous line is emitted rather than
# two near-identical ones for whoever does step 2 to choose between.
- DIGEST=$(cut -d@ -f2 /kaniko/z2m-seed.digest | sort -u | head -1)
- echo "PIN THIS: gitea.renner.uno/gitea_admin/z2m-seed@$DIGEST"
+21
View File
@@ -0,0 +1,21 @@
FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d
# Runtime image, not CI tooling: the base for the zigbee2mqtt `seed-data` init
# container.
#
# It exists for exactly one reason — jq. That init container reads
# `.network_key.key` out of the Open Coordinator Backup JSON to render
# /app/data/secret.yaml; everything else it does (sh, sed, cp, cat) is already
# in busybox. jq is baked in here rather than `apk add`ed when the container
# starts, so the init container has no network dependency at start and no
# package-index drift between pod restarts.
#
# Parsing this with busybox sed/awk instead was considered and rejected: "key"
# occurs 12 times in the real backup (once per device with an APS link_key) and
# the FIRST occurrence is a device key, because "devices" sorts before
# "network_key". Hand-rolled extraction that isn't correctly anchored yields a
# device link key, and herdsman then forms a NEW network and drops every
# device — so a real JSON parser earns its keep here.
#
# Stays root: the init container writes to the root-owned zigbee2mqtt-data PVC.
RUN apk add --no-cache jq