...
1
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