Skip to content

Commit 32e3b76

Browse files
dmcgowandcantah
authored andcommitted
Add diffservice to contrib
Signed-off-by: Derek McGowan <[email protected]> (cherry picked from commit 745ec84) Signed-off-by: Danny Canter <[email protected]>
1 parent 661e505 commit 32e3b76

1 file changed

Lines changed: 140 additions & 0 deletions

File tree

contrib/diffservice/service.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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+
}

0 commit comments

Comments
 (0)