Use typeurl.Any instead of github.com/gogo/protobuf/types.Any

This commit upgrades github.com/containerd/typeurl to use typeurl.Any.
The interface hides gogo/protobuf/types.Any from containerd's Go client.

Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
This commit is contained in:
Kazuyoshi Kato 2022-03-22 00:40:39 +00:00
parent 551516a18d
commit 96b16b447d
42 changed files with 336 additions and 152 deletions

View File

@ -38,13 +38,13 @@ import (
"github.com/containerd/containerd/events" "github.com/containerd/containerd/events"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/process" "github.com/containerd/containerd/pkg/process"
"github.com/containerd/containerd/protobuf"
shimlog "github.com/containerd/containerd/runtime/v1" shimlog "github.com/containerd/containerd/runtime/v1"
"github.com/containerd/containerd/runtime/v1/shim" "github.com/containerd/containerd/runtime/v1/shim"
shimapi "github.com/containerd/containerd/runtime/v1/shim/v1" shimapi "github.com/containerd/containerd/runtime/v1/shim/v1"
"github.com/containerd/containerd/sys/reaper" "github.com/containerd/containerd/sys/reaper"
"github.com/containerd/containerd/version" "github.com/containerd/containerd/version"
"github.com/containerd/ttrpc" "github.com/containerd/ttrpc"
"github.com/containerd/typeurl"
ptypes "github.com/gogo/protobuf/types" ptypes "github.com/gogo/protobuf/types"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
exec "golang.org/x/sys/execabs" exec "golang.org/x/sys/execabs"
@ -301,7 +301,7 @@ type remoteEventsPublisher struct {
func (l *remoteEventsPublisher) Publish(ctx context.Context, topic string, event events.Event) error { func (l *remoteEventsPublisher) Publish(ctx context.Context, topic string, event events.Event) error {
ns, _ := namespaces.Namespace(ctx) ns, _ := namespaces.Namespace(ctx)
encoded, err := typeurl.MarshalAny(event) encoded, err := protobuf.MarshalAnyToProto(event)
if err != nil { if err != nil {
return err return err
} }

View File

@ -280,7 +280,7 @@ var infoCommand = cli.Command{
return nil return nil
} }
if info.Spec != nil && info.Spec.Value != nil { if info.Spec != nil && info.Spec.GetValue() != nil {
v, err := typeurl.UnmarshalAny(info.Spec) v, err := typeurl.UnmarshalAny(info.Spec)
if err != nil { if err != nil {
return err return err

View File

@ -42,7 +42,7 @@ func RemoveCniNetworkIfExist(ctx context.Context, container containerd.Container
return nil return nil
} }
data, err := typeurl.UnmarshalAny(&networkMeta) data, err := typeurl.UnmarshalAny(networkMeta)
if err != nil { if err != nil {
return fmt.Errorf("failed to unmarshal cni metadata extension %s", commands.CtrCniMetadataExtension) return fmt.Errorf("failed to unmarshal cni metadata extension %s", commands.CtrCniMetadataExtension)
} }

View File

@ -32,10 +32,10 @@ import (
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/fifo" "github.com/containerd/fifo"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
prototypes "github.com/gogo/protobuf/types"
ver "github.com/opencontainers/image-spec/specs-go" ver "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
@ -74,7 +74,7 @@ type Container interface {
// SetLabels sets the provided labels for the container and returns the final label set // SetLabels sets the provided labels for the container and returns the final label set
SetLabels(context.Context, map[string]string) (map[string]string, error) SetLabels(context.Context, map[string]string) (map[string]string, error)
// Extensions returns the extensions set on the container // Extensions returns the extensions set on the container
Extensions(context.Context) (map[string]prototypes.Any, error) Extensions(context.Context) (map[string]typeurl.Any, error)
// Update a container // Update a container
Update(context.Context, ...UpdateContainerOpts) error Update(context.Context, ...UpdateContainerOpts) error
// Checkpoint creates a checkpoint image of the current container // Checkpoint creates a checkpoint image of the current container
@ -120,7 +120,7 @@ func (c *container) Info(ctx context.Context, opts ...InfoOpts) (containers.Cont
return c.metadata, nil return c.metadata, nil
} }
func (c *container) Extensions(ctx context.Context) (map[string]prototypes.Any, error) { func (c *container) Extensions(ctx context.Context) (map[string]typeurl.Any, error) {
r, err := c.get(ctx) r, err := c.get(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
@ -163,7 +163,7 @@ func (c *container) Spec(ctx context.Context) (*oci.Spec, error) {
return nil, err return nil, err
} }
var s oci.Spec var s oci.Spec
if err := json.Unmarshal(r.Spec.Value, &s); err != nil { if err := json.Unmarshal(r.Spec.GetValue(), &s); err != nil {
return nil, err return nil, err
} }
return &s, nil return &s, nil
@ -284,7 +284,7 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N
if err != nil { if err != nil {
return nil, err return nil, err
} }
request.Options = any request.Options = protobuf.FromAny(any)
} }
t := &task{ t := &task{
client: c.client, client: c.client,

View File

@ -28,9 +28,9 @@ import (
"github.com/containerd/containerd/diff" "github.com/containerd/containerd/diff"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms" "github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/rootfs" "github.com/containerd/containerd/rootfs"
"github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/typeurl"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
) )
@ -57,7 +57,7 @@ func WithCheckpointImage(ctx context.Context, client *Client, c *containers.Cont
// WithCheckpointTask includes the running task // WithCheckpointTask includes the running task
func WithCheckpointTask(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error { func WithCheckpointTask(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
any, err := typeurl.MarshalAny(copts) any, err := protobuf.MarshalAnyToProto(copts)
if err != nil { if err != nil {
return nil return nil
} }
@ -98,8 +98,8 @@ func WithCheckpointTask(ctx context.Context, client *Client, c *containers.Conta
// WithCheckpointRuntime includes the container runtime info // WithCheckpointRuntime includes the container runtime info
func WithCheckpointRuntime(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error { func WithCheckpointRuntime(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
if c.Runtime.Options != nil { if c.Runtime.Options != nil && c.Runtime.Options.GetValue() != nil {
data, err := c.Runtime.Options.Marshal() data, err := protobuf.FromAny(c.Runtime.Options).Marshal()
if err != nil { if err != nil {
return err return err
} }

View File

@ -27,9 +27,9 @@ import (
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
"github.com/gogo/protobuf/types"
"github.com/opencontainers/image-spec/identity" "github.com/opencontainers/image-spec/identity"
v1 "github.com/opencontainers/image-spec/specs-go/v1" v1 "github.com/opencontainers/image-spec/specs-go/v1"
) )
@ -57,7 +57,7 @@ type InfoConfig struct {
func WithRuntime(name string, options interface{}) NewContainerOpts { func WithRuntime(name string, options interface{}) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error { return func(ctx context.Context, client *Client, c *containers.Container) error {
var ( var (
any *types.Any any typeurl.Any
err error err error
) )
if options != nil { if options != nil {
@ -288,9 +288,9 @@ func WithContainerExtension(name string, extension interface{}) NewContainerOpts
} }
if c.Extensions == nil { if c.Extensions == nil {
c.Extensions = make(map[string]types.Any) c.Extensions = make(map[string]typeurl.Any)
} }
c.Extensions[name] = *any c.Extensions[name] = any
return nil return nil
} }
} }
@ -315,7 +315,7 @@ func WithSpec(s *oci.Spec, opts ...oci.SpecOpts) NewContainerOpts {
} }
var err error var err error
c.Spec, err = typeurl.MarshalAny(s) c.Spec, err = protobuf.MarshalAnyToProto(s)
return err return err
} }
} }

View File

@ -20,7 +20,7 @@ import (
"context" "context"
"time" "time"
"github.com/gogo/protobuf/types" "github.com/containerd/typeurl"
) )
// Container represents the set of data pinned by a container. Unless otherwise // Container represents the set of data pinned by a container. Unless otherwise
@ -53,7 +53,7 @@ type Container struct {
// container. // container.
// //
// This field is required but mutable. // This field is required but mutable.
Spec *types.Any Spec typeurl.Any
// SnapshotKey specifies the snapshot key to use for the container's root // SnapshotKey specifies the snapshot key to use for the container's root
// filesystem. When starting a task from this container, a caller should // filesystem. When starting a task from this container, a caller should
@ -75,13 +75,13 @@ type Container struct {
UpdatedAt time.Time UpdatedAt time.Time
// Extensions stores client-specified metadata // Extensions stores client-specified metadata
Extensions map[string]types.Any Extensions map[string]typeurl.Any
} }
// RuntimeInfo holds runtime specific information // RuntimeInfo holds runtime specific information
type RuntimeInfo struct { type RuntimeInfo struct {
Name string Name string
Options *types.Any Options typeurl.Any
} }
// Store interacts with the underlying container storage // Store interacts with the underlying container storage

View File

@ -24,6 +24,8 @@ import (
containersapi "github.com/containerd/containerd/api/services/containers/v1" containersapi "github.com/containerd/containerd/api/services/containers/v1"
"github.com/containerd/containerd/containers" "github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/typeurl"
ptypes "github.com/gogo/protobuf/types" ptypes "github.com/gogo/protobuf/types"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -148,18 +150,22 @@ func (r *remoteContainers) Delete(ctx context.Context, id string) error {
} }
func containerToProto(container *containers.Container) containersapi.Container { func containerToProto(container *containers.Container) containersapi.Container {
extensions := make(map[string]ptypes.Any)
for k, v := range container.Extensions {
extensions[k] = *protobuf.FromAny(v)
}
return containersapi.Container{ return containersapi.Container{
ID: container.ID, ID: container.ID,
Labels: container.Labels, Labels: container.Labels,
Image: container.Image, Image: container.Image,
Runtime: &containersapi.Container_Runtime{ Runtime: &containersapi.Container_Runtime{
Name: container.Runtime.Name, Name: container.Runtime.Name,
Options: container.Runtime.Options, Options: protobuf.FromAny(container.Runtime.Options),
}, },
Spec: container.Spec, Spec: protobuf.FromAny(container.Spec),
Snapshotter: container.Snapshotter, Snapshotter: container.Snapshotter,
SnapshotKey: container.SnapshotKey, SnapshotKey: container.SnapshotKey,
Extensions: container.Extensions, Extensions: extensions,
} }
} }
@ -171,6 +177,11 @@ func containerFromProto(containerpb *containersapi.Container) containers.Contain
Options: containerpb.Runtime.Options, Options: containerpb.Runtime.Options,
} }
} }
extensions := make(map[string]typeurl.Any)
for k, v := range containerpb.Extensions {
v := v
extensions[k] = &v
}
return containers.Container{ return containers.Container{
ID: containerpb.ID, ID: containerpb.ID,
Labels: containerpb.Labels, Labels: containerpb.Labels,
@ -181,7 +192,7 @@ func containerFromProto(containerpb *containersapi.Container) containers.Contain
SnapshotKey: containerpb.SnapshotKey, SnapshotKey: containerpb.SnapshotKey,
CreatedAt: containerpb.CreatedAt, CreatedAt: containerpb.CreatedAt,
UpdatedAt: containerpb.UpdatedAt, UpdatedAt: containerpb.UpdatedAt,
Extensions: containerpb.Extensions, Extensions: extensions,
} }
} }

View File

@ -22,6 +22,7 @@ import (
eventsapi "github.com/containerd/containerd/api/services/events/v1" eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events" "github.com/containerd/containerd/events"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
) )
@ -51,7 +52,7 @@ func (e *eventRemote) Publish(ctx context.Context, topic string, event events.Ev
} }
req := &eventsapi.PublishRequest{ req := &eventsapi.PublishRequest{
Topic: topic, Topic: topic,
Event: any, Event: protobuf.FromAny(any),
} }
if _, err := e.client.Publish(ctx, req); err != nil { if _, err := e.client.Publish(ctx, req); err != nil {
return errdefs.FromGRPC(err) return errdefs.FromGRPC(err)
@ -65,7 +66,7 @@ func (e *eventRemote) Forward(ctx context.Context, envelope *events.Envelope) er
Timestamp: envelope.Timestamp, Timestamp: envelope.Timestamp,
Namespace: envelope.Namespace, Namespace: envelope.Namespace,
Topic: envelope.Topic, Topic: envelope.Topic,
Event: envelope.Event, Event: protobuf.FromAny(envelope.Event),
}, },
} }
if _, err := e.client.Forward(ctx, req); err != nil { if _, err := e.client.Forward(ctx, req); err != nil {

View File

@ -21,7 +21,6 @@ import (
"time" "time"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
"github.com/gogo/protobuf/types"
) )
// Envelope provides the packaging for an event. // Envelope provides the packaging for an event.
@ -29,7 +28,7 @@ type Envelope struct {
Timestamp time.Time Timestamp time.Time
Namespace string Namespace string
Topic string Topic string
Event *types.Any Event typeurl.Any
} }
// Field returns the value for the given fieldpath as a string, if defined. // Field returns the value for the given fieldpath as a string, if defined.

View File

@ -30,7 +30,6 @@ import (
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
goevents "github.com/docker/go-events" goevents "github.com/docker/go-events"
"github.com/gogo/protobuf/types"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -63,7 +62,7 @@ func (e *Exchange) Forward(ctx context.Context, envelope *events.Envelope) (err
logger := log.G(ctx).WithFields(logrus.Fields{ logger := log.G(ctx).WithFields(logrus.Fields{
"topic": envelope.Topic, "topic": envelope.Topic,
"ns": envelope.Namespace, "ns": envelope.Namespace,
"type": envelope.Event.TypeUrl, "type": envelope.Event.GetTypeUrl(),
}) })
if err != nil { if err != nil {
@ -82,7 +81,6 @@ func (e *Exchange) Forward(ctx context.Context, envelope *events.Envelope) (err
func (e *Exchange) Publish(ctx context.Context, topic string, event events.Event) (err error) { func (e *Exchange) Publish(ctx context.Context, topic string, event events.Event) (err error) {
var ( var (
namespace string namespace string
encoded *types.Any
envelope events.Envelope envelope events.Envelope
) )
@ -94,7 +92,7 @@ func (e *Exchange) Publish(ctx context.Context, topic string, event events.Event
return fmt.Errorf("envelope topic %q: %w", topic, err) return fmt.Errorf("envelope topic %q: %w", topic, err)
} }
encoded, err = typeurl.MarshalAny(event) encoded, err := typeurl.MarshalAny(event)
if err != nil { if err != nil {
return err return err
} }
@ -108,7 +106,7 @@ func (e *Exchange) Publish(ctx context.Context, topic string, event events.Event
logger := log.G(ctx).WithFields(logrus.Fields{ logger := log.G(ctx).WithFields(logrus.Fields{
"topic": envelope.Topic, "topic": envelope.Topic,
"ns": envelope.Namespace, "ns": envelope.Namespace,
"type": envelope.Event.TypeUrl, "type": envelope.Event.GetTypeUrl(),
}) })
if err != nil { if err != nil {

2
go.mod
View File

@ -17,7 +17,7 @@ require (
github.com/containerd/imgcrypt v1.1.4-0.20220322210345-7eff50ecc4f6 github.com/containerd/imgcrypt v1.1.4-0.20220322210345-7eff50ecc4f6
github.com/containerd/nri v0.1.0 github.com/containerd/nri v0.1.0
github.com/containerd/ttrpc v1.1.0 github.com/containerd/ttrpc v1.1.0
github.com/containerd/typeurl v1.0.2 github.com/containerd/typeurl v1.0.3-0.20220324183432-6193a0e03259
github.com/containerd/zfs v1.0.0 github.com/containerd/zfs v1.0.0
github.com/containernetworking/plugins v1.0.1 github.com/containernetworking/plugins v1.0.1
github.com/coreos/go-systemd/v22 v22.3.2 github.com/coreos/go-systemd/v22 v22.3.2

3
go.sum
View File

@ -253,8 +253,9 @@ github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Ev
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
github.com/containerd/typeurl v1.0.3-0.20220324183432-6193a0e03259 h1:bJv9qgjarrsdd4XIIczeRdYXON88Fgn3GdXVfnQjcSo=
github.com/containerd/typeurl v1.0.3-0.20220324183432-6193a0e03259/go.mod h1:HDkcKOXRnX6yKnXv3P0QrogFi0DoiauK/LpQi961f0A=
github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw=
github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=
github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=

View File

@ -1440,11 +1440,11 @@ func TestContainerExtensions(t *testing.T) {
if len(cExts) != 1 { if len(cExts) != 1 {
t.Errorf("expected 1 container extension") t.Errorf("expected 1 container extension")
} }
if cExts["hello"].TypeUrl != ext.TypeUrl { if actual := cExts["hello"].GetTypeUrl(); actual != ext.TypeUrl {
t.Errorf("got unexpected type url for extension: %s", cExts["hello"].TypeUrl) t.Errorf("got unexpected type url for extension: %s", actual)
} }
if !bytes.Equal(cExts["hello"].Value, ext.Value) { if actual := cExts["hello"].GetValue(); !bytes.Equal(actual, ext.Value) {
t.Errorf("expected extension value %q, got: %q", ext.Value, cExts["hello"].Value) t.Errorf("expected extension value %q, got: %q", ext.Value, actual)
} }
} }

View File

@ -10,7 +10,7 @@ require (
github.com/containerd/containerd v1.5.10 github.com/containerd/containerd v1.5.10
github.com/containerd/go-runc v1.0.0 github.com/containerd/go-runc v1.0.0
github.com/containerd/ttrpc v1.1.0 github.com/containerd/ttrpc v1.1.0
github.com/containerd/typeurl v1.0.2 github.com/containerd/typeurl v1.0.3-0.20220324183432-6193a0e03259
github.com/gogo/protobuf v1.3.2 github.com/gogo/protobuf v1.3.2
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1 github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1

View File

@ -152,8 +152,9 @@ github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8h
github.com/containerd/ttrpc v1.1.0 h1:GbtyLRxb0gOLR0TYQWt3O6B0NvT8tMdorEHqIQo/lWI= github.com/containerd/ttrpc v1.1.0 h1:GbtyLRxb0gOLR0TYQWt3O6B0NvT8tMdorEHqIQo/lWI=
github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ=
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
github.com/containerd/typeurl v1.0.3-0.20220324183432-6193a0e03259 h1:bJv9qgjarrsdd4XIIczeRdYXON88Fgn3GdXVfnQjcSo=
github.com/containerd/typeurl v1.0.3-0.20220324183432-6193a0e03259/go.mod h1:HDkcKOXRnX6yKnXv3P0QrogFi0DoiauK/LpQi961f0A=
github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y=
github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE=

View File

@ -20,6 +20,8 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/typeurl"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
"github.com/gogo/protobuf/types" "github.com/gogo/protobuf/types"
bolt "go.etcd.io/bbolt" bolt "go.etcd.io/bbolt"
@ -151,7 +153,7 @@ func WriteTimestamps(bkt *bolt.Bucket, created, updated time.Time) error {
// WriteExtensions will write a KV map to the given bucket, // WriteExtensions will write a KV map to the given bucket,
// where `K` is a string key and `V` is a protobuf's Any type that represents a generic extension. // where `K` is a string key and `V` is a protobuf's Any type that represents a generic extension.
func WriteExtensions(bkt *bolt.Bucket, extensions map[string]types.Any) error { func WriteExtensions(bkt *bolt.Bucket, extensions map[string]typeurl.Any) error {
if len(extensions) == 0 { if len(extensions) == 0 {
return nil return nil
} }
@ -162,8 +164,8 @@ func WriteExtensions(bkt *bolt.Bucket, extensions map[string]types.Any) error {
} }
for name, ext := range extensions { for name, ext := range extensions {
ext := ext ext := protobuf.FromAny(ext)
p, err := proto.Marshal(&ext) p, err := proto.Marshal(ext)
if err != nil { if err != nil {
return err return err
} }
@ -177,9 +179,9 @@ func WriteExtensions(bkt *bolt.Bucket, extensions map[string]types.Any) error {
} }
// ReadExtensions will read back a map of extensions from the given bucket, previously written by WriteExtensions // ReadExtensions will read back a map of extensions from the given bucket, previously written by WriteExtensions
func ReadExtensions(bkt *bolt.Bucket) (map[string]types.Any, error) { func ReadExtensions(bkt *bolt.Bucket) (map[string]typeurl.Any, error) {
var ( var (
extensions = make(map[string]types.Any) extensions = make(map[string]typeurl.Any)
ebkt = bkt.Bucket(bucketKeyExtensions) ebkt = bkt.Bucket(bucketKeyExtensions)
) )
@ -193,7 +195,7 @@ func ReadExtensions(bkt *bolt.Bucket) (map[string]types.Any, error) {
return err return err
} }
extensions[string(k)] = t extensions[string(k)] = &t
return nil return nil
}); err != nil { }); err != nil {
return nil, err return nil, err
@ -203,12 +205,13 @@ func ReadExtensions(bkt *bolt.Bucket) (map[string]types.Any, error) {
} }
// WriteAny write a protobuf's Any type to the bucket // WriteAny write a protobuf's Any type to the bucket
func WriteAny(bkt *bolt.Bucket, name []byte, any *types.Any) error { func WriteAny(bkt *bolt.Bucket, name []byte, any typeurl.Any) error {
if any == nil { pbany := protobuf.FromAny(any)
if pbany == nil {
return nil return nil
} }
data, err := proto.Marshal(any) data, err := proto.Marshal(pbany)
if err != nil { if err != nil {
return err return err
} }

View File

@ -30,6 +30,7 @@ import (
"github.com/containerd/containerd/labels" "github.com/containerd/containerd/labels"
"github.com/containerd/containerd/metadata/boltutil" "github.com/containerd/containerd/metadata/boltutil"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/typeurl"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
"github.com/gogo/protobuf/types" "github.com/gogo/protobuf/types"
bolt "go.etcd.io/bbolt" bolt "go.etcd.io/bbolt"
@ -211,7 +212,7 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai
if strings.HasPrefix(path, "extensions.") { if strings.HasPrefix(path, "extensions.") {
if updated.Extensions == nil { if updated.Extensions == nil {
updated.Extensions = map[string]types.Any{} updated.Extensions = map[string]typeurl.Any{}
} }
key := strings.TrimPrefix(path, "extensions.") key := strings.TrimPrefix(path, "extensions.")
updated.Extensions[key] = container.Extensions[key] updated.Extensions[key] = container.Extensions[key]

View File

@ -30,10 +30,13 @@ import (
"github.com/containerd/containerd/filters" "github.com/containerd/containerd/filters"
"github.com/containerd/containerd/log/logtest" "github.com/containerd/containerd/log/logtest"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
"github.com/gogo/protobuf/types" "github.com/gogo/protobuf/types"
"github.com/google/go-cmp/cmp"
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
bolt "go.etcd.io/bbolt" bolt "go.etcd.io/bbolt"
"gotest.tools/v3/assert"
) )
func init() { func init() {
@ -47,7 +50,7 @@ func TestContainersList(t *testing.T) {
store := NewContainerStore(NewDB(db, nil, nil)) store := NewContainerStore(NewDB(db, nil, nil))
spec := &specs.Spec{} spec := &specs.Spec{}
encoded, err := typeurl.MarshalAny(spec) encoded, err := protobuf.MarshalAnyToProto(spec)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -179,13 +182,13 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
store := NewContainerStore(NewDB(db, nil, nil)) store := NewContainerStore(NewDB(db, nil, nil))
spec := &specs.Spec{} spec := &specs.Spec{}
encoded, err := typeurl.MarshalAny(spec) encoded, err := protobuf.MarshalAnyToProto(spec)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
spec.Annotations = map[string]string{"updated": "true"} spec.Annotations = map[string]string{"updated": "true"}
encodedUpdated, err := typeurl.MarshalAny(spec) encodedUpdated, err := protobuf.MarshalAnyToProto(spec)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -467,8 +470,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("hello"), Value: []byte("hello"),
}, },
@ -479,8 +482,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("world"), Value: []byte("world"),
}, },
@ -491,8 +494,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("world"), Value: []byte("world"),
}, },
@ -506,8 +509,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("hello"), Value: []byte("hello"),
}, },
@ -518,8 +521,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("world"), Value: []byte("world"),
}, },
@ -531,8 +534,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("hello"), Value: []byte("hello"),
}, },
@ -546,8 +549,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("hello"), Value: []byte("hello"),
}, },
@ -557,8 +560,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Labels: map[string]string{ Labels: map[string]string{
"foo": "one", "foo": "one",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("world"), Value: []byte("world"),
}, },
@ -570,8 +573,8 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("world"), Value: []byte("world"),
}, },
@ -585,21 +588,21 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
// leaves hello in place. // leaves hello in place.
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("hello"), Value: []byte("hello"),
}, },
}, },
}, },
input: containers.Container{ input: containers.Container{
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("universe"), // this will be ignored Value: []byte("universe"), // this will be ignored
}, },
"bar": { "bar": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("foo"), // this will be added Value: []byte("foo"), // this will be added
}, },
@ -611,12 +614,12 @@ func TestContainersCreateUpdateDelete(t *testing.T) {
Runtime: containers.RuntimeInfo{ Runtime: containers.RuntimeInfo{
Name: "testruntime", Name: "testruntime",
}, },
Extensions: map[string]types.Any{ Extensions: map[string]typeurl.Any{
"hello": { "hello": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("hello"), // remains as world Value: []byte("hello"), // remains as world
}, },
"bar": { "bar": &types.Any{
TypeUrl: "test.update.extensions", TypeUrl: "test.update.extensions",
Value: []byte("foo"), // this will be added Value: []byte("foo"), // this will be added
}, },
@ -702,10 +705,26 @@ func checkContainerTimestamps(t *testing.T, c *containers.Container, now time.Ti
} }
} }
func checkContainersEqual(t *testing.T, a, b *containers.Container, format string, args ...interface{}) { // isNil returns true if the given parameter is nil or typed nil.
if !reflect.DeepEqual(a, b) { func isNil(x interface{}) bool {
t.Fatalf("containers not equal \n\t%v != \n\t%v: "+format, append([]interface{}{a, b}, args...)...) if x == nil {
return true
} }
v := reflect.ValueOf(x)
return v.Kind() == reflect.Ptr && v.IsNil()
}
func checkContainersEqual(t *testing.T, a, b *containers.Container, format string, args ...interface{}) {
// Ignore the difference of nil and typed nil.
opt := cmp.FilterValues(
func(x, y interface{}) bool {
return isNil(x) && isNil(y)
},
cmp.Comparer(func(_, _ interface{}) bool {
return true
}),
)
assert.DeepEqual(t, a, b, opt)
} }
func testEnv(t *testing.T) (context.Context, *bolt.DB, func()) { func testEnv(t *testing.T) (context.Context, *bolt.DB, func()) {

View File

@ -33,7 +33,6 @@ import (
sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox"
ctrdutil "github.com/containerd/containerd/pkg/cri/util" ctrdutil "github.com/containerd/containerd/pkg/cri/util"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
gogotypes "github.com/gogo/protobuf/types"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"k8s.io/utils/clock" "k8s.io/utils/clock"
) )
@ -207,7 +206,7 @@ func (em *eventMonitor) startContainerExitMonitor(ctx context.Context, id string
return stopCh return stopCh
} }
func convertEvent(e *gogotypes.Any) (string, interface{}, error) { func convertEvent(e typeurl.Any) (string, interface{}, error) {
id := "" id := ""
evt, err := typeurl.UnmarshalAny(e) evt, err := typeurl.UnmarshalAny(e)
if err != nil { if err != nil {

View File

@ -374,10 +374,11 @@ func getRuntimeOptionsType(t string) interface{} {
// getRuntimeOptions get runtime options from container metadata. // getRuntimeOptions get runtime options from container metadata.
func getRuntimeOptions(c containers.Container) (interface{}, error) { func getRuntimeOptions(c containers.Container) (interface{}, error) {
if c.Runtime.Options == nil { from := c.Runtime.Options
if from == nil || from.GetValue() == nil {
return nil, nil return nil, nil
} }
opts, err := typeurl.UnmarshalAny(c.Runtime.Options) opts, err := typeurl.UnmarshalAny(from)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -23,6 +23,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
criconfig "github.com/containerd/containerd/pkg/cri/config" criconfig "github.com/containerd/containerd/pkg/cri/config"
@ -32,6 +33,8 @@ import (
"github.com/containerd/containerd/reference/docker" "github.com/containerd/containerd/reference/docker"
"github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/containerd/runtime/linux/runctypes"
runcoptions "github.com/containerd/containerd/runtime/v2/runc/options" runcoptions "github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/typeurl"
"github.com/gogo/protobuf/types"
imagedigest "github.com/opencontainers/go-digest" imagedigest "github.com/opencontainers/go-digest"
runtimespec "github.com/opencontainers/runtime-spec/specs-go" runtimespec "github.com/opencontainers/runtime-spec/specs-go"
@ -599,3 +602,13 @@ func TestValidateTargetContainer(t *testing.T) {
} }
} }
func TestGetRuntimeOptions(t *testing.T) {
_, err := getRuntimeOptions(containers.Container{})
require.NoError(t, err)
var pbany *types.Any // This is nil.
var typeurlAny typeurl.Any = pbany // This is typed nil.
_, err = getRuntimeOptions(containers.Container{Runtime: containers.RuntimeInfo{Options: typeurlAny}})
require.NoError(t, err)
}

View File

@ -166,7 +166,7 @@ func (c *criService) loadContainer(ctx context.Context, cntr containerd.Containe
if !ok { if !ok {
return container, fmt.Errorf("metadata extension %q not found", containerMetadataExtension) return container, fmt.Errorf("metadata extension %q not found", containerMetadataExtension)
} }
data, err := typeurl.UnmarshalAny(&ext) data, err := typeurl.UnmarshalAny(ext)
if err != nil { if err != nil {
return container, fmt.Errorf("failed to unmarshal metadata extension %q: %w", ext, err) return container, fmt.Errorf("failed to unmarshal metadata extension %q: %w", ext, err)
} }
@ -335,7 +335,7 @@ func (c *criService) loadSandbox(ctx context.Context, cntr containerd.Container)
if !ok { if !ok {
return sandbox, fmt.Errorf("metadata extension %q not found", sandboxMetadataExtension) return sandbox, fmt.Errorf("metadata extension %q not found", sandboxMetadataExtension)
} }
data, err := typeurl.UnmarshalAny(&ext) data, err := typeurl.UnmarshalAny(ext)
if err != nil { if err != nil {
return sandbox, fmt.Errorf("failed to unmarshal metadata extension %q: %w", ext, err) return sandbox, fmt.Errorf("failed to unmarshal metadata extension %q: %w", ext, err)
} }

47
protobuf/any.go Normal file
View File

@ -0,0 +1,47 @@
/*
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 protobuf
import (
"github.com/containerd/typeurl"
"github.com/gogo/protobuf/types"
)
// FromAny converts typeurl.Any to github.com/gogo/protobuf/types.Any.
func FromAny(from typeurl.Any) *types.Any {
if from == nil {
return nil
}
if pbany, ok := from.(*types.Any); ok {
return pbany
}
return &types.Any{
TypeUrl: from.GetTypeUrl(),
Value: from.GetValue(),
}
}
// FromAny converts an arbitrary interface to github.com/gogo/protobuf/types.Any.
func MarshalAnyToProto(from interface{}) (*types.Any, error) {
any, err := typeurl.MarshalAny(from)
if err != nil {
return nil, err
}
return FromAny(any), nil
}

26
protobuf/any_test.go Normal file
View File

@ -0,0 +1,26 @@
/*
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 protobuf
import "testing"
func TestFromAny(t *testing.T) {
actual := FromAny(nil)
if actual != nil {
t.Fatalf("expected nil, got %v", actual)
}
}

View File

@ -21,7 +21,7 @@ import (
"time" "time"
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
"github.com/gogo/protobuf/types" "github.com/containerd/typeurl"
) )
// IO holds process IO information // IO holds process IO information
@ -35,7 +35,7 @@ type IO struct {
// CreateOpts contains task creation data // CreateOpts contains task creation data
type CreateOpts struct { type CreateOpts struct {
// Spec is the OCI runtime spec // Spec is the OCI runtime spec
Spec *types.Any Spec typeurl.Any
// Rootfs mounts to perform to gain access to the container's filesystem // Rootfs mounts to perform to gain access to the container's filesystem
Rootfs []mount.Mount Rootfs []mount.Mount
// IO for the container's main process // IO for the container's main process
@ -43,9 +43,9 @@ type CreateOpts struct {
// Checkpoint digest to restore container state // Checkpoint digest to restore container state
Checkpoint string Checkpoint string
// RuntimeOptions for the runtime // RuntimeOptions for the runtime
RuntimeOptions *types.Any RuntimeOptions typeurl.Any
// TaskOptions received for the task // TaskOptions received for the task
TaskOptions *types.Any TaskOptions typeurl.Any
// Runtime name to use (e.g. `io.containerd.NAME.VERSION`). // Runtime name to use (e.g. `io.containerd.NAME.VERSION`).
// As an alternative full abs path to binary may be specified instead. // As an alternative full abs path to binary may be specified instead.
Runtime string Runtime string

View File

@ -41,6 +41,7 @@ import (
"github.com/containerd/containerd/pkg/process" "github.com/containerd/containerd/pkg/process"
"github.com/containerd/containerd/platforms" "github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/containerd/runtime/linux/runctypes"
v1 "github.com/containerd/containerd/runtime/v1" v1 "github.com/containerd/containerd/runtime/v1"
@ -178,7 +179,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
bundle, err := newBundle(id, bundle, err := newBundle(id,
filepath.Join(r.state, namespace), filepath.Join(r.state, namespace),
filepath.Join(r.root, namespace), filepath.Join(r.root, namespace),
opts.Spec.Value) opts.Spec.GetValue())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -191,7 +192,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
shimopt := ShimLocal(r.config, r.events) shimopt := ShimLocal(r.config, r.events)
if !r.config.NoShim { if !r.config.NoShim {
var cgroup string var cgroup string
if opts.TaskOptions != nil { if opts.TaskOptions != nil && opts.TaskOptions.GetValue() != nil {
v, err := typeurl.UnmarshalAny(opts.TaskOptions) v, err := typeurl.UnmarshalAny(opts.TaskOptions)
if err != nil { if err != nil {
return nil, err return nil, err
@ -244,7 +245,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
Stderr: opts.IO.Stderr, Stderr: opts.IO.Stderr,
Terminal: opts.IO.Terminal, Terminal: opts.IO.Terminal,
Checkpoint: opts.Checkpoint, Checkpoint: opts.Checkpoint,
Options: opts.TaskOptions, Options: protobuf.FromAny(opts.TaskOptions),
} }
for _, m := range opts.Rootfs { for _, m := range opts.Rootfs {
sopts.Rootfs = append(sopts.Rootfs, &types.Mount{ sopts.Rootfs = append(sopts.Rootfs, &types.Mount{
@ -537,7 +538,7 @@ func (r *Runtime) getRuncOptions(ctx context.Context, id string) (*runctypes.Run
return nil, err return nil, err
} }
if container.Runtime.Options != nil { if container.Runtime.Options != nil && container.Runtime.Options.GetValue() != nil {
v, err := typeurl.UnmarshalAny(container.Runtime.Options) v, err := typeurl.UnmarshalAny(container.Runtime.Options)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -31,11 +31,11 @@ import (
"github.com/containerd/containerd/events/exchange" "github.com/containerd/containerd/events/exchange"
"github.com/containerd/containerd/identifiers" "github.com/containerd/containerd/identifiers"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/runtime/v1/shim/client" "github.com/containerd/containerd/runtime/v1/shim/client"
"github.com/containerd/containerd/runtime/v1/shim/v1" "github.com/containerd/containerd/runtime/v1/shim/v1"
"github.com/containerd/ttrpc" "github.com/containerd/ttrpc"
"github.com/containerd/typeurl"
"github.com/gogo/protobuf/types" "github.com/gogo/protobuf/types"
) )
@ -326,7 +326,7 @@ func (t *Task) Stats(ctx context.Context) (*types.Any, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return typeurl.MarshalAny(stats) return protobuf.MarshalAnyToProto(stats)
} }
// Cgroup returns the underlying cgroup for a linux task // Cgroup returns the underlying cgroup for a linux task

View File

@ -37,6 +37,7 @@ import (
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/process" "github.com/containerd/containerd/pkg/process"
"github.com/containerd/containerd/pkg/stdio" "github.com/containerd/containerd/pkg/stdio"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/containerd/runtime/linux/runctypes"
shimapi "github.com/containerd/containerd/runtime/v1/shim/v1" shimapi "github.com/containerd/containerd/runtime/v1/shim/v1"
@ -417,7 +418,7 @@ func (s *Service) ListPids(ctx context.Context, r *shimapi.ListPidsRequest) (*sh
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err) return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err)
} }
pInfo.Info = a pInfo.Info = protobuf.FromAny(a)
break break
} }
} }

View File

@ -34,6 +34,7 @@ import (
"github.com/containerd/containerd/pkg/timeout" "github.com/containerd/containerd/pkg/timeout"
"github.com/containerd/containerd/platforms" "github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
shimbinary "github.com/containerd/containerd/runtime/v2/shim" shimbinary "github.com/containerd/containerd/runtime/v2/shim"
"github.com/containerd/containerd/runtime/v2/task" "github.com/containerd/containerd/runtime/v2/task"
@ -157,7 +158,7 @@ func (m *ShimManager) ID() string {
// Start launches a new shim instance // Start launches a new shim instance
func (m *ShimManager) Start(ctx context.Context, id string, opts runtime.CreateOpts) (_ ShimProcess, retErr error) { func (m *ShimManager) Start(ctx context.Context, id string, opts runtime.CreateOpts) (_ ShimProcess, retErr error) {
bundle, err := NewBundle(ctx, m.root, m.state, id, opts.Spec.Value) bundle, err := NewBundle(ctx, m.root, m.state, id, opts.Spec.GetValue())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -198,7 +199,7 @@ func (m *ShimManager) startShim(ctx context.Context, bundle *Bundle, id string,
} }
topts := opts.TaskOptions topts := opts.TaskOptions
if topts == nil { if topts == nil || topts.GetValue() == nil {
topts = opts.RuntimeOptions topts = opts.RuntimeOptions
} }
@ -213,7 +214,7 @@ func (m *ShimManager) startShim(ctx context.Context, bundle *Bundle, id string,
ttrpcAddress: m.containerdTTRPCAddress, ttrpcAddress: m.containerdTTRPCAddress,
schedCore: m.schedCore, schedCore: m.schedCore,
}) })
shim, err := b.Start(ctx, topts, func() { shim, err := b.Start(ctx, protobuf.FromAny(topts), func() {
log.G(ctx).WithField("id", id).Info("shim disconnected") log.G(ctx).WithField("id", id).Info("shim disconnected")
cleanupAfterDeadShim(context.Background(), id, ns, m.shims, m.events, b) cleanupAfterDeadShim(context.Background(), id, ns, m.shims, m.events, b)

View File

@ -49,12 +49,14 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
} }
var opts options.Options var opts options.Options
if r.Options != nil && r.Options.GetTypeUrl() != "" { if r.Options.GetValue() != nil {
v, err := typeurl.UnmarshalAny(r.Options) v, err := typeurl.UnmarshalAny(r.Options)
if err != nil { if err != nil {
return nil, err return nil, err
} }
opts = *v.(*options.Options) if v != nil {
opts = *v.(*options.Options)
}
} }
var mounts []process.Mount var mounts []process.Mount

View File

@ -38,6 +38,7 @@ import (
"github.com/containerd/containerd/pkg/shutdown" "github.com/containerd/containerd/pkg/shutdown"
"github.com/containerd/containerd/pkg/stdio" "github.com/containerd/containerd/pkg/stdio"
"github.com/containerd/containerd/pkg/userns" "github.com/containerd/containerd/pkg/userns"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime/v2/runc" "github.com/containerd/containerd/runtime/v2/runc"
"github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/containerd/runtime/v2/shim" "github.com/containerd/containerd/runtime/v2/shim"
@ -375,7 +376,7 @@ func (s *service) Pids(ctx context.Context, r *taskAPI.PidsRequest) (*taskAPI.Pi
d := &options.ProcessDetails{ d := &options.ProcessDetails{
ExecID: p.ID(), ExecID: p.ID(),
} }
a, err := typeurl.MarshalAny(d) a, err := protobuf.MarshalAnyToProto(d)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err) return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err)
} }
@ -503,7 +504,7 @@ func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.
return nil, err return nil, err
} }
return &taskAPI.StatsResponse{ return &taskAPI.StatsResponse{
Stats: data, Stats: protobuf.FromAny(data),
}, nil }, nil
} }

View File

@ -41,6 +41,7 @@ import (
"github.com/containerd/containerd/pkg/process" "github.com/containerd/containerd/pkg/process"
"github.com/containerd/containerd/pkg/schedcore" "github.com/containerd/containerd/pkg/schedcore"
"github.com/containerd/containerd/pkg/stdio" "github.com/containerd/containerd/pkg/stdio"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime/v2/runc" "github.com/containerd/containerd/runtime/v2/runc"
"github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/containerd/runtime/v2/shim" "github.com/containerd/containerd/runtime/v2/shim"
@ -507,7 +508,7 @@ func (s *service) Pids(ctx context.Context, r *taskAPI.PidsRequest) (*taskAPI.Pi
d := &options.ProcessDetails{ d := &options.ProcessDetails{
ExecID: p.ID(), ExecID: p.ID(),
} }
a, err := typeurl.MarshalAny(d) a, err := protobuf.MarshalAnyToProto(d)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err) return nil, fmt.Errorf("failed to marshal process %d info: %w", pid, err)
} }
@ -617,7 +618,7 @@ func (s *service) Stats(ctx context.Context, r *taskAPI.StatsRequest) (*taskAPI.
return nil, err return nil, err
} }
return &taskAPI.StatsResponse{ return &taskAPI.StatsResponse{
Stats: data, Stats: protobuf.FromAny(data),
}, nil }, nil
} }

View File

@ -33,6 +33,7 @@ import (
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/timeout" "github.com/containerd/containerd/pkg/timeout"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
client "github.com/containerd/containerd/runtime/v2/shim" client "github.com/containerd/containerd/runtime/v2/shim"
"github.com/containerd/containerd/runtime/v2/task" "github.com/containerd/containerd/runtime/v2/task"
@ -323,7 +324,7 @@ func (s *shimTask) delete(ctx context.Context, removeTask func(ctx context.Conte
func (s *shimTask) Create(ctx context.Context, opts runtime.CreateOpts) (runtime.Task, error) { func (s *shimTask) Create(ctx context.Context, opts runtime.CreateOpts) (runtime.Task, error) {
topts := opts.TaskOptions topts := opts.TaskOptions
if topts == nil { if topts == nil || topts.GetValue() == nil {
topts = opts.RuntimeOptions topts = opts.RuntimeOptions
} }
request := &task.CreateTaskRequest{ request := &task.CreateTaskRequest{
@ -334,7 +335,7 @@ func (s *shimTask) Create(ctx context.Context, opts runtime.CreateOpts) (runtime
Stderr: opts.IO.Stderr, Stderr: opts.IO.Stderr,
Terminal: opts.IO.Terminal, Terminal: opts.IO.Terminal,
Checkpoint: opts.Checkpoint, Checkpoint: opts.Checkpoint,
Options: topts, Options: protobuf.FromAny(topts),
} }
for _, m := range opts.Rootfs { for _, m := range opts.Rootfs {
request.Rootfs = append(request.Rootfs, &types.Mount{ request.Rootfs = append(request.Rootfs, &types.Mount{

View File

@ -25,8 +25,8 @@ import (
"github.com/containerd/containerd/events" "github.com/containerd/containerd/events"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/ttrpcutil" "github.com/containerd/containerd/pkg/ttrpcutil"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/ttrpc" "github.com/containerd/ttrpc"
"github.com/containerd/typeurl"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -110,7 +110,7 @@ func (l *RemoteEventsPublisher) Publish(ctx context.Context, topic string, event
if err != nil { if err != nil {
return err return err
} }
any, err := typeurl.MarshalAny(event) any, err := protobuf.MarshalAnyToProto(event)
if err != nil { if err != nil {
return err return err
} }

View File

@ -19,6 +19,9 @@ package containers
import ( import (
api "github.com/containerd/containerd/api/services/containers/v1" api "github.com/containerd/containerd/api/services/containers/v1"
"github.com/containerd/containerd/containers" "github.com/containerd/containerd/containers"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/typeurl"
"github.com/gogo/protobuf/types"
) )
func containersToProto(containers []containers.Container) []api.Container { func containersToProto(containers []containers.Container) []api.Container {
@ -33,20 +36,24 @@ func containersToProto(containers []containers.Container) []api.Container {
} }
func containerToProto(container *containers.Container) api.Container { func containerToProto(container *containers.Container) api.Container {
extensions := make(map[string]types.Any)
for k, v := range container.Extensions {
extensions[k] = *protobuf.FromAny(v)
}
return api.Container{ return api.Container{
ID: container.ID, ID: container.ID,
Labels: container.Labels, Labels: container.Labels,
Image: container.Image, Image: container.Image,
Runtime: &api.Container_Runtime{ Runtime: &api.Container_Runtime{
Name: container.Runtime.Name, Name: container.Runtime.Name,
Options: container.Runtime.Options, Options: protobuf.FromAny(container.Runtime.Options),
}, },
Spec: container.Spec, Spec: protobuf.FromAny(container.Spec),
Snapshotter: container.Snapshotter, Snapshotter: container.Snapshotter,
SnapshotKey: container.SnapshotKey, SnapshotKey: container.SnapshotKey,
CreatedAt: container.CreatedAt, CreatedAt: container.CreatedAt,
UpdatedAt: container.UpdatedAt, UpdatedAt: container.UpdatedAt,
Extensions: container.Extensions, Extensions: extensions,
} }
} }
@ -58,6 +65,11 @@ func containerFromProto(containerpb *api.Container) containers.Container {
Options: containerpb.Runtime.Options, Options: containerpb.Runtime.Options,
} }
} }
extensions := make(map[string]typeurl.Any)
for k, v := range containerpb.Extensions {
v := v
extensions[k] = &v
}
return containers.Container{ return containers.Container{
ID: containerpb.ID, ID: containerpb.ID,
Labels: containerpb.Labels, Labels: containerpb.Labels,
@ -66,6 +78,6 @@ func containerFromProto(containerpb *api.Container) containers.Container {
Spec: containerpb.Spec, Spec: containerpb.Spec,
Snapshotter: containerpb.Snapshotter, Snapshotter: containerpb.Snapshotter,
SnapshotKey: containerpb.SnapshotKey, SnapshotKey: containerpb.SnapshotKey,
Extensions: containerpb.Extensions, Extensions: extensions,
} }
} }

View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd/events" "github.com/containerd/containerd/events"
"github.com/containerd/containerd/events/exchange" "github.com/containerd/containerd/events/exchange"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/ttrpc" "github.com/containerd/ttrpc"
ptypes "github.com/gogo/protobuf/types" ptypes "github.com/gogo/protobuf/types"
"google.golang.org/grpc" "google.golang.org/grpc"
@ -115,7 +116,7 @@ func toProto(env *events.Envelope) *api.Envelope {
Timestamp: env.Timestamp, Timestamp: env.Timestamp,
Namespace: env.Namespace, Namespace: env.Namespace,
Topic: env.Topic, Topic: env.Topic,
Event: env.Event, Event: protobuf.FromAny(env.Event),
} }
} }

View File

@ -41,6 +41,7 @@ import (
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
"github.com/containerd/containerd/pkg/timeout" "github.com/containerd/containerd/pkg/timeout"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/containerd/runtime/linux/runctypes"
"github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/containerd/runtime/v2/runc/options"
@ -462,7 +463,7 @@ func (l *local) ListPids(ctx context.Context, r *api.ListPidsRequest, _ ...grpc.
Pid: p.Pid, Pid: p.Pid,
} }
if p.Info != nil { if p.Info != nil {
a, err := typeurl.MarshalAny(p.Info) a, err := protobuf.MarshalAnyToProto(p.Info)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to marshal process %d info: %w", p.Pid, err) return nil, fmt.Errorf("failed to marshal process %d info: %w", p.Pid, err)
} }
@ -577,7 +578,7 @@ func (l *local) Checkpoint(ctx context.Context, r *api.CheckpointTaskRequest, _
return nil, err return nil, err
} }
// write the config to the content store // write the config to the content store
data, err := container.Spec.Marshal() data, err := protobuf.FromAny(container.Spec).Marshal()
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -38,6 +38,7 @@ import (
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
"github.com/containerd/containerd/plugin" "github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/protobuf"
"github.com/containerd/containerd/rootfs" "github.com/containerd/containerd/rootfs"
"github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/containerd/runtime/linux/runctypes"
"github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/containerd/runtime/v2/runc/options"
@ -346,7 +347,7 @@ func (t *task) Exec(ctx context.Context, id string, spec *specs.Process, ioCreat
i.Close() i.Close()
} }
}() }()
any, err := typeurl.MarshalAny(spec) any, err := protobuf.MarshalAnyToProto(spec)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -446,7 +447,7 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag
} }
request.ParentCheckpoint = i.ParentCheckpoint.String() request.ParentCheckpoint = i.ParentCheckpoint.String()
if i.Options != nil { if i.Options != nil {
any, err := typeurl.MarshalAny(i.Options) any, err := protobuf.MarshalAnyToProto(i.Options)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -535,7 +536,7 @@ func (t *task) Update(ctx context.Context, opts ...UpdateTaskOpts) error {
if err != nil { if err != nil {
return err return err
} }
request.Resources = any request.Resources = protobuf.FromAny(any)
} }
if i.Annotations != nil { if i.Annotations != nil {
request.Annotations = i.Annotations request.Annotations = i.Annotations

View File

@ -7,7 +7,7 @@
A Go package for managing the registration, marshaling, and unmarshaling of encoded types. A Go package for managing the registration, marshaling, and unmarshaling of encoded types.
This package helps when types are sent over a GRPC API and marshaled as a [protobuf.Any](https://github.com/gogo/protobuf/blob/master/protobuf/google/protobuf/any.proto). This package helps when types are sent over a ttrpc/GRPC API and marshaled as a protobuf [Any](https://pkg.go.dev/google.golang.org/protobuf@v1.27.1/types/known/anypb#Any)
## Project details ## Project details

View File

@ -18,13 +18,14 @@ package typeurl
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt"
"path" "path"
"reflect" "reflect"
"sync" "sync"
"github.com/gogo/protobuf/proto" gogoproto "github.com/gogo/protobuf/proto"
"github.com/gogo/protobuf/types" "google.golang.org/protobuf/proto"
"github.com/pkg/errors"
) )
var ( var (
@ -39,10 +40,35 @@ var (
// //
// To detect an error class, use errors.Is() functions to tell whether an // To detect an error class, use errors.Is() functions to tell whether an
// error is of this type. // error is of this type.
var ( var (
ErrNotFound = errors.New("not found") ErrNotFound = errors.New("not found")
) )
type Any interface {
GetTypeUrl() string
GetValue() []byte
}
type any struct {
typeURL string
value []byte
}
func (a *any) GetTypeUrl() string {
if a == nil {
return ""
}
return a.typeURL
}
func (a *any) GetValue() []byte {
if a == nil {
return nil
}
return a.value
}
// Register a type with a base URL for JSON marshaling. When the MarshalAny and // Register a type with a base URL for JSON marshaling. When the MarshalAny and
// UnmarshalAny functions are called they will treat the Any type value as JSON. // UnmarshalAny functions are called they will treat the Any type value as JSON.
// To use protocol buffers for handling the Any value the proto.Register // To use protocol buffers for handling the Any value the proto.Register
@ -56,7 +82,7 @@ func Register(v interface{}, args ...string) {
defer mu.Unlock() defer mu.Unlock()
if et, ok := registry[t]; ok { if et, ok := registry[t]; ok {
if et != p { if et != p {
panic(errors.Errorf("type registered with alternate path %q != %q", et, p)) panic(fmt.Errorf("type registered with alternate path %q != %q", et, p))
} }
return return
} }
@ -69,41 +95,47 @@ func TypeURL(v interface{}) (string, error) {
u, ok := registry[tryDereference(v)] u, ok := registry[tryDereference(v)]
mu.RUnlock() mu.RUnlock()
if !ok { if !ok {
// fallback to the proto registry if it is a proto message switch t := v.(type) {
pb, ok := v.(proto.Message) case proto.Message:
if !ok { return string(t.ProtoReflect().Descriptor().FullName()), nil
return "", errors.Wrapf(ErrNotFound, "type %s", reflect.TypeOf(v)) case gogoproto.Message:
return gogoproto.MessageName(t), nil
default:
return "", fmt.Errorf("type %s: %w", reflect.TypeOf(v), ErrNotFound)
} }
return proto.MessageName(pb), nil
} }
return u, nil return u, nil
} }
// Is returns true if the type of the Any is the same as v. // Is returns true if the type of the Any is the same as v.
func Is(any *types.Any, v interface{}) bool { func Is(any Any, v interface{}) bool {
// call to check that v is a pointer // call to check that v is a pointer
tryDereference(v) tryDereference(v)
url, err := TypeURL(v) url, err := TypeURL(v)
if err != nil { if err != nil {
return false return false
} }
return any.TypeUrl == url return any.GetTypeUrl() == url
} }
// MarshalAny marshals the value v into an any with the correct TypeUrl. // MarshalAny marshals the value v into an any with the correct TypeUrl.
// If the provided object is already a proto.Any message, then it will be // If the provided object is already a proto.Any message, then it will be
// returned verbatim. If it is of type proto.Message, it will be marshaled as a // returned verbatim. If it is of type proto.Message, it will be marshaled as a
// protocol buffer. Otherwise, the object will be marshaled to json. // protocol buffer. Otherwise, the object will be marshaled to json.
func MarshalAny(v interface{}) (*types.Any, error) { func MarshalAny(v interface{}) (Any, error) {
var marshal func(v interface{}) ([]byte, error) var marshal func(v interface{}) ([]byte, error)
switch t := v.(type) { switch t := v.(type) {
case *types.Any: case Any:
// avoid reserializing the type if we have an any. // avoid reserializing the type if we have an any.
return t, nil return t, nil
case proto.Message: case proto.Message:
marshal = func(v interface{}) ([]byte, error) { marshal = func(v interface{}) ([]byte, error) {
return proto.Marshal(t) return proto.Marshal(t)
} }
case gogoproto.Message:
marshal = func(v interface{}) ([]byte, error) {
return gogoproto.Marshal(t)
}
default: default:
marshal = json.Marshal marshal = json.Marshal
} }
@ -117,15 +149,15 @@ func MarshalAny(v interface{}) (*types.Any, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &types.Any{ return &any{
TypeUrl: url, typeURL: url,
Value: data, value: data,
}, nil }, nil
} }
// UnmarshalAny unmarshals the any type into a concrete type. // UnmarshalAny unmarshals the any type into a concrete type.
func UnmarshalAny(any *types.Any) (interface{}, error) { func UnmarshalAny(any Any) (interface{}, error) {
return UnmarshalByTypeURL(any.TypeUrl, any.Value) return UnmarshalByTypeURL(any.GetTypeUrl(), any.GetValue())
} }
// UnmarshalByTypeURL unmarshals the given type and value to into a concrete type. // UnmarshalByTypeURL unmarshals the given type and value to into a concrete type.
@ -136,11 +168,11 @@ func UnmarshalByTypeURL(typeURL string, value []byte) (interface{}, error) {
// UnmarshalTo unmarshals the any type into a concrete type passed in the out // UnmarshalTo unmarshals the any type into a concrete type passed in the out
// argument. It is identical to UnmarshalAny, but lets clients provide a // argument. It is identical to UnmarshalAny, but lets clients provide a
// destination type through the out argument. // destination type through the out argument.
func UnmarshalTo(any *types.Any, out interface{}) error { func UnmarshalTo(any Any, out interface{}) error {
return UnmarshalToByTypeURL(any.TypeUrl, any.Value, out) return UnmarshalToByTypeURL(any.GetTypeUrl(), any.GetValue(), out)
} }
// UnmarshalTo unmarshals the given type and value into a concrete type passed // UnmarshalToByTypeURL unmarshals the given type and value into a concrete type passed
// in the out argument. It is identical to UnmarshalByTypeURL, but lets clients // in the out argument. It is identical to UnmarshalByTypeURL, but lets clients
// provide a destination type through the out argument. // provide a destination type through the out argument.
func UnmarshalToByTypeURL(typeURL string, value []byte, out interface{}) error { func UnmarshalToByTypeURL(typeURL string, value []byte, out interface{}) error {
@ -149,6 +181,10 @@ func UnmarshalToByTypeURL(typeURL string, value []byte, out interface{}) error {
} }
func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error) { func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error) {
if value == nil {
return nil, nil
}
t, err := getTypeByUrl(typeURL) t, err := getTypeByUrl(typeURL)
if err != nil { if err != nil {
return nil, err return nil, err
@ -163,12 +199,17 @@ func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error)
return nil, err return nil, err
} }
if typeURL != vURL { if typeURL != vURL {
return nil, errors.Errorf("can't unmarshal type %q to output %q", typeURL, vURL) return nil, fmt.Errorf("can't unmarshal type %q to output %q", typeURL, vURL)
} }
} }
if t.isProto { if t.isProto {
err = proto.Unmarshal(value, v.(proto.Message)) switch t := v.(type) {
case proto.Message:
err = proto.Unmarshal(value, t)
case gogoproto.Message:
err = gogoproto.Unmarshal(value, t)
}
} else { } else {
err = json.Unmarshal(value, v) err = json.Unmarshal(value, v)
} }
@ -193,7 +234,7 @@ func getTypeByUrl(url string) (urlType, error) {
} }
mu.RUnlock() mu.RUnlock()
// fallback to proto registry // fallback to proto registry
t := proto.MessageType(url) t := gogoproto.MessageType(url)
if t != nil { if t != nil {
return urlType{ return urlType{
// get the underlying Elem because proto returns a pointer to the type // get the underlying Elem because proto returns a pointer to the type
@ -201,7 +242,7 @@ func getTypeByUrl(url string) (urlType, error) {
isProto: true, isProto: true,
}, nil }, nil
} }
return urlType{}, errors.Wrapf(ErrNotFound, "type with url %s", url) return urlType{}, fmt.Errorf("type with url %s: %w", url, ErrNotFound)
} }
func tryDereference(v interface{}) reflect.Type { func tryDereference(v interface{}) reflect.Type {

2
vendor/modules.txt vendored
View File

@ -116,7 +116,7 @@ github.com/containerd/nri/types/v1
## explicit; go 1.13 ## explicit; go 1.13
github.com/containerd/ttrpc github.com/containerd/ttrpc
github.com/containerd/ttrpc/plugin github.com/containerd/ttrpc/plugin
# github.com/containerd/typeurl v1.0.2 # github.com/containerd/typeurl v1.0.3-0.20220324183432-6193a0e03259
## explicit; go 1.13 ## explicit; go 1.13
github.com/containerd/typeurl github.com/containerd/typeurl
# github.com/containerd/zfs v1.0.0 # github.com/containerd/zfs v1.0.0