From 55a8102ec159181307c454324d44ddaef67e3f41 Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Wed, 28 Jun 2023 04:03:18 -0700 Subject: [PATCH 1/4] mount: Add From/ToProto helpers Helpers to convert from containerd's [Mount] to its protobuf structure for [Mount] and vice-versa appear three times. It seems sane to just expose this facility in /mount. Signed-off-by: Danny Canter --- contrib/diffservice/service.go | 19 +++--------------- contrib/snapshotservice/service.go | 20 +++---------------- diff/proxy/differ.go | 19 +++--------------- mount/mount.go | 31 ++++++++++++++++++++++++++++++ services/diff/local.go | 19 +++--------------- services/snapshots/service.go | 20 +++---------------- snapshots/proxy/proxy.go | 20 +++---------------- 7 files changed, 49 insertions(+), 99 deletions(-) diff --git a/contrib/diffservice/service.go b/contrib/diffservice/service.go index a28db0536..c8e25a371 100644 --- a/contrib/diffservice/service.go +++ b/contrib/diffservice/service.go @@ -50,7 +50,7 @@ func (s *service) Apply(ctx context.Context, er *diffapi.ApplyRequest) (*diffapi ocidesc ocispec.Descriptor err error desc = toDescriptor(er.Diff) - mounts = toMounts(er.Mounts) + mounts = mount.FromProto(er.Mounts) ) var opts []diff.ApplyOpt @@ -79,8 +79,8 @@ func (s *service) Diff(ctx context.Context, dr *diffapi.DiffRequest) (*diffapi.D var ( ocidesc ocispec.Descriptor err error - aMounts = toMounts(dr.Left) - bMounts = toMounts(dr.Right) + aMounts = mount.FromProto(dr.Left) + bMounts = mount.FromProto(dr.Right) ) var opts []diff.Opt @@ -108,19 +108,6 @@ func (s *service) Diff(ctx context.Context, dr *diffapi.DiffRequest) (*diffapi.D }, 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, diff --git a/contrib/snapshotservice/service.go b/contrib/snapshotservice/service.go index a649d73df..d7ca2b38b 100644 --- a/contrib/snapshotservice/service.go +++ b/contrib/snapshotservice/service.go @@ -20,7 +20,6 @@ import ( "context" snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" - "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/protobuf" @@ -51,7 +50,7 @@ func (s service) Prepare(ctx context.Context, pr *snapshotsapi.PrepareSnapshotRe } return &snapshotsapi.PrepareSnapshotResponse{ - Mounts: fromMounts(mounts), + Mounts: mount.ToProto(mounts), }, nil } @@ -65,7 +64,7 @@ func (s service) View(ctx context.Context, pr *snapshotsapi.ViewSnapshotRequest) return nil, errdefs.ToGRPC(err) } return &snapshotsapi.ViewSnapshotResponse{ - Mounts: fromMounts(mounts), + Mounts: mount.ToProto(mounts), }, nil } @@ -75,7 +74,7 @@ func (s service) Mounts(ctx context.Context, mr *snapshotsapi.MountsRequest) (*s return nil, errdefs.ToGRPC(err) } return &snapshotsapi.MountsResponse{ - Mounts: fromMounts(mounts), + Mounts: mount.ToProto(mounts), }, nil } @@ -199,19 +198,6 @@ func fromInfo(info snapshots.Info) *snapshotsapi.Info { } } -func fromMounts(mounts []mount.Mount) []*types.Mount { - out := make([]*types.Mount, len(mounts)) - for i, m := range mounts { - out[i] = &types.Mount{ - Type: m.Type, - Source: m.Source, - Target: m.Target, - Options: m.Options, - } - } - return out -} - func toInfo(info *snapshotsapi.Info) snapshots.Info { return snapshots.Info{ Name: info.Name, diff --git a/diff/proxy/differ.go b/diff/proxy/differ.go index f0e547f81..67b0efc66 100644 --- a/diff/proxy/differ.go +++ b/diff/proxy/differ.go @@ -60,7 +60,7 @@ func (r *diffRemote) Apply(ctx context.Context, desc ocispec.Descriptor, mounts req := &diffapi.ApplyRequest{ Diff: fromDescriptor(desc), - Mounts: fromMounts(mounts), + Mounts: mount.ToProto(mounts), Payloads: payloads, } resp, err := r.client.Apply(ctx, req) @@ -85,8 +85,8 @@ func (r *diffRemote) Compare(ctx context.Context, a, b []mount.Mount, opts ...di sourceDateEpoch = timestamppb.New(*config.SourceDateEpoch) } req := &diffapi.DiffRequest{ - Left: fromMounts(a), - Right: fromMounts(b), + Left: mount.ToProto(a), + Right: mount.ToProto(b), MediaType: config.MediaType, Ref: config.Reference, Labels: config.Labels, @@ -119,16 +119,3 @@ func fromDescriptor(d ocispec.Descriptor) *types.Descriptor { 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 -} diff --git a/mount/mount.go b/mount/mount.go index ae7520f98..defb1b944 100644 --- a/mount/mount.go +++ b/mount/mount.go @@ -20,6 +20,7 @@ import ( "fmt" "strings" + "github.com/containerd/containerd/api/types" "github.com/containerd/continuity/fs" ) @@ -130,3 +131,33 @@ func readonlyOverlay(opt []string) []string { } return out } + +// ToProto converts from [Mount] to the containerd +// APIs protobuf definition of a Mount. +func ToProto(mounts []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 +} + +// FromProto converts from the protobuf definition [types.Mount] to +// [Mount]. +func FromProto(mm []*types.Mount) []Mount { + mounts := make([]Mount, len(mm)) + for i, m := range mm { + mounts[i] = Mount{ + Type: m.Type, + Source: m.Source, + Target: m.Target, + Options: m.Options, + } + } + return mounts +} diff --git a/services/diff/local.go b/services/diff/local.go index a6c5c39d4..20c5468fb 100644 --- a/services/diff/local.go +++ b/services/diff/local.go @@ -98,7 +98,7 @@ func (l *local) Apply(ctx context.Context, er *diffapi.ApplyRequest, _ ...grpc.C ocidesc ocispec.Descriptor err error desc = toDescriptor(er.Diff) - mounts = toMounts(er.Mounts) + mounts = mount.FromProto(er.Mounts) ) var opts []diff.ApplyOpt @@ -131,8 +131,8 @@ func (l *local) Diff(ctx context.Context, dr *diffapi.DiffRequest, _ ...grpc.Cal var ( ocidesc ocispec.Descriptor err error - aMounts = toMounts(dr.Left) - bMounts = toMounts(dr.Right) + aMounts = mount.FromProto(dr.Left) + bMounts = mount.FromProto(dr.Right) ) var opts []diff.Opt @@ -165,19 +165,6 @@ func (l *local) Diff(ctx context.Context, dr *diffapi.DiffRequest, _ ...grpc.Cal }, 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, diff --git a/services/snapshots/service.go b/services/snapshots/service.go index 4249f02e9..7d1c22e58 100644 --- a/services/snapshots/service.go +++ b/services/snapshots/service.go @@ -21,7 +21,6 @@ import ( "errors" snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" - "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" @@ -102,7 +101,7 @@ func (s *service) Prepare(ctx context.Context, pr *snapshotsapi.PrepareSnapshotR } return &snapshotsapi.PrepareSnapshotResponse{ - Mounts: fromMounts(mounts), + Mounts: mount.ToProto(mounts), }, nil } @@ -121,7 +120,7 @@ func (s *service) View(ctx context.Context, pr *snapshotsapi.ViewSnapshotRequest return nil, errdefs.ToGRPC(err) } return &snapshotsapi.ViewSnapshotResponse{ - Mounts: fromMounts(mounts), + Mounts: mount.ToProto(mounts), }, nil } @@ -137,7 +136,7 @@ func (s *service) Mounts(ctx context.Context, mr *snapshotsapi.MountsRequest) (* return nil, errdefs.ToGRPC(err) } return &snapshotsapi.MountsResponse{ - Mounts: fromMounts(mounts), + Mounts: mount.ToProto(mounts), }, nil } @@ -304,19 +303,6 @@ func fromUsage(usage snapshots.Usage) *snapshotsapi.UsageResponse { } } -func fromMounts(mounts []mount.Mount) []*types.Mount { - out := make([]*types.Mount, len(mounts)) - for i, m := range mounts { - out[i] = &types.Mount{ - Type: m.Type, - Source: m.Source, - Target: m.Target, - Options: m.Options, - } - } - return out -} - func toInfo(info *snapshotsapi.Info) snapshots.Info { return snapshots.Info{ Name: info.Name, diff --git a/snapshots/proxy/proxy.go b/snapshots/proxy/proxy.go index 3ef3b2698..1ceda91f8 100644 --- a/snapshots/proxy/proxy.go +++ b/snapshots/proxy/proxy.go @@ -21,7 +21,6 @@ import ( "io" snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" - "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/protobuf" @@ -89,7 +88,7 @@ func (p *proxySnapshotter) Mounts(ctx context.Context, key string) ([]mount.Moun if err != nil { return nil, errdefs.FromGRPC(err) } - return toMounts(resp.Mounts), nil + return mount.FromProto(resp.Mounts), nil } func (p *proxySnapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { @@ -108,7 +107,7 @@ func (p *proxySnapshotter) Prepare(ctx context.Context, key, parent string, opts if err != nil { return nil, errdefs.FromGRPC(err) } - return toMounts(resp.Mounts), nil + return mount.FromProto(resp.Mounts), nil } func (p *proxySnapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) { @@ -127,7 +126,7 @@ func (p *proxySnapshotter) View(ctx context.Context, key, parent string, opts .. if err != nil { return nil, errdefs.FromGRPC(err) } - return toMounts(resp.Mounts), nil + return mount.FromProto(resp.Mounts), nil } func (p *proxySnapshotter) Commit(ctx context.Context, name, key string, opts ...snapshots.Opt) error { @@ -220,19 +219,6 @@ func toUsage(resp *snapshotsapi.UsageResponse) snapshots.Usage { } } -func toMounts(mm []*types.Mount) []mount.Mount { - mounts := make([]mount.Mount, len(mm)) - for i, m := range mm { - mounts[i] = mount.Mount{ - Type: m.Type, - Source: m.Source, - Target: m.Target, - Options: m.Options, - } - } - return mounts -} - func fromKind(kind snapshots.Kind) snapshotsapi.Kind { if kind == snapshots.KindActive { return snapshotsapi.Kind_ACTIVE From 0a6b8f0ee00c7bca5b4d1c9b8443bb15f0b5309e Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Wed, 28 Jun 2023 04:12:42 -0700 Subject: [PATCH 2/4] OCI: Add From/ToProto helpers for Descriptor Helpers to convert from the OCI image specs [Descriptor] to its protobuf structure for Descriptor and vice-versa appear three times. It seems sane to just expose this facility in /oci. Signed-off-by: Danny Canter --- contrib/diffservice/service.go | 27 ++++----------------------- diff/proxy/differ.go | 30 ++++-------------------------- oci/spec.go | 25 +++++++++++++++++++++++++ services/diff/local.go | 27 ++++----------------------- 4 files changed, 37 insertions(+), 72 deletions(-) diff --git a/contrib/diffservice/service.go b/contrib/diffservice/service.go index c8e25a371..fc5092670 100644 --- a/contrib/diffservice/service.go +++ b/contrib/diffservice/service.go @@ -20,12 +20,11 @@ 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/oci" "github.com/containerd/typeurl/v2" - "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -49,7 +48,7 @@ func (s *service) Apply(ctx context.Context, er *diffapi.ApplyRequest) (*diffapi var ( ocidesc ocispec.Descriptor err error - desc = toDescriptor(er.Diff) + desc = oci.DescriptorFromProto(er.Diff) mounts = mount.FromProto(er.Mounts) ) @@ -68,7 +67,7 @@ func (s *service) Apply(ctx context.Context, er *diffapi.ApplyRequest) (*diffapi } return &diffapi.ApplyResponse{ - Applied: fromDescriptor(ocidesc), + Applied: oci.DescriptorToProto(ocidesc), }, nil } @@ -104,24 +103,6 @@ func (s *service) Diff(ctx context.Context, dr *diffapi.DiffRequest) (*diffapi.D } return &diffapi.DiffResponse{ - Diff: fromDescriptor(ocidesc), + Diff: oci.DescriptorToProto(ocidesc), }, 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, - } -} diff --git a/diff/proxy/differ.go b/diff/proxy/differ.go index 67b0efc66..4e61bfdee 100644 --- a/diff/proxy/differ.go +++ b/diff/proxy/differ.go @@ -20,14 +20,13 @@ 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/oci" "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" @@ -59,7 +58,7 @@ func (r *diffRemote) Apply(ctx context.Context, desc ocispec.Descriptor, mounts } req := &diffapi.ApplyRequest{ - Diff: fromDescriptor(desc), + Diff: oci.DescriptorToProto(desc), Mounts: mount.ToProto(mounts), Payloads: payloads, } @@ -67,7 +66,7 @@ func (r *diffRemote) Apply(ctx context.Context, desc ocispec.Descriptor, mounts if err != nil { return ocispec.Descriptor{}, errdefs.FromGRPC(err) } - return toDescriptor(resp.Applied), nil + return oci.DescriptorFromProto(resp.Applied), nil } func (r *diffRemote) Compare(ctx context.Context, a, b []mount.Mount, opts ...diff.Opt) (ocispec.Descriptor, error) { @@ -96,26 +95,5 @@ func (r *diffRemote) Compare(ctx context.Context, a, b []mount.Mount, opts ...di if err != nil { return ocispec.Descriptor{}, errdefs.FromGRPC(err) } - return toDescriptor(resp.Diff), nil -} - -func toDescriptor(d *types.Descriptor) ocispec.Descriptor { - if d == nil { - return 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, - } + return oci.DescriptorFromProto(resp.Diff), nil } diff --git a/oci/spec.go b/oci/spec.go index bee3b44d6..23961b75d 100644 --- a/oci/spec.go +++ b/oci/spec.go @@ -21,8 +21,11 @@ import ( "path/filepath" "runtime" + "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runtime-spec/specs-go" + "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/platforms" @@ -220,3 +223,25 @@ func populateDefaultDarwinSpec(s *Spec) error { } return nil } + +// DescriptorFromProto converts containerds protobuf [types.Descriptor] +// to the OCI image specs [ocispec.Descriptor]. +func DescriptorFromProto(d *types.Descriptor) ocispec.Descriptor { + return ocispec.Descriptor{ + MediaType: d.MediaType, + Digest: digest.Digest(d.Digest), + Size: d.Size, + Annotations: d.Annotations, + } +} + +// DescriptorToProto converts the OCI image specs [ocispec.Descriptor] +// to containerds protobuf [types.Descriptor]. +func DescriptorToProto(d ocispec.Descriptor) *types.Descriptor { + return &types.Descriptor{ + MediaType: d.MediaType, + Digest: d.Digest.String(), + Size: d.Size, + Annotations: d.Annotations, + } +} diff --git a/services/diff/local.go b/services/diff/local.go index 20c5468fb..5f7d3f2b3 100644 --- a/services/diff/local.go +++ b/services/diff/local.go @@ -21,14 +21,13 @@ import ( "fmt" 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/oci" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/services" "github.com/containerd/typeurl/v2" - "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "google.golang.org/grpc" ) @@ -97,7 +96,7 @@ func (l *local) Apply(ctx context.Context, er *diffapi.ApplyRequest, _ ...grpc.C var ( ocidesc ocispec.Descriptor err error - desc = toDescriptor(er.Diff) + desc = oci.DescriptorFromProto(er.Diff) mounts = mount.FromProto(er.Mounts) ) @@ -122,7 +121,7 @@ func (l *local) Apply(ctx context.Context, er *diffapi.ApplyRequest, _ ...grpc.C } return &diffapi.ApplyResponse{ - Applied: fromDescriptor(ocidesc), + Applied: oci.DescriptorToProto(ocidesc), }, nil } @@ -161,24 +160,6 @@ func (l *local) Diff(ctx context.Context, dr *diffapi.DiffRequest, _ ...grpc.Cal } return &diffapi.DiffResponse{ - Diff: fromDescriptor(ocidesc), + Diff: oci.DescriptorToProto(ocidesc), }, 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, - } -} From b3ab1f26c4b90f6895888774a64d63565c2d01aa Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Wed, 28 Jun 2023 04:32:22 -0700 Subject: [PATCH 3/4] Snapshots: Add From/ToProto helpers for types Helpers to convert from snapshot types to their protobuf structures and vice-versa appear three times. It seems sane to just expose this facility in the snapshots pkg. From/ToKind weren't used anywhere but doesn't hurt to round out the types by exposing them. Signed-off-by: Danny Canter --- contrib/snapshotservice/service.go | 51 ++--------------------- services/snapshots/service.go | 60 +++----------------------- snapshots/proxy/proxy.go | 60 +++----------------------- snapshots/snapshotter.go | 67 ++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 157 deletions(-) diff --git a/contrib/snapshotservice/service.go b/contrib/snapshotservice/service.go index d7ca2b38b..d4508971e 100644 --- a/contrib/snapshotservice/service.go +++ b/contrib/snapshotservice/service.go @@ -22,7 +22,6 @@ import ( snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/protobuf" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/snapshots" ) @@ -104,16 +103,16 @@ func (s service) Stat(ctx context.Context, sr *snapshotsapi.StatSnapshotRequest) return nil, errdefs.ToGRPC(err) } - return &snapshotsapi.StatSnapshotResponse{Info: fromInfo(info)}, nil + return &snapshotsapi.StatSnapshotResponse{Info: snapshots.InfoToProto(info)}, nil } func (s service) Update(ctx context.Context, sr *snapshotsapi.UpdateSnapshotRequest) (*snapshotsapi.UpdateSnapshotResponse, error) { - info, err := s.sn.Update(ctx, toInfo(sr.Info), sr.UpdateMask.GetPaths()...) + info, err := s.sn.Update(ctx, snapshots.InfoFromProto(sr.Info), sr.UpdateMask.GetPaths()...) if err != nil { return nil, errdefs.ToGRPC(err) } - return &snapshotsapi.UpdateSnapshotResponse{Info: fromInfo(info)}, nil + return &snapshotsapi.UpdateSnapshotResponse{Info: snapshots.InfoToProto(info)}, nil } func (s service) List(sr *snapshotsapi.ListSnapshotsRequest, ss snapshotsapi.Snapshots_ListServer) error { @@ -126,7 +125,7 @@ func (s service) List(sr *snapshotsapi.ListSnapshotsRequest, ss snapshotsapi.Sna } ) err := s.sn.Walk(ss.Context(), func(ctx context.Context, info snapshots.Info) error { - buffer = append(buffer, fromInfo(info)) + buffer = append(buffer, snapshots.InfoToProto(info)) if len(buffer) >= 100 { if err := sendBlock(buffer); err != nil { @@ -176,45 +175,3 @@ func (s service) Cleanup(ctx context.Context, cr *snapshotsapi.CleanupRequest) ( return empty, nil } - -func fromKind(kind snapshots.Kind) snapshotsapi.Kind { - if kind == snapshots.KindActive { - return snapshotsapi.Kind_ACTIVE - } - if kind == snapshots.KindView { - return snapshotsapi.Kind_VIEW - } - return snapshotsapi.Kind_COMMITTED -} - -func fromInfo(info snapshots.Info) *snapshotsapi.Info { - return &snapshotsapi.Info{ - Name: info.Name, - Parent: info.Parent, - Kind: fromKind(info.Kind), - CreatedAt: protobuf.ToTimestamp(info.Created), - UpdatedAt: protobuf.ToTimestamp(info.Updated), - Labels: info.Labels, - } -} - -func toInfo(info *snapshotsapi.Info) snapshots.Info { - return snapshots.Info{ - Name: info.Name, - Parent: info.Parent, - Kind: toKind(info.Kind), - Created: protobuf.FromTimestamp(info.CreatedAt), - Updated: protobuf.FromTimestamp(info.UpdatedAt), - Labels: info.Labels, - } -} - -func toKind(kind snapshotsapi.Kind) snapshots.Kind { - if kind == snapshotsapi.Kind_ACTIVE { - return snapshots.KindActive - } - if kind == snapshotsapi.Kind_VIEW { - return snapshots.KindView - } - return snapshots.KindCommitted -} diff --git a/services/snapshots/service.go b/services/snapshots/service.go index 7d1c22e58..8a760f40c 100644 --- a/services/snapshots/service.go +++ b/services/snapshots/service.go @@ -25,7 +25,6 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/plugin" - "github.com/containerd/containerd/protobuf" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" "github.com/containerd/containerd/snapshots" @@ -184,7 +183,7 @@ func (s *service) Stat(ctx context.Context, sr *snapshotsapi.StatSnapshotRequest return nil, errdefs.ToGRPC(err) } - return &snapshotsapi.StatSnapshotResponse{Info: fromInfo(info)}, nil + return &snapshotsapi.StatSnapshotResponse{Info: snapshots.InfoToProto(info)}, nil } func (s *service) Update(ctx context.Context, sr *snapshotsapi.UpdateSnapshotRequest) (*snapshotsapi.UpdateSnapshotResponse, error) { @@ -194,12 +193,12 @@ func (s *service) Update(ctx context.Context, sr *snapshotsapi.UpdateSnapshotReq return nil, err } - info, err := sn.Update(ctx, toInfo(sr.Info), sr.UpdateMask.GetPaths()...) + info, err := sn.Update(ctx, snapshots.InfoFromProto(sr.Info), sr.UpdateMask.GetPaths()...) if err != nil { return nil, errdefs.ToGRPC(err) } - return &snapshotsapi.UpdateSnapshotResponse{Info: fromInfo(info)}, nil + return &snapshotsapi.UpdateSnapshotResponse{Info: snapshots.InfoToProto(info)}, nil } func (s *service) List(sr *snapshotsapi.ListSnapshotsRequest, ss snapshotsapi.Snapshots_ListServer) error { @@ -217,7 +216,7 @@ func (s *service) List(sr *snapshotsapi.ListSnapshotsRequest, ss snapshotsapi.Sn } ) err = sn.Walk(ss.Context(), func(ctx context.Context, info snapshots.Info) error { - buffer = append(buffer, fromInfo(info)) + buffer = append(buffer, snapshots.InfoToProto(info)) if len(buffer) >= 100 { if err := sendBlock(buffer); err != nil { @@ -253,7 +252,7 @@ func (s *service) Usage(ctx context.Context, ur *snapshotsapi.UsageRequest) (*sn return nil, errdefs.ToGRPC(err) } - return fromUsage(usage), nil + return snapshots.UsageToProto(usage), nil } func (s *service) Cleanup(ctx context.Context, cr *snapshotsapi.CleanupRequest) (*ptypes.Empty, error) { @@ -274,52 +273,3 @@ func (s *service) Cleanup(ctx context.Context, cr *snapshotsapi.CleanupRequest) return empty, nil } - -func fromKind(kind snapshots.Kind) snapshotsapi.Kind { - if kind == snapshots.KindActive { - return snapshotsapi.Kind_ACTIVE - } - if kind == snapshots.KindView { - return snapshotsapi.Kind_VIEW - } - return snapshotsapi.Kind_COMMITTED -} - -func fromInfo(info snapshots.Info) *snapshotsapi.Info { - return &snapshotsapi.Info{ - Name: info.Name, - Parent: info.Parent, - Kind: fromKind(info.Kind), - CreatedAt: protobuf.ToTimestamp(info.Created), - UpdatedAt: protobuf.ToTimestamp(info.Updated), - Labels: info.Labels, - } -} - -func fromUsage(usage snapshots.Usage) *snapshotsapi.UsageResponse { - return &snapshotsapi.UsageResponse{ - Inodes: usage.Inodes, - Size: usage.Size, - } -} - -func toInfo(info *snapshotsapi.Info) snapshots.Info { - return snapshots.Info{ - Name: info.Name, - Parent: info.Parent, - Kind: toKind(info.Kind), - Created: protobuf.FromTimestamp(info.CreatedAt), - Updated: protobuf.FromTimestamp(info.UpdatedAt), - Labels: info.Labels, - } -} - -func toKind(kind snapshotsapi.Kind) snapshots.Kind { - if kind == snapshotsapi.Kind_ACTIVE { - return snapshots.KindActive - } - if kind == snapshotsapi.Kind_VIEW { - return snapshots.KindView - } - return snapshots.KindCommitted -} diff --git a/snapshots/proxy/proxy.go b/snapshots/proxy/proxy.go index 1ceda91f8..215a7f311 100644 --- a/snapshots/proxy/proxy.go +++ b/snapshots/proxy/proxy.go @@ -23,7 +23,6 @@ import ( snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/protobuf" protobuftypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/snapshots" ) @@ -51,14 +50,14 @@ func (p *proxySnapshotter) Stat(ctx context.Context, key string) (snapshots.Info if err != nil { return snapshots.Info{}, errdefs.FromGRPC(err) } - return toInfo(resp.Info), nil + return snapshots.InfoFromProto(resp.Info), nil } func (p *proxySnapshotter) Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error) { resp, err := p.client.Update(ctx, &snapshotsapi.UpdateSnapshotRequest{ Snapshotter: p.snapshotterName, - Info: fromInfo(info), + Info: snapshots.InfoToProto(info), UpdateMask: &protobuftypes.FieldMask{ Paths: fieldpaths, }, @@ -66,7 +65,7 @@ func (p *proxySnapshotter) Update(ctx context.Context, info snapshots.Info, fiel if err != nil { return snapshots.Info{}, errdefs.FromGRPC(err) } - return toInfo(resp.Info), nil + return snapshots.InfoFromProto(resp.Info), nil } func (p *proxySnapshotter) Usage(ctx context.Context, key string) (snapshots.Usage, error) { @@ -77,7 +76,7 @@ func (p *proxySnapshotter) Usage(ctx context.Context, key string) (snapshots.Usa if err != nil { return snapshots.Usage{}, errdefs.FromGRPC(err) } - return toUsage(resp), nil + return snapshots.UsageFromProto(resp), nil } func (p *proxySnapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) { @@ -173,7 +172,7 @@ func (p *proxySnapshotter) Walk(ctx context.Context, fn snapshots.WalkFunc, fs . return nil } for _, info := range resp.Info { - if err := fn(ctx, toInfo(info)); err != nil { + if err := fn(ctx, snapshots.InfoFromProto(info)); err != nil { return err } } @@ -190,52 +189,3 @@ func (p *proxySnapshotter) Cleanup(ctx context.Context) error { }) return errdefs.FromGRPC(err) } - -func toKind(kind snapshotsapi.Kind) snapshots.Kind { - if kind == snapshotsapi.Kind_ACTIVE { - return snapshots.KindActive - } - if kind == snapshotsapi.Kind_VIEW { - return snapshots.KindView - } - return snapshots.KindCommitted -} - -func toInfo(info *snapshotsapi.Info) snapshots.Info { - return snapshots.Info{ - Name: info.Name, - Parent: info.Parent, - Kind: toKind(info.Kind), - Created: protobuf.FromTimestamp(info.CreatedAt), - Updated: protobuf.FromTimestamp(info.UpdatedAt), - Labels: info.Labels, - } -} - -func toUsage(resp *snapshotsapi.UsageResponse) snapshots.Usage { - return snapshots.Usage{ - Inodes: resp.Inodes, - Size: resp.Size, - } -} - -func fromKind(kind snapshots.Kind) snapshotsapi.Kind { - if kind == snapshots.KindActive { - return snapshotsapi.Kind_ACTIVE - } - if kind == snapshots.KindView { - return snapshotsapi.Kind_VIEW - } - return snapshotsapi.Kind_COMMITTED -} - -func fromInfo(info snapshots.Info) *snapshotsapi.Info { - return &snapshotsapi.Info{ - Name: info.Name, - Parent: info.Parent, - Kind: fromKind(info.Kind), - CreatedAt: protobuf.ToTimestamp(info.Created), - UpdatedAt: protobuf.ToTimestamp(info.Updated), - Labels: info.Labels, - } -} diff --git a/snapshots/snapshotter.go b/snapshots/snapshotter.go index 5fa5aa530..a35cd4883 100644 --- a/snapshots/snapshotter.go +++ b/snapshots/snapshotter.go @@ -22,7 +22,9 @@ import ( "strings" "time" + snapshotsapi "github.com/containerd/containerd/api/services/snapshots/v1" "github.com/containerd/containerd/mount" + "github.com/containerd/containerd/protobuf" ) const ( @@ -98,6 +100,29 @@ func (k *Kind) UnmarshalJSON(b []byte) error { return nil } +// KindToProto converts from [Kind] to the protobuf definition [snapshots.Kind]. +func KindToProto(kind Kind) snapshotsapi.Kind { + if kind == KindActive { + return snapshotsapi.Kind_ACTIVE + } + if kind == KindView { + return snapshotsapi.Kind_VIEW + } + return snapshotsapi.Kind_COMMITTED +} + +// KindFromProto converts from the protobuf definition [snapshots.Kind] to +// [Kind]. +func KindFromProto(kind snapshotsapi.Kind) Kind { + if kind == snapshotsapi.Kind_ACTIVE { + return KindActive + } + if kind == snapshotsapi.Kind_VIEW { + return KindView + } + return KindCommitted +} + // Info provides information about a particular snapshot. // JSON marshalling is supported for interacting with tools like ctr, type Info struct { @@ -114,6 +139,31 @@ type Info struct { Updated time.Time `json:",omitempty"` // Last update time } +// InfoToProto converts from [Info] to the protobuf definition [snapshots.Info]. +func InfoToProto(info Info) *snapshotsapi.Info { + return &snapshotsapi.Info{ + Name: info.Name, + Parent: info.Parent, + Kind: KindToProto(info.Kind), + CreatedAt: protobuf.ToTimestamp(info.Created), + UpdatedAt: protobuf.ToTimestamp(info.Updated), + Labels: info.Labels, + } +} + +// InfoFromProto converts from the protobuf definition [snapshots.Info] to +// [Info]. +func InfoFromProto(info *snapshotsapi.Info) Info { + return Info{ + Name: info.Name, + Parent: info.Parent, + Kind: KindFromProto(info.Kind), + Created: protobuf.FromTimestamp(info.CreatedAt), + Updated: protobuf.FromTimestamp(info.UpdatedAt), + Labels: info.Labels, + } +} + // Usage defines statistics for disk resources consumed by the snapshot. // // These resources only include the resources consumed by the snapshot itself @@ -133,6 +183,23 @@ func (u *Usage) Add(other Usage) { u.Inodes += other.Inodes } +// UsageFromProto converts from the protobuf definition [snapshots.Usage] to +// [Usage]. +func UsageFromProto(resp *snapshotsapi.UsageResponse) Usage { + return Usage{ + Inodes: resp.Inodes, + Size: resp.Size, + } +} + +// UsageToProto converts from [Usage] to the protobuf definition [snapshots.Usage]. +func UsageToProto(usage Usage) *snapshotsapi.UsageResponse { + return &snapshotsapi.UsageResponse{ + Inodes: usage.Inodes, + Size: usage.Size, + } +} + // WalkFunc defines the callback for a snapshot walk. type WalkFunc func(context.Context, Info) error From f3b7436b61d2c3c69d7782d6bd817c2623be52e1 Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Wed, 28 Jun 2023 15:12:30 -0700 Subject: [PATCH 4/4] Platforms: Add From/ToProto helpers for types Helpers to convert from a slice of platforms to our protobuf representation and vice-versa appear a couple times. It seems sane to just expose this facility in the platforms pkg. Signed-off-by: Danny Canter --- pkg/transfer/archive/exporter.go | 10 +--------- pkg/transfer/image/imagestore.go | 28 ++-------------------------- platforms/platforms.go | 28 ++++++++++++++++++++++++++++ services/introspection/local.go | 13 ++----------- 4 files changed, 33 insertions(+), 46 deletions(-) diff --git a/pkg/transfer/archive/exporter.go b/pkg/transfer/archive/exporter.go index c7e3f707f..d71f75c4a 100644 --- a/pkg/transfer/archive/exporter.go +++ b/pkg/transfer/archive/exporter.go @@ -156,15 +156,7 @@ func (iis *ImageExportStream) UnmarshalAny(ctx context.Context, sm streaming.Str return err } - var specified []v1.Platform - for _, p := range s.Platforms { - specified = append(specified, v1.Platform{ - OS: p.OS, - Architecture: p.Architecture, - Variant: p.Variant, - }) - } - + specified := platforms.FromProto(s.Platforms) iis.stream = tstreaming.WriteByteStream(ctx, stream) iis.mediaType = s.MediaType iis.platforms = specified diff --git a/pkg/transfer/image/imagestore.go b/pkg/transfer/image/imagestore.go index e18bfb0cf..975fc7f25 100644 --- a/pkg/transfer/image/imagestore.go +++ b/pkg/transfer/image/imagestore.go @@ -363,7 +363,7 @@ func (is *Store) MarshalAny(context.Context, streaming.StreamCreator) (typeurl.A Labels: is.imageLabels, ManifestLimit: uint32(is.manifestLimit), AllMetadata: is.allMetadata, - Platforms: platformsToProto(is.platforms), + Platforms: platforms.ToProto(is.platforms), ExtraReferences: referencesToProto(is.extraReferences), Unpacks: unpackToProto(is.unpacks), } @@ -380,37 +380,13 @@ func (is *Store) UnmarshalAny(ctx context.Context, sm streaming.StreamGetter, a is.imageLabels = s.Labels is.manifestLimit = int(s.ManifestLimit) is.allMetadata = s.AllMetadata - is.platforms = platformFromProto(s.Platforms) + is.platforms = platforms.FromProto(s.Platforms) is.extraReferences = referencesFromProto(s.ExtraReferences) is.unpacks = unpackFromProto(s.Unpacks) return nil } -func platformsToProto(platforms []ocispec.Platform) []*types.Platform { - ap := make([]*types.Platform, len(platforms)) - for i := range platforms { - p := types.Platform{ - OS: platforms[i].OS, - Architecture: platforms[i].Architecture, - Variant: platforms[i].Variant, - } - - ap[i] = &p - } - return ap -} - -func platformFromProto(platforms []*types.Platform) []ocispec.Platform { - op := make([]ocispec.Platform, len(platforms)) - for i := range platforms { - op[i].OS = platforms[i].OS - op[i].Architecture = platforms[i].Architecture - op[i].Variant = platforms[i].Variant - } - return op -} - func referencesToProto(references []Reference) []*transfertypes.ImageReference { ir := make([]*transfertypes.ImageReference, len(references)) for i := range references { diff --git a/platforms/platforms.go b/platforms/platforms.go index 8dcde7db7..bef6b598a 100644 --- a/platforms/platforms.go +++ b/platforms/platforms.go @@ -116,6 +116,7 @@ import ( specs "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/errdefs" ) @@ -262,3 +263,30 @@ func Normalize(platform specs.Platform) specs.Platform { return platform } + +// ToProto converts from a slice of [Platform] to a slice of +// the protobuf definition [types.Platform]. +func ToProto(platforms []Platform) []*types.Platform { + ap := make([]*types.Platform, len(platforms)) + for i := range platforms { + p := types.Platform{ + OS: platforms[i].OS, + Architecture: platforms[i].Architecture, + Variant: platforms[i].Variant, + } + ap[i] = &p + } + return ap +} + +// FromProto converts a slice of the protobuf definition [types.Platform] +// to a slice of [Platform]. +func FromProto(platforms []*types.Platform) []Platform { + op := make([]Platform, len(platforms)) + for i := range platforms { + op[i].OS = platforms[i].OS + op[i].Architecture = platforms[i].Architecture + op[i].Variant = platforms[i].Variant + } + return op +} diff --git a/services/introspection/local.go b/services/introspection/local.go index 7aa291b47..f1e1853cf 100644 --- a/services/introspection/local.go +++ b/services/introspection/local.go @@ -24,9 +24,9 @@ import ( "sync" api "github.com/containerd/containerd/api/services/introspection/v1" - "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/filters" + "github.com/containerd/containerd/platforms" "github.com/containerd/containerd/plugin" ptypes "github.com/containerd/containerd/protobuf/types" "github.com/containerd/containerd/services" @@ -189,15 +189,6 @@ func adaptPlugin(o interface{}) filters.Adaptor { func pluginsToPB(plugins []*plugin.Plugin) []*api.Plugin { var pluginsPB []*api.Plugin for _, p := range plugins { - var platforms []*types.Platform - for _, p := range p.Meta.Platforms { - platforms = append(platforms, &types.Platform{ - OS: p.OS, - Architecture: p.Architecture, - Variant: p.Variant, - }) - } - var requires []string for _, r := range p.Registration.Requires { requires = append(requires, r.String()) @@ -231,7 +222,7 @@ func pluginsToPB(plugins []*plugin.Plugin) []*api.Plugin { Type: p.Registration.Type.String(), ID: p.Registration.ID, Requires: requires, - Platforms: platforms, + Platforms: platforms.ToProto(p.Meta.Platforms), Capabilities: p.Meta.Capabilities, Exports: p.Meta.Exports, InitErr: initErr,