Files
container/Sources/Services/ContainerAPIService/Client/ClientKernel.swift
T
J Logan 356c8d2f88 Reorganize client libraries. (#1020)
- Closes #461.
- Extract core types into ContainerResources target.
- Extract ContainerNetworkServiceClient from ContainerNetworkService.
- Relocate sandbox client from ContainerClient to
ContainerSandboxServiceClient.
- Relocate ContainerClient to ContainerAPIServiceClient.
- Common structure from services and clients under Source/Services.

Updated project hierarchy:

```
Sources/CAuditToken - audit token access wrapper
Sources/CLI - CLI executable
Sources/ContainerBuild - builder
Sources/ContainerCommands - CLI command implementations
Sources/ContainerLog - logging helpers
Sources/ContainerPersistence - persistent data and system property helpers
Sources/ContainerPlugin - plugin system
Sources/ContainerResource - resource (container, image, volume, network) types
Sources/ContainerVersion - version helpers
Sources/ContainerXPC - XPC helpers
Sources/CVersion - injected project version
Sources/DNSServer - container DNS resolver
Sources/Helpers - service executables
Sources/Services/*/Client - service clients
Sources/Services/*/Server - service implementations
Sources/SocketForwarder - port forwarding
Sources/TerminalProgress - progress bar
```

## Type of Change
- [ ] Bug fix
- [ ] New feature  
- [x] Breaking change
- [ ] Documentation update

## Motivation and Context
The ContainerClient library was a bit of a grab bag. This refactor
applies a more sensible project and library structure for resource data
types, services, and clients.

## Testing
- [x] Tested locally
- [x] Added/updated tests
- [ ] Added/updated docs
2026-01-06 08:27:14 -08:00

104 lines
3.8 KiB
Swift

//===----------------------------------------------------------------------===//
// Copyright © 2026 Apple Inc. and the container 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 ContainerXPC
import Containerization
import ContainerizationError
import ContainerizationOCI
import Foundation
import TerminalProgress
public struct ClientKernel {
static let serviceIdentifier = "com.apple.container.apiserver"
}
extension ClientKernel {
private static func newClient() -> XPCClient {
XPCClient(service: serviceIdentifier)
}
public static func installKernel(kernelFilePath: String, platform: SystemPlatform, force: Bool) async throws {
let client = newClient()
let message = XPCMessage(route: .installKernel)
message.set(key: .kernelFilePath, value: kernelFilePath)
message.set(key: .kernelForce, value: force)
let platformData = try JSONEncoder().encode(platform)
message.set(key: .systemPlatform, value: platformData)
try await client.send(message)
}
public static func installKernelFromTar(tarFile: String, kernelFilePath: String, platform: SystemPlatform, progressUpdate: ProgressUpdateHandler? = nil, force: Bool)
async throws
{
let client = newClient()
let message = XPCMessage(route: .installKernel)
message.set(key: .kernelTarURL, value: tarFile)
message.set(key: .kernelFilePath, value: kernelFilePath)
message.set(key: .kernelForce, value: force)
let platformData = try JSONEncoder().encode(platform)
message.set(key: .systemPlatform, value: platformData)
var progressUpdateClient: ProgressUpdateClient?
if let progressUpdate {
progressUpdateClient = await ProgressUpdateClient(for: progressUpdate, request: message)
}
try await client.send(message)
await progressUpdateClient?.finish()
}
@discardableResult
public static func getDefaultKernel(for platform: SystemPlatform) async throws -> Kernel {
let client = newClient()
let message = XPCMessage(route: .getDefaultKernel)
let platformData = try JSONEncoder().encode(platform)
message.set(key: .systemPlatform, value: platformData)
do {
let reply = try await client.send(message)
guard let kData = reply.dataNoCopy(key: .kernel) else {
throw ContainerizationError(.internalError, message: "missing kernel data from XPC response")
}
let kernel = try JSONDecoder().decode(Kernel.self, from: kData)
return kernel
} catch let err as ContainerizationError {
guard err.isCode(.notFound) else {
throw err
}
throw ContainerizationError(
.notFound, message: "default kernel not configured for architecture \(platform.architecture), please use the `container system kernel set` command to configure it")
}
}
}
extension SystemPlatform {
public static var current: SystemPlatform {
switch Platform.current.architecture {
case "arm64":
return .linuxArm
case "amd64":
return .linuxAmd
default:
fatalError("unknown architecture")
}
}
}