Repository navigation
check-kolla-images: resolve the deployed tags - #2833
Merged
Merged
Conversation
kolla-ansible sets the image tags of the kolla services in Ansible
variables, and some tags are templates over other variables. Reading
them correctly means rendering them the way ansible-core 2.18 does, so
src/ansible_templar.py implements that subset of Jinja2 templating for
the check that compares those tags with the released images.
ansible-core 2.18 renders with jinja2_native off. A template renders to
text, and only text that looks like a dict, a list or True/False is
converted back. A string without template markers is not templated at
all, so a tag such as "2026.10" keeps its text, while "{{ false }}"
used as a condition is a boolean.
Variables come from layers with a rank. A higher rank wins. Layers of
the same rank must agree on a value once each is resolved. Jinja2
looks up every name of a template before it evaluates the template,
including names in a branch it does not take. A variable whose
resolution fails (a recursive loop, a rendering error, a disagreement)
therefore becomes a failed value that raises only when it is used, so
an unused broken branch does not fail the reference.
requirements.txt gains Jinja2==3.1.6.
Assisted-by: Claude:claude-haiku-5-5
Signed-off-by: Roger Luethi <luethi@osism.tech>
check-kolla-images deploys containers from the *_image_full references kolla-ansible declares per role. Nothing so far checked that the tag a role deploys is the tag the release build pushed, so a role can keep a stale tag, e.g. a sidecar inheriting its parent's tag, unnoticed. Add kolla_tags.check, which resolves every role's *_image_full in the role's scope with the Ansible 2.18 templar from ansible_templar: the role defaults first, then the OSISM layers (overlay, versions.yml and osism/defaults all/*.yml), which win. The image name is the last path segment of the resolved reference and the tag what follows its last colon. A reference naming an image the build pushed is compared with the pushed tag; a difference is a mismatch. A reference that does not resolve, or names no tag, is unresolvable. One naming an image the build did not push is not a finding. The check reports the images that have a mismatch or an unresolvable reference, and the hops that led to each resolved value, so a reader can see which layer set the tag. Assisted-by: Claude:claude-haiku-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
The kolla tag check compares the image references of kolla-ansible with the tags of the kolla build. To resolve a reference, it needs the inputs the kolla-ansible image is deployed from. Before the image exists (step 1 of the release), those inputs have to be reconstructed from the source repositories. Add src/kolla_tag_inputs.py with gather(), which reads them in predicted mode at the commits they are built from: - role defaults: upstream kolla-ansible at the series' ref, with the patches of container-image-kolla-ansible applied as the image build applies them (patch -p1, forward, dry run first) - versions.yml: container-image-kolla-ansible's template rendered with the same context as files/src/render-versions.py (the context keys are checked against that file in the tests), at the v<version> tag or main - overlay: overlays/<series>/kolla-ansible.yml of the same commit - defaults: osism/defaults all/*.yml at the defaults_version of the inventory-reconciler release, or --defaults-ref - SBOM: the kolla release SBOM of the version, or of the build named in next/kolla-ansible-v<version>.yml on main Versions are read from the tags of osism/release, and ansible-core other than 2.18 is refused, as the templating of ansible-core 2.19 differs. The Registry wrapper reads the labels of osism/<image>:<tag> by digest, from the amd64 image of an index. tests/fixtures/render-versions.py.txt is a copy of files/src/render-versions.py from container-image-kolla-ansible, so the test can check the rendering context against it. It is not linted, hence the suffix. Assisted-by: Claude:claude-haiku-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
When osism/kolla-ansible:<version> exists, the tag check now reads the inputs that image was built from, from its labels, instead of predicting them: the release commit, the kolla-ansible commit, the container-image-kolla-ansible commit, the SBOM digest and the defaults commit of the inventory-reconciler image. Predicted mode remains for images that do not exist yet or with --predicted. A missing or unusable required label is an error that names the label and points to --predicted for images built before the label baseline (osism/issues#1463). A label naming a commit that is not in the repository is an error as well, and so is an SBOM digest that Harbor no longer serves. An SBOM of another kolla build is noted, as in predicted mode. An inventory-reconciler image that does not exist yet falls back to the predicted defaults with a note. Assisted-by: Claude:claude-haiku-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
Add a tag resolution section to the check. For every container kolla-ansible deploys, the image reference is resolved as Ansible would and its tag is compared with the tag the build pushed. The inputs come from kolla_tag_inputs, either reconstructed from the sources (predicted) or read from the kolla-ansible image of the release (recorded). New options select the kolla-ansible and inventory-reconciler versions, the refs of the source repositories, predicted mode and local clones. Every mismatch or unresolvable reference fails the check; images kolla-ansible does not deploy are only listed. The script now requires Python 3.10 and jinja2. Assisted-by: Claude:claude-sonnet-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
Add a regression test that runs the kolla image tag check against the published OSISM 11.0.0 inputs: the SBOM image list, the role defaults, versions.yml and overlay of osism/kolla-ansible:0.20261008.0, and the osism/defaults files from osism/inventory-reconciler:0.20261008.0. The fixture is tests/fixtures/kolla-tags-11.0.0.json.gz. It was read from the images once, outside this repository, because those images predate the label baseline that the check reads (osism/issues#1463). The fixture is a snapshot and is not regenerated by the test. 11.0.0 shipped ten containers that request tags its build never pushed (osism/issues#1462). The test asserts that the check reports exactly those ten mismatches, that no reference is unresolvable, and the reference and unconsumed-image counts for the release. Assisted-by: Claude:claude-haiku-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
check-kolla-images.py now also checks that every container kolla-ansible deploys requests a tag the build pushed. Describe the check in the README section on checking the kolla images of a tag: what it compares, the predicted and recorded input modes, and the options that select other sources. Extend the header and usage of check-kolla-images.sh with the new options. Assisted-by: Claude:claude-sonnet-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
The kolla-ansible image build moves overlays/release/<VERSION>/release-kolla-ansible.yml into the image and the inventory-reconciler installs it as group_vars. The tag check does not model that layer and would check against the wrong variables, so it now stops with an error when the file exists in either the v-prefixed or the plain spelling, in predicted and in recorded mode. The module header no longer claims an image-content fallback in recorded mode; an image without labels is an error pointing to --predicted. The tests also assert the mode in two recorded cases. Assisted-by: Claude:claude-sonnet-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
check_tags let jinja2.TemplateError, OSError and a malformed SBOM escape as a traceback. Run the check inside the try block so these end the section with an Error line, after the sources have been gathered. ansible_concat chained the already consumed head back onto its argument even for a list, repeating the first two items. As in ansible-core, only do so for a generator. Assisted-by: Claude:claude-sonnet-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
List the tag resolution options in the wrapper header, name Jinja2 among its dependencies, and note in the README that the printed variable chain includes default() fallbacks that were read but not needed. Assisted-by: Claude:claude-sonnet-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
Pass the defaults files out of name order so the sort in osism_layers is exercised. Assisted-by: Claude:claude-sonnet-5-5 Signed-off-by: Roger Luethi <luethi@osism.tech>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OSISM 11.0.0 shipped ten kolla containers that request image tags its build never pushed (osism/issues#1462). The ten tags were fixed in 11.0.1. The release checks were added and tightened during the same days:
check-versions.pychecks thatlatest/pins the newest OSISM versions (Add a check that latest/ pins the newest OSISM versions #2795) and that the Ceph and OpenStack symlinks oflatest/point at the newest series (check-versions: check the Ceph and OpenStack symlinks of latest/ #2797).check-kolla-images.pychecks that every image in a kolla build's SBOM is complete in the registry, labelled and signed (Add a script to check the kolla images of a release build #2800). This PR extends that script.check-osism-images.pydoes the same for the other images of a release build (Add a script to check the other images of a release build #2803).check-kolla-images.pychecks that a build belongs to its release tag (Compare image builds with the release tags on origin #2807).check-osism-images.pychecks the commit label of all five non-kolla images (check-osism-images: commit label on all images #2829).One gap stays open after all of these. No check works out the tag a deployment actually requests and compares it with what the build pushed:
latest, where every kolla image carries the same series tag. They cannot see an image that inherits its parent's tag:prometheus_valkey_exporter_tag: "{{ prometheus_tag }}"is a valid reference, it just names a tag that only exists for Prometheus. The same is true of a producer-map value that names an image the series no longer builds (letsencrypt_webserver).check-versions.pychecks which versionslatest/pins, not the tags a release deploys.check-kolla-images.py,check-osism-images.py) prove that every pushed image is complete and belongs to the release, not that anything deploys it under the tag it was pushed with.The next release could ship the same class of defect again: a new nested image with an inherited tag, or a renamed image upstream.
This PR adds that check to
check-kolla-images.py. After the registry checks, it resolves every kolla-ansible image reference (<x>_image_full) as Ansible would, per role, through these layers:versions.ymland the overlay of the kolla-ansible image;It then compares each resolved tag with the tags the build pushed, according to its SBOM:
How it works
src/ansible_templar.py: a small model of ansible-core 2.18 templating for these variables, covering layered precedence, lazy and recursive resolution,ansible_eval_concat, and cycle detection. The check refuses a release that pins a different ansible-core version.src/kolla_tags.py: resolves the references and compares them with the build. The result is aReportof mismatches, unresolvable references, and images no container uses.src/kolla_tag_inputs.py: gathers the inputs in one of two modes:osism/kolla-ansible:<version>doesn't exist yet: the inputs are rebuilt from the sources the next build will use (upstreamstable/<series>, container-image-kolla-ansible at its tag ormain, and the osism/defaults release thatbase.ymlpins);--predicted.--predicted,--kolla-ansible-version,--inventory-reconciler-version,--kolla-ansible-ref,--defaults-ref, and--base-dir/--remote-fallback.scripts/check-kolla-images.shdescribe the check.The drift checks
kolla_version_chain_*stay: they catch a subset of these problems earlier, onlatest. A static check of the producer-map values (every value inSBOM_IMAGE_TO_VERSIONmust name an image the release builds) would report theletsencrypt_webservercase weeks before a release too. It is not part of this PR; this check only catches its effect, at release time.Built on the image labels of osism/issues#1463
Recorded mode is possible because every release image now records what it was built from. It reads these labels:
de.osism.sbom,de.osism.sbom.digest), alongside the commit labels from Label the image with the commits it contains container-image-kolla-ansible#949;de.osism.commit.defaults).Without these labels, the inputs of a past release could only be recovered by downloading and unpacking the images, several hundred MB per run. Images built before the labels existed (11.0.1 and older) get an error that names
--predictedinstead of a fallback that downloads the images.Testing
tests/fixtures/kolla-tags-11.0.0.json.gz), with the inputs of the published 11.0.0:versions.ymland overlay ofosism/kolla-ansible:0.20261008.0, and osism/defaults fromosism/inventory-reconciler:0.20261008.0.--predicted v0.20261008.0(11.0.0):Tags: 120 ok, 8 failed, 4 not deployed (10 of 134 image references).--predicted v0.20261011.0(11.0.1):Tags: 128 ok, 0 failed, 4 not deployed (0 of 134 image references).v0.20261008.0without--predicted: stops with the error for images built before the label baseline.Related
🤖 Generated with Claude Code