Repository navigation
Commit 99de79f
authored
fix(cdi): pin the CDI release kubevirt-cdi is reconciled against and stop update overwriting it (#4107)
## What this PR does
`packages/system/kubevirt-cdi` resolved its CDI version at run time from
GitHub's `releases/latest` redirect and wrote the result straight over
`templates/cdi-cr.yaml`. That file is not vendored. Upstream ships a
bare CDI object; ours adds Helm templating for `cloneStrategyOverride`,
`uploadProxyURL` and the worker-pod `podResourceRequirements`, the
`ExpandDisks` feature gate, a `CriticalAddonsOnly` toleration, and the
two RBAC documents that let a tenant clone from the golden-image
namespace. I diffed the two at v1.66.1 to write that list, so it is
complete as of that release rather than only hedged: upstream ships 283
bytes with one feature gate, two nodeSelectors and an `imagePullPolicy`,
and we are a strict superset of it. Every entry arrived by hand, so
`wget -O templates/cdi-cr.yaml` was not refreshing a vendored file, it
was overwriting a first-party one. Same loss as the `rm -rf templates`
that #4097 removes, arriving through the fetch instead of the wipe.
`update` now pins the release the object is reconciled against, and
fetches it only to confirm the bytes still hash to a digest I measured.
Nothing is written under `templates/`. At the next CDI bump whose asset
differs, that check fails, which is the point: upstream moving its own
defaults is when the local copy needs a human to reconcile it, not an
overwrite. The download is kept on a mismatch, since reconciling one
starts by reading it.
`RELEASE` is `v1.66.1`, which is the release `kubevirt-cdi-operator`
vendors, so the pin and the deployed version agree. What the platform
deploys is decided by that package, and it can move to another release
without this file changing, so this line is pointed at it by hand.
`update` then checks the two agree: it compares `RELEASE` with the
`cdi-operator` image tag that package vendors and fails naming both
versions when they differ, because otherwise its closing line would
report a release the platform may no longer run. That is a check and not
a derivation, so `RELEASE` stays a pin a human moves.
Upstream publishes no checksum for the asset, so the pin comes from a
download rather than from a published file:
`a497f90de608c1df26f9ee4095289373f17132d74a2042ca03e00c17c964f8a7`. It
catches an asset that moved under a tag that should be immutable. It is
not authenticity verification, and the comment beside it says so.
The digest command is chosen when `update` expands it, `sha256sum` when
it is on PATH and `shasum -a 256` otherwise. Which one ran here is worth
stating, because the usual claim about macOS is out of date: this
machine picked `sha256sum`, and that binary is `/sbin/sha256sum`, a
native Darwin one rather than GNU coreutils. It reports `sha256sum
(Darwin) 1.0` and prints the same `<digest> <path>` format.
The package already had a `test:` target, from `0418577f5`, so what it
gains here is the `.PHONY` line that commit did not add.
`hack/package.mk` declares only the nine targets it defines itself, so
without it a file or directory named `test` or `update` beside the
Makefile makes make consider that target up to date and skip the recipe
in silence. The new suite pins the `ExpandDisks` gate, the toleration,
`podResourceRequirements`, the `uploadProxyURL` override and the clone
RBAC, and renders the upload-proxy Ingress and TLSRoute, each under the
`gateway-enabled` value that selects it. The clone-strategy override is
pinned by `tests/clone_strategy_test.yaml`, which is already on `main`.
One consequence of the pin move is a claim rather than a number, so it
gets its own line. Upstream carried `WebhookPvcRendering` from v1.63.0
through v1.65.0 and dropped it by v1.66.0; the local object never
carried it, so the divergence ran both ways across those three releases
and one way since. The comment says to re-derive the delta at each bump
instead of trusting it, because that was a fact about a span of releases
and not about CDI.
`packages/system/kubevirt-cdi/Makefile` carried two identical `test:`
targets, one from `0418577f5` and one appended by a later merge, so make
printed `overriding commands for target 'test'` on every invocation in
the package. The second sat inside the span this recipe rewrites, so it
goes with the rewrite rather than being re-authored into it. The comment
kept above it is the reason a reader should not add another. Closes
#4157.
### Scope
An earlier revision also pinned and tested `kubevirt-cdi-operator`.
#3920 has since landed the two real bugs in that recipe, the patch strip
level and `patches/tolerations.diff`, so that half is dropped here
rather than merged twice. Pinning and testing the operator package is
#4190.
Named improvements left alone, so they read as choices.
- The two upload-proxy tests each render their route under the
`gateway-enabled` value that selects it and neither asserts the other is
absent; the templates already settle that with `ne "true"` and `eq
"true"` on the same variable, and `tests/standalone_render_test.yaml`
already asserts each route absent under the values that select the
other. So the package does cover it; these two cases just do not, and a
third copy would not add anything.
- The CDI object carries no version string for a rendered-output
assertion, so `RELEASE` is checked by `make update` rather than by `make
test`.
- Neither route case pins the backend service port, 443 in both
templates; that is outside what the suite claims.
- The template-loss guard still counts `cdi-cr.yaml` as named, because
the download line in `update` mentions the stem, so re-adding a wipe
here would have it report two files instead of three; the guard's header
already says a mention is not proof of a write, and the case needs a
wipe this recipe no longer has.
- The suite pins the local additions by design, and most of the
upstream-derived half is pinned by nothing: `imagePullPolicy` and the
two `nodeSelector` blocks have no assertion anywhere under `tests/`.
`HonorWaitForFirstConsumer` is the exception and only as a side effect:
`featureGates` is pinned whole, so that gate rides along with
`ExpandDisks`. The rest are maintained by the same hand reconciliation
the pin forces whenever the upstream asset changes, so a carry-over that
drops one of them is green. Three asserts would close what is left.
- One more, remote enough to name rather than code around: if the digest
tool is missing entirely, `$$actual` comes out empty, the comparison
against `CR_SHA256` fails, and the error text diagnoses a moved asset
when the real cause is a machine with neither `sha256sum` nor `shasum`.
Busybox ships the first and macOS ships the second, so nobody has hit
it. Closing it means an executable line, which would then owe mutation
coverage of its own, and that is disproportionate to a case with no
known instance. The mechanism is written here so the next reader does
not have to re-derive it from an error message that points the wrong
way.
- Separately, the per-package `.PHONY` gap this Makefile's own line
argues against is not specific to this package: most package Makefiles
do not declare their own `test:` or `update:` phony, and #4214 tracks
that.
- A key that does not exist yet is not held either: every item in the
delta is pinned whole, but a NEW key appearing at `spec` or
`spec.config` level passes unnoticed, and such a key can change
behaviour rather than sit inert. I confirmed it on a copy extracted from
this commit, appending `spec.config.filesystemOverhead.global: "0.99"`
and getting a green suite. That is the shape to recognise at the next
bump: not a changed value, which is caught, but a new sibling key beside
the ones we pin.
- And `spec.config.podResourceRequirements` is now pinned whole here and
by four leaves in `tests/importer-resources_test.yaml`: the whole-map
form is the stronger one and the leaves are a subset of it, so changing
the default takes two edits and the second failure reads as a surprise
until you know why both exist.
- If the operator's image reference ever gains a digest
(`:v1.66.1@sha256:...`), `${deployed##*:}` takes the digest's hex
instead of the tag, and `update` fails with a loud false mismatch rather
than passing silently.
- Deriving `RELEASE` with `$(shell ...)` from the sibling manifest was
suggested and declined on merits: a derived value is not a pin, the
point is that a human chooses which CDI release this object is
reconciled against, and computing it from whatever the neighbour last
vendored hides that choice from the diff.
The operator comparison lives in `update` and not in `test:`, even
though `kubevirt-operator` ties its own manifest to the tree from
`test:`. A mismatch calls for a hand reconciliation, and `update` is the
recipe that asks for one; it is also where the success line that would
otherwise name the wrong release is printed. I checked it on a copy
extracted from this commit. With the operator's image tag moved to
v1.67.0, `make update` exits 2 and names both versions. With the tags
equal it passes. With the check's `exit 1` removed, the moved tag passes
again, so the red comes from the check.
Worth knowing when reading the mismatch path: `kubevirt-operator`
deletes its download on a hash mismatch and this package keeps it. That
is deliberate here, since reconciling a moved asset starts by reading
it, but the two packages do read oppositely and neither file says so.
### Base and ordering
This stacks on #4097 and should land after it. Both edit
`packages/system/kubevirt-cdi/Makefile`, and this change builds directly
on that one's edit to the same recipe, so it is based on the head of
`fix/cdi-update-keeps-local-templates` rather than on `main`. GitHub
computes mergeability against the PR's base branch, which here is that
stack branch and not `main`. Both branches are rebased onto current
`main`, which has not touched these paths since the previous merge-base.
### Screenshots
No UI changes.
### Downstream repositories
Walked the trigger map against the diff. Two entries come close and
neither fires.
The website triggers on developer tooling and package Makefiles, but
`content/en/docs/next/development.md` documents `make update` only as
"Update Helm chart and versions from the upstream source", which still
holds, and its worked example is cilium, which this does not touch. Its
`make test` line refers to the e2e sandbox in `packages/core/testing`,
not per-package unit tests.
`ccp` triggers on `hack/` layout and on what a make target does, and
nothing under `hack/` is touched. Its `package-bump` skill already
assumes a package's `update` recipe hardcodes the upstream version
instead of resolving it at run time, and names cilium, kafka-operator,
opensearch-operator and postgres-operator as examples. `kubevirt-cdi`
was one of those counterexamples and now is not. Pinning
`kubevirt-cdi-operator` the same way is #4190 and out of scope here. The
skill handles vendored Helm charts, in-repo image builds and version
enums, and a raw manifest download is none of those. Everything else in
the map needs an app, a schema, an installer value, a variant or a
release asset.
- [x] No downstream repository is affected by this change
- [ ] [cozystack/website](https://github.com/cozystack/website) -
follow-up:
- [ ]
[cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack)
- follow-up:
- [ ]
[cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack)
- follow-up:
- [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up:
- [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up:
- [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) -
follow-up:
- [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) -
follow-up:
- [ ]
[cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server)
- follow-up:
- [ ]
[cozystack/external-apps-example](https://github.com/cozystack/external-apps-example)
- follow-up:
- [ ] [cozystack/examples](https://github.com/cozystack/examples) -
follow-up:
- [ ] [cozystack/community](https://github.com/cozystack/community) -
follow-up:
### Release note
```release-note
fix(cdi): `make update` in kubevirt-cdi no longer overwrites the hand-maintained CDI object. It pins the CDI release that object is reconciled against instead of resolving GitHub's releases/latest at run time, and verifies the fetched asset against a pinned sha256 without writing under templates/.
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Reliability**
* Updates now use verified, pinned CDI releases to prevent unintended
manifest changes.
* Failed or checksum-mismatched downloads no longer overwrite existing
configuration.
* **Bug Fixes**
* Preserved local CDI customizations during release updates.
* Added validation for CDI resources, access controls, upload-proxy
routing, and TLS configuration.
* **Tests**
* Added automated checks for incomplete template refreshes and generated
Kubernetes resources.
* Added chart tests covering CDI behavior, clone permissions, and
upload-proxy networking.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->4 files changed
Lines changed: 241 additions & 38 deletions
File tree
- hack
- packages/system/kubevirt-cdi
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
19 | 18 | | |
20 | 19 | | |
21 | 20 | | |
| |||
269 | 268 | | |
270 | 269 | | |
271 | 270 | | |
272 | | - | |
273 | | - | |
274 | | - | |
| 271 | + | |
| 272 | + | |
275 | 273 | | |
276 | 274 | | |
277 | 275 | | |
| |||
341 | 339 | | |
342 | 340 | | |
343 | 341 | | |
344 | | - | |
345 | | - | |
346 | | - | |
347 | | - | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
348 | 346 | | |
349 | 347 | | |
350 | 348 | | |
| |||
383 | 381 | | |
384 | 382 | | |
385 | 383 | | |
386 | | - | |
387 | | - | |
| 384 | + | |
| 385 | + | |
388 | 386 | | |
389 | 387 | | |
390 | 388 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
4 | 25 | | |
5 | 26 | | |
6 | | - | |
7 | | - | |
8 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
9 | 35 | | |
10 | 36 | | |
11 | 37 | | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
16 | 45 | | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
21 | 57 | | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
0 commit comments