Files
container/Sources/ContainerClient/Core/ClientKernel.swift
T
Kathryn Baldauf 8e9670c8f8 Initial commit
Co-authored-by: Aditya Ramani <a_ramani@apple.com>
Co-authored-by: Agam Dua <agam_dua@apple.com>
Co-authored-by: Danny Canter <danny_canter@apple.com>
Co-authored-by: Dmitry Kovba <dkovba@apple.com>
Co-authored-by: Eric Ernst <eric_ernst@apple.com>
Co-authored-by: Evan Hazlett <ehazlett@apple.com>
Co-authored-by: Gilbert Song <gilbertsong@apple.com>
Co-authored-by: Hugh Bussell <hbussell@apple.com>
Co-authored-by: John Logan <john_logan@apple.com>
Co-authored-by: Kathryn Baldauf <k_baldauf@apple.com>
Co-authored-by: Madhu Venugopal <mvenugopal@apple.com>
Co-authored-by: Michael Crosby <michael_crosby@apple.com>
Co-authored-by: Sidhartha Mani <sidhartha_mani@apple.com>
Co-authored-by: Tanweer Noor <tnoor@apple.com>
Co-authored-by: Ximena Perez Diaz <xperez528@gmail.com>
Co-authored-by: Yibo Zhuang <yzhuang@apple.com>
2025-06-05 15:51:55 -07:00

100 lines
3.7 KiB
Swift

//===----------------------------------------------------------------------===//
// 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 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) async throws {
let client = newClient()
let message = XPCMessage(route: .installKernel)
message.set(key: .kernelFilePath, value: kernelFilePath)
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) async throws {
let client = newClient()
let message = XPCMessage(route: .installKernel)
message.set(key: .kernelTarURL, value: tarFile)
message.set(key: .kernelFilePath, value: kernelFilePath)
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` 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")
}
}
}