github.com/containerd/Containerd@v1.4.13/rootfs/diff.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 rootfs 18 19 import ( 20 "context" 21 "fmt" 22 23 "github.com/containerd/containerd/diff" 24 "github.com/containerd/containerd/mount" 25 "github.com/containerd/containerd/namespaces" 26 "github.com/containerd/containerd/snapshots" 27 ocispec "github.com/opencontainers/image-spec/specs-go/v1" 28 ) 29 30 // CreateDiff creates a layer diff for the given snapshot identifier from the 31 // parent of the snapshot. A content ref is provided to track the progress of 32 // the content creation and the provided snapshotter and mount differ are used 33 // for calculating the diff. The descriptor for the layer diff is returned. 34 func CreateDiff(ctx context.Context, snapshotID string, sn snapshots.Snapshotter, d diff.Comparer, opts ...diff.Opt) (ocispec.Descriptor, error) { 35 // dctx is used to handle cleanup things just in case the param ctx 36 // has been canceled, which causes that the defer cleanup fails. 37 dctx := context.Background() 38 if ns, ok := namespaces.Namespace(ctx); ok { 39 dctx = namespaces.WithNamespace(dctx, ns) 40 } 41 42 info, err := sn.Stat(ctx, snapshotID) 43 if err != nil { 44 return ocispec.Descriptor{}, err 45 } 46 47 lowerKey := fmt.Sprintf("%s-parent-view", info.Parent) 48 lower, err := sn.View(ctx, lowerKey, info.Parent) 49 if err != nil { 50 return ocispec.Descriptor{}, err 51 } 52 defer sn.Remove(dctx, lowerKey) 53 54 var upper []mount.Mount 55 if info.Kind == snapshots.KindActive { 56 upper, err = sn.Mounts(ctx, snapshotID) 57 if err != nil { 58 return ocispec.Descriptor{}, err 59 } 60 } else { 61 upperKey := fmt.Sprintf("%s-view", snapshotID) 62 upper, err = sn.View(ctx, upperKey, snapshotID) 63 if err != nil { 64 return ocispec.Descriptor{}, err 65 } 66 defer sn.Remove(dctx, upperKey) 67 } 68 69 return d.Compare(ctx, lower, upper, opts...) 70 }