feat(forgejo-package-prune): protect image tags running live in the cluster
Adds collect_live_cluster_versions() — enumerates pod container images via kubectl and protects any forgejo.coulomb.social/coulomb/<name>:<tag>. Closes the gap where CI-deployed apps (e.g. state-hub) pin a live tag absent from Helm values. On by default (--no-protect-live to skip); emits protection_notes + live_protection in the JSON summary so consumers can detect reduced coverage. Verified against production: protects state-hub/vergabe/issue-core live tags. ACTIVITY-WP-0020 T07 (partial — see workplan note re multi-cluster coverage). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
6f7ca31a6d
commit
e9e631fbf4
2 changed files with 89 additions and 0 deletions
|
|
@ -64,5 +64,35 @@ image:
|
|||
self.assertEqual(protected_plans, {("vergabe-teilnahme", "old-prod")})
|
||||
|
||||
|
||||
def test_collect_live_cluster_versions_protects_forgejo_tags(self) -> None:
|
||||
images = "\n".join([
|
||||
"forgejo.coulomb.social/coulomb/state-hub:f2e042a",
|
||||
"forgejo.coulomb.social/coulomb/vergabe-teilnahme:064d295",
|
||||
"registry.k8s.io/pause:3.9", # unrelated registry → ignored
|
||||
"gitea.coulomb.social/coulomb/old-app:x", # non-forgejo → ignored
|
||||
"",
|
||||
])
|
||||
with mock.patch.object(prune.shutil, "which", return_value="/usr/bin/kubectl"), \
|
||||
mock.patch.object(
|
||||
prune.subprocess, "run",
|
||||
return_value=mock.Mock(stdout=images, returncode=0),
|
||||
):
|
||||
protected, notes = prune.collect_live_cluster_versions()
|
||||
self.assertEqual(notes, [])
|
||||
self.assertEqual(
|
||||
protected,
|
||||
{
|
||||
("container", "state-hub", "f2e042a"),
|
||||
("container", "vergabe-teilnahme", "064d295"),
|
||||
},
|
||||
)
|
||||
|
||||
def test_collect_live_cluster_versions_skips_without_kubectl(self) -> None:
|
||||
with mock.patch.object(prune.shutil, "which", return_value=None):
|
||||
protected, notes = prune.collect_live_cluster_versions()
|
||||
self.assertEqual(protected, set())
|
||||
self.assertTrue(notes and "kubectl not found" in notes[0])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue