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.
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.
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.
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.
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.
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.
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.
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
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).
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.
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.
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.
Until 6.2 officially releases lets pin to a static version of the 6.2
snapshots. The Linux SDK and swift version must be aligned so this
should be less fickle than using `6.2-snapshot` as this is a friendly
identifier to choose the latest uploaded snapshot.
fixes#165
`init` depends on `vminitd/bin/vminitd`, `vminitd/bin/vmexec`, and
`bin/cctl`
`integration` depends on `bin/containerization-integration`
`bin/*` get generated via `make containerization`
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.
Currently, when a user runs `make cross-prep`, we install the latest
version of Swift. This requires installing the latest version of Static
Linux SDK, which we should update as a new version is released.
This PR resolves the following error for new users:
```
% make cross-prep
Installing Swiftly...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 8549k 100 8549k 0 0 14.7M 0 --:--:-- --:--:-- --:--:-- 14.8M
installer: Package name is
installer: Installing at base path /Users/Dmitry
installer: The install was successful.
Welcome to swiftly, the Swift toolchain manager for Linux and macOS!
Please read the following information carefully before proceeding with the installation. If you
wish to customize the steps performed during the installation process, refer to 'swiftly init -h'
for configuration options.
Swiftly installs files into the following locations:
/Users/Dmitry/.swiftly - Directory for configuration files
/Users/Dmitry/.swiftly/bin - Links to the binaries of the active toolchain
/Users/Dmitry/Library/Developer/Toolchains - Directory hosting installed toolchains
These locations can be changed by setting the environment variables
SWIFTLY_HOME_DIR, SWIFTLY_BIN_DIR, and SWIFTLY_TOOLCHAINS_DIR before running 'swiftly init' again.
For your convenience, swiftly will also attempt to modify your shell's profile file to make
installed items available in your environment upon login. This can be suppressed with the
'--no-modify-profile' option.
Proceed? (Y/n):
Installing swiftly in /Users/Dmitry/.swiftly/bin/swiftly...
Error: The file “swiftly” couldn’t be opened because there is no such file.
make[1]: *** [swiftly] Error 1
make: *** [cross-prep] Error 2
```
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.
## 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
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>
Fixes#103 (and should fix
https://github.com/apple/container/issues/108)
Today we only parse if the username field of the runtime spec is set,
but this misses if someone just supplied the integer uid and gid fields
only.