apple / apple/container

[Bug]: image prune can remove active infrastructure image aliases

Open
#2,030 0 comments 0 reactions 0 assignees View on GitHub
stability
Dominant language
Swift
Stars
49.9k
Forks
1.8k
Avg merge
1d 20h
Merged PRs (30d)
22

Description

## I have done the following

- [x] I have searched the existing issues
- [x] I reproduced the issue against `apple/container` `main` at `27e5043165178edb095c901624857b51a2ea8e1a`

## Steps to reproduce

1. Configure an equivalent short reference for the stock builder image:

```toml
[registry]
domain = "ghcr.io"

[build]
image = "apple/container-builder-shim/builder:0.13.0"
```

2. Start the system and builder:

```sh
container system start
container builder start
```

3. Pull an unrelated image:

```sh
container image pull docker.io/library/alpine:3.20
```

4. Prune all unused images and check the builder:

```sh
container image prune --all
container builder status
```

The prune output should include the unrelated Alpine image but not the builder image, and the builder should remain running.

The deterministic source regressions create two `ImageDescription` values with the same OCI descriptor digest but different references, then evaluate the `image prune --all` in-use decision. The integration regression also queries the unfiltered image service before and after prune to verify that the builder digest remains stored. On current `main`, `ImagePrune` compares the references and considers the stored image unused even though an active container uses the same OCI digest.

## Problem description

`image prune --all` identifies images used by active containers by comparing image reference strings. References are aliases, not image identities: a configured short reference can be stored on the container while the image service stores the normalised registry reference. The mismatch allows prune to remove an image that an active container uses.

The builder path has the same alias problem in two other places:

- `builder start` stores the configured reference rather than the fetched image reference and can unnecessarily recreate an otherwise matching builder.
- infrastructure-image filtering compares configured and stored references literally, so normalised builder or init images can be exposed to image list, inspect, delete, or prune operations.

The expected behaviour is:

- active images are matched by OCI digest;
- configured infrastructure references are matched using their original, OCI-normalised, and registry-normalised aliases;
- the builder container stores the fetched image reference;
- prune removes the unrelated Alpine image but preserves the builder image and leaves the builder running.

## Environment

- OS: macOS 26.5.1 (25F80)
- Xcode: 26.6 (17F113)
- Swift: Apple Swift 6.3.3
- Container source: `apple/container` `main` at `27e5043165178edb095c901624857b51a2ea8e1a`

## Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Contributor guide

Open the contributing guide

Research direction

Start at ImagePrune and the image service's in-use decision, then trace builder start and infrastructure-image filtering for the reference comparisons described in the issue. Use the deterministic source regressions and integration regression to verify digest-based preservation, alias matching, fetched-reference storage, and that pruning removes Alpine while the builder remains running.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
cli, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.