chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# Copyright © 2025-2026 Apple Inc. and the Containerization project authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# ctr-example Makefile
|
||||
|
||||
SWIFT = /usr/bin/swift
|
||||
|
||||
UNAME_M := $(shell uname -m)
|
||||
KERNEL_ARCH := $(if $(filter $(UNAME_M),aarch64 arm64),arm64,$(UNAME_M))
|
||||
|
||||
.PHONY: all build clean run
|
||||
|
||||
all: run
|
||||
|
||||
build:
|
||||
$(SWIFT) build --configuration release
|
||||
codesign --force --sign - --entitlements ctr-example.entitlements ./.build/release/ctr-example
|
||||
cp ./.build/release/ctr-example ./ctr-example
|
||||
|
||||
clean:
|
||||
$(SWIFT) package clean
|
||||
rm -f ./ctr-example
|
||||
|
||||
run: build
|
||||
./ctr-example
|
||||
|
||||
# Development targets
|
||||
debug:
|
||||
$(SWIFT) build
|
||||
codesign --force --sign - --entitlements ctr-example.entitlements ./.build/debug/ctr-example
|
||||
|
||||
fmt:
|
||||
$(SWIFT) format --in-place --recursive Sources/
|
||||
fetch-default-kernel:
|
||||
$(MAKE) -C ../.. fetch-default-kernel
|
||||
cp -L ../../.local/vmlinux-$(KERNEL_ARCH) ./vmlinux-$(KERNEL_ARCH)
|
||||
@@ -0,0 +1,267 @@
|
||||
{
|
||||
"originHash" : "f9b523ded39c0fa3565fd16d3b4097384449d541048751be7efee4a43af79fd4",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "async-http-client",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/swift-server/async-http-client.git",
|
||||
"state" : {
|
||||
"revision" : "7744c2a035c68ec14726c709f031835e3e30bde1",
|
||||
"version" : "1.34.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "containerization",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/containerization.git",
|
||||
"state" : {
|
||||
"revision" : "9275f365dd555c8f072e7d250d809f5eb7bdd746",
|
||||
"version" : "0.33.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "grpc-swift-2",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/grpc/grpc-swift-2.git",
|
||||
"state" : {
|
||||
"revision" : "21fe69ab7ce0e87ac089534733c52f037e74a3eb",
|
||||
"version" : "2.4.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "grpc-swift-nio-transport",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/grpc/grpc-swift-nio-transport.git",
|
||||
"state" : {
|
||||
"revision" : "e7d463749f9037b047dcd6da4e633718ddc432b8",
|
||||
"version" : "2.8.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "grpc-swift-protobuf",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/grpc/grpc-swift-protobuf.git",
|
||||
"state" : {
|
||||
"revision" : "b05885fa9bdd88f1eab2e7162f1ee81340b0da33",
|
||||
"version" : "2.4.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-algorithms",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-algorithms.git",
|
||||
"state" : {
|
||||
"revision" : "87e50f483c54e6efd60e885f7f5aa946cee68023",
|
||||
"version" : "1.2.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-argument-parser",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-argument-parser.git",
|
||||
"state" : {
|
||||
"revision" : "6a52f3251125d74daf04fcbd5e6f08a75d074382",
|
||||
"version" : "1.8.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-asn1",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-asn1.git",
|
||||
"state" : {
|
||||
"revision" : "a9a5efd40eaf558a2bcd48d64b1d1646be686008",
|
||||
"version" : "1.7.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-async-algorithms",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-async-algorithms.git",
|
||||
"state" : {
|
||||
"revision" : "d0b4a06d0f173a2f3be27d3ea21b3c3aa18db440",
|
||||
"version" : "1.1.4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-atomics",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-atomics.git",
|
||||
"state" : {
|
||||
"revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7",
|
||||
"version" : "1.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-certificates",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-certificates.git",
|
||||
"state" : {
|
||||
"revision" : "bde8ca32a096825dfce37467137c903418c1893d",
|
||||
"version" : "1.19.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-collections",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-collections.git",
|
||||
"state" : {
|
||||
"revision" : "a0cb0954ecb21e4e31b0070e6ed5674e8556685a",
|
||||
"version" : "1.6.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-configuration",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-configuration.git",
|
||||
"state" : {
|
||||
"revision" : "be76c4ad929eb6c4bcaf3351799f2adf9e6848a9",
|
||||
"version" : "1.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-crypto",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-crypto.git",
|
||||
"state" : {
|
||||
"revision" : "95ba0316a9b733e92bb6b071255ff46263bbe7dc",
|
||||
"version" : "3.15.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-distributed-tracing",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-distributed-tracing.git",
|
||||
"state" : {
|
||||
"revision" : "dc4030184203ffafbb2ec614352487235d747fe0",
|
||||
"version" : "1.4.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-http-structured-headers",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-http-structured-headers.git",
|
||||
"state" : {
|
||||
"revision" : "933538faa42c432d385f02e07df0ace7c5ecfc47",
|
||||
"version" : "1.7.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-http-types",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-http-types.git",
|
||||
"state" : {
|
||||
"revision" : "db774a277f60063a32d854f2980299caf06da041",
|
||||
"version" : "1.6.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-log",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-log.git",
|
||||
"state" : {
|
||||
"revision" : "92448c359f00ebe36ae97d3bd9086f13c7692b5a",
|
||||
"version" : "1.13.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio.git",
|
||||
"state" : {
|
||||
"revision" : "77b84ac2cd2ac9e4ac67d19f045fd5b434f56967",
|
||||
"version" : "2.101.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-extras",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-extras.git",
|
||||
"state" : {
|
||||
"revision" : "d2eeec0339074034f11a040a74aa2a341a2c4506",
|
||||
"version" : "1.34.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-http2",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-http2.git",
|
||||
"state" : {
|
||||
"revision" : "61d1b44f6e4e118792be1cff88ee2bc0267c6f9a",
|
||||
"version" : "1.44.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-ssl",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-ssl.git",
|
||||
"state" : {
|
||||
"revision" : "407d82d5b6cc00e1c3fb83a81b1539b70c788c5e",
|
||||
"version" : "2.37.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-nio-transport-services",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-nio-transport-services.git",
|
||||
"state" : {
|
||||
"revision" : "67787bb645a5e67d2edcdfbe48a216cc549222d5",
|
||||
"version" : "1.28.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-numerics",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-numerics.git",
|
||||
"state" : {
|
||||
"revision" : "0c0290ff6b24942dadb83a929ffaaa1481df04a2",
|
||||
"version" : "1.1.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-protobuf",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-protobuf.git",
|
||||
"state" : {
|
||||
"revision" : "f6506eaa86ed2e01cb0ae14a75035b7fdbf0918f",
|
||||
"version" : "1.38.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-service-context",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-service-context.git",
|
||||
"state" : {
|
||||
"revision" : "d0997351b0c7779017f88e7a93bc30a1878d7f29",
|
||||
"version" : "1.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-service-lifecycle",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/swift-server/swift-service-lifecycle.git",
|
||||
"state" : {
|
||||
"revision" : "9829955b385e5bb88128b73f1b8389e9b9c3191a",
|
||||
"version" : "2.11.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-system",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-system.git",
|
||||
"state" : {
|
||||
"revision" : "7502b711c92a17741fa625d722b0ccbd595d8ed1",
|
||||
"version" : "1.7.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "zstd",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/facebook/zstd.git",
|
||||
"state" : {
|
||||
"revision" : "f8745da6ff1ad1e7bab384bd1f9d742439278e99",
|
||||
"version" : "1.5.7"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// swift-tools-version: 6.2
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Copyright © 2025-2026 Apple Inc. and the Containerization project authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let scVersion = "0.33.4"
|
||||
|
||||
let package = Package(
|
||||
name: "ctr-example",
|
||||
platforms: [
|
||||
.macOS("26.0")
|
||||
],
|
||||
products: [
|
||||
.executable(
|
||||
name: "ctr-example",
|
||||
targets: ["ctr-example"]
|
||||
)
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/apple/containerization.git", exact: Version(stringLiteral: scVersion))
|
||||
],
|
||||
targets: [
|
||||
.executableTarget(
|
||||
name: "ctr-example",
|
||||
dependencies: [
|
||||
.product(name: "Containerization", package: "containerization"),
|
||||
.product(name: "ContainerizationOS", package: "containerization"),
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
@@ -0,0 +1,48 @@
|
||||
# Container Example
|
||||
|
||||
Very basic example of launching a Linux container using Containerization.
|
||||
|
||||
## Build and Run
|
||||
|
||||
### 1. Fetch Kernel
|
||||
|
||||
In your terminal, change directories to examples/ctr-example and run:
|
||||
|
||||
**Option A: Using Makefile (recommended)**
|
||||
```bash
|
||||
make fetch-default-kernel
|
||||
```
|
||||
|
||||
**Option B: Copy from installed container tool**
|
||||
```bash
|
||||
cp "$(ls -t ~/Library/Application\ Support/com.apple.container/kernels/vmlinux-* | head -1)" ./vmlinux
|
||||
```
|
||||
|
||||
You should now see the `vmlinux` image in examples/ctr-example
|
||||
|
||||
### 2. Build/Run ctr-example
|
||||
|
||||
From examples/ctr-example run:
|
||||
```bash
|
||||
make all
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> If you get the following error, try building from the default macOS terminal:
|
||||
> `error: compiled module was created by a newer version of the compiler`
|
||||
|
||||
After the build completes, the example will run. In your terminal you should see something like:
|
||||
|
||||
```
|
||||
Starting container example...
|
||||
Fetching container initial filesystem...
|
||||
Creating container from docker.io/library/alpine:3.16...
|
||||
Starting container...
|
||||
/ #
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> If you get the following error, try moving the `ctr-example` binary to `/var/tmp` and run it from there.
|
||||
> `Swift/ErrorType.swift:254: Fatal error: Error raised at top level: unsupported: "failed to create vmnet network with status vmnet_return_t(rawValue: 1001)"`
|
||||
|
||||
**Congratulations, you've started the example container!**
|
||||
@@ -0,0 +1,84 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Copyright © 2025-2026 Apple Inc. and the Containerization project authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Containerization
|
||||
import ContainerizationOS
|
||||
import Foundation
|
||||
|
||||
@main
|
||||
struct CtrExample {
|
||||
static func main() async throws {
|
||||
print("Starting container example...")
|
||||
|
||||
// Set up terminal in raw mode (like cctl)
|
||||
let current = try Terminal.current
|
||||
try current.setraw()
|
||||
defer { current.tryReset() }
|
||||
|
||||
let initfsReference = "ghcr.io/apple/containerization/vminit:0.26.5"
|
||||
#if arch(arm64)
|
||||
let kernelCandidates = ["./vmlinux-arm64"]
|
||||
#elseif arch(x86_64)
|
||||
let kernelCandidates = ["./vmlinuz-x86_64", "./vmlinux-x86_64"]
|
||||
#else
|
||||
let kernelCandidates = ["./vmlinux"]
|
||||
#endif
|
||||
let kernelPath = kernelCandidates.first(where: { FileManager.default.fileExists(atPath: $0) }) ?? kernelCandidates[0]
|
||||
print("Fetching base container filesystem...")
|
||||
// Create container manager with file-based initfs
|
||||
var manager = try await ContainerManager(
|
||||
kernel: Kernel(path: URL(fileURLWithPath: kernelPath), platform: .linuxArm),
|
||||
initfsReference: initfsReference,
|
||||
network: try VmnetNetwork()
|
||||
)
|
||||
|
||||
let containerId = "ctr-example"
|
||||
let imageReference = "docker.io/library/alpine:3.16"
|
||||
|
||||
print("Creating container from \(imageReference)...")
|
||||
|
||||
// Create container with simple configuration
|
||||
let container = try await manager.create(
|
||||
containerId,
|
||||
reference: imageReference,
|
||||
rootfsSizeInBytes: 1.gib()
|
||||
) { @Sendable config in
|
||||
config.cpus = 2
|
||||
config.memoryInBytes = 512.mib()
|
||||
config.process.setTerminalIO(terminal: current)
|
||||
config.process.arguments = ["/bin/sh"]
|
||||
config.process.workingDirectory = "/"
|
||||
}
|
||||
|
||||
// Clean up on exit
|
||||
defer {
|
||||
try? manager.delete(containerId)
|
||||
}
|
||||
|
||||
print("Starting container...")
|
||||
try await container.create()
|
||||
try await container.start()
|
||||
|
||||
// Resize terminal to match current window
|
||||
try? await container.resize(to: try current.size)
|
||||
|
||||
// Wait for container to finish
|
||||
let exitCode = try await container.wait()
|
||||
|
||||
print("Container exited with code \(exitCode)")
|
||||
try await container.stop()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.virtualization</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,58 @@
|
||||
#
|
||||
|
||||
## Install and test the container tool:
|
||||
|
||||
See https://github.com/apple/container/releases
|
||||
|
||||
Once installed, start the service and follow prompts.
|
||||
|
||||
```bash
|
||||
container system start
|
||||
```
|
||||
|
||||
This'll install your kernel.
|
||||
|
||||
After this start your first container. On first launch, this'll install another artifact for our guest init process:
|
||||
|
||||
```bash
|
||||
container run alpine uname
|
||||
```
|
||||
|
||||
Container starts after this will be fast!
|
||||
|
||||
## Get the Containerization sources:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/apple/containerization.git
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> There is a bug in the `vmnet` framework on macOS 26 that causes network creation to fail if the creating applications are located under your `Documents` or `Desktop` directories. To workaround this, clone the project elsewhere, such as `~/projects/containerization`, until this issue is resolved.
|
||||
|
||||
## Take a look at ctr-example
|
||||
|
||||
Read through the sources:
|
||||
|
||||
- ContainerManager:
|
||||
- manager.create()
|
||||
- container.create(), start(), wait(), stop()
|
||||
|
||||
## Fetch the kernel
|
||||
|
||||
Run
|
||||
|
||||
```bash
|
||||
cp "$(ls -t ~/Library/Application\ Support/com.apple.container/kernels/vmlinux-* | head -1)" ./vmlinux
|
||||
```
|
||||
|
||||
## Build and run the example
|
||||
|
||||
```bash
|
||||
$ cd examples/ctr-example
|
||||
$ make
|
||||
```
|
||||
|
||||
## Modify the project
|
||||
|
||||
- Change the command run by the container
|
||||
- Change the image
|
||||
Reference in New Issue
Block a user