[Request]: `cp` command tar stream support
- Dominant language
- Swift
- Stars
- 49.9k
- Forks
- 1.8k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 22
Description
### Feature or enhancement request details
## Request
Please add tar stream support to `container cp`, matching the common `docker cp`/`podman cp` pattern where `-` can be used as stdin/stdout for a tar archive:
```sh
container cp CONTAINER:/path -
container cp - CONTAINER:/path
```
At a minimum this would include support for uncompressed tar streams. Docker, for example, supports compressed tar stream inputs, but doesn't call that out in their API documentation so it's probably reasonable to consider it optional.
## Background
The original `cp` request was tracked in:
- #232
The basic `container copy` / `container cp` command was added by:
- #1190
However, #1190 intentionally avoided requiring tar support inside the container image by using guest-agent copy operations. That solves ordinary file/directory copy, but it does not cover the tar stream mode described in the original issue.
The earlier discussion in #232 called out the main blockers for tar stream support:
- https://github.com/apple/container/issues/232#issuecomment-3063076085
- https://github.com/apple/container/issues/232#issuecomment-3064247728
Those comments described an intended design where one side creates a tar archive, streams it through the vminit/vminitd boundary, and the receiving side unpacks it. They also noted that Swift lacks standard library support for tar operations and that the existing `ContainerizationArchive` library depends on native libraries that were not available in the Swift Linux SDK build used for `vminitd`:
```text
ld.lld: error: unable to find library -lbz2
ld.lld: error: unable to find library -llzma
ld.lld: error: unable to find library -larchive
```
## Why tar stream support matters
While basic `cp` operations can transfer file contents, they only work with files that exist on the host filesystem and can end up preserving host-side metadata such as ownership and permissions which may not be correct in the container. Tar streams allow copying in files from memory and give full control over the mode and ownership of the files in the container. Effectively the tar stream can be thought of as a dynamic image layer applied to the container filesystem. This is something that makes `cp` much more powerful than a basic bind mount.Combined with the fact that `cp` is applied _after_ volume are attached, it's the only way to reliably inject files into a container without worrying that they'll be shadowed by a volume mount.
Basic `cp`, bind mounts, and init container volumes are not a suitable alternative because they can leak host-side metadata, shadow image contents, or require container-specific entrypoint wrapper logic. Relying on `tar` inside the target image is also not sufficient because minimal images may not include a tar binary.
We make heavy use of `cp` tar stream support in the Aspire orchestration framework (https://github.com/microsoft/aspire) to inject certificates and config files into containers with the correct ownership and permissions. We want to add the Apple container runtime as a supported backend for Aspire on macOS, but lack of tar stream support in `container cp` is a blocker for that work. We're tracking features required for parity with our Docker and Podman support in a tracking issue on our core orchestration repo: https://github.com/microsoft/dcp/issues/206.
## Proposed behavior
Support `-` as a tar stream source or destination:
```sh
# stream a tar archive out
container cp my-container:/some/path - > files.tar
# stream a tar archive in and extract it
container cp - my-container:/some/destination < files.tar
```
Suggested initial scope:
- uncompressed tar only
- regular files
- directories
- symlinks
- basic modes
- uid/gid where possible
- safe path handling: reject absolute paths, `..` traversal, and malformed headers
- clear error for compressed tar streams or unsupported tar features
Future optional scope:
- gzip/zstd/etc stream filters
- hardlinks
- sparse files
- xattrs/ACLs
- broader GNU/PAX compatibility
## Implementation options
There seem to be two possible implementation paths (as called out in the original `cp` support issue).
### Option 1: Swift tar implementation
Implement enough tar reader/writer support in Swift for the required uncompressed tar subset.
Pros:
- avoids new native dependencies in `vminitd`
- keeps the guest runtime build simpler
- supports the minimum Docker-compatible tar stream behavior
- compression can be layered later as optional stream filters
- avoids depending on tools inside the container image
Cons:
- introduces new archive parsing/extraction code
- needs careful security review for path traversal, symlinks, ownership, and overwrite behavior
- needs compatibility tests for tar variants such as ustar/pax
- may duplicate some functionality already available through `ContainerizationArchive`
### Option 2: enable native libarchive support for vminitd
Update the vminitd/Linux SDK build so `ContainerizationArchive` can be used on the guest side.
Pros:
- reuses existing archive infrastructure
- likely broader tar compatibility
- compression and other archive features may become easier to support
- avoids maintaining a separate tar implementation
Cons:
- adds native dependency/build complexity
- requires packaging or linking `libarchive`, `libbz2`, `liblzma`, etc.
- increases maintenance surface for dependency updates and CVEs
- may be heavier than needed if the required feature is only uncompressed tar streams
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Research direction
Start with the existing container cp implementation from #1190 and the vminit/vminitd boundary, then review the linked #232 discussion about archive handling and ContainerizationArchive. Completion should cover uncompressed tar input and output for -, including regular files, directories, symlinks, modes, uid/gid, and safe path rejection, with clear errors for compressed or unsupported streams.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- backend, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100