mirror of
https://github.com/apple/container.git
synced 2026-07-13 04:57:08 +00:00
Optionally resolve wrapper index to single-platform manifest based on com.apple.containerization.index.indirect annotation (#397)
Fixes #212 This PR: - adds a `package func resolved()` on `ClientImage` that makes use of the new `com.apple.containerization.index.indirect` annotation to identify and resolve wrapper indices created by Containerization; - replace the digest displayed in `container image list` with the one of the resolved manifest; - use the resolved manifest for `container image inspect` if the index is a wrapper.
This commit is contained in:
@@ -51,6 +51,7 @@ extension Application {
|
||||
var rows = createVerboseHeader()
|
||||
for image in images {
|
||||
let formatter = ByteCountFormatter()
|
||||
let imageDigest = try await image.resolved().digest
|
||||
for descriptor in try await image.index().manifests {
|
||||
// Don't list attestation manifests
|
||||
if let referenceType = descriptor.annotations?["vnd.docker.reference.type"],
|
||||
@@ -85,7 +86,7 @@ extension Application {
|
||||
let row = [
|
||||
reference.name,
|
||||
reference.tag ?? "<none>",
|
||||
Utility.trimDigest(digest: image.descriptor.digest),
|
||||
Utility.trimDigest(digest: imageDigest),
|
||||
os,
|
||||
arch,
|
||||
variant,
|
||||
@@ -130,10 +131,11 @@ extension Application {
|
||||
for image in images {
|
||||
let processedReferenceString = try ClientImage.denormalizeReference(image.reference)
|
||||
let reference = try ContainerizationOCI.Reference.parse(processedReferenceString)
|
||||
let digest = try await image.resolved().digest
|
||||
rows.append([
|
||||
reference.name,
|
||||
reference.tag ?? "<none>",
|
||||
Utility.trimDigest(digest: image.descriptor.digest),
|
||||
Utility.trimDigest(digest: digest),
|
||||
])
|
||||
}
|
||||
let formatter = TableOutput(rows: rows)
|
||||
|
||||
@@ -69,6 +69,24 @@ public struct ClientImage: Sendable {
|
||||
}
|
||||
return try content.decode()
|
||||
}
|
||||
|
||||
/// Returns the resolved OCI descriptor for the image.
|
||||
package func resolved() async throws -> Descriptor {
|
||||
let index = try await self.index()
|
||||
let indirect = index.annotations?[AnnotationKeys.containerizationIndexIndirect]
|
||||
// If this is not an indirect index, return its own descriptor
|
||||
guard let indirect, ["1", "true"].contains(indirect.lowercased()) else {
|
||||
return self.descriptor
|
||||
}
|
||||
// For indirect indices, return the first (and only) manifest
|
||||
guard let manifest = index.manifests.first else {
|
||||
throw ContainerizationError(
|
||||
.internalError,
|
||||
message: "Failed to resolve indirect index \(self.digest): no manifests found"
|
||||
)
|
||||
}
|
||||
return manifest
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: ClientImage constants
|
||||
|
||||
@@ -43,7 +43,7 @@ public struct ImageDetail: Codable {
|
||||
|
||||
extension ClientImage {
|
||||
public func details() async throws -> ImageDetail {
|
||||
let indexDescriptor = self.descriptor
|
||||
let descriptor = try await self.resolved()
|
||||
let reference = self.reference
|
||||
var variants: [ImageDetail.Variants] = []
|
||||
for desc in try await self.index().manifests {
|
||||
@@ -61,6 +61,6 @@ extension ClientImage {
|
||||
let size = desc.size + manifest.config.size + manifest.layers.reduce(0, { (l, r) in l + r.size })
|
||||
variants.append(.init(platform: platform, size: size, config: config))
|
||||
}
|
||||
return ImageDetail(name: reference, index: indexDescriptor, variants: variants)
|
||||
return ImageDetail(name: reference, index: descriptor, variants: variants)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user