Skip to content

[container]: add container export for live containers - #1630

Merged
jglogan merged 1 commit into
apple:mainfrom
saehejkang:live-flag-for-container-export
Aug 2, 2026
Merged

jglogan merged 1 commit into
apple:mainfrom
saehejkang:live-flag-for-container-export

Conversation

@saehejkang

@saehejkang saehejkang commented Jun 3, 2026 •

Copy link
Copy Markdown
Contributor

Type of Change

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

Motivation and Context

Closes #1400

Testing

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

@jglogan

jglogan commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@saehejkang Let's tackle these two PRs right after next week's release.

@jglogan
jglogan self-requested a review June 15, 2026 17:45
@jglogan jglogan assigned saehejkang and unassigned saehejkang Jun 20, 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.

@saehejkang see the suggestion for simplifying this change. What do you think?

Comment thread Sources/APIServer/APIServer+Start.swift Resolved
@github-actions

github-actions Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

Code Coverage

Tier Line Coverage
Unit 24.31%
Integration 66.13%
Combined 75.51%

@saehejkang
saehejkang force-pushed the live-flag-for-container-export branch 2 times, most recently from 253a941 to c8a9cdf Compare July 5, 2026 10:44
stephenlclarke added a commit to stephenlclarke/container-compose that referenced this pull request Jul 12, 2026
Treat omitted compose commit --index and --index=0 like Docker Compose's unset service-container selection, while keeping explicit positive indexes targeted and rejecting negative indexes.

Refresh commit parity docs and runtime blocker references now that apple/containerization#685 has landed and apple/container#1630 plus apple/container#1762 track the remaining live export/commit path.
@saehejkang
saehejkang force-pushed the live-flag-for-container-export branch from 18751f8 to 912a240 Compare July 15, 2026 04:16
@jglogan jglogan changed the title [container]: add --live flag to export command [container]: add container export for live containers Aug 1, 2026
@jglogan

jglogan commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Local test configuration, run ./test.sh to test:

entrypoint.sh

#!/bin/sh
#
# Continuously writes random 256-byte files under /tmp/output.
#
set -eu

mkdir -p /tmp/output

while true; do
    tmpfile=$(mktemp /tmp/output/.tmp.XXXXXX)
    dd if=/dev/urandom of="$tmpfile" bs=1 count=256 2>/dev/null
    hash=$(sha256sum "$tmpfile" | awk '{print $1}')
    mv "$tmpfile" "/tmp/output/$hash"
done

Dockerfile:

FROM alpine:3.20

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]

test.sh:

#!/bin/sh
#
# Build and run a container that performs continuous I/O.
# Use live export to obtain two different tar archives.
# Import these in Colima or other Docker-like and run
# to measure how many files were created.
#
set -euox pipefail

CONTAINER="${CONTAINER:-container}"
EXPORT_OPTS=${EXPORT_OPTS:-}
IMAGE=liveexport-test
NAME=liveexport-test-run

${CONTAINER} build -t "${IMAGE}" .
${CONTAINER} run -d --rm --name "${NAME}" "${IMAGE}"

trap '${CONTAINER} rm -f "${NAME}"' EXIT

sleep 2
${CONTAINER} export ${EXPORT_OPTS} -o "${NAME}-1.tar" "${NAME}"

sleep 2
${CONTAINER} export ${EXPORT_OPTS} -o "${NAME}-2.tar" "${NAME}"

docker import "${NAME}-1.tar" "${IMAGE}-1"
docker import "${NAME}-2.tar" "${IMAGE}-2"

docker run -it --rm "${IMAGE}-1" ls /tmp/output | wc -l
docker run -it --rm "${IMAGE}-2" ls /tmp/output | wc -l

@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.

Test feedback, from exporting with container and docker (via Colima):

EXPORT_OPTS=--live ./test.sh
CONTAINER=docker ./test.sh
  • Basic functionality looks good. With the --live flag, and for the first run, it works fine.
  • Please remove the --live flag, and instead, in the RuntimeService, just use the is-running detection result to determine whether freeze/thaw is necessary. The user shouldn't have to concern themselves with the state of the container. The test should pass using ./test.sh without EXPORT_OPTS.
  • container export fails on back-to-back runs because it refuses to overwrite the output file (Error: “archive.tar” couldn’t be moved to “20260801-container-liveexport” because an item with the same name already exists.). The command should overwrite the previous file without consulting the user.

@saehejkang
saehejkang force-pushed the live-flag-for-container-export branch from 29e88e5 to c6694ba Compare August 2, 2026 05:21
@jglogan
jglogan merged commit da8bec6 into apple:main Aug 2, 2026
3 checks passed
@saehejkang
saehejkang deleted the live-flag-for-container-export branch August 3, 2026 02:27
henrywang added a commit to henrywang/Berthly that referenced this pull request Aug 15, 2026
## Summary
- `container export`'s daemon-side guard was relaxed in 1.2.1
(apple/container#1630) to accept a running container
(freeze/snapshot/thaw), not just a stopped one. Berthly's "Export
Filesystem…" was still unconditionally disabled outside `.stopped`.
- Adds `ContainerCompatibility.isAtLeast(installed:_:)` — a full
major.minor.patch comparison, unlike `isCompatible`/`mismatch`'s
major.minor-only floor (which is the right floor for overall daemon
compatibility, but too coarse for gating one capability that landed in a
specific patch). Gates the button on the connected daemon actually being
1.2.1+, so a user on an older daemon still sees it disabled instead of
hitting a raw "container is not stopped" error.
- Updates the one existing UI test whose assumption the fix invalidates
(`testContainerContextMenuOnRunningShowsLifecycleActionsAndGates` — the
mock reports daemon 1.2.2 since #109, so a running container's export is
now correctly enabled).
- Splits `ContainerCompatibilityTests` into its own file — the new
`isAtLeast` tests would have pushed `BerthlyTests.swift` past the
swiftlint file-length ratchet (which the project deliberately doesn't
raise to absorb growth), and the project already splits large test
groups out this way (`PruneSelectionTests.swift`,
`ImageStalenessTests.swift`).

## Test plan
- [x] `xcodebuild build` succeeds
- [x] `BerthlyTests` suite passes, including new `isAtLeast` coverage
- [x] `BerthlyUITests/ContextMenuTests` passes (all 15 tests, mock mode)
- [x] `swiftlint lint --strict` — 0 violations

Fixes #107
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]: add container export for running containers.

2 participants