This PR adds a feature passing resource directory for the plugins.
When a `resources` directory is detected under the plugin's
`installURL`, the path to `resources` directory is passed as an argument
(i.e., `--resources <path>`) to the plugin `start`.
Resource files are distributed and installed together with the
`container` binary.
## Type of Change
- [ ] Bug fix
- [X] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
Plugin developers can convey resource files (e.g., shell scripts) under
the `resources` directory.
## Testing
- [X] Tested locally
- [ ] Added/updated tests
- [ ] Added/updated docs
## Type of Change
- [x] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
Build fails with:
> - note: closure captures reference to mutable var 'self' which is
accessible to code in the current task
> - error: passing closure as a 'sending' parameter risks causing data
races between code in the current task and concurrent execution of the
closure [#SendingClosureRisksDataRace]
## Testing
- [x] Tested locally
- [ ] Added/updated tests
- [ ] Added/updated docs
Same as we'd done with kill.
```
➜ container git:(stop-kill-throw-error) ✗ ./bin/container stop foo bar baz
Warning! Running debug build. Performance may be degraded.
Error: internalError: "failed to stop container" (cause: "notFound: "container with ID baz not found"")
internalError: "failed to stop container" (cause: "notFound: "container with ID bar not found"")
internalError: "failed to stop container" (cause: "notFound: "container with ID foo not found"")
➜ container git:(stop-kill-throw-error) ✗ ./bin/container kill foo bar baz
Warning! Running debug build. Performance may be degraded.
Error: internalError: "failed to kill container" (cause: "notFound: "container with ID foo not found"")
internalError: "failed to kill container" (cause: "notFound: "container with ID bar not found"")
internalError: "failed to kill container" (cause: "notFound: "container with ID baz not found"")
➜ container git:(stop-kill-throw-error) ✗ ./bin/container delete foo bar baz
Warning! Running debug build. Performance may be degraded.
Error: internalError: "failed to delete container" (cause: "notFound: "container with ID foo not found"")
internalError: "failed to delete container" (cause: "notFound: "container with ID baz not found"")
internalError: "failed to delete container" (cause: "notFound: "container with ID bar not found"")
```
## Type of Change
- [x] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
`TestCLIVersion` isn't in the integration test; we should include this.
And update the output to align with the real output.
Follow up #911
## Testing
- [x] Tested locally
- [x] Added/updated tests
- [ ] Added/updated docs
---------
Signed-off-by: ChengHao Yang <17496418+tico88612@users.noreply.github.com>
- Closes#1268.
- The types we were using weren't very usable with Swift 6 structured
concurrency.
- Implements just the subset of records that we use.
- Use notImplemented instead of formatError for unknown record types.
- Use pure actor for LocalhostDNSHandler now that we have sendable
types.
- Use DNSName as key for table lookups in LocalhostDNSHandler and
HostTableResolver.
- Utilize dot-suffixed domain names everywhere in the lookup chain.
- Huge thanks to @manojmahapatra and @katiewasnothere for their
diligent and patient review :D
This PR adds an option in `ContainerCreateOption` to override the root
filesystem of container. When `ContainerCreateOption.rootFsOverride` is
set, container uses that as the root fs instead of the one cloned from
image snapshot.
## Type of Change
- [ ] Bug fix
- [X] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
[Why is this change needed?]
## Testing
- [X] Tested locally
- [ ] Added/updated tests
- [ ] Added/updated docs
This reverts commit 50900938c4, restoring
the grpc-swift-1 based builder API while preserving build secrets and
hidden docker dir support added in a00ec5c.
Signed-off-by: Eric Ernst <eric_ernst@apple.com>
## Type of Change
- [x] Bug fix
- [ ] New feature
- [x] Breaking change
- [ ] Documentation update
## Motivation and Context
Adds backward-compatible JSON decoding/encoding fallback for
`Attachment` and `NetworkStatus` to prevent `keyNotFound` errors when
communicating with older `container-apiserver` versions.
Temporary fix but closes#1196
## Testing
Tests ✅ based on comment
[here](https://github.com/apple/container/issues/1196#issuecomment-3902754548)
---------
Co-authored-by: Ed Saipetch <ed@twentybelow.com>
This PR fixes `container build` to use docker specific ignore (#1169).
This PR relies on apple/container-builder-shim#68.
When docker specific ignore file is detected, it creates a hidden docker
directory (i.e., `.hidden-docker-dir`) under the build context, and
places Dockerfile and ignore file under there. This hidden directory is
passed to the builder shim and used by buildkit daemon to correctly
figure out the docker specific ignore file.
Docker specific ignore file is detected regardless of whether i) they
are under nested directory, ii) outside build context, iii) using custom
names. If docker specific ignore is not provided, hidden directory is
also not created, and buildkit daemon will use the docker ignore file at
build context root as usual.
## Type of Change
- [X] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
Docker specific ignore works.
## Testing
- [X] Tested locally
- [ ] Added/updated tests
- [ ] Added/updated docs
- Closes#1308.
- Applies dependency and code changes similar to
apple/containerization#578.
- Upgrades hawkeye to latest version.
- Update StderrLogHandler not to create a (non-Sendable) Swift time
formatter object for every log message.
This PR reaps already running containers with auto remove flag on
container system start.
Container API server shutdown ideally should stop every running
container, and reap the containers with auto remove flag. However, crash
or unexpected exit of API server leaves the containers running. In such
case, next system start should stop running containers (i.e., launchd
services) and reap the containers with auto remove flag.
## Type of Change
- [X] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
Preserve the system to be in a consistent state after unexpected
failure.
## Testing
- [X] Tested locally
- [ ] Added/updated tests
- [ ] Added/updated docs
---------
Co-authored-by: Raj <realrajaryan@gmail.com>
- Closes#1252 (part of #913).
- Commands that accept `--platform` currently require it
to be passed explicitly every time. Users working
consistently with a non-native platform (e.g. `linux/amd64`
on Apple Silicon) have no way to set a default, unlike
Docker's `DOCKER_DEFAULT_PLATFORM`.
- This adds support for the `CONTAINER_DEFAULT_PLATFORM`
environment variable as a fallback when `--platform` is not
explicitly provided.
- Previously we weren't tolerating a throw from
the check.
- We have #1250 open for root cause analysis of
this particular throw that trips the test up.
This PR fixes#1277.
`SandboxService.waiters` had a consistency issue (not exactly race).
`SandboxService.wait` XPC can be executed on arbitrary `id`, and it will
hang forever if no other handler resumes it. Without knowing this
internal, the high level entity can run into this issue, and deadlock.
This PR simplifies the mental model: **`SandboxService.waiters[id]:
ExitWaiter(continuations, exitCode)` can only be in three states: i)
non-existing, ii) existing with nil `exitCode`, and iii) existing with
concrete `exitCode`.**
**If it is non-existing, no handler has been registered to resume it
later. If existing with nil `exitCode`, It is guaranteed the registered
`continuations` will be resumed later with a concrete `exitCode`.
Finally, if already a concrete `exitCode`, a handler has been
registered, and already resumed (with that `exitCode`).**
Thus, `SandboxService.wait` should return immediately if `waiters[id]`
is non-existing or existing with a concrete `exitCode` (as no handler
will resume it later). It should only block when `waiters[id]` is
existing with nil `exitCode` as it is guaranteed to be resumed later. By
doing so, we can guarantee there is no deadlock at all.
For that this PR does followings:
1. Introduce `ExitMonitor` class to updates `continuations` and
`exitCode` all together atomically. Initially, `state` variable saved
the `exitCode`, but it cannot be tied with `continuations` as they are
protected by different primitives (i.e., lock and actor).
2. Gather `waiters` related operations into a single actor method,
guaranteeing those are performed atomically under actor
protection---i.e., we actually don't need Mutex here.
3. Ensure initialized `waiters` are released (i.e., resumed) later
(under any possible circumstances).
4. Move `process.wait` after `process.start` in `io.handleProcess` to
run `SandboxService.wait` only after the `waiters[id]` is initialized.
By doing fourth step, we can guarantee `SandboxService.wait` can meet
only one of two following `ExitMonitor` state: i) existing with nil
`exitCode`, or ii) existing with concrete `exitCode` (in case the
process exited too early). In both cases, `exitCode` is preserved and
returned.
## Type of Change
- [X] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
[Why is this change needed?]
## Testing
- [X] Tested locally
- [ ] Added/updated tests
- [ ] Added/updated docs
Fix container hang when starting an invalid executable (#1277).
Ensure the `SandboxService.waiters` updated atomically, preventing a slow `wait` from registering continuation after the `SandboxService` has been stopped.
Current `ProcessIO.handleProcess` has races between `process.wait()` and
`process.start()`. In `process.wait`, `SandboxService.wait` registers
and block on a continuation so that later exit of that `LinuxContainer`
can resume it.
Even if `SandboxService.wait` checks the container state, there can be a
race so that `SandboxService.startInitProcess` fails earlier with no
continuation to resume, then `SandboxService.wait` registers the
continuation, which forever hang the thread.
- Closes#1270.
- The current test is a bit baroque. It tries to run `nc`, either to
`8.8.8.8:53` or a proxy server port if `HTTP_PROXY` is in the
environment. It seems that for an alpine image, a proxy-aware
`Dockerfile` and a `RUN apk install curl` directive is a more natural
test of "network access".
- Current DirectoryWatcher fails if `/etc/resolver` does not exist. This
PR fixes DirectoryWatcher to handle non-existing `/etc/resolver`
directory. If that directory does not exist, it first watches `/etc`
directory to check if `/etc/resolver` directory is created later. Once
it detects new `/etc/resolver` directory, it starts watching new DNS
resolver files there.
- This PR also fixes to log the exception thrown by API server's tasks.
- Closes#1207
Closes#1225
Add a flag to signify that we'd like to run a minimal init process that
can reap zombie processes. The actual support for this is in the
Containerization library so the plumbing here is very simple.
- This reverts commit 1942a399e3.
- This approach to getting variant into the runtime helper was fine for
proof of concept work but we need a persistent runtime config file so
that the variant is available for `container start`.
- Adds plugin variant selection to bootstrap() on the Container API
service in such a way that we can revert the change soon without
compatibility issues when we work out a more permanent approach, and
requires no persistent data migration.
- Restore lexical ordering on ManagementFlags (except `--runtime`, will
take care of that next PR).
- Add a couple plugin loader tests to improve coverage.
## Type of Change
- [x] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
As reported in [1212](https://github.com/apple/container/issues/1212),
environment variables defined in a Dockerfile (ENV) were not being
overridden when passed via -e at runtime, resulting in duplicate entries
in the container's environment.
**Root cause:** `Parser.allEnv()` simply merged image, env-file, and
user-provided environment variables without deduplication. Since
`getenv()` returns the first match, the image default took precedence
over the user override.
**Fix:** `allEnv()` now deduplicates by key, with later sources
overriding earlier ones
## Testing
- [x] Tested locally
- [x] Added/updated tests
- [ ] Added/updated docs
- Closes#1236.
- As with other resources, default to tabular output, with `--format
json` alternative.
- Also changes common workflow to collect logs even when test step times
out.