From 6231f9502145deee46fdaea7fe3187c31370572f Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 7 Jul 2026 12:36:36 -0400 Subject: [PATCH] fix(save): use Docker v2s2 manifest format for skopeo compatibility --- Sources/tart/OCI/Manifest.swift | 4 ++++ Sources/tart/OCI/OCIArchiveWriter.swift | 2 +- Sources/tart/VMDirectory+OCIArchive.swift | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Sources/tart/OCI/Manifest.swift b/Sources/tart/OCI/Manifest.swift index 897bd97..c466435 100644 --- a/Sources/tart/OCI/Manifest.swift +++ b/Sources/tart/OCI/Manifest.swift @@ -4,6 +4,10 @@ import Foundation let ociManifestMediaType = "application/vnd.oci.image.manifest.v1+json" let ociConfigMediaType = "application/vnd.oci.image.config.v1+json" +// Docker manifest and config media types (schema v2) +let dockerManifestMediaType = "application/vnd.docker.distribution.manifest.v2+json" +let dockerConfigMediaType = "application/vnd.docker.container.image.v1+json" + // Layer media types let configMediaType = "application/vnd.cirruslabs.tart.config.v1" let diskV2MediaType = "application/vnd.cirruslabs.tart.disk.v2" diff --git a/Sources/tart/OCI/OCIArchiveWriter.swift b/Sources/tart/OCI/OCIArchiveWriter.swift index 80021ba..b573866 100644 --- a/Sources/tart/OCI/OCIArchiveWriter.swift +++ b/Sources/tart/OCI/OCIArchiveWriter.swift @@ -66,7 +66,7 @@ extension OCIArchiveWriter: BlobStorage { var manifests: [[String: Any]] = [] let baseDescriptor: [String: Any] = [ - "mediaType": ociManifestMediaType, + "mediaType": dockerManifestMediaType, "digest": manifestDigest, "size": manifestSize, ] diff --git a/Sources/tart/VMDirectory+OCIArchive.swift b/Sources/tart/VMDirectory+OCIArchive.swift index 0f51e98..00336bd 100644 --- a/Sources/tart/VMDirectory+OCIArchive.swift +++ b/Sources/tart/VMDirectory+OCIArchive.swift @@ -29,12 +29,17 @@ extension VMDirectory { let ociConfigContainer = OCIConfig.ConfigContainer(Labels: labels) let ociConfigJSON = try OCIConfig(architecture: config.arch, os: config.os, config: ociConfigContainer).toJSON() let ociConfigDigest = try await archive.pushBlob(fromData: ociConfigJSON, chunkSizeMb: 0, digest: nil) - let manifest = OCIManifest( - config: OCIManifestConfig(size: ociConfigJSON.count, digest: ociConfigDigest), + + var manifestConfig = OCIManifestConfig(size: ociConfigJSON.count, digest: ociConfigDigest) + manifestConfig.mediaType = dockerConfigMediaType + + var manifest = OCIManifest( + config: manifestConfig, layers: layers, uncompressedDiskSize: UInt64(diskSize), uploadDate: Date() ) + manifest.mediaType = dockerManifestMediaType let tagRef = tag ?? "latest" defaultLogger.appendNewLine("saving manifest...")