Skip to content

[container]: add clean command - #1949

Merged
jglogan merged 1 commit into
apple:mainfrom
saehejkang:container-clean-command
Sep 1, 2026
Merged

jglogan merged 1 commit into
apple:mainfrom
saehejkang:container-clean-command

Conversation

@saehejkang

@saehejkang saehejkang commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Motivation and Context

Closes #1763

Testing

  • Tested locally
  • Added/updated tests
  • Added/updated docs

@saehejkang
saehejkang force-pushed the container-clean-command branch 2 times, most recently from c9c01f4 to 65a1d09 Compare July 15, 2026 03:34
@saehejkang
saehejkang marked this pull request as ready for review July 15, 2026 03:35
@saehejkang
saehejkang force-pushed the container-clean-command branch 2 times, most recently from b6c6af6 to 083b3ec Compare July 15, 2026 04:13
@saehejkang saehejkang changed the title [container]: implement clean command [container]: add clean command Jul 15, 2026

@jglogan jglogan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All looks good. I'm building locally to test. Only changes are to remove a probably-unneeded test and to ensure blocks are getting returned to the host OS.

Comment thread Tests/IntegrationTests/Containers/TestCLIClean.swift Outdated
Comment thread Tests/IntegrationTests/Containers/TestCLIClean.swift Outdated

@jglogan jglogan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you missing a new route in Sources/Plugins/RuntimeLinux/RuntimeLinuxHelper+Start.swift?

I see:

% container clean d027f0a1-dfae-4c04-8e66-3687d511593b
Warning! Running debug build. Performance may be degraded.
Error: internalError: "failed to clean container" (cause: "internalError: "failed to clean container d027f0a1-dfae-4c04-8e66-3687d511593b (cause: "interrupted: "XPC connection error: Connection interrupted"")"")
Ensure container system service has been started with `container system start`.

Comment thread Tests/IntegrationTests/Containers/TestCLIClean.swift Outdated
@jglogan

jglogan commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@saehejkang It looks like the root fs gets cleaned but not a mounted named volume?

I'm testing your branch locally and doing this (the --cap-add is only so I can run fstrim):

container volume create scratch
container run -it --rm --name clean-test --cap-add ALL -v scratch:/mnt/data ubuntu:noble

Baseline measurement from the host shell:

du -sm ~/Library/Application\ Support/com.apple.container/containers/clean-test/rootfs.ext4
du -sm ~/Library/Application\ Support/com.apple.container/volumes/scratch/volume.img

In the container:

dd if=/dev/urandom of=/test.dat bs=65536 count=4096
dd if=/dev/urandom of=/mnt/data/test.dat bs=65536 count=4096
sync

The measured sizes of the files should be larger now.

Then, in the container:

rm /test.dat
rm /mnt/data/test.dat
sync

Measured sizes should not decrease yet.

From the host:

container clean clean-test

At this point the measured sizes should be close to the original (or less even, for the root volume).

What I'm seeing is that the root fs decreases but the volume does not. If I run fstrim in the container on the mount point I do see the decrease:

fstrim /mnt/data

@jglogan

jglogan commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

With a debugger attached, I see a filesystemOperation call for .trim with the paths:

  • /run/container/clean-test/rootfs
  • /run/container/clean-test/rootfs/mnt/data

@recrack

recrack commented Aug 4, 2026

Copy link
Copy Markdown

I investigated the named-volume behavior while updating this PR against the current main. The remaining issue is that filesystem operations are resolved in vminitd's mount namespace, while OCI block mounts such as named volumes exist only in the workload container's mount namespace.

I opened apple/containerization#830 as a draft companion change. It carries the workload container ID through the filesystem-operation RPC, pins the init process root to avoid PID-reuse races, and resolves canonical container paths with openat2(RESOLVE_IN_ROOT | RESOLVE_NO_MAGICLINKS).

I also opened #2068 as an upstream draft based on this PR's commit history. It preserves the original authorship, updates the branch to current main, resolves the current API/test-fixture conflicts, and adds runtime identity checks and integration coverage. I closed the temporary fork-targeted PR so review stays in the official Apple repositories.

The containerization PR is ready for review. #2068 remains a draft while its dependency revision and host allocated-size assertions are finalized. Maintainers and the original author can choose whether to continue in #2068 or fold those commits back into this PR.

@saehejkang

Copy link
Copy Markdown
Contributor Author

Hey @recrack! Thanks for taking a look into this. You are correct in that "filesystem operations are resolved in vminitd's mount namespace" and that is causing issues with trimming volume mounts. I was working on changes that I was just able to push. Here is a solution that @jglogan and I came up with, if you want to take a look.

apple/containerization#838

@jglogan

jglogan commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

@saehejkang I updated this to pick up your containerization fix. It looks like all that's needed now are some adjustments to accommodate changes to the test fixtures.

@saehejkang
saehejkang force-pushed the container-clean-command branch from 35cb6e1 to ce203d9 Compare September 1, 2026 03:57
@saehejkang

Copy link
Copy Markdown
Contributor Author

It looks like all that's needed now are some adjustments to accommodate changes to the test fixtures.

Should be fixed and ready

@jglogan

jglogan commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Seeing some test failures:

✔ Test testAnonymousVolumeMixedWithNamedVolume() passed after 1116.770 seconds.
✘ Test testCleanAfterFileCreation() recorded an issue at TestCLIClean.swift:63:9: Expectation failed: (writeAllocated → 0) > 0
✘ Test testCleanAfterFileCreation() recorded an issue at TestCLIClean.swift:66:9: Expectation failed: (reclaimed → 0) > 0
✘ Test testCleanAfterFileCreation() failed after 9.430 seconds with 2 issues.
◇ Test testCleanWithVolume() started.
✔ Test testMultipleAnonymousVolumes() passed after 1117.200 seconds.
✔ Suite TestCLIAnonymousVolumes passed after 1117.205 seconds.
✘ Test testCleanWithVolume() recorded an issue at TestCLIClean.swift:63:9: Expectation failed: (writeAllocated → 0) > 0
✘ Test testCleanWithVolume() recorded an issue at TestCLIClean.swift:66:9: Expectation failed: (reclaimed → 0) > 0
✘ Test testCleanWithVolume() failed after 8.275 seconds with 2 issues.
✘ Suite TestCLIClean failed after 1125.449 seconds with 4 issues.
✘ Test run with 280 tests in 33 suites failed after 1125.450 seconds with 4 issues.
Ensuring apiserver stopped after the CLI integration tests
make: *** [coverage-integration] Error 1

@saehejkang
saehejkang force-pushed the container-clean-command branch from ce203d9 to 4f7b217 Compare September 1, 2026 05:35
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

Code Coverage

Tier Line Coverage
Unit 24.87%
Integration 66.63%
Combined 76.12%

@jglogan
jglogan merged commit b8ffd38 into apple:main Sep 1, 2026
3 checks passed
@saehejkang
saehejkang deleted the container-clean-command branch September 5, 2026 02:11
henrywang added a commit to henrywang/Berthly that referenced this pull request Sep 15, 2026
## Summary

- Bumps the audit header to container CLI 1.4.1.
- Adds `clean` (1.4.1, apple/container#1949) to Deliberate gaps —
corrected from the issue's framing: `clean` runs fstrim on a *running*
container's rootfs and non-read-only block mounts to reclaim host disk
space. It deletes nothing, so it's unrelated to `delete`/`prune` and
doesn't belong as a System-section row mapped onto prune actions
(there's no volume-safety divergence to state, since no data is at
risk). It's reachable over the same `ContainerClient` XPC surface
Berthly already uses, but a niche maintenance op with no GUI need
identified.
- Confirms `system status`'s richer output and the JSON slash-escaping
change (#1769, #2205) are no-ops — but for a different reason than the
issue assumed: Berthly *does* consume the changed `apiServerVersion`
field, it survives because `ContainerCompatibility.extractVersion`'s
regex extracts the version number rather than assuming a fixed string
shape, so the field's format change (full descriptive string → bare
version) doesn't affect it.
- Re-confirms the k8s deliberate-gap rationale against 1.4.1: only a
plugin reference doc landed (apple/container#2244), no source changes.
- Verified via `gh api repos/apple/container/compare/1.3.1...1.4.1` that
no other CLI-surface files changed beyond the above.

## Note for #150

`clean`'s abstract is "Clean one or more running containers" (top-level
`container clean <ids>`, not `container system clean`), and its
implementation (`RuntimeService.clean`) calls
`filesystemOperation(operation: .trim, path:)` — an fstrim, not a
delete. The issue's "sweeps volumes" / volume-safety-divergence framing
read prune semantics into #2228's title; there's no data-loss risk here
to document.

## Test plan
- [x] Docs-only change; no swiftlint/test gate applies.
- [x] Verified all cited PRs/commits and source against the
apple/container repo directly.

Closes #150.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: container clean command

4 participants

Sponsor
SponsoredKunjungi sekarang
Promo