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 }