package diff import ( diffapi "github.com/containerd/containerd/api/services/diff/v1" "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/diff" "github.com/containerd/containerd/mount" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/net/context" ) // NewApplierFromClient returns a new Applier which communicates // over a GRPC connection. func NewDiffServiceFromClient(client diffapi.DiffClient) diff.Differ { return &remote{ client: client, } } type remote struct { client diffapi.DiffClient } func (r *remote) Apply(ctx context.Context, diff ocispec.Descriptor, mounts []mount.Mount) (ocispec.Descriptor, error) { req := &diffapi.ApplyRequest{ Diff: fromDescriptor(diff), Mounts: fromMounts(mounts), } resp, err := r.client.Apply(ctx, req) if err != nil { return ocispec.Descriptor{}, err } return toDescriptor(resp.Applied), nil } func (r *remote) DiffMounts(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) { var config diff.Config for _, opt := range opts { if err := opt(&config); err != nil { return ocispec.Descriptor{}, err } } req := &diffapi.DiffRequest{ Left: fromMounts(a), Right: fromMounts(b), MediaType: config.MediaType, Ref: config.Reference, Labels: config.Labels, } resp, err := r.client.Diff(ctx, req) if err != nil { return ocispec.Descriptor{}, err } return toDescriptor(resp.Diff), nil } func toDescriptor(d *types.Descriptor) ocispec.Descriptor { return ocispec.Descriptor{ MediaType: d.MediaType, Digest: d.Digest, Size: d.Size_, } } func fromDescriptor(d ocispec.Descriptor) *types.Descriptor { return &types.Descriptor{ MediaType: d.MediaType, Digest: d.Digest, Size_: d.Size, } } func fromMounts(mounts []mount.Mount) []*types.Mount { apiMounts := make([]*types.Mount, len(mounts)) for i, m := range mounts { apiMounts[i] = &types.Mount{ Type: m.Type, Source: m.Source, Options: m.Options, } } return apiMounts }