From 745ec84e5adbadcabc37dad974768a6ba5917eb8 Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Sat, 15 Apr 2023 23:16:29 -0700 Subject: [PATCH] Add diffservice to contrib Signed-off-by: Derek McGowan --- contrib/diffservice/service.go | 140 +++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 contrib/diffservice/service.go diff --git a/contrib/diffservice/service.go b/contrib/diffservice/service.go new file mode 100644 index 000000000..a28db0536 --- /dev/null +++ b/contrib/diffservice/service.go @@ -0,0 +1,140 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package diffservice + +import ( + "context" + + diffapi "github.com/containerd/containerd/api/services/diff/v1" + "github.com/containerd/containerd/api/types" + "github.com/containerd/containerd/diff" + "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/mount" + "github.com/containerd/typeurl/v2" + "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +type service struct { + applier diff.Applier + comparer diff.Comparer + diffapi.UnimplementedDiffServer +} + +func FromApplierAndComparer(a diff.Applier, c diff.Comparer) diffapi.DiffServer { + return &service{ + applier: a, + comparer: c, + } +} +func (s *service) Apply(ctx context.Context, er *diffapi.ApplyRequest) (*diffapi.ApplyResponse, error) { + if s.applier == nil { + return nil, errdefs.ToGRPC(errdefs.ErrNotImplemented) + } + + var ( + ocidesc ocispec.Descriptor + err error + desc = toDescriptor(er.Diff) + mounts = toMounts(er.Mounts) + ) + + var opts []diff.ApplyOpt + if er.Payloads != nil { + payloads := make(map[string]typeurl.Any) + for k, v := range er.Payloads { + payloads[k] = v + } + opts = append(opts, diff.WithPayloads(payloads)) + } + + ocidesc, err = s.applier.Apply(ctx, desc, mounts, opts...) + if err != nil { + return nil, errdefs.ToGRPC(err) + } + + return &diffapi.ApplyResponse{ + Applied: fromDescriptor(ocidesc), + }, nil +} + +func (s *service) Diff(ctx context.Context, dr *diffapi.DiffRequest) (*diffapi.DiffResponse, error) { + if s.comparer == nil { + return nil, errdefs.ToGRPC(errdefs.ErrNotImplemented) + } + var ( + ocidesc ocispec.Descriptor + err error + aMounts = toMounts(dr.Left) + bMounts = toMounts(dr.Right) + ) + + var opts []diff.Opt + if dr.MediaType != "" { + opts = append(opts, diff.WithMediaType(dr.MediaType)) + } + if dr.Ref != "" { + opts = append(opts, diff.WithReference(dr.Ref)) + } + if dr.Labels != nil { + opts = append(opts, diff.WithLabels(dr.Labels)) + } + if dr.SourceDateEpoch != nil { + tm := dr.SourceDateEpoch.AsTime() + opts = append(opts, diff.WithSourceDateEpoch(&tm)) + } + + ocidesc, err = s.comparer.Compare(ctx, aMounts, bMounts, opts...) + if err != nil { + return nil, errdefs.ToGRPC(err) + } + + return &diffapi.DiffResponse{ + Diff: fromDescriptor(ocidesc), + }, nil +} + +func toMounts(apim []*types.Mount) []mount.Mount { + mounts := make([]mount.Mount, len(apim)) + for i, m := range apim { + mounts[i] = mount.Mount{ + Type: m.Type, + Source: m.Source, + Target: m.Target, + Options: m.Options, + } + } + return mounts +} + +func toDescriptor(d *types.Descriptor) ocispec.Descriptor { + return ocispec.Descriptor{ + MediaType: d.MediaType, + Digest: digest.Digest(d.Digest), + Size: d.Size, + Annotations: d.Annotations, + } +} + +func fromDescriptor(d ocispec.Descriptor) *types.Descriptor { + return &types.Descriptor{ + MediaType: d.MediaType, + Digest: d.Digest.String(), + Size: d.Size, + Annotations: d.Annotations, + } +}