fix(ansible): the swarm prune never runs a docker prune that touches images; it lives in its own folder (#6399)
The first applied run lost VDNT-Docker03 29 images (10.4 GB) before its script ran. Its `docker system prune` removes dangling images, and Docker counts an image with no tag as dangling: every image a swarm task pulled by digest. Docker03 was left holding only its own tasks' images, as under the old prune. Nothing went down, since a running container's image can't be removed. - Step 1 now prunes containers, networks, build cache and (prune_volumes) volumes one by one. Every image decision is left to the script, which keeps the images services are pinned to. - A test guards against any image-pruning command in the playbook. - The playbook moves to maintenance/swarm_prune/, with its script in that folder's files/, so a helper's name can't collide with another playbook's (the operator's direction for playbooks with helpers). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ BUILTIN = Path(get_sources({"sources": []})[0]["path"])
|
||||
@pytest.fixture
|
||||
def prune():
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"swarm_prune", BUILTIN / "maintenance" / "files" / "swarm_prune.py")
|
||||
"swarm_prune", BUILTIN / "maintenance" / "swarm_prune" / "files" / "swarm_prune.py")
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(mod)
|
||||
return mod
|
||||
@@ -27,13 +27,19 @@ def _image(id_, tags=(), digests=(), size=100):
|
||||
|
||||
|
||||
def test_the_playbook_is_listed_and_asks_before_it_runs():
|
||||
assert "maintenance/swarm_prune.yml" in discover_playbooks(str(BUILTIN))
|
||||
content = (BUILTIN / "maintenance" / "swarm_prune.yml").read_text()
|
||||
assert "maintenance/swarm_prune/swarm_prune.yml" in discover_playbooks(str(BUILTIN))
|
||||
content = (BUILTIN / "maintenance" / "swarm_prune" / "swarm_prune.yml").read_text()
|
||||
meta = discover_playbook_meta(content)
|
||||
assert meta["confirm"] is True and meta["category"] == "maintenance" and meta["description"]
|
||||
play = yaml.safe_load(content)[0]
|
||||
script = next(t for t in play["tasks"] if "ansible.builtin.script" in t)
|
||||
assert script["check_mode"] is False and "--dry-run" in script["ansible.builtin.script"]["cmd"]
|
||||
# No docker prune touches images: an image swarm pulled by digest has no
|
||||
# tag, and Docker calls that dangling (on 2026-10-25 a `system prune`
|
||||
# took 29 a node was keeping for the other's services).
|
||||
commands = yaml.safe_dump([t for t in play["tasks"] if "ansible.builtin.command" in t])
|
||||
assert "'system'" not in commands and "'image'" not in commands
|
||||
assert "'container', 'prune'" in commands and "'builder', 'prune'" in commands
|
||||
|
||||
|
||||
def test_services_are_matched_by_digest_or_else_by_tag(prune):
|
||||
|
||||
Reference in New Issue
Block a user