//===----------------------------------------------------------------------===// // 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 ContainerAPIClient import ContainerPersistence import ContainerizationError import ContainerizationOCI import Logging extension ClusterHelper { // MARK: - Image management public static func ensureImage(nodeImage: String = ClusterHelper.nodeImage, log: Logger, containerSystemConfig: ContainerSystemConfig) async throws { do { _ = try await ClientImage.get(reference: nodeImage, containerSystemConfig: containerSystemConfig) log.debug("cluster node image present", metadata: ["ref": "\(nodeImage)"]) return } catch let error as ContainerizationError where error.code == .notFound { log.info("Pulling cluster node image", metadata: ["ref": "\(nodeImage)"]) } let platform = try Platform(from: "linux/\(Arch.hostArchitecture().rawValue)") _ = try await ClientImage.fetch( reference: nodeImage, platform: platform, containerSystemConfig: containerSystemConfig, progressUpdate: nil) } // MARK: - Image reference helpers static func isShortName(_ reference: String) -> Bool { guard let ref = try? Reference.parse(reference) else { return true } return ref.domain == nil } static func fqReference(_ reference: String) -> String { guard let ref = try? Reference.parse(reference) else { return reference } ref.normalize() return ref.description } }