github.com/containerd/nerdctl@v1.7.7/pkg/imgutil/snapshotter.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 imgutil 18 19 import ( 20 "strings" 21 22 socisource "github.com/awslabs/soci-snapshotter/fs/source" 23 "github.com/containerd/containerd" 24 "github.com/containerd/containerd/images" 25 ctdsnapshotters "github.com/containerd/containerd/pkg/snapshotters" 26 "github.com/containerd/log" 27 "github.com/containerd/nerdctl/pkg/imgutil/pull" 28 "github.com/containerd/stargz-snapshotter/fs/source" 29 ) 30 31 const ( 32 snapshotterNameOverlaybd = "overlaybd" 33 snapshotterNameStargz = "stargz" 34 snapshotterNameNydus = "nydus" 35 snapshotterNameSoci = "soci" 36 snapshotterNameCvmfs = "cvmfs-snapshotter" 37 38 // prefetch size for stargz 39 prefetchSize = 10 * 1024 * 1024 40 ) 41 42 // remote snapshotters explicitly handled by nerdctl 43 var builtinRemoteSnapshotterOpts = map[string]snapshotterOpts{ 44 snapshotterNameOverlaybd: &remoteSnapshotterOpts{snapshotter: "overlaybd"}, 45 snapshotterNameStargz: &remoteSnapshotterOpts{snapshotter: "stargz", extraLabels: stargzExtraLabels}, 46 snapshotterNameNydus: &remoteSnapshotterOpts{snapshotter: "nydus"}, 47 snapshotterNameSoci: &remoteSnapshotterOpts{snapshotter: "soci", extraLabels: sociExtraLabels}, 48 snapshotterNameCvmfs: &remoteSnapshotterOpts{snapshotter: "cvmfs-snapshotter"}, 49 } 50 51 type RemoteSnapshotterFlags struct { 52 SociIndexDigest string 53 } 54 55 // snapshotterOpts is used to update pull config 56 // for different snapshotters 57 type snapshotterOpts interface { 58 apply(config *pull.Config, ref string, rFlags RemoteSnapshotterFlags) 59 isRemote() bool 60 } 61 62 // getSnapshotterOpts get snapshotter opts by fuzzy matching of the snapshotter name 63 func getSnapshotterOpts(snapshotter string) snapshotterOpts { 64 for sn, sno := range builtinRemoteSnapshotterOpts { 65 if strings.Contains(snapshotter, sn) { 66 if snapshotter != sn { 67 log.L.Debugf("assuming %s to be a %s-compatible snapshotter", snapshotter, sn) 68 } 69 return sno 70 } 71 } 72 73 return &defaultSnapshotterOpts{snapshotter: snapshotter} 74 } 75 76 // remoteSnapshotterOpts is used as a remote snapshotter implementation for 77 // interface `snapshotterOpts.isRemote()` function 78 type remoteSnapshotterOpts struct { 79 snapshotter string 80 extraLabels func(func(images.Handler) images.Handler, RemoteSnapshotterFlags) func(images.Handler) images.Handler 81 } 82 83 func (rs *remoteSnapshotterOpts) isRemote() bool { 84 return true 85 } 86 87 func (rs *remoteSnapshotterOpts) apply(config *pull.Config, ref string, rFlags RemoteSnapshotterFlags) { 88 h := ctdsnapshotters.AppendInfoHandlerWrapper(ref) 89 if rs.extraLabels != nil { 90 h = rs.extraLabels(h, rFlags) 91 } 92 config.RemoteOpts = append( 93 config.RemoteOpts, 94 containerd.WithImageHandlerWrapper(h), 95 containerd.WithPullSnapshotter(rs.snapshotter), 96 ) 97 } 98 99 // defaultSnapshotterOpts is for snapshotters that 100 // not handled separately 101 type defaultSnapshotterOpts struct { 102 snapshotter string 103 } 104 105 func (dsn *defaultSnapshotterOpts) apply(config *pull.Config, _ref string, rFlags RemoteSnapshotterFlags) { 106 config.RemoteOpts = append( 107 config.RemoteOpts, 108 containerd.WithPullSnapshotter(dsn.snapshotter)) 109 } 110 111 // defaultSnapshotterOpts is not a remote snapshotter 112 func (dsn *defaultSnapshotterOpts) isRemote() bool { 113 return false 114 } 115 116 func stargzExtraLabels(f func(images.Handler) images.Handler, rFlags RemoteSnapshotterFlags) func(images.Handler) images.Handler { 117 return source.AppendExtraLabelsHandler(prefetchSize, f) 118 } 119 120 func sociExtraLabels(f func(images.Handler) images.Handler, rFlags RemoteSnapshotterFlags) func(images.Handler) images.Handler { 121 return socisource.AppendDefaultLabelsHandlerWrapper(rFlags.SociIndexDigest, f) 122 }