...

Source file src/github.com/containerd/containerd/contrib/diffservice/service.go

Documentation: github.com/containerd/containerd/contrib/diffservice

     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 diffservice
    18  
    19  import (
    20  	"context"
    21  
    22  	diffapi "github.com/containerd/containerd/api/services/diff/v1"
    23  	"github.com/containerd/containerd/api/types"
    24  	"github.com/containerd/containerd/diff"
    25  	"github.com/containerd/containerd/errdefs"
    26  	"github.com/containerd/containerd/mount"
    27  	"github.com/containerd/typeurl/v2"
    28  	"github.com/opencontainers/go-digest"
    29  	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
    30  )
    31  
    32  type service struct {
    33  	applier  diff.Applier
    34  	comparer diff.Comparer
    35  	diffapi.UnimplementedDiffServer
    36  }
    37  
    38  func FromApplierAndComparer(a diff.Applier, c diff.Comparer) diffapi.DiffServer {
    39  	return &service{
    40  		applier:  a,
    41  		comparer: c,
    42  	}
    43  }
    44  func (s *service) Apply(ctx context.Context, er *diffapi.ApplyRequest) (*diffapi.ApplyResponse, error) {
    45  	if s.applier == nil {
    46  		return nil, errdefs.ToGRPC(errdefs.ErrNotImplemented)
    47  	}
    48  
    49  	var (
    50  		ocidesc ocispec.Descriptor
    51  		err     error
    52  		desc    = toDescriptor(er.Diff)
    53  		mounts  = toMounts(er.Mounts)
    54  	)
    55  
    56  	var opts []diff.ApplyOpt
    57  	if er.Payloads != nil {
    58  		payloads := make(map[string]typeurl.Any)
    59  		for k, v := range er.Payloads {
    60  			payloads[k] = v
    61  		}
    62  		opts = append(opts, diff.WithPayloads(payloads))
    63  	}
    64  
    65  	ocidesc, err = s.applier.Apply(ctx, desc, mounts, opts...)
    66  	if err != nil {
    67  		return nil, errdefs.ToGRPC(err)
    68  	}
    69  
    70  	return &diffapi.ApplyResponse{
    71  		Applied: fromDescriptor(ocidesc),
    72  	}, nil
    73  }
    74  
    75  func (s *service) Diff(ctx context.Context, dr *diffapi.DiffRequest) (*diffapi.DiffResponse, error) {
    76  	if s.comparer == nil {
    77  		return nil, errdefs.ToGRPC(errdefs.ErrNotImplemented)
    78  	}
    79  	var (
    80  		ocidesc ocispec.Descriptor
    81  		err     error
    82  		aMounts = toMounts(dr.Left)
    83  		bMounts = toMounts(dr.Right)
    84  	)
    85  
    86  	var opts []diff.Opt
    87  	if dr.MediaType != "" {
    88  		opts = append(opts, diff.WithMediaType(dr.MediaType))
    89  	}
    90  	if dr.Ref != "" {
    91  		opts = append(opts, diff.WithReference(dr.Ref))
    92  	}
    93  	if dr.Labels != nil {
    94  		opts = append(opts, diff.WithLabels(dr.Labels))
    95  	}
    96  	if dr.SourceDateEpoch != nil {
    97  		tm := dr.SourceDateEpoch.AsTime()
    98  		opts = append(opts, diff.WithSourceDateEpoch(&tm))
    99  	}
   100  
   101  	ocidesc, err = s.comparer.Compare(ctx, aMounts, bMounts, opts...)
   102  	if err != nil {
   103  		return nil, errdefs.ToGRPC(err)
   104  	}
   105  
   106  	return &diffapi.DiffResponse{
   107  		Diff: fromDescriptor(ocidesc),
   108  	}, nil
   109  }
   110  
   111  func toMounts(apim []*types.Mount) []mount.Mount {
   112  	mounts := make([]mount.Mount, len(apim))
   113  	for i, m := range apim {
   114  		mounts[i] = mount.Mount{
   115  			Type:    m.Type,
   116  			Source:  m.Source,
   117  			Target:  m.Target,
   118  			Options: m.Options,
   119  		}
   120  	}
   121  	return mounts
   122  }
   123  
   124  func toDescriptor(d *types.Descriptor) ocispec.Descriptor {
   125  	return ocispec.Descriptor{
   126  		MediaType:   d.MediaType,
   127  		Digest:      digest.Digest(d.Digest),
   128  		Size:        d.Size,
   129  		Annotations: d.Annotations,
   130  	}
   131  }
   132  
   133  func fromDescriptor(d ocispec.Descriptor) *types.Descriptor {
   134  	return &types.Descriptor{
   135  		MediaType:   d.MediaType,
   136  		Digest:      d.Digest.String(),
   137  		Size:        d.Size,
   138  		Annotations: d.Annotations,
   139  	}
   140  }
   141  

View as plain text