fix(resources): attribute free images to managed prune by repository family (#1769)

* fix(resources): attribute free images to managed prune by repository family

After a stack update, unused previous tags lost compose labels and dropped out of managed prune. Match free image repositories still used by managed containers (excluding foreign Compose projects), and clarify the fleet dry-run unlock on the prune card footer.

* fix(resources): omit stackName on repo-match managed prune items

Repository sharing is not ownership; the confirm list must not show stack attribution for repo-matched free images. Pin repository-key normalization with exact Set assertions so the duplicated parser cannot drift silently.

* fix(fleet): bind prune fingerprints to image tag sets

RepoTag churn on an already-planned image Id no longer leaves the dry-run fingerprint unchanged, so fleet preflight rejects the whole execute when any node retags. Itemized delete also refuses on reference drift and reports multi-repository refuse without implying a clean no-op.
This commit is contained in:
Anso
2026-08-04 16:38:37 -04:00
committed by GitHub
parent 011f084e24
commit a29d451875
10 changed files with 928 additions and 60 deletions
+7 -3
View File
@@ -29,9 +29,11 @@ The left card under the hero breaks down your Docker disk usage into three tiles
| Tile | Meaning |
|------|---------|
| **Sencho managed** (green) | Images and volumes used by stacks in your `COMPOSE_DIR` |
| **Sencho managed** (green) | Images and volumes **currently used** by stacks in your `COMPOSE_DIR` |
| **External** (amber) | Images and volumes used by Docker projects outside Sencho |
| **Reclaimable** (neutral) | Unused images, stopped containers, and dangling volumes safe to delete |
| **Reclaimable** (neutral) | Unused images, stopped containers, and dangling volumes Docker can free |
The managed tile does not count free (unused) images. Those rows appear under reclaimable space and in the Images tab as unused until you prune them.
Each tile shows its size and its share of the total footprint as a percentage. The layout itself is fixed (Sencho managed on the left, External and Reclaimable stacked on the right); tile size does not scale with the percentage, so read the numbers rather than the proportions. Click any tile to filter the resource tabs below to that category.
@@ -41,11 +43,13 @@ The right card under the hero exposes four prune actions. Each tile has a single
| Action | What it removes |
|--------|----------------|
| **Prune Unused Images** | Images with no running containers in Sencho stacks |
| **Prune Unused Images** | Free images owned by or still matching repositories used by your Sencho stacks |
| **Prune Unused Volumes** | Volumes not attached to any Sencho container |
| **Prune Dead Networks** | Networks not connected to any Sencho container |
| **Purge Unmanaged Containers** | Containers Sencho doesn't recognize (started outside it) |
Managed image prune is broader than the green **Sencho managed** tile: after a stack update leaves an older tag unused, that free image can appear in the managed prune plan when a running stack container still uses the same image repository. Images labeled for Compose projects Sencho does not manage stay out of managed prune (use **All Docker** for a full host reclaim). Untagged dangling layers have no repository to match and usually require **All Docker** / all-scope prune.
The first three tiles also show a **More options** menu with a single destructive entry, **All Docker (includes external)**, that broadens the prune to every Docker resource on the host. Use it carefully, since it can affect other Compose projects sharing the same daemon. The **Purge Unmanaged Containers** tile has no menu and always targets unmanaged containers only.
A confirmation dialog appears before any destructive prune. Sencho first builds an itemized plan of exactly which resources will be removed, shows that list in the dialog, and only then enables confirm. The confirm action is bound to that plan: if the daemon state changes before you confirm, Sencho refreshes the plan instead of deleting a different set. While the operation runs, a loading notification keeps you informed; on completion it is replaced with a success or error notification, including how much space was reclaimed.