diff --git a/diff/walking/differ.go b/diff/walking/differ.go index eb6c2df70..f1dbf43f5 100644 --- a/diff/walking/differ.go +++ b/diff/walking/differ.go @@ -6,7 +6,6 @@ import ( "fmt" "io" "io/ioutil" - "strings" "time" "github.com/containerd/containerd/archive" @@ -75,18 +74,10 @@ func (s *walkingDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts }).Debugf("diff applied") } }() - var isCompressed bool - switch desc.MediaType { - case ocispec.MediaTypeImageLayer, images.MediaTypeDockerSchema2Layer: - case ocispec.MediaTypeImageLayerGzip, images.MediaTypeDockerSchema2LayerGzip: - isCompressed = true - default: - // Still apply all generic media types *.tar[.+]gzip and *.tar - if strings.HasSuffix(desc.MediaType, ".tar.gzip") || strings.HasSuffix(desc.MediaType, ".tar+gzip") { - isCompressed = true - } else if !strings.HasSuffix(desc.MediaType, ".tar") { - return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", desc.MediaType) - } + + isCompressed, err := images.IsCompressedDiff(ctx, desc.MediaType) + if err != nil { + return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", desc.MediaType) } var ocidesc ocispec.Descriptor diff --git a/diff/windows/windows.go b/diff/windows/windows.go index b288027c9..0bb79e15e 100644 --- a/diff/windows/windows.go +++ b/diff/windows/windows.go @@ -5,7 +5,6 @@ package windows import ( "io" "io/ioutil" - "strings" "time" winio "github.com/Microsoft/go-winio" @@ -74,18 +73,10 @@ func (s *windowsDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts }).Debugf("diff applied") } }() - var isCompressed bool - switch desc.MediaType { - case ocispec.MediaTypeImageLayer, images.MediaTypeDockerSchema2Layer: - case ocispec.MediaTypeImageLayerGzip, images.MediaTypeDockerSchema2LayerGzip: - isCompressed = true - default: - // Still apply all generic media types *.tar[.+]gzip and *.tar - if strings.HasSuffix(desc.MediaType, ".tar.gzip") || strings.HasSuffix(desc.MediaType, ".tar+gzip") { - isCompressed = true - } else if !strings.HasSuffix(desc.MediaType, ".tar") { - return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", desc.MediaType) - } + + isCompressed, err := images.IsCompressedDiff(ctx, desc.MediaType) + if err != nil { + return emptyDesc, errors.Wrapf(errdefs.ErrNotImplemented, "unsupported diff media type: %v", desc.MediaType) } ra, err := s.store.ReaderAt(ctx, desc.Digest) diff --git a/images/image.go b/images/image.go index 3f58e0620..5fea0dcfc 100644 --- a/images/image.go +++ b/images/image.go @@ -3,6 +3,7 @@ package images import ( "context" "encoding/json" + "strings" "time" "github.com/containerd/containerd/content" @@ -359,3 +360,22 @@ func RootFS(ctx context.Context, provider content.Provider, configDesc ocispec.D } return config.RootFS.DiffIDs, nil } + +// IsCompressedDiff returns true if mediaType is a known compressed diff media type. +// It returns false if the media type is a diff, but not compressed. If the media type +// is not a known diff type, it returns errdefs.ErrNotImplemented +func IsCompressedDiff(ctx context.Context, mediaType string) (bool, error) { + switch mediaType { + case ocispec.MediaTypeImageLayer, MediaTypeDockerSchema2Layer: + case ocispec.MediaTypeImageLayerGzip, MediaTypeDockerSchema2LayerGzip: + return true, nil + default: + // Still apply all generic media types *.tar[.+]gzip and *.tar + if strings.HasSuffix(mediaType, ".tar.gzip") || strings.HasSuffix(mediaType, ".tar+gzip") { + return true, nil + } else if !strings.HasSuffix(mediaType, ".tar") { + return false, errdefs.ErrNotImplemented + } + } + return false, nil +}