diff --git a/image/internal/image/oci.go b/image/internal/image/oci.go index 8ddb2875e0..b95ccdc836 100644 --- a/image/internal/image/oci.go +++ b/image/internal/image/oci.go @@ -290,6 +290,8 @@ func (m *manifestOCI1) convertToManifestSchema2(_ context.Context, options *type case ociencspec.MediaTypeLayerEnc, ociencspec.MediaTypeLayerGzipEnc, ociencspec.MediaTypeLayerZstdEnc, ociencspec.MediaTypeLayerNonDistributableEnc, ociencspec.MediaTypeLayerNonDistributableGzipEnc, ociencspec.MediaTypeLayerNonDistributableZstdEnc: return nil, fmt.Errorf("during manifest conversion: encrypted layers (%q) are not supported in docker images", layers[idx].MediaType) + case internalManifest.NydusBootstrapLayerMediaType, internalManifest.NydusBlobLayerMediaType: + return nil, fmt.Errorf("during manifest conversion: Nydus layers (%q) are not supported in docker images", layers[idx].MediaType) default: return nil, fmt.Errorf("Unknown media type during manifest conversion: %q", layers[idx].MediaType) } diff --git a/image/internal/image/oci_test.go b/image/internal/image/oci_test.go index af6ee7349f..b943060fda 100644 --- a/image/internal/image/oci_test.go +++ b/image/internal/image/oci_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.podman.io/image/v5/docker/reference" + internalManifest "go.podman.io/image/v5/internal/manifest" "go.podman.io/image/v5/internal/testing/mocks" "go.podman.io/image/v5/manifest" "go.podman.io/image/v5/pkg/compression" @@ -884,8 +885,9 @@ func TestManifestOCI1CanChangeLayerCompression(t *testing.T) { manifestOCI1FromComponentsLikeFixture(nil), } { assert.True(t, m.CanChangeLayerCompression(imgspecv1.MediaTypeImageLayerGzip)) - // Some projects like to use squashfs and other unspecified formats for layers; don’t touch those. assert.False(t, m.CanChangeLayerCompression("a completely unknown and quite possibly invalid MIME type")) + assert.False(t, m.CanChangeLayerCompression(internalManifest.NydusBootstrapLayerMediaType)) + assert.False(t, m.CanChangeLayerCompression(internalManifest.NydusBlobLayerMediaType)) } artifact := manifestOCI1FromFixture(t, mocks.ForbiddenImageSource{}, "oci1-artifact.json") diff --git a/image/internal/manifest/manifest.go b/image/internal/manifest/manifest.go index 46e1e4df17..e7d6886cf2 100644 --- a/image/internal/manifest/manifest.go +++ b/image/internal/manifest/manifest.go @@ -34,6 +34,10 @@ const ( DockerV2Schema2ForeignLayerMediaType = "application/vnd.docker.image.rootfs.foreign.diff.tar" // DockerV2Schema2ForeignLayerMediaType is the MIME type used for gzipped schema 2 foreign layers. DockerV2Schema2ForeignLayerMediaTypeGzip = "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip" + // NydusBootstrapLayerMediaType is the MIME type used for Nydus bootstrap layers. + NydusBootstrapLayerMediaType = "application/vnd.containers.image.nydus.bootstrap.v1+json" + // NydusBlobLayerMediaType is the MIME type used for Nydus data blob layers. + NydusBlobLayerMediaType = "application/vnd.containers.image.nydus.blob.v1" ) // GuessMIMEType guesses MIME type of a manifest and returns it _if it is recognized_, or "" if unknown or unrecognized. diff --git a/image/manifest/oci.go b/image/manifest/oci.go index 286d58c423..395b33d565 100644 --- a/image/manifest/oci.go +++ b/image/manifest/oci.go @@ -47,7 +47,8 @@ func SupportedOCI1MediaType(m string) error { imgspecv1.MediaTypeImageLayerNonDistributable, imgspecv1.MediaTypeImageLayerNonDistributableGzip, imgspecv1.MediaTypeImageLayerNonDistributableZstd, //nolint:staticcheck // NonDistributable layers are deprecated, but we want to continue to support manipulating pre-existing images. imgspecv1.MediaTypeImageManifest, imgspecv1.MediaTypeLayoutHeader, - ociencspec.MediaTypeLayerEnc, ociencspec.MediaTypeLayerGzipEnc: + ociencspec.MediaTypeLayerEnc, ociencspec.MediaTypeLayerGzipEnc, + manifest.NydusBootstrapLayerMediaType, manifest.NydusBlobLayerMediaType: return nil default: return fmt.Errorf("unsupported OCIv1 media type: %q", m) @@ -142,10 +143,13 @@ func (m *OCI1) UpdateLayerInfos(layerInfos []types.BlobInfo) error { } mimeType = decMimeType } - mimeType, err := updatedMIMEType(oci1CompressionMIMETypeSets, mimeType, info) + + var err error + mimeType, err = updatedMIMEType(oci1CompressionMIMETypeSets, mimeType, info) if err != nil { return fmt.Errorf("preparing updated manifest, layer %q: %w", info.Digest, err) } + if info.CryptoOperation == types.Encrypt { encMediaType, err := getEncryptedMediaType(mimeType) if err != nil { diff --git a/image/manifest/oci_test.go b/image/manifest/oci_test.go index 50d2b463e0..f5811e3ab0 100644 --- a/image/manifest/oci_test.go +++ b/image/manifest/oci_test.go @@ -9,6 +9,7 @@ import ( imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + internalManifest "go.podman.io/image/v5/internal/manifest" "go.podman.io/image/v5/pkg/compression" "go.podman.io/image/v5/types" ) @@ -405,9 +406,13 @@ func TestOCI1CanChangeLayerCompression(t *testing.T) { m := manifestOCI1FromFixture(t, "ociv1.manifest.json") assert.True(t, m.CanChangeLayerCompression(imgspecv1.MediaTypeImageLayerGzip)) - // Some projects like to use squashfs and other unspecified formats for layers; don’t touch those. + // Some projects like to use squashfs and other unspecified formats for layers; don't touch those. assert.False(t, m.CanChangeLayerCompression("a completely unknown and quite possibly invalid MIME type")) artifact := manifestOCI1FromFixture(t, "ociv1.artifact.json") assert.False(t, artifact.CanChangeLayerCompression(imgspecv1.MediaTypeImageLayerGzip)) + + // Nydus layer types don't support compression changes + assert.False(t, m.CanChangeLayerCompression(internalManifest.NydusBootstrapLayerMediaType)) + assert.False(t, m.CanChangeLayerCompression(internalManifest.NydusBlobLayerMediaType)) }