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.
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
- 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.
- Data/recovery prediction: baseline JENKINS_HOME remains unchanged because candidate uses a copied volume; deleting candidate volume cannot delete baseline state.
- Compatibility prediction: synthetic candidate requiring Jenkins 2.600.1 will be rejected before any plugin file changes.
- 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
.jpiarchives, - 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.
Knowledge check
Answer before revealing the explanation.
1. What makes the checkpoint inventory “SBOM-like” rather than a plain plugin-name list?
It records exact versions, provenance/update-center source, dependency relationships, required core, security/health review state, hashes and the controller/core/Java context in which those plugins were accepted.
2. What does the synthetic incompatibility gate prove?
That candidate compatibility can and should be rejected before a plugin reaches the controller. It demonstrates policy logic without intentionally installing an incompatible or malicious plugin.
3. What is the rollback artifact for the checkpoint?
The exact baseline controller image/plugin manifest plus a cloned JENKINS_HOME snapshot and verification record. The old .jpi by itself is not treated as sufficient.
4. Why should the upgrade be tested with representative jobs even if Jenkins starts cleanly?
Successful controller startup only proves one lifecycle state. Plugin extension points, Pipeline steps, reports, credentials, agents and job configuration can still fail at runtime.
5. What does Chapter 25 add to the production operating model?
Controller extensions now have explicit provenance, dependency/compatibility gates, advisory review, reproducible manifests, clone-based testing, controlled retirement and snapshot-backed rollback evidence.
Official references and version notes
- Jenkins — Managing Plugins — installation/update/removal, dependency safety, disable/uninstall behavior, old-data handling and legacy pinning semantics.
- Jenkins Update Sites — default and version-specific update-center behavior.
- Jenkins Plugin Site — exact releases, minimum core, dependency pages, health and security warnings.
- Jenkins Security Advisories — active/historical core and plugin advisories.
- Jenkins Security Advisory 2026-09-02 — current chapter-era example showing why exact plugin/core versions matter.
-
Plugin Installation Manager Tool
— reproducible plugin resolution, dependency/security reporting
and
jenkins-plugin-cli. - Dark Theme plugin and dependency page — maintained disposable lifecycle example.
- Theme Manager plugin — Dark Theme dependency and secondary dependency chain.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.