Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Bug Report
description: File a bug report.
title: "[Bug]: "
labels: ["bug", "triage"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: checkboxes
id: prereqs
attributes:
label:
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/apple/container/blob/main/CONTRIBUTING.md).
options:
- label: I have searched the existing issues
required: true
- label: If possible, I've reproduced the issue using the 'main' branch of this project
required: false
- type: input
id: contact
attributes:
label: Contact Details
description: How can we get in touch with you if we need more info? ex. email@example.com
validations:
required: false
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce
description: Explain how to reproduce the incorrect behavior.
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: Current behavior
description: A concise description of what you're experiencing.
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Environment
description: |
examples:
- **OS**: MacOS 26 Beta 1
- **Swift**: Apple Swift version 6.2
- **Xcode**: Xcode 26 Beta 17A5241e
value: |
- OS:
- Swift:
- Xcode:
render: markdown
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/apple/container/blob/main/CONTRIBUTING.md).
options:
- label: I agree to follow this project's Code of Conduct
required: true
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Security disclosure process
url: https://github.com/apple/container/security/advisories/new
about: Please report security vulnerabilities here.
32 changes: 32 additions & 0 deletions .github/ISSUE_TEMPLATE/feature.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Feature request
description: File a request for a feature
title: "[Request]: "
labels: ["feature", "triage"]
body:
- type: markdown
attributes:
value: |
Thanks for contributing to the container project!
- type: input
id: contact
attributes:
label: Contact Details
description: How can we get in touch with you if we need more info?
placeholder: ex. email@example.com
validations:
required: false
- type: textarea
id: request
attributes:
label: Feature request details
description: Describe your proposed feature. Code samples that show what's missing, or what new capabilities will be possible, are very helpful! Provide links to existing issues or external references/discussions, if appropriate.
validations:
required: true
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com).
options:
- label: I agree to follow this project's Code of Conduct
required: true
7 changes: 1 addition & 6 deletions .github/workflows/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,20 @@ jobs:
- name: Update containerization
run: |
/usr/bin/swift package update containerization
env:
CONTAINERIZATION_REPO: https://${{ secrets.REPO_READ }}@github.com/apple/containerization.git
- name: Check formatting
run: |
./scripts/install-hawkeye.sh
make fmt
if ! git diff --quiet -- . ':(exclude)Package.swift' ':(exclude)Package.resolved'; then echo "The following files require formatting or license header updates:\n$(git diff --name-only)" ; false ; fi
- name: Check protobuf
run: |
make BUILDER_SHIM_REPO=https://${{ secrets.REPO_READ }}@github.com/apple/container-builder-shim.git protos
make protos

# TODO [launch]: TEMPORARILY we need to exclude these files since we had to modify them to add
# the github token for pulling the private repos.
if ! git diff --quiet -- . ':(exclude)Package.swift' ':(exclude)Package.resolved' ':(exclude)Protobuf.Makefile'; then echo "The following files require formatting or license header updates:\n$(git diff --name-only)" ; false ; fi
env:
CURRENT_SDK: y
CONTAINERIZATION_REPO: https://${{ secrets.REPO_READ }}@github.com/apple/containerization.git
- name: Set build configuration
run: |
echo "BUILD_CONFIGURATION=debug" >> $GITHUB_ENV
Expand All @@ -54,7 +51,6 @@ jobs:
env:
DEVELOPER_DIR: "/Applications/Xcode_16.3.app/Contents/Developer"
CURRENT_SDK: y
CONTAINERIZATION_REPO: https://${{ secrets.REPO_READ }}@github.com/apple/containerization.git
- name: Create package
run: |
mkdir -p outputs
Expand All @@ -70,7 +66,6 @@ jobs:
CONTAINER_REGISTRY_HOST: ghcr.io
DEVELOPER_DIR: "/Applications/Xcode_16.3.app/Contents/Developer"
CURRENT_SDK: y
CONTAINERIZATION_REPO: https://${{ secrets.REPO_READ }}@github.com/apple/containerization.git
- name: Save documentation artifact
uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
jobs:
checkBranch:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags') || startsWith(github.ref, 'refs/heads/release')
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags') || startsWith(github.ref, 'refs/heads/release')
steps:
- name: Branch validation
run: echo "Branch ${{ github.ref_name }} is allowed"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ test_results/

# API docs for local preview only.
_site/
_serve/
10 changes: 5 additions & 5 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Build `container` and the background services from source, and run basic and int
make all test integration
```

Copy the binaries to `/usr/local/bin` and `/usr/local/libexec` (requires entering the an administrator password):
Copy the binaries to `/usr/local/bin` and `/usr/local/libexec` (requires entering an administrator password):

```bash
make install
Expand All @@ -36,19 +36,19 @@ of the `container` repository. Ensure that you [follow containerization instruct
to prepare your build environment.

2. In your development shell, go to the `container` project directory.

```
cd container
```

3. If the `container` services are already running, stop them.
3. If the `container` services are already running, stop them.

```
bin/container system stop
```

4. Configure the environment variable `CONTAINERIZATION_PATH` to refer to your Containerization project, and update your `Package.resolved` file.

```
export CONTAINERIZATION_PATH=../containerization
swift package update containerization
Expand All @@ -75,7 +75,7 @@ to prepare your build environment.
To revert to using the Containerization dependency from your `Package.swift`:

1. Unset your `CONTAINERIZATION_PATH` environment variable, and update `Package.resolved`.

```
unset CONTAINERIZATION_PATH
swift package update containerization
Expand Down
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -170,16 +170,19 @@ check-licenses:

.PHONY: serve-docs
serve-docs:
@echo 'to browse: open http://127.0.0.1:8000/documentation/'
@python3 -m http.server --bind 127.0.0.1 --directory ./_site
@echo 'to browse: open http://127.0.0.1:8000/container/documentation/'
@rm -rf _serve
@mkdir -p _serve
@cp -a _site _serve/container
@python3 -m http.server --bind 127.0.0.1 --directory ./_serve

.PHONY: docs
docs: _site

_site:
@echo Updating API documentation...
rm -rf $@
@scripts/make-docs.sh $@
@scripts/make-docs.sh $@ container

.PHONY: cleancontent
cleancontent:
Expand All @@ -191,4 +194,5 @@ cleancontent:
clean:
@echo Cleaning the build files...
@rm -rf bin/ libexec/
@rm -rf _site _serve
@$(SWIFT) package clean
6 changes: 3 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ let package = Package(
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.26.0"),
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.29.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.80.0"),
.package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.1.0"),
.package(url: "https://github.com/swiftlang/swift-docc-plugin.git", from: "1.1.0"),
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.20.1"),
.package(url: "https://github.com/orlandos-nl/DNSClient", from: "2.4.1"),
.package(url: "https://github.com/Bouke/DNS", from: "1.2.0"),
.package(url: "https://github.com/orlandos-nl/DNSClient.git", from: "2.4.1"),
.package(url: "https://github.com/Bouke/DNS.git", from: "1.2.0"),
scDependency,
],
targets: [
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# `container`

`container` is a tool that you can use to create and run Linux containers as lightweight virtual machines on your Mac. It's written in Swift, and optimized for Apple silicon.
`container` is a tool that you can use to create and run Linux containers as lightweight virtual machines on your Mac. It's written in Swift, and optimized for Apple silicon.

The tool consumes and produces OCI-compliant container images, so you can pull and run images from any standard container registry. You can push images that you build to those registries as well, and run the images in any other OCI-compliant application.

Expand Down Expand Up @@ -50,7 +50,7 @@ uninstall-container.sh -k
- Take [a guided tour of `container`](./docs/tutorial.md) by building, running, and publishing a simple web server image.
- Learn how to [use various `container` features](./docs/how-to.md).
- Read a brief description and [technical overview](./docs/technical-overview.md) of `container`.
- View the project [API documentation](https://pages.github.com/apple/container/).
- View the project [API documentation](https://apple.github.io/container/documentation/).

## Contributing

Expand Down
3 changes: 0 additions & 3 deletions Sources/CLI/Registry/Login.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ extension Application {
@Argument(help: "Registry server name")
var server: String

@OptionGroup
var global: Flags.Global

@OptionGroup
var registry: Flags.Registry

Expand Down
1 change: 1 addition & 0 deletions Sources/CLI/System/SystemCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extension Application {
SystemRestart.self,
SystemStart.self,
SystemStop.self,
SystemStatus.self,
SystemKernel.self,
],
aliases: ["s"]
Expand Down
52 changes: 52 additions & 0 deletions Sources/CLI/System/SystemStatus.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the container project authors. All rights reserved.
//
// 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 ArgumentParser
import ContainerClient
import ContainerPlugin
import ContainerizationError
import Foundation
import Logging

extension Application {
struct SystemStatus: AsyncParsableCommand {
static let configuration = CommandConfiguration(
commandName: "status",
abstract: "Show the status of `container` services"
)

@Option(name: .shortAndLong, help: "Launchd prefix for `container` services")
var prefix: String = "com.apple.container."

func run() async throws {
let isRegistered = try ServiceManager.isRegistered(fullServiceLabel: "\(prefix)apiserver")
if !isRegistered {
print("apiserver is not running and not registered with launchd")
Application.exit(withError: ExitCode(1))
}

// Now ping our friendly daemon. Fail after 10 seconds with no response.
do {
print("Verifying apiserver is running...")
try await ClientHealthCheck.ping(timeout: .seconds(10))
print("apiserver is running")
} catch {
print("apiserver is not running")
Application.exit(withError: ExitCode(1))
}
}
}
}
10 changes: 10 additions & 0 deletions Sources/Services/ContainerImagesService/Server/SnapshotStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public actor SnapshotStore {
guard let platform = desc.platform else {
throw ContainerizationError(.internalError, message: "Missing platform for descriptor \(desc.digest)")
}
guard Self.shouldUnpackPlatform(platform) else {
continue
}
let currentSubTask = await taskManager.startTask()
if let progressUpdate {
let _taskUpdateProgress = ProgressTaskCoordinator.handler(for: currentSubTask, from: progressUpdate)
Expand Down Expand Up @@ -183,6 +186,13 @@ public actor SnapshotStore {
try self.fm.createDirectory(at: uniqueDirectoryURL, withIntermediateDirectories: true, attributes: nil)
return uniqueDirectoryURL
}

private static func shouldUnpackPlatform(_ platform: Platform) -> Bool {
guard platform.os == "linux" else {
return false
}
return true
}
}

extension FileManager {
Expand Down
6 changes: 3 additions & 3 deletions docs/how-to.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ container images push registry.example.com/fido/web-test:latest
Use the `inspect` command and send the result to the `jq` command to get pretty-printed JSON for the images or containers that you specify:

<pre>
% container images inspect web-test | jq
% container images inspect web-test | jq
[
{
"name": "web-test:latest",
Expand Down Expand Up @@ -152,9 +152,9 @@ The `container logs` command displays the output from your containerized applica
<pre>
% container run -d --dns-domain test --name my-web-server --rm registry.example.com/fido/web-test:latest
my-web-server
% curl http://my-web-server.test
% curl http://my-web-server.test
&lt;!DOCTYPE html>&lt;html>&lt;head>&lt;title>Hello&lt;/title>&lt;/head>&lt;body>&lt;h1>Hello, world!&lt;/h1>&lt;/body>&lt;/html>
% container logs my-web-server
% container logs my-web-server
192.168.64.1 - - [15/May/2025 03:00:03] "GET / HTTP/1.1" 200 -
%
</pre>
Expand Down
Loading
Loading