123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*
- 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 proxy
- 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/containerd/pkg/epoch"
- "github.com/containerd/containerd/protobuf"
- ptypes "github.com/containerd/containerd/protobuf/types"
- "github.com/opencontainers/go-digest"
- ocispec "github.com/opencontainers/image-spec/specs-go/v1"
- "google.golang.org/protobuf/types/known/timestamppb"
- )
- // NewDiffApplier returns a new comparer and applier which communicates
- // over a GRPC connection.
- func NewDiffApplier(client diffapi.DiffClient) interface{} {
- return &diffRemote{
- client: client,
- }
- }
- type diffRemote struct {
- client diffapi.DiffClient
- }
- func (r *diffRemote) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount, opts ...diff.ApplyOpt) (ocispec.Descriptor, error) {
- var config diff.ApplyConfig
- for _, opt := range opts {
- if err := opt(ctx, desc, &config); err != nil {
- return ocispec.Descriptor{}, err
- }
- }
- payloads := make(map[string]*ptypes.Any)
- for k, v := range config.ProcessorPayloads {
- payloads[k] = protobuf.FromAny(v)
- }
- req := &diffapi.ApplyRequest{
- Diff: fromDescriptor(desc),
- Mounts: fromMounts(mounts),
- Payloads: payloads,
- SyncFs: config.SyncFs,
- }
- resp, err := r.client.Apply(ctx, req)
- if err != nil {
- return ocispec.Descriptor{}, errdefs.FromGRPC(err)
- }
- return toDescriptor(resp.Applied), nil
- }
- func (r *diffRemote) Compare(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
- }
- }
- if tm := epoch.FromContext(ctx); tm != nil && config.SourceDateEpoch == nil {
- config.SourceDateEpoch = tm
- }
- var sourceDateEpoch *timestamppb.Timestamp
- if config.SourceDateEpoch != nil {
- sourceDateEpoch = timestamppb.New(*config.SourceDateEpoch)
- }
- req := &diffapi.DiffRequest{
- Left: fromMounts(a),
- Right: fromMounts(b),
- MediaType: config.MediaType,
- Ref: config.Reference,
- Labels: config.Labels,
- SourceDateEpoch: sourceDateEpoch,
- }
- resp, err := r.client.Diff(ctx, req)
- if err != nil {
- return ocispec.Descriptor{}, errdefs.FromGRPC(err)
- }
- return toDescriptor(resp.Diff), nil
- }
- 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,
- }
- }
- 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,
- Target: m.Target,
- Options: m.Options,
- }
- }
- return apiMounts
- }
|