Commit Graph
57 Commits
Author SHA1 Message Date
Dmitry Kovba a829fdcdfd Improve log and error messages (#352)
Improved log and error messages.
2025-10-27 09:21:54 -07:00
J Logan 3897e578c3 Use exact permissions for socket mount into guest. (#362)
- Closes #361.
2025-10-25 22:19:06 -07:00
Dmitry Kovba c7af5b8222 Rename process to command (#354)
Rename `process` to `command` (assuming we agree on the change).
2025-10-24 13:27:56 -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
Dmitry Kovba 57ad7ad629 Throw an error in StandardIO.resize() (#350)
Throw an error in `StandardIO.resize()`, which is unsupported.
2025-10-24 12:52:58 -07:00
Dmitry Kovba 2dbba786d2 Use a protocol type instead of the concrete type (#353)
Use a protocol type instead of the concrete type.
2025-10-24 12:49:03 -07:00
Dmitry Kovba 9f5aaf247a Remove an unnecessary function (#351)
Remove an unnecessary function to simplify the code.
2025-10-24 11:48:55 -07:00
Dmitry Kovba a405d88e6d Throw an error for an empty array (#349)
Throw an error for an empty array before accessing the first element.
2025-10-24 11:19:25 -07:00
Dmitry Kovba 3d7bb7bb5c Fix log metadata when starting a process (#345) 2025-10-23 13:28:21 -07:00
Danny Canter 21d0c799b8 Add runc process launch wrapper (#333)
Somewhat simple and missing events and some other bits I believe, but
it's a start. Maybe should use the async subprocess type as well instead
of our homegrown Command.
2025-10-16 14:24:25 -04:00
Kathryn Baldauf e283e023ab Use container's environment when starting the init process (#329)
Fixes an issue first described in
https://github.com/apple/container/issues/740.

Previously the initial process of the container was using vminitd's
environment variables to find the target executable. This PR updates the
code to use the container's configured environment for the initial
process instead. The behavior of an exec in a container should be the
same as before.

Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
2025-10-13 21:33:18 -07:00
Danny Canter 40727e49ba Vminitd: Write cgroup limits (#322)
Fixes #320

Today we don't actually setup any cgroup limits, as because there's a
1-1 mapping from container<->vm we can just use the VMs resources as the
limit (can't use more than 1GB if that's all the guest sees :) ).
However, if we ever supported > 1 container in the guest it'd be
necessary to actually setup the cg limits. This change just sets a
memory limit and cpu toggles to match whatever was specific for the
container.
2025-10-09 16:03:40 -04:00
Danny Canter 06d3a37f8d Add support for container statistics (#318)
Closes #138

This rounds up cgroup and network stats (via netlink) and exposes them
via an agent rpc and on LinuxContainer. While this is not an entirely
accurate view into the full resources being used by the container given
the virtualized nature (doesn't account for vcpu, device etc overhead)
it should give an accurate overview of the workload resource usage in
the guest.

This change besides the stated goal also removes the interfaceStatistics
rpc and just moves these network stats into the new containerStatistics
one. Related to that, it also renames the InterfaceStatistics struct to
NetworkStatistics and moves this into ContainerStatistics as a nested
struct.
2025-10-08 10:09:10 -04:00
J Logan 995a231348 Removes "all rights reserved" from license header. (#309) 2025-10-03 13:27:59 -07:00
Danny Canter 80e2813bcf Netlink: Add stats support (#308)
Adds support for grabbing stats for an iface. This will be surfaced in a
coming change to get container level statistics from the guest, where
one field will be network stats.
2025-10-03 12:53:35 -07:00
Danny Canter 183255ee0e Vminitd: Add cgroup stats support (#306)
This is not wired up to anything right now, but it will be used for
implementing stats gathering on the host via an rpc in the future. I've
left off the rpc portion as this is already a decent amount to review.
2025-10-01 11:26:45 -04:00
Danny Canter 82f2d887dd LinuxContainer/LinuxProcess: Have wait return ExitStatus (#300)
Have wait return a struct containing the exit code and the time at which
the process actually exited. This is useful so higher level tools (like
container) don't need to craft a date themselves, and it will be more
accurate as it's taken in the guest directly after the process exits.
2025-09-29 14:09:37 -04:00
Danny Canter 13e74cd99a Vminitd: Remove some fatalError's (#290)
No reason they need to be as destructive.
2025-09-18 10:42:15 -04:00
Danny Canter b422e036da ContainerizationOS: Rework User type (#279) 2025-09-04 18:16:17 -07:00
Agam Dua 4099bdccd6 vminitd: Removed extraneous import (#276)
We shouldn't need this import anymore

cc: @crosbymichael

Signed-off-by: Agam Dua <agam_dua@apple.com>
2025-08-26 09:36:44 -07:00
Danny Canter df2425ef7f vminitd: Wait for execvpe to return to continue (#275)
Today, because we don't wait for execvpe to finish to continue onwards,
it's possible that if you did an exec quick enough after starting an
init process for a container, that you could join the init processes
namespaces before pivot_root has taken place which is quite fun. Let's
wait for exec to finish (or an error to occur) to prevent this.
2025-08-26 09:34:13 -07:00
Danny Canter 48e2f412b3 vminitd: Log spec for exec processes (#274)
We had a log for the initial oci runtime spec, but we don't log anything
for execed processes. This makes it hard to look into issues that may be
due to just a mistake in the spec and nothing wrong with the actual
logic of the program.
2025-08-25 12:26:35 -07:00
Danny Canter 53021bec36 Cgroup2Manager: Various adjustments (#270)
Systemd loves to move the root cgroups processes to one it created named
/init.scope and then write the root cgs subtree_control file. Because of
this we can't just add exec processes to the cg we made for the
container anymore as we'll get EBUSY. We should follow where the init
processes cg is actually at (/proc/pid/cgroup) and add it there.
2025-08-19 17:31:51 -07:00
Danny Canter 2f32e36a0d Cgroup2Manager: Fix error log mistake (#269)
I accidentally made the creation log error level. Additionally adds a
log to deletion of the cg.
2025-08-18 12:19:55 -04:00
Danny Canter 531ccd6205 vminitd: Rename CgroupManager -> Cgroup2Manager (#266)
To be more explicit.
2025-08-13 20:16:03 -04:00
Danny Canter 79e07b43ce vminitd: Add init and execs to cgroup (#265)
We currently weren't doing any cgroup setup whatsoever. For the most
part this doesn't matter too much, however certain images that may fool
around with cgroups don't like this :). Lets do the bare minimum these
expect which is to at least have the process running in a nested cg and
not apart of the root cg.
2025-08-13 12:58:49 -04:00
Danny Canter 985dac83e5 vminitd: Proper pty setup / mount /dev/console (#248) 2025-08-12 20:03:27 -04:00
Danny Canter 87541cbe65 Agent: Add and implement writeFile (#259)
This change adds in a new rpc that we probably should swap to for the
underlying implementation of a couple rpcs we currently have. This new
rpc simply writes to an existing or new file some data. This is useful
for guest (and container) setup for things like /etc/hosts,
/etc/resolv.conf, writing to one-off cgroup files and so on.

Currently I've just implemented subtree_control toggling for the root cg
in standardSetup with this new change, but in the future I'd like to
swap the implementations of our /etc/hosts and /etc/resolv.conf logic
with this.
2025-08-11 12:33:30 -04:00
Danny Canter 88aeffe4db Add /dev/rtc symlink (#252)
Closes #251

We use devtmpfs today so our pal /dev/rtc0 is there. It's typical to
have a /dev/rtc symlink to /dev/rtc0.
2025-08-07 13:09:57 -04:00
Dmitry Kovba 14482784db Ensure mutable properties aren't accessed outside their intended thread-safe usage patterns (#247)
This PR modifies the access level of certain mutable properties to
ensure their thread-safe usage. It doesn't address
https://github.com/apple/containerization/issues/246 at this time.
2025-08-06 18:44:27 -07:00
Danny Canter b2b2d41d77 Revert "Vminitd: Remove special cased /run mount (#233)" (#253)
This reverts commit 5f7dcd2a16. Rosetta is
setup at /run because the guest rootfs is ro, and unfortunately this
happens prior to LinuxContainer getting to mount any of this. I'm not
super happy about this, but we can figure something out later.

Additionally this adds a rosetta flag to cctl so we can quickly
spotcheck things like this again.
2025-08-06 17:34:00 -07:00
Dmitry Kovba d512fcb7cc Transition to actors (#225)
Due to the reduced use of the macro, we can now fully transition to
`Mutex`.
2025-07-29 08:10:48 -04:00
Danny Canter 5f7dcd2a16 Vminitd: Remove special cased /run mount (#233)
Revisiting this, I'm not a huge fan of having /run be special cased for
some reason
2025-07-25 09:43:48 -07:00
Danny Canter c4b6b68ce7 LinuxContainer: Add /etc/hosts writing functionality (#207)
Closes #206 

Much like we have support for supplying DNS configurations and writing
out /etc/resolv.conf, this adds a way to write out /etc/hosts for a
given container.
2025-07-18 00:54:18 -07:00
Dmitry Kovba 197e9b63a9 Use Mutex for thread-safe access to structs (#208)
Changes in this PR prevent a race caused by an implicit call to a
computed property getter when updating the property value.
2025-07-11 15:45:27 -07:00
Danny Canter f254f48bfc LinuxContainer: Add ability to close stdin (#201)
This allows the user the ability to raise an EOF for the containers
stdin. Today there's no way to close stdin so something as simple as
"cat" and relying on EOF to move the process forward doesn't work
2025-07-08 18:38:04 -07:00
Raj ad219fecf1 Make MTU configurable for Netlink (#204)
Here we add the implementation to make MTU value configurable instead of
hardcoding in `linkSet`.
2025-07-08 15:54:57 -07:00
Danny Canter 9775528495 Vminitd: Rework ManagedProcess.IO protocols (#194)
I think the way these types were structured made reasoning about them a
bit difficult. I don't think this fully solves the problem, but this
change aims to make things a bit simpler by hoisting a lot of the logic
for the IO relays to a new IOPair type thats goal is to simply take in a
reader and writer and handle their resource cleanup after a relay
finishes. Bundled in with this is also the buffer we'll use to copy
between them.

This change:

- Alters ManagedProcess.IO `start` to take in the process to alter
instead of this just being a side effect of the constructors.
- Gets rid of `close()` in favor of `CloseStdin`. The IO will get closed
when the relays finish, which will naturally happen if the process exits
or just closes its side of the pipes/pty. This makes it so that the one
special case (a client wants to signal no more input is coming) is still
sane.
- Move all relay logic and resource cleanup to a new IOPair type that
takes in protocols that are easily conformable by all of our various io
types ( Socket, Terminal, FileHandle).
2025-07-03 14:11:29 -07:00
Dmitry Kovba 8573b80fac Use a State struct for mutable properties in Sendable types (#191)
This PR introduces a pattern of grouping mutable properties within the
`Sendable` types, encapsulated within a `State` struct. This approach
enables simultaneous updates to multiple properties and serves as a tool
against reentrancy issues.
2025-07-03 01:19:55 -07:00
Danny Canter 633205f171 Vminitd: Change some process log levels (#192)
The two starting and exiting logs I feel are important enough to get
promoted to info level.
2025-07-02 13:01:28 -04:00
Danny Canter 61b01cc1ee LCShim: Add CZ prefixes/pidfd wrappers (#189)
We should namespace these a bit, and we need pidfd for some upcoming
terminal work. This also just gets rid of syscall2 and replaces with a
pivot_root wrapper.
2025-07-01 02:16:17 -07:00
Danny Canter c7763c76cf vmexec: Set perms on stdio (#174)
We don't chown the container's stdio today.
2025-06-27 11:03:21 -04:00
Danny Canter 059ff4033f Makefile: Revert recent reworking (#177)
Reverts f9198d6ff7

We can explore better approaches to some of the targets, but for now
lets revert as it interferes with being able to build even if we have
local changes.
2025-06-26 19:31:46 -04:00
Elijah Wright 538ea78c33 run cleanupRelay only once in TerminalIO and StandardIO (#153) 2025-06-26 12:03:17 -04:00
Danny Canter 2dfabeb4f9 Vminitd: Rework ManagedContainer (#168)
This gets rid of some design decisions that I was not fond of. This
changes the process start for both execs and the init process to happen
internally in the object, as well as makes it so that all exec
functionalities can happen on the container object itself. This allows
us to get rid of the `if request.id == containerID` branches in the
rpcs, and handle this entirely in the object itself using its internal
state.

The existing integration tests should stress this just fine I believe.
2025-06-25 14:07:31 -04:00
Danny Canter 2a96a0d447 Containerization: Always set TERM (#146)
Make sure we always set TERM for containers that ask for a tty. Right
now this handling was spread around in a bunch of spots, but I'd wager
setting it for the client on the host via LinuxContainer/Process is more
sane and already what we do for a lot of the other fields.
2025-06-18 17:00:00 -07:00
Nandha Reddy 35a821f041 fix: vminitd incorrectly overwrites custom HOME environment variable (#136)
## Summary

The vminitd service was using `process.env.contains("HOME")` which
checks for exact string match rather than environment variables starting
with "HOME=".

Since environment variables are stored as `"KEY=value"` strings, the
condition was always false, causing vminitd to always override custom
HOME values even when explicitly provided by the client.

## Changes

- Updates the logic in `vminitd/Sources/vminitd/Server+GRPC.swift` to
use `contains(where: { $0.hasPrefix("HOME=") })` to properly detect
existing HOME environment variables
- Adds regression test `testProcessCustomHomeEnvvar()` to verify that
custom HOME environment variables are preserved when provided by the
client

## Testing

The fix has been tested with the new integration test that:
  - Sets a custom HOME environment variable (`HOME=/tmp/custom/home`)
- Runs a shell command that outputs the HOME variable on the container
runtime
- Verifies the custom HOME value is preserved and not overwritten with
the default

## Environment

  - macOS: 26.0 (25A5279m)
  - Hardware: M4 Pro
  - Xcode: 26 beta
  - Swift: 6.2-dev

Fixes #135
2025-06-17 21:51:11 -07:00
Josh Soref c00ede68c1 fix comment misspellings (#131)
This PR corrects misspellings identified by the [check-spelling
action](https://github.com/marketplace/actions/check-spelling)

The misspellings have been reported at
https://github.com/jsoref/containerization/actions/runs/15662940240/attempts/1#summary-44123291170
The action reports that the changes in this PR would make it happy:
https://github.com/jsoref/containerization/actions/runs/15662940315/attempts/1#summary-44123291367

---------

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2025-06-16 16:06:37 -04:00
Danny Canter 8923495949 Vminitd: Remove unneeded mkdir (#123)
The rootfs should be mounted by this point in oci alteration code.
2025-06-13 21:56:25 -07:00
Aditya Ramani a4a0cdfae1 Add a way to detect if a process' io has completed (#110)
This change adds a new private method `waitIoComplete` on the
`LinuxProcess` type.

This method is called internally when the user calls `wait` for a
process - and it tries to give the IO streams some time to clear their
buffers.

Internally, this method sets up an `AsyncStream` down which an item is
sent when the vsock connection for either stdout/stderr is terminated.
We get this termination signal when the readability handler for the
associated fd fires with a no available data.

Inside the guest - once we are done relaying the IO from the process
into the socket connection, we close the socket fd which triggers the
above.

All this logic is wrapped around a timeout of 3 seconds, just to ensure
the method does not block forever.

---------

Signed-off-by: Aditya Ramani <a_ramani@apple.com>
2025-06-13 11:23:41 -04:00