diff --git a/copy/copy.go b/copy/copy.go index ff88af77fa..6a925d7819 100644 --- a/copy/copy.go +++ b/copy/copy.go @@ -14,6 +14,7 @@ import ( "time" "github.com/containers/image/image" + "github.com/containers/image/manifest" "github.com/containers/image/pkg/blobinfocache" "github.com/containers/image/pkg/compression" "github.com/containers/image/signature" @@ -813,6 +814,17 @@ func (c *copier) copyBlobFromStream(ctx context.Context, srcStream io.Reader, sr return types.BlobInfo{}, errors.Wrap(err, "Error writing blob") } + switch compressionOperation { + case types.Compress: + uploadedInfo.MediaType = manifest.DockerV2Schema2LayerMediaType + case types.Decompress: + uploadedInfo.MediaType = manifest.DockerV2SchemeLayerMediaTypeUncompressed + case types.PreserveOriginal: + // preserve whatever the destination sets by default + default: + panic("unexpected compression operation") + } + // This is fairly horrible: the writer from getOriginalLayerCopyWriter wants to consumer // all of the input (to compute DiffIDs), even if dest.PutBlob does not need it. // So, read everything from originalLayerReader, which will cause the rest to be diff --git a/directory/directory_dest.go b/directory/directory_dest.go index 4b2ab022e2..ed5a8257fe 100644 --- a/directory/directory_dest.go +++ b/directory/directory_dest.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" + "github.com/containers/image/manifest" "github.com/containers/image/types" "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -172,7 +173,7 @@ func (d *dirImageDestination) PutBlob(ctx context.Context, stream io.Reader, inp return types.BlobInfo{}, err } succeeded = true - return types.BlobInfo{Digest: computedDigest, Size: size}, nil + return types.BlobInfo{Digest: computedDigest, Size: size, MediaType: manifest.DockerV2SchemeLayerMediaTypeUncompressed}, nil } // TryReusingBlob checks whether the transport already contains, or can efficiently reuse, a blob, and if so, applies it to the current destination @@ -194,7 +195,7 @@ func (d *dirImageDestination) TryReusingBlob(ctx context.Context, info types.Blo if err != nil { return false, types.BlobInfo{}, err } - return true, types.BlobInfo{Digest: info.Digest, Size: finfo.Size()}, nil + return true, types.BlobInfo{Digest: info.Digest, Size: finfo.Size(), MediaType: manifest.DockerV2SchemeLayerMediaTypeUncompressed}, nil } diff --git a/manifest/docker_schema2.go b/manifest/docker_schema2.go index 0671aed9f0..c288373cd3 100644 --- a/manifest/docker_schema2.go +++ b/manifest/docker_schema2.go @@ -207,7 +207,10 @@ func (m *Schema2) UpdateLayerInfos(layerInfos []types.BlobInfo) error { original := m.LayersDescriptors m.LayersDescriptors = make([]Schema2Descriptor, len(layerInfos)) for i, info := range layerInfos { - m.LayersDescriptors[i].MediaType = original[i].MediaType + m.LayersDescriptors[i].MediaType = info.MediaType + if m.LayersDescriptors[i].MediaType == "" { + m.LayersDescriptors[i].MediaType = original[i].MediaType + } m.LayersDescriptors[i].Digest = info.Digest m.LayersDescriptors[i].Size = info.Size m.LayersDescriptors[i].URLs = info.URLs diff --git a/manifest/manifest.go b/manifest/manifest.go index ae1921b6cc..5227c07d1c 100644 --- a/manifest/manifest.go +++ b/manifest/manifest.go @@ -24,6 +24,8 @@ const ( DockerV2Schema2ConfigMediaType = "application/vnd.docker.container.image.v1+json" // DockerV2Schema2LayerMediaType is the MIME type used for schema 2 layers. DockerV2Schema2LayerMediaType = "application/vnd.docker.image.rootfs.diff.tar.gzip" + // DockerV2SchemeLayerMediaTypeUncompressed is the mediaType used for layers which are not compressed. + DockerV2SchemeLayerMediaTypeUncompressed = "application/vnd.docker.image.rootfs.diff.tar" // DockerV2ListMediaType MIME type represents Docker manifest schema 2 list DockerV2ListMediaType = "application/vnd.docker.distribution.manifest.list.v2+json" // DockerV2Schema2ForeignLayerMediaType is the MIME type used for schema 2 foreign layers.