Chapter 25Lesson 05~230 minutes

Checkpoint Lab — Plugin Ecosystem, Plugin Dependencies, Update Center, Compatibility, Pinning, Removal, and Plugin Governance

Create an SBOM-like plugin inventory, stage and verify one disposable plugin upgrade, reject a synthetic incompatible candidate before installation, restore a cloned baseline after a simulated failure, and capture the evidence needed for a controlled production change review.

Checkpoint labSBOM-like manifestUpgradeIncompatibility gateSnapshotGovernance

Learning objectives

  • Create an attributable plugin inventory with exact controller/core/Java context.
  • Stage one low-risk maintained plugin upgrade through a tested clone.
  • Reject an incompatible candidate before installation.
  • Simulate failure and restore the known-good snapshot/plugin set.
  • Document governance, security review, evidence, cleanup and rollout boundaries.

1. Scenario and success criteria

You operate a disposable Jenkins lab with Dark Theme 574.va_19f05d54df5. The target is Dark Theme 652.vea_da_dfea_e769. You must prove the exact dependency/runtime state, test the upgrade on a clone, demonstrate a pre-install compatibility rejection, then restore a known-good clone after a simulated bad candidate. No production controller, real credential or proprietary job is used.

Success means more than “the UI is dark”: you can show an exact manifest, candidate provenance, dependency/core gate, restart logs, representative smoke-test evidence, rollback artifact and cleanup record.

2. Current assumptions and preflight

Component Lab identity Verification
Jenkins 2.568.3 LTS startup/About; current LTS as of 2026-09-17
Java 21 java -version; 2.568.3 also supports/tests Java 25
Controller image jenkins/jenkins:2.568.3-lts-jdk21 record platform RepoDigest before use
Baseline direct plugin Dark Theme 574.va_19f05d54df5 baseline installed list
Candidate direct plugin Dark Theme 652.vea_da_dfea_e769 plugin site; requires core 2.528.3
Key dependency Theme Manager ≥327; current 346.v06cca_64c6a_37 dependency/plugin page + resolved controller version
Plugin resolver jenkins-plugin-cli record exact --version; upstream current 2.15.0

Preflight: Docker works; ports 8080/8081 are free; at least several GB of disk are available; no pre-existing volume/container name begins with ch25- unless it belongs to this lab.

3. Predict before execution

  1. Plugin state prediction: candidate clone will resolve/load Dark Theme 652 while keeping Jenkins core at 2.568.3; one or more dependency versions may differ from baseline.
  2. Data/recovery prediction: baseline JENKINS_HOME remains unchanged because candidate uses a copied volume; deleting candidate volume cannot delete baseline state.
  3. Compatibility prediction: synthetic candidate requiring Jenkins 2.600.1 will be rejected before any plugin file changes.
  4. Runtime prediction: successful controller startup does not alone prove representative job/UI/plugin behavior; smoke tests remain required.

Write these predictions to ch25/evidence/predictions.md before building the candidate.

4. Build and launch the known-good baseline

FROM jenkins/jenkins:2.568.3-lts-jdk21
RUN jenkins-plugin-cli --plugins dark-theme:574.va_19f05d54df5 --latest=false
docker build -t ch25-checkpoint:baseline ch25/baseline
docker volume create ch25-cp-home-baseline
docker run -d --name ch25-cp-baseline \
  -p 127.0.0.1:8080:8080 \
  -v ch25-cp-home-baseline:/var/jenkins_home \
  ch25-checkpoint:baseline

Complete only local lab setup. Create one harmless Pipeline item ch25/plugin-smoke that runs on an existing trusted disposable agent (not the built-in node) and prints only non-sensitive controller/build metadata. Its purpose is representative smoke validation after plugin changes.

5. Build the SBOM-like evidence packet

Capture:

  • controller image digest, Jenkins core and Java version,
  • exact installed plugin short-name/version list,
  • hashes of installed .jpi archives,
  • Update Center URL/source and timestamp,
  • Dark Theme/Theme Manager minimum-core/dependency metadata,
  • current Jenkins security advisory review result,
  • baseline startup log and smoke build number/URL/source SHA if SCM-backed.
mkdir -p ch25/evidence
# Save image identity
docker image inspect ch25-checkpoint:baseline --format '{{.Id}} {{json .RepoDigests}}' \
  > ch25/evidence/controller-baseline-image.txt
# Save plugin binary identities
docker exec ch25-cp-baseline bash -lc \
 'cd /var/jenkins_home/plugins && sha256sum *.jpi 2>/dev/null | sort' \
 > ch25/evidence/plugins-baseline.sha256
# Preserve startup evidence
docker logs ch25-cp-baseline > ch25/evidence/startup-baseline.log 2>&1

6. Snapshot/clone before upgrade

docker stop ch25-cp-baseline
docker volume create ch25-cp-home-candidate
docker run --rm \
  -v ch25-cp-home-baseline:/from:ro \
  -v ch25-cp-home-candidate:/to \
  alpine:3.22 sh -c 'cd /from && cp -a . /to/'

Verify volume names twice. This copy is the recovery boundary for the exercise. The accepted baseline volume remains read-only during the copy.

7. Stage and test the candidate plugin set

FROM jenkins/jenkins:2.568.3-lts-jdk21
RUN jenkins-plugin-cli --plugins dark-theme:652.vea_da_dfea_e769 --latest=false
docker build -t ch25-checkpoint:candidate ch25/candidate
docker run -d --name ch25-cp-candidate \
  -p 127.0.0.1:8081:8080 \
  -v ch25-cp-home-candidate:/var/jenkins_home \
  ch25-checkpoint:candidate
docker logs -f ch25-cp-candidate

Verification checklist: no failed/deferred-plugin errors; exact candidate direct/dependency versions recorded; Appearance renders; login/permissions unchanged; representative ch25/plugin-smoke still runs on its disposable agent; build artifact/report behavior (if used) unchanged; no credential scope widened.

8. Simulate incompatibility and reject it before install

Create ch25/synthetic-candidate.json:

{"shortName":"lab-example","version":"9.9.9","requiresJenkins":"2.600.1"}
import json
from packaging.version import Version
candidate=json.load(open('ch25/synthetic-candidate.json'))
core=Version('2.568.3')
required=Version(candidate['requiresJenkins'])
if core < required:
    raise SystemExit(f"REJECT {candidate['shortName']}:{candidate['version']} — requires Jenkins {required}")

Expected result: non-zero exit and a clear rejection message. Preserve it as compatibility-gate.txt. This faithful simulation teaches the gate without installing an incompatible plugin.

9. Simulate a bad plugin state, preserve evidence, then restore

Do not corrupt the baseline. On the candidate clone only, disable Dark Theme, restart and record the resulting UI/config difference. This is a reversible failure simulation.

# Use local Jenkins CLI/UI with fake lab admin on candidate only.
# Preserve disable/restart output and startup log before repair.

Then discard ch25-cp-home-candidate and create a fresh restore clone from ch25-cp-home-baseline. Start it with the baseline image and rerun the smoke test. That proves the recovery artifact rather than merely re-enabling a file in place.

10. Required evidence packet

Evidence What it proves
Core/Java/image digest Controller runtime identity
Baseline/candidate plugin manifests Exact direct/transitive versions
JPI SHA-256 files Binary identity
Update Center/plugin page snapshot references Provenance, minimum core, dependency review
Security advisory review note Known-warning check at decision time
Startup logs Load/dependency/restart behavior
Smoke build number/URL and source SHA Representative runtime behavior tied to build identity
Compatibility-gate output Pre-install rejection policy works
Restore startup + smoke result Rollback artifact is actually usable
Assumptions/limitations note What was simulated versus exercised

11. Governance record for a real change request

A production change ticket should include: owner; business capability; direct plugin and exact version; full resolved manifest; required core/Java; advisory/health review; dependency diff; plugin-owned data/config identified; clone/canary test results; maintenance/restart plan; snapshot/restore location; rollback stop condition; representative jobs; and post-change verification owner. “Plugin Manager shows an update” is not sufficient justification.

12. Cleanup and rollback

for c in ch25-cp-candidate ch25-cp-baseline ch25-cp-restored; do
  docker rm -f "$c" 2>/dev/null || true
done
for v in ch25-cp-home-candidate ch25-cp-home-restored; do
  docker volume rm "$v" 2>/dev/null || true
done
# Remove ch25-cp-home-baseline only after you have verified evidence/restore completion.

Never wildcard-delete Jenkins volumes. Confirm each exact ch25-* resource before removal.

13. What Chapter 25 adds to the production operating model

Jenkins plugins are now governed as privileged platform dependencies with exact provenance, core/dependency compatibility, security-advisory review, reproducible manifests, clone/canary testing, restart boundaries, disable-first retirement and snapshot-backed recovery. Chapter 26 applies the same discipline to Jenkins Configuration as Code: declarative controller configuration, secret references, YAML validation, reload semantics and drift.

Next chapter

Jenkins Configuration as Code, YAML Bundles, Secrets, Reloading, Validation, and Git-Managed Controller State

Separate plugin installation from declarative configuration and make controller state reviewable, testable and recoverable through versioned JCasC.

Knowledge check

Answer before revealing the explanation.

1. What makes the checkpoint inventory “SBOM-like” rather than a plain plugin-name list?

2. What does the synthetic incompatibility gate prove?

3. What is the rollback artifact for the checkpoint?

4. Why should the upgrade be tested with representative jobs even if Jenkins starts cleanly?

5. What does Chapter 25 add to the production operating model?

Official references and version notes

Verified baseline — 17 September 2026. Labs use Jenkins 2.568.3 LTS with Java 21; Jenkins 2.568.3 is tested with Java 21 and 25. The disposable controller image is jenkins/jenkins:2.568.3-lts-jdk21; record its platform-specific digest before execution. Dark Theme is 652.vea_da_dfea_e769 (requires Jenkins 2.528.3) and requires Theme Manager ≥ 327.v780d7096ec29; current Theme Manager is 346.v06cca_64c6a_37 (requires Jenkins 2.504.3). Current upstream Plugin Installation Manager Tool is 2.15.0; verify the exact jenkins-plugin-cli --version bundled in the selected controller image. Re-check all of these before reuse because plugin releases, dependency graphs and advisories change independently.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.