github.com/demonoid81/containerd@v1.3.4/images/mediatypes.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package images
    18  
    19  import (
    20  	"context"
    21  	"sort"
    22  	"strings"
    23  
    24  	"github.com/containerd/containerd/errdefs"
    25  	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
    26  )
    27  
    28  // mediatype definitions for image components handled in containerd.
    29  //
    30  // oci components are generally referenced directly, although we may centralize
    31  // here for clarity.
    32  const (
    33  	MediaTypeDockerSchema2Layer            = "application/vnd.docker.image.rootfs.diff.tar"
    34  	MediaTypeDockerSchema2LayerForeign     = "application/vnd.docker.image.rootfs.foreign.diff.tar"
    35  	MediaTypeDockerSchema2LayerGzip        = "application/vnd.docker.image.rootfs.diff.tar.gzip"
    36  	MediaTypeDockerSchema2LayerForeignGzip = "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip"
    37  	MediaTypeDockerSchema2Config           = "application/vnd.docker.container.image.v1+json"
    38  	MediaTypeDockerSchema2Manifest         = "application/vnd.docker.distribution.manifest.v2+json"
    39  	MediaTypeDockerSchema2ManifestList     = "application/vnd.docker.distribution.manifest.list.v2+json"
    40  	// Checkpoint/Restore Media Types
    41  	MediaTypeContainerd1Checkpoint               = "application/vnd.containerd.container.criu.checkpoint.criu.tar"
    42  	MediaTypeContainerd1CheckpointPreDump        = "application/vnd.containerd.container.criu.checkpoint.predump.tar"
    43  	MediaTypeContainerd1Resource                 = "application/vnd.containerd.container.resource.tar"
    44  	MediaTypeContainerd1RW                       = "application/vnd.containerd.container.rw.tar"
    45  	MediaTypeContainerd1CheckpointConfig         = "application/vnd.containerd.container.checkpoint.config.v1+proto"
    46  	MediaTypeContainerd1CheckpointOptions        = "application/vnd.containerd.container.checkpoint.options.v1+proto"
    47  	MediaTypeContainerd1CheckpointRuntimeName    = "application/vnd.containerd.container.checkpoint.runtime.name"
    48  	MediaTypeContainerd1CheckpointRuntimeOptions = "application/vnd.containerd.container.checkpoint.runtime.options+proto"
    49  	// Legacy Docker schema1 manifest
    50  	MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
    51  )
    52  
    53  // DiffCompression returns the compression as defined by the layer diff media
    54  // type. For Docker media types without compression, "unknown" is returned to
    55  // indicate that the media type may be compressed. If the media type is not
    56  // recognized as a layer diff, then it returns errdefs.ErrNotImplemented
    57  func DiffCompression(ctx context.Context, mediaType string) (string, error) {
    58  	base, ext := parseMediaTypes(mediaType)
    59  	switch base {
    60  	case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerForeign:
    61  		if len(ext) > 0 {
    62  			// Type is wrapped
    63  			return "", nil
    64  		}
    65  		// These media types may have been compressed but failed to
    66  		// use the correct media type. The decompression function
    67  		// should detect and handle this case.
    68  		return "unknown", nil
    69  	case MediaTypeDockerSchema2LayerGzip, MediaTypeDockerSchema2LayerForeignGzip:
    70  		if len(ext) > 0 {
    71  			// Type is wrapped
    72  			return "", nil
    73  		}
    74  		return "gzip", nil
    75  	case ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerNonDistributable:
    76  		if len(ext) > 0 {
    77  			switch ext[len(ext)-1] {
    78  			case "gzip":
    79  				return "gzip", nil
    80  			}
    81  		}
    82  		return "", nil
    83  	default:
    84  		return "", errdefs.ErrNotImplemented
    85  	}
    86  }
    87  
    88  // parseMediaTypes splits the media type into the base type and
    89  // an array of sorted extensions
    90  func parseMediaTypes(mt string) (string, []string) {
    91  	if mt == "" {
    92  		return "", []string{}
    93  	}
    94  
    95  	s := strings.Split(mt, "+")
    96  	ext := s[1:]
    97  	sort.Strings(ext)
    98  
    99  	return s[0], ext
   100  }
   101  
   102  // IsLayerTypes returns true if the media type is a layer
   103  func IsLayerType(mt string) bool {
   104  	if strings.HasPrefix(mt, "application/vnd.oci.image.layer.") {
   105  		return true
   106  	}
   107  
   108  	// Parse Docker media types, strip off any + suffixes first
   109  	base, _ := parseMediaTypes(mt)
   110  	switch base {
   111  	case MediaTypeDockerSchema2Layer, MediaTypeDockerSchema2LayerGzip,
   112  		MediaTypeDockerSchema2LayerForeign, MediaTypeDockerSchema2LayerForeignGzip:
   113  		return true
   114  	}
   115  	return false
   116  }
   117  
   118  // IsKnownConfig returns true if the media type is a known config type
   119  func IsKnownConfig(mt string) bool {
   120  	switch mt {
   121  	case MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig,
   122  		MediaTypeContainerd1Checkpoint, MediaTypeContainerd1CheckpointConfig:
   123  		return true
   124  	}
   125  	return false
   126  }