Commit Graph
174 Commits
Author SHA1 Message Date
GAUTAM RAJU 031cd72e2a Implement pdeathSignal handling in Runc (#431)
Add support for parent death signal (pdeathSignal) to ensure child
processes receive a signal when the parent process dies. This addresses
the FIXME comment in Runc.execute().

## Changes
- Add pdeathSignal field to exec_command_attrs C struct
- Implement prctl(PR_SET_PDEATHSIG) in child process handler (Linux
only)
- Expose pdeathSignal through Command.Attrs Swift API
- Wire up pdeathSignal in Runc.execute() to remove FIXME

## Implementation Details
The implementation uses Linux-specific prctl() to set the parent death
signal, ensuring proper cleanup when parent processes terminate. The
feature is conditionally compiled for Linux only, maintaining
compatibility with other platforms.
2025-12-01 02:35:09 -08:00
Danny Canter 4a8f945f87 vminitd: Add memory threshold monitoring (#427)
Add a small bit of logic to monitor if vminitd goes over a (somewhat
arbitrary) memory threshold. On average, when running one container it
seems to hover around 25MiB, so this is mostly to catch cases where it's
exceeding a limit we don't deem normal.
2025-11-21 14:54:13 -08:00
Raj 35ebe365ba Add calculateOrphanedBlobsSize() to calculate the size of orphaned blobs (#428)
Adds `calculateOrphanedBlobsSize()` to calculate the size of orphaned
blobs, will need this to include them under size and reclaimable space
for images in the `container system df` command so it matches up with
what `container image prune` frees up on disk.
2025-11-21 14:50:28 -08:00
Danny Canter 836b699a91 Wire up experimental OCI runtime support (#416) 2025-11-21 12:16:58 -08:00
Raj 860139bd1a Fix ImageStore.prune() behavior to actually remove images (#420)
- Fixes #417.

Rename `_prune()` to `cleanupOrphanedBlobs()` to clarify what it
actually does, and remove `prune()` method as we'll do all that logic in
container directly.
2025-11-20 15:22:54 -08:00
Danny Canter 79d7e398c1 vminitd client: Remove connection backoff (#423)
For the constructor we're using where we pass an already connected
socket, I'm not sure this even does anything, and if it does that's a
bug I'd rather just avoid altogether.

Also gets rid of the unused constructor we have to pass in a UDS.
2025-11-20 12:00:56 -08:00
RahulThennarasu f31d2005b5 ManagedProcess: Capture vmexec stderr and convert to Containerization Error (#411)
Fixes #277

When vmexec fails, it logs to stderr and exits with code 1. Previously,
the error details were lost. This change captures stderr and converts it
into a proper ContainerizationError.

Signed-off-by: Rahul Thennarasu <rahulthennarasu07@gmail.com>
2025-11-19 23:56:09 -08:00
Kathryn Baldauf 86f5051fe6 Fix compiler errors in socket types when building with glibc (#421)
* on glibc, swift expects that the msg_controllen is type Int
* on glibc, socket shutdown options should be an Int32

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2025-11-19 17:36:38 -08:00
Danny Canter 85a3544750 LinuxContainer: "Harden" stop (#388) 2025-11-16 14:13:41 -08:00
RahulThennarasu 4d47c58a3d Fix: Allow OCI archives without manifest annotations (#397)
Fixes #369

Per the OCI Image Spec, manifest descriptor annotations are optional.
Previously, archives without annotations would fail to import with
"Failed to import image".

**Changes:**
- Modified `getImageReferencefromDescriptor` to return digest-based
references (`untagged@sha256:...`) when annotations are missing
- Removed guard that skipped manifests without annotations
- Added test case with `scratch_no_annotations.tar`

**Testing:**
All 167 tests pass, including new test for images without annotations.
2025-11-15 00:32:15 -03:00
Danny Canter 4c761d50c6 Add new FileHandle option for serial console output (#410)
Taking in a filehandle gives the user quite a bit more freedom on how to
handle boot log output. They can set up a kqueue watch on it and
redirect output somewhere else etc etc. The implementation for this has
us take in a new BootLog type that has two options:

1. .file, which is analogous to what we had prior. Just provide a URL
and a true by default append field.
2. .fileHandle which is the new addition. Can pass any fd that is
writable, and the VMM should write serial console output to it.
2025-11-14 10:40:32 -08:00
Danny Canter b501931267 Integration: Actually run testContainerStopIdempotency (#409)
We (I) forgot to add it :)
2025-11-13 14:37:42 -08:00
Danny Canter c8549315ed LinuxContainer: Keep reference to vended execs (#408)
This change is aimed at making forgetting to call .delete() on a
LinuxProcess less destructive than it can be. Because Virt.framework
invalidates any vsock fds it vended if the vm is stopped, trying to
perform some operations on the grpc client through any of the process
methods could trigger an ebadf, which NIO asserts on. This keeps a
reference to the execs and deletes all of them for you once the
container dies. I still think leaving .delete a public method is useful
as otherwise the stdio fds are left open, but cleanup should occur all
in one place now if you don't care about this.

This additionally:

1. Fixes two of our tests that forgot to delete() an exec.
2. Adds two new tests to verify that process.delete() is now idempotent,
and we don't need to call delete().
2025-11-13 02:13:09 -08:00
Danny Canter 322a724024 VZVirtualMachineInstance: Remove tracking agent conns (#403)
This was added to try and see if it alleviated the infrequent ebadf nio
panics, but they still occur, so back to the drawing board :)
2025-11-12 14:37:04 -08:00
Dmitry Kovba b94be374ae Set the default PATH and fix the bug in retrieving the PATH value (#383)
- We're already setting the default `HOME` and `TERM`. Setting the
default `PATH` as well seems reasonable.
- This PR also fixes the bug in retrieving the `PATH` value (`PATH=` has
to be removed, and `=` should be allowed in folder names).
2025-11-12 15:48:02 -03:00
J Logan 6bf00ad796 Make socket proxy logging less chatty. (#405)
- Move data transfers to trace level.
- Move shutdown errors to warning.
- Only log listen, connect, and cleanup at info.
2025-11-12 09:45:30 -08:00
Danny Canter 01437a44a2 Vminitd: Sync(2) on shutdown (#400) 2025-11-12 09:39:46 -08:00
Danny Canter bbe9ebd8fa TimeSyncer: Amend some bits (#404) 2025-11-12 09:39:26 -08:00
Danny Canter a31abd73a4 Vminitd: Remove unused method (#401) 2025-11-12 09:39:00 -08:00
Danny Canter 8a9b0deb82 LinuxProcess: Swap from logging in delete (#386)
This changes LinuxProcess to not just log errors but return them.
2025-11-11 14:42:41 -08:00
Danny Canter cfe4fd77cb Socket: Return Int32 and not FileHandle for uds receives (#398)
Gives more flexibility. The caller doesn't need to carry around this
FileHandle object if they don't really need it.
2025-11-10 15:48:06 -08:00
Danny Canter 4855310dca OCI: Don't umount the rootfs path if it's not a mountpoint (#387)
Given this package is generic, and we use it in the guest where today we
actually umount via an rpc, just skip this if it's not a mountpoint.
2025-11-07 14:25:34 -08:00
Danny Canter 3de29338e1 Integration: Add stdio ingest test (#385)
Add a test to ingest 200MiB of data across stdout/stderr. Useful to test
how fast we can ingest stdio. The timing will always be a tad off as it
times between start and wait returning, and there's quite a lot in the
way.. but it's a good enough metric.
2025-11-07 11:08:01 -08:00
Danny Canter 619354ef74 Don't ignore possible errors from dup(2) (#382)
Everytime we grab a vsock connection we dup the conn and close the
original, otherwise we'd need to carry around the vsock connection type
everywhere as it closes the fd in its destructor. We weren't checking
the return value of dup however, so if it did fail we'd have a useless
filehandle with an fd of -1.
2025-11-06 15:48:02 -08:00
Raj 52ed5b542c Revert "Add filesystem notification (FSNotify) support" (#384)
Reverts apple/containerization#294. This is causing the CI to break
because of concurrency issues with tests. Let's revert while we
investigate.
2025-11-05 15:06:24 -08:00
Raj 80e84a9ce1 Add filesystem notification (FSNotify) support (#294)
Addresses apple/container#141, where containers don't receive filesystem
events on mounted volumes, preventing incremental rebuilds and other
file-watching features. This PR implements the guest-side components for
FSNotify. Host-side implementation in the container repo will complete
the pipeline.

Summary:
- Add gRPC protocol definitions for filesystem event notifications
- Implement guest-side event handler that generates Linux inotify events
- Add CLI testing tool (`cctl fsnotify`) and integration test
infrastructure
2025-11-05 12:20:15 -08:00
Danny Canter bec1008f4d VsockConnectionStream: Conform to AsyncSequence (#380)
I didn't like how we expose the asyncstream via a public connections
field. We should have the type conform to AsyncSequence and then hide
the underlying stream. This also stops listening on the stdio ports
after we get the initial connection.
2025-11-03 14:09:56 -08:00
Danny Canter 8b39713a00 EXT4: Optimize unpack (#378)
Optimize unpack a little by trying to reduce allocations in the hot
path. Today for every file we read the entire file into memory and then
pass the data blob to the ext4 writer to eventually be written to the
sparse file. Before being written to the sparse file the data is copied
*again* to a temp buffer before finally hitting write(2) in FileHandle.

This change moves things around such that we can pass an optional buffer
to the ext4 create() (so we can reuse a buffer for file writes), as well
as stops reading entire files into memory by passing the archive entry
itself (wrapped in a ReaderStream object albeit) down to the writer.

Testing with unpacking every platform for
`docker.io/jenkins/jenkins:lts` on an M1 Max:

Old Avg (5 runs): 7.43s
New Avg (5 runs): 5.31s
2025-11-03 12:22:38 -08:00
Danny Canter f3d998975c LinuxContainer: Add new constructor (#377)
Add a constructor that allows just passing in a configuration without
doing the closure dance.
2025-10-31 14:27:39 -07:00
Danny Canter 07325561f3 Integration: Add UDS test (#374) 2025-10-30 01:00:54 -07:00
Danny Canter df8b97a9f7 Chore: Use guestVsockPorts (#373)
This was a funny oversight. We have two port spaces, one for listening
sockets on the host, and one for vsock proxies in the guest, but only
the host "allocator" was being used. This didn't really matter as the
ports in the guest would still be unique, but would still be good to
fix.
2025-10-29 16:44:28 -07:00
Mark Baseggio d7814e4421 Make Index.mediaType optional to comply with OCI spec (#368)
The `mediaType` field in the `Index` struct was defined as a required
field, but according to the [OCI Image Index
Specification](https://github.com/opencontainers/image-spec/blob/main/image-index.md),
this field is optional.

This caused failures when loading OCI archives where the `index.json`
omits the top-level `mediaType` field, which is valid per the spec.
Tools like skopeo can generate such archives.

## Error before fix
```
keyNotFound(CodingKeys(stringValue: "mediaType", intValue: nil))
```

## Changes
- Changed `Index.mediaType` from `String` to `String?`
- Updated initializer to accept optional `mediaType` parameter
- Added comment documenting that field is optional per OCI spec

## Testing
Verified that OCI archives without a top-level `mediaType` field in
`index.json` now load successfully.

Fixes https://github.com/apple/container/issues/330
2025-10-29 01:46:16 -07:00
Danny Canter cc66529b59 VirtualMachineManager: Take in EventLoopGroup directly (#367) 2025-10-28 02:24:53 -07:00
Danny Canter 02fa190aeb Always close agent connections (#365) 2025-10-27 21:19:48 -07:00
Danny Canter eb1b8741b5 LinuxContainer/Pod: Remove pause/resume (#366) 2025-10-27 17:33:49 -07:00
Danny Canter 939108b27a VZVirtualMachineInstance: Move some extensions around (#364)
Move the implemention of VirtualMachineInstance to a standalone
extension and all the other helper methods outside of this.
2025-10-27 09:28:25 -07:00
Danny Canter 1b10836c41 VZVirtualMachineInstance: Remove sandbox references (#363)
This type used to be named Sandbox iirc. Remove these references now
that this is no longer the case.
2025-10-27 09:26:05 -07:00
Kathryn Baldauf 1165faabd8 Use correct flag size in Mount for glibc (#360)
The mount flags are defined as `Int`s for musl but as `Int32`s for
glibc, despite the mount methods expecting `Int32` for both. This was
leading to build errors when building with glibc like:

```
 |         "async": .init(true, MS_SYNCHRONOUS),
 |                              `- error: cannot convert value of type 'Int' to expected type 'Int32'
```

This PR allows for different Int sizes based on if we're building for
glibc or not to avoid this build error.

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2025-10-24 17:32:35 -07:00
Kathryn Baldauf 41eda106e3 Only load epoll file if we can import musl (#359)
This class does not work for glibc due to missing flags and methods.
This PR removes the ability to load the `Epoll` class when using glibc
for now.

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2025-10-24 16:48:25 -07:00
Kathryn Baldauf a27fefbb59 Add custom decoder inits for various oci types that use omitempty (#347)
Many fields on the various OCI types use "omitempty" for encoding and
decoding the json representation in golang. This PR adds custom json
decoder functions to allow for behavior similar to "omitempty".

---------

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2025-10-24 15:05:40 -07:00
Danny Canter f697215e54 LinuxContainer: Stop all relays on create failure (#358)
If create fails we don't cleanup the relays we may have setup.
2025-10-24 14:48:26 -07:00
J Logan 6f7601e475 Handle EOF on one side of a UnixSocketRelay. (#323)
- Current implementation shuts down everything as soon as EOF is
detected on DispatchSourceRead for the relay. This is problematic for,
say an HTTP request where the client makes a request, and calls
`shutdown(fd, SHUT_WR)` to close the send side, but it expects to be
able to keep calling `recv()` to get the response.
- Changed cancel handlers so that the one that sees that both sources
have been cancelled then closes both the UDS and vsock fds.
- Updated vminitd VsockProxy to also do `shutdown(fd, SHUT_WR)` for read
hangup or EOF, and only close the underlying fds and unwire pollers on
full hangup, broken pipe, error, or when both sides half-close.
2025-10-24 13:13:13 -07:00
Danny Canter ca657f5009 Always provide a serial console (#346) 2025-10-23 14:32:56 -07:00
Danny Canter dc4284a149 Introduce new experimental LinuxPod type (#343)
Closes #319

Introduces a new type capable of running > 1 container in the guest. The
API mostly follows LinuxContainer, and each individual container can be
addressed via any of the methods that require you to pass the
containerID as the first param. Today there's no support for namespace
sharing, but that shouldn't be terrible to support.
2025-10-23 13:59:58 -07:00
Danny Canter 22f7b6ac13 LinuxContainer: Add bootlog as configuration field (#344)
Closes #227

Previously, the bootlog was supplied once in the constructor to
VZVirtualMachineManager which meant that if you used this same manager
for multiple ctrs that all logs would end up going to the same file,
which becomes quite cumbersome to follow..

This change moves bootlog to be a container configuration param and also
moves it to be a VMConfiguration param, so it can be threaded through
from LinuxContainer -> vmm.create() and be truly container unique now.
The largest driver for this was the integration tests which today every
single test spits out logs to a singular file, making guest
investigations tricky to actually look into.

Result after:
```
➜  containerization git:(bootlog-per-ctr) ✗ ls -alh bin/bootlogs
total 1520
drwxr-xr-x@ 24 dcantah  staff   768B Oct 22 17:34 .
drwxr-xr-x@  8 dcantah  staff   256B Oct 22 17:34 ..
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-cat-mount.log
-rw-------@  1 dcantah  staff    22K Oct 22 17:34 test-cgroup-limits.log
-rw-------@  1 dcantah  staff   249K Oct 22 17:34 test-concurrent-processes-output-stress.log
-rw-------@  1 dcantah  staff   167K Oct 22 17:34 test-concurrent-processes.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-container-devconsole.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-container-hostname.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-container-hosts-file.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-container-manager.log
-rw-------@  1 dcantah  staff    22K Oct 22 17:34 test-container-reuse.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-container-statistics.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-container-stdin.log
-rw-------@  1 dcantah  staff     0B Oct 22 17:34 test-nested-virt.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-pause-resume-io.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-pause-resume-wait.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-pause-resume.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-process-custom-home-envvar.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-process-echo-hi.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-process-false.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-process-home-envvar.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-process-true.log
-rw-------@  1 dcantah  staff    11K Oct 22 17:34 test-process-tty-envvar.log
-rw-------@  1 dcantah  staff    38K Oct 22 17:34 test-process-user.log
```
2025-10-23 03:27:24 -07:00
Danny Canter 1fa051bb69 VZVirtualMachineInstance: Move event loop shutdown slightly up (#342)
This and the work on it should likely be gone before vm shutdown.
2025-10-22 14:35:18 -04:00
Danny Canter 056a909081 VirtualMachineManager: Rework protocol (#341)
Today this protocols create method is just odd. Our only implementation
of it immediately casts to LinuxContainer, failing if it cannot do so. I
think what might make more sense is to pass in a configuration itself
with core parameters that we expect every vmm to be able to support, and
then in a specific implementation they can continue to cast this type to
a specific one to possibly extract some extra configuration values
(rosetta for VZ for example).

This rework will also make it simpler to support a Pod type, as the vm
setup is identical and simple.
2025-10-21 01:23:00 -07:00
Danny Canter 4f996d3509 LinuxContainer: Move Process type out of Configuration (#340)
As a first step to making a pod type, move the nested process
configuration out of LinuxContainer.Configuration.Process and into a
standalone LinuxProcessConfiguration type.
2025-10-20 10:52:48 -07:00
Kathryn Baldauf 09da9205c6 Make vmm create protocol async (#338)
The `vmm.create` call is already made within an async function. This PR
updates the protocol to allow other vmm implementations more flexibility
in `create`.

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2025-10-17 14:54:57 -07:00
Kathryn Baldauf a14fd26a24 Add fallback to use lstat to get file permissions in archive writer (#337)
Allow different path for getting file permissions in archive writer,
gated by OS check

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2025-10-16 16:04:00 -07:00