Skip to content

Commit 11e2415

Browse files
authored
Merge branch 'main' into feature/ipv6-support
2 parents d125a79 + 474906d commit 11e2415

59 files changed

Lines changed: 748 additions & 361 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/pr-build.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,35 @@ on:
88
types: [opened, reopened, synchronize]
99

1010
jobs:
11+
verify-signatures:
12+
name: Verify commit signatures
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Check all commits are signed
16+
env:
17+
GH_TOKEN: ${{ github.token }}
18+
run: |
19+
commits=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/commits --paginate)
20+
unsigned_commits=""
21+
22+
while IFS='|' read -r sha author verified; do
23+
if [ "$verified" != "true" ]; then
24+
unsigned_commits="$unsigned_commits - $sha by $author\n"
25+
fi
26+
done < <(echo "$commits" | jq -r '.[] | "\(.sha)|\(.commit.author.name)|\(.commit.verification.verified)"')
27+
28+
if [ -n "$unsigned_commits" ]; then
29+
echo "::error::The following commits are not signed:"
30+
echo -e "$unsigned_commits"
31+
echo ""
32+
echo "Please sign your commits. See:"
33+
echo " - https://github.com/apple/containerization/blob/main/CONTRIBUTING.md#pull-requests"
34+
echo " - https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits"
35+
exit 1
36+
fi
37+
38+
echo "All commits are signed!"
39+
1140
build:
1241
name: Invoke build
1342
uses: ./.github/workflows/common.yml

.github/workflows/pr-label-apply.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,12 @@ jobs:
2929
run-id: ${{ github.event.workflow_run.id }}
3030
pattern: pr-metadata-*
3131
merge-multiple: false
32-
continue-on-error: true
3332
id: download-artifact
3433

3534
- name: Read PR number
3635
id: pr-number
3736
run: |
38-
METADATA_DIR=$(find . -type d -name "pr-metadata-*" 2>/dev/null | head -n 1)
39-
40-
if [ -z "$METADATA_DIR" ]; then
41-
echo "No metadata found"
42-
exit 1
43-
fi
44-
45-
PR_NUMBER=$(cat "${METADATA_DIR}/pr-number.txt")
37+
PR_NUMBER=$(cat "pr-number.txt")
4638
echo "number=${PR_NUMBER}" >> $GITHUB_OUTPUT
4739
echo "PR Number: ${PR_NUMBER}"
4840

BUILDING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ Attach debugger to the XPC helpers using their launchd service labels:
137137
% container system start
138138
% container run -d --name test debian:bookworm sleep infinity
139139
test
140-
% launchd list | grep container
140+
% launchctl list | grep container
141141
27068 0 com.apple.container.container-network-vmnet.default
142142
27072 0 com.apple.container.container-core-images
143143
26980 0 com.apple.container.apiserver

Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import PackageDescription
2222

2323
let releaseVersion = ProcessInfo.processInfo.environment["RELEASE_VERSION"] ?? "0.0.0"
2424
let gitCommit = ProcessInfo.processInfo.environment["GIT_COMMIT"] ?? "unspecified"
25-
let builderShimVersion = "0.7.0"
26-
let scVersion = "0.24.5"
25+
let builderShimVersion = "0.8.0"
26+
let scVersion = "0.25.0"
2727

2828
let package = Package(
2929
name: "container",

Sources/ContainerBuild/BuildFSSync.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Collections
1818
import ContainerAPIClient
1919
import ContainerizationArchive
2020
import ContainerizationOCI
21+
import CryptoKit
2122
import Foundation
2223
import GRPC
2324

@@ -199,7 +200,7 @@ actor BuildFSSync: BuildPipelineHandler {
199200
format: .paxRestricted,
200201
filter: .none)
201202

202-
try Archiver.compress(
203+
let tarHash = try Archiver.compress(
203204
source: contextDir,
204205
destination: tarURL,
205206
writerConfiguration: writerCfg
@@ -229,6 +230,25 @@ actor BuildFSSync: BuildPipelineHandler {
229230
pathInArchive: URL(fileURLWithPath: rel))
230231
}
231232

233+
let hash = tarHash.compactMap { String(format: "%02x", $0) }.joined()
234+
let header = BuildTransfer(
235+
id: packet.id,
236+
source: tarURL.path,
237+
complete: false,
238+
isDir: false,
239+
metadata: [
240+
"os": "linux",
241+
"stage": "fssync",
242+
"mode": "tar",
243+
"hash": hash,
244+
]
245+
)
246+
var resp = ClientStream()
247+
resp.buildID = buildID
248+
resp.buildTransfer = header
249+
resp.packetType = .buildTransfer(header)
250+
sender.yield(resp)
251+
232252
for try await chunk in try tarURL.bufferedCopyReader() {
233253
let part = BuildTransfer(
234254
id: packet.id,

Sources/ContainerBuild/BuildImageResolver.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ struct BuildImageResolver: BuildPipelineHandler {
2626
let contentStore: ContentStore
2727
let quiet: Bool
2828
let output: FileHandle
29+
let pull: Bool
2930

30-
public init(_ contentStore: ContentStore, quiet: Bool = false, output: FileHandle = FileHandle.standardError) throws {
31+
public init(_ contentStore: ContentStore, quiet: Bool = false, output: FileHandle = FileHandle.standardError, pull: Bool = false) throws {
3132
self.contentStore = contentStore
3233
self.quiet = quiet
3334
self.output = output
35+
self.pull = pull
3436
}
3537

3638
func accept(_ packet: ServerStream) throws -> Bool {
@@ -72,6 +74,9 @@ struct BuildImageResolver: BuildPipelineHandler {
7274
defer { progress.finish() }
7375
progress.start()
7476

77+
if self.pull {
78+
return try await ClientImage.pull(reference: ref, platform: platform, progressUpdate: progress.handler)
79+
}
7580
// Use fetch() which checks cache first, then pulls if needed
7681
return try await ClientImage.fetch(reference: ref, platform: platform, progressUpdate: progress.handler)
7782
}()

Sources/ContainerBuild/BuildPipelineHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public actor BuildPipeline {
3030
[
3131
try BuildFSSync(URL(filePath: config.contextDir)),
3232
try BuildRemoteContentProxy(config.contentStore),
33-
try BuildImageResolver(config.contentStore, quiet: config.quiet, output: config.terminal?.handle ?? FileHandle.standardError),
33+
try BuildImageResolver(config.contentStore, quiet: config.quiet, output: config.terminal?.handle ?? FileHandle.standardError, pull: config.pull),
3434
try BuildStdio(quiet: config.quiet, output: config.terminal?.handle ?? FileHandle.standardError),
3535
]
3636
}

Sources/ContainerBuild/Builder.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ public struct Builder: Sendable {
251251
public let exports: [BuildExport]
252252
public let cacheIn: [String]
253253
public let cacheOut: [String]
254+
public let pull: Bool
254255

255256
public init(
256257
buildID: String,
@@ -268,6 +269,7 @@ public struct Builder: Sendable {
268269
exports: [BuildExport],
269270
cacheIn: [String],
270271
cacheOut: [String],
272+
pull: Bool
271273
) {
272274
self.buildID = buildID
273275
self.contentStore = contentStore
@@ -284,6 +286,7 @@ public struct Builder: Sendable {
284286
self.exports = exports
285287
self.cacheIn = cacheIn
286288
self.cacheOut = cacheOut
289+
self.pull = pull
287290
}
288291
}
289292
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===----------------------------------------------------------------------===//
2+
// Copyright © 2026 Apple Inc. and the container project authors.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//===----------------------------------------------------------------------===//
16+
17+
/// An error type that aggregates multiple errors into one.
18+
///
19+
/// When displayed, each underlying error is printed on its own line.
20+
public struct AggregateError: Swift.Error, Sendable {
21+
public let errors: [any Error]
22+
23+
public init(_ errors: [any Error]) {
24+
self.errors = errors
25+
}
26+
}
27+
28+
extension AggregateError: CustomStringConvertible {
29+
public var description: String {
30+
errors.map { String(describing: $0) }.joined(separator: "\n")
31+
}
32+
}

0 commit comments

Comments
 (0)