Skip to content

fix(cleanup): compare container mounts as a set - #614

Merged
Mola-maker merged 1 commit into
mainfrom
claude/angry-goldberg-62c8a8
Nov 8, 2026
Merged

Mola-maker merged 1 commit into
mainfrom
claude/angry-goldberg-62c8a8

Conversation

@yifanxuaaa

Copy link
Copy Markdown
Contributor

Fixes the cleanup script refusing an untouched exited container with "Container identity or execution state changed since plan".

Why

The docker-container action records docker inspect identity at plan time, then compares it at apply time and again after recovery capture. Docker returns Mounts in no fixed order, so plan and apply could differ only in mount order and the action was refused.

  • First reproduced 2026-11-06 in the PostgreSQL round-2 cleanup.
  • Hit again on 2026-11-07, where it stopped a pass at its first container. That cleanup could only finish by running this branch's copy of the script.

Change

  • identity() sorts Mounts by type, name, source and destination.
  • Both checks compare through same(), which also normalizes the recorded side, so plans written before this change still apply.
  • A changed image, state, mount set or new process still refuses.
  • docs/general/cleanup.md describes the identity comparison.

Tests

  • Two inspect payloads that differ only in mount order pass the apply check, for both new- and old-format plans.
  • A changed, missing or replaced mount, a changed image or a changed state refuses before any Docker command.
  • The order test fails on the previous code.
  • Full tools/test_cleanup.py: 46 OK (re-run 2026-11-08 at this head, 22 s).
  • Ruff was not run (not installed on this host).

Production LOC: 102831 -> 102831 (delta 0). This is tooling only.

layerfs_v2_0_0 has the same comparison (tools/cleanup_docker.py) and needs the same fix separately.

🤖 Generated with Claude Code

The docker-container action records `docker inspect` identity at plan time
and compares it at apply time and again after recovery capture. Docker
returns `Mounts` in no fixed order, so an untouched exited container was
refused with "Container identity or execution state changed since plan"
(reproduced 2026-11-06 in the PostgreSQL round-2 cleanup, where the plan
and a fresh inspect differed only in mount order).

identity() now sorts Mounts by type, name, source and destination, and both
checks compare through same(), which normalizes the recorded side too, so
plans written before this change still apply. A changed image, state,
mount set or new process still refuses.

Tests: two inspect payloads that differ only in mount order pass the apply
check (new and old-format plans); a changed, missing or replaced mount, a
changed image or a changed state refuses before any Docker command. The
order test fails on the previous code. Full tools/test_cleanup.py: 46 OK.
docs/general/cleanup.md describes the identity comparison.

Production LOC: 102831 -> 102831 (delta 0)
Scope: tools/production_loc.py at the parent and staged tree (core 38395,
engine 61777, api 2659, dsh 0); tools-, test- and docs-only change.
Reference absent (retired R9c; last counted 65,417 at tree 498dd19).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@yhcedpn yhcedpn added the bug Something isn't working label Nov 8, 2026
@yhcedpn yhcedpn added this to the LayerFS v2.0.0 milestone Nov 8, 2026
@Mola-maker
Mola-maker merged commit 5ea0005 into main Nov 8, 2026
4 checks passed
@Mola-maker
Mola-maker deleted the claude/angry-goldberg-62c8a8 branch November 8, 2026 14:06
@Mola-maker
Mola-maker restored the claude/angry-goldberg-62c8a8 branch November 8, 2026 18:32
Mola-maker added a commit that referenced this pull request Nov 8, 2026
…626)

* docs(readme): point to layerfs_v2_0_0 for 2.0.0 development

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* docs(readme): move the 2.0.0 branch note below the badges

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(cleanup): compare container mounts as a set

The docker-container action records `docker inspect` identity at plan time
and compares it at apply time and again after recovery capture. Docker
returns `Mounts` in no fixed order, so an untouched exited container was
refused with "Container identity or execution state changed since plan"
(reproduced 2026-11-06 in the PostgreSQL round-2 cleanup, where the plan
and a fresh inspect differed only in mount order).

identity() now sorts Mounts by type, name, source and destination, and both
checks compare through same(), which normalizes the recorded side too, so
plans written before this change still apply. A changed image, state,
mount set or new process still refuses.

Tests: two inspect payloads that differ only in mount order pass the apply
check (new and old-format plans); a changed, missing or replaced mount, a
changed image or a changed state refuses before any Docker command. The
order test fails on the previous code. Full tools/test_cleanup.py: 46 OK.
docs/general/cleanup.md describes the identity comparison.

Production LOC: 102831 -> 102831 (delta 0)
Scope: tools/production_loc.py at the parent and staged tree (core 38395,
engine 61777, api 2659, dsh 0); tools-, test- and docs-only change.
Reference absent (retired R9c; last counted 65,417 at tree 498dd19).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: YifanXu1999 <yifanxu1999@gmail.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@Mola-maker
Mola-maker deleted the claude/angry-goldberg-62c8a8 branch November 8, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants