Skip to content

The template-loss guard cannot see a first-party file that its own recipe refetches, because fetching it counts as naming it #4206

Open

Description

The invariant added in #4097 reports a tracked file under templates/ when the package's update recipe clears the directory and never mentions that file. The mention test is a substring search for the file's stem across the whole Makefile:

printf '%s\n' "$_code" | grep -Fq -- "$_stem" || printf '%s\n' "$_dir/$_f"

A file the recipe refetches is therefore named by the line that fetches it. packages/system/kubevirt-cdi/Makefile writes wget ... -O templates/cdi-cr.yaml, so cdi-cr.yaml is never reported.

That file is not vendored. It carries Helm templating, the ExpandDisks feature gate, a toleration, and the two RBAC documents that preauthorize cloning from cozy-public. The fetch truncates all of it on every run, and the guard is silent by construction, because the loss is an overwrite of a named file rather than a deletion of an unnamed one.

So the check covers one of the two ways a first-party template disappears and cannot cover the other. That limit is written in the header of hack/package-update-templates.bats and nowhere a reader would look before editing a recipe.

There is a per-file mitigation in the tree already, by hand. #4107 pins the release and the published digest for that one asset, so a refetch that would change it fails instead of writing. That works because someone decided it was worth the maintenance, not because anything points at the file as needing it.

What a general form would need is a way to tell "this template is entirely refetched" from "this template is refetched and then hand-edited", and the Makefile does not carry that distinction today. Recording the gap rather than proposing a mechanism, since the honest options are a per-package declaration of which templates are hand-maintained, or accepting that the digest pin is the answer and applying it wherever a refetched file is first-party.

Correction: this particular file is not lost silently

The paragraph above says the guard is silent, and that part stands. It reads as though the loss goes unnoticed, and for cdi-cr.yaml it does not. The package's own helm-unittest suites assert against that file seven times, four in tests/clone_strategy_test.yaml and three in tests/importer-resources_test.yaml, so an overwrite that dropped the templating or the RBAC documents turns make test red in that package.

That is a materially better position than the upload-proxy manifests were in before #4097, where nothing asserted on them at all and the loss reached a cluster. It also changes what this issue is asking for. The guard's blind spot is real and worth closing, but the urgency comes from files nothing asserts on, not from this one.

So the shape to keep in mind when someone picks this up: a refetched first-party file is exposed exactly to the degree that no suite names it. Where a suite does, the package already has the loud failure the guard would otherwise have to provide.

Activity

  1. lexfrei commented on Sep 10, 2026

    @lexfrei
    ContributorAuthor

    Same gap, wider than this issue states it. The text here develops it on kubevirt-cdi and generalises from there. The guard keys on the wipe shape alone, so a recipe that fetches straight over a first-party file under templates/ is invisible to it in every package that has one. kubevirt-cdi is where it got noticed.

    Checked before writing this: the helper line quoted above is unchanged on the branch, and kubevirt-cdi's recipe still writes wget ... -O templates/cdi-cr.yaml on main. Both still hold.

  2. added
    area/ciIssues or PRs related to CI workflows, GitHub Actions, automation
    triage/acceptedIndicates an issue is ready to be actively worked on
    priority/backlogGeneral backlog priority. Lower than priority/important-longterm
    and removed
    triage/needs-triageIndicates an issue needs triage by a maintainer
    on Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/ciIssues or PRs related to CI workflows, GitHub Actions, automationkind/bugCategorizes issue or PR as related to a bugpriority/backlogGeneral backlog priority. Lower than priority/important-longtermtriage/acceptedIndicates an issue is ready to be actively worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions