Fix env.FAILURE NPE and buildx read-only-mount failure

Build #5 got through checkout, loadConfig, and the pre_build hook,
then hit two real bugs at the actual docker build step:

1. `docker build` failed with "mkdir /root/.docker/buildx: read-only
   file system" — dind-pod.yaml mounts the Harbor push-auth secret
   read-only at /root/.docker, but modern docker defaults to
   BuildKit/buildx, which wants to write its own state there. Forces
   the classic builder via DOCKER_BUILDKIT=0 instead.

2. The subsequent error-handling itself then threw a
   NullPointerException — every stage file (including untouched
   legacy ones from the real devops-lib) reads env.FAILURE when
   setting currentBuild.result, but nothing in this repo ever defined
   it, so it was null. Defined once in homelabPipeline.groovy rather
   than touching 40+ individual occurrences across every stage file.
This commit is contained in:
Mukul Sharma
2026-09-02 16:17:56 +05:30
parent 1b09c98b3c
commit 51d3a0a033
2 changed files with 23 additions and 0 deletions
+10
View File
@@ -28,6 +28,16 @@ spec:
env: env:
- name: DOCKER_HOST - name: DOCKER_HOST
value: tcp://localhost:2375 value: tcp://localhost:2375
# docker-config below mounts the Harbor push-auth secret
# read-only at /root/.docker (needed so `docker push` finds
# config.json without an explicit `docker login` step) — but
# modern `docker build` defaults to BuildKit/buildx, which wants
# to create its own state dir at /root/.docker/buildx and fails
# with "read-only file system" since the whole mount is
# read-only. Forcing the classic builder avoids needing to write
# there at all.
- name: DOCKER_BUILDKIT
value: "0"
# For syncArgoApp.groovy — read directly from the ESO-managed # For syncArgoApp.groovy — read directly from the ESO-managed
# Secret, not a Jenkins-native credential (nothing in this # Secret, not a Jenkins-native credential (nothing in this
# pipeline uses Jenkins' own credential store; staying consistent # pipeline uses Jenkins' own credential store; staying consistent
+13
View File
@@ -27,6 +27,19 @@ def call(Map config) {
config.helm_repo_url = config.helm_repo_url ?: 'http://gitea.192.168.1.7.nip.io/mukul/devops-helm-charts.git' config.helm_repo_url = config.helm_repo_url ?: 'http://gitea.192.168.1.7.nip.io/mukul/devops-helm-charts.git'
config.image_tag_yq_path = config.image_tag_yq_path ?: '.deployment.image.tag' config.image_tag_yq_path = config.image_tag_yq_path ?: '.deployment.image.tag'
// Every stage file (both the ones adapted for this homelab and the
// untouched legacy ones carried over from the real devops-lib) reads
// `env.FAILURE` when setting currentBuild.result on error — the real
// system must define this as a global Jenkins environment variable
// somewhere upstream of buildPipeline.groovy, since it's referenced
// everywhere but never set anywhere in this repo. Left undefined,
// `env.FAILURE` is null, and `currentBuild.result = null` throws
// `NoSuchMethodError`/`NullPointerException` deep inside Jenkins'
// own result-normalization code — masking whatever the real error
// was. Defining it once here, before any stage runs, is the minimal
// fix rather than touching every individual stage file.
env.FAILURE = 'FAILURE'
podTemplate(yaml: libraryResource('org/homelab/dind-pod.yaml')) { podTemplate(yaml: libraryResource('org/homelab/dind-pod.yaml')) {
node(POD_LABEL) { node(POD_LABEL) {
def checkOutObj = new com.homelab.stages.checkOut() def checkOutObj = new com.homelab.stages.checkOut()