diff --git a/go.mod b/go.mod index febfda580..86b5172a9 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/containerd/platforms v1.0.0-rc.0 github.com/containerd/plugin v1.0.0 github.com/containerd/ttrpc v1.2.6 - github.com/containerd/typeurl/v2 v2.2.0 + github.com/containerd/typeurl/v2 v2.2.1 github.com/containerd/zfs/v2 v2.0.0-rc.0 github.com/containernetworking/cni v1.2.3 github.com/containernetworking/plugins v1.5.1 diff --git a/go.sum b/go.sum index cd410c5ec..d7bd5e20c 100644 --- a/go.sum +++ b/go.sum @@ -698,8 +698,8 @@ github.com/containerd/plugin v1.0.0/go.mod h1:hQfJe5nmWfImiqT1q8Si3jLv3ynMUIBB47 github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak= github.com/containerd/ttrpc v1.2.6 h1:zG+Kn5EZ6MUYCS1t2Hmt2J4tMVaLSFEJVOraDQwNPC4= github.com/containerd/ttrpc v1.2.6/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= -github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= -github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= +github.com/containerd/typeurl/v2 v2.2.1 h1:/X1Kgcz4sKS/NTKQvvRS0pEVpUYqmPTwGQontm9pl0w= +github.com/containerd/typeurl/v2 v2.2.1/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= github.com/containerd/zfs/v2 v2.0.0-rc.0 h1:0dRlgpoaepW7HuovtcvYQMF7NlpceQVdn7+3Udeth4M= github.com/containerd/zfs/v2 v2.0.0-rc.0/go.mod h1:g36g/XCEGDRxUXIFdM3oWAEvmTvhfz/eKWElqg4Secw= github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM= diff --git a/vendor/github.com/containerd/typeurl/v2/README.md b/vendor/github.com/containerd/typeurl/v2/README.md index 8d86600a4..3098526ab 100644 --- a/vendor/github.com/containerd/typeurl/v2/README.md +++ b/vendor/github.com/containerd/typeurl/v2/README.md @@ -18,3 +18,9 @@ As a containerd sub-project, you will find the: * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) information in our [`containerd/project`](https://github.com/containerd/project) repository. + +## Optional + +By default, support for gogoproto is available along side the standard Google +protobuf types. +You can choose to leave gogo support out by using the `!no_gogo` build tag. diff --git a/vendor/github.com/containerd/typeurl/v2/types.go b/vendor/github.com/containerd/typeurl/v2/types.go index 78817b701..156335b3c 100644 --- a/vendor/github.com/containerd/typeurl/v2/types.go +++ b/vendor/github.com/containerd/typeurl/v2/types.go @@ -24,7 +24,6 @@ import ( "reflect" "sync" - gogoproto "github.com/gogo/protobuf/proto" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/known/anypb" @@ -33,8 +32,16 @@ import ( var ( mu sync.RWMutex registry = make(map[reflect.Type]string) + handlers []handler ) +type handler interface { + Marshaller(interface{}) func() ([]byte, error) + Unmarshaller(interface{}) func([]byte) error + TypeURL(interface{}) string + GetType(url string) reflect.Type +} + // Definitions of common error types used throughout typeurl. // // These error types are used with errors.Wrap and errors.Wrapf to add context @@ -112,9 +119,12 @@ func TypeURL(v interface{}) (string, error) { switch t := v.(type) { case proto.Message: return string(t.ProtoReflect().Descriptor().FullName()), nil - case gogoproto.Message: - return gogoproto.MessageName(t), nil default: + for _, h := range handlers { + if u := h.TypeURL(v); u != "" { + return u, nil + } + } return "", fmt.Errorf("type %s: %w", reflect.TypeOf(v), ErrNotFound) } } @@ -149,12 +159,19 @@ func MarshalAny(v interface{}) (Any, error) { marshal = func(v interface{}) ([]byte, error) { return proto.Marshal(t) } - case gogoproto.Message: - marshal = func(v interface{}) ([]byte, error) { - return gogoproto.Marshal(t) - } default: - marshal = json.Marshal + for _, h := range handlers { + if m := h.Marshaller(v); m != nil { + marshal = func(v interface{}) ([]byte, error) { + return m() + } + break + } + } + + if marshal == nil { + marshal = json.Marshal + } } url, err := TypeURL(v) @@ -229,7 +246,7 @@ func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error) } if v == nil { - v = reflect.New(t.t).Interface() + v = reflect.New(t).Interface() } else { // Validate interface type provided by client vURL, err := TypeURL(v) @@ -241,51 +258,45 @@ func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error) } } - if t.isProto { - switch t := v.(type) { - case proto.Message: - err = proto.Unmarshal(value, t) - case gogoproto.Message: - err = gogoproto.Unmarshal(value, t) - } - } else { - err = json.Unmarshal(value, v) + pm, ok := v.(proto.Message) + if ok { + return v, proto.Unmarshal(value, pm) } - return v, err + for _, h := range handlers { + if unmarshal := h.Unmarshaller(v); unmarshal != nil { + return v, unmarshal(value) + } + } + + // fallback to json unmarshaller + return v, json.Unmarshal(value, v) } -type urlType struct { - t reflect.Type - isProto bool -} - -func getTypeByUrl(url string) (urlType, error) { +func getTypeByUrl(url string) (reflect.Type, error) { mu.RLock() for t, u := range registry { if u == url { mu.RUnlock() - return urlType{ - t: t, - }, nil + return t, nil } } mu.RUnlock() - // fallback to proto registry - t := gogoproto.MessageType(url) - if t != nil { - return urlType{ - // get the underlying Elem because proto returns a pointer to the type - t: t.Elem(), - isProto: true, - }, nil - } mt, err := protoregistry.GlobalTypes.FindMessageByURL(url) if err != nil { - return urlType{}, fmt.Errorf("type with url %s: %w", url, ErrNotFound) + e := protoregistry.NotFound + if !errors.Is(err, e) { + return nil, fmt.Errorf("type with url %s: %w", url, ErrNotFound) + } + + for _, h := range handlers { + if t := h.GetType(url); t != nil { + return t, nil + } + } } empty := mt.New().Interface() - return urlType{t: reflect.TypeOf(empty).Elem(), isProto: true}, nil + return reflect.TypeOf(empty).Elem(), nil } func tryDereference(v interface{}) reflect.Type { diff --git a/vendor/github.com/containerd/typeurl/v2/types_gogo.go b/vendor/github.com/containerd/typeurl/v2/types_gogo.go new file mode 100644 index 000000000..fa293323b --- /dev/null +++ b/vendor/github.com/containerd/typeurl/v2/types_gogo.go @@ -0,0 +1,68 @@ +//go:build !no_gogo + +/* + 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 typeurl + +import ( + "reflect" + + gogoproto "github.com/gogo/protobuf/proto" +) + +func init() { + handlers = append(handlers, gogoHandler{}) +} + +type gogoHandler struct{} + +func (gogoHandler) Marshaller(v interface{}) func() ([]byte, error) { + pm, ok := v.(gogoproto.Message) + if !ok { + return nil + } + return func() ([]byte, error) { + return gogoproto.Marshal(pm) + } +} + +func (gogoHandler) Unmarshaller(v interface{}) func([]byte) error { + pm, ok := v.(gogoproto.Message) + if !ok { + return nil + } + + return func(dt []byte) error { + return gogoproto.Unmarshal(dt, pm) + } +} + +func (gogoHandler) TypeURL(v interface{}) string { + pm, ok := v.(gogoproto.Message) + if !ok { + return "" + } + return gogoproto.MessageName(pm) +} + +func (gogoHandler) GetType(url string) reflect.Type { + t := gogoproto.MessageType(url) + if t == nil { + return nil + } + return t.Elem() +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6ff69cb77..2064e0ef2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -194,7 +194,7 @@ github.com/containerd/plugin/registry # github.com/containerd/ttrpc v1.2.6 ## explicit; go 1.19 github.com/containerd/ttrpc -# github.com/containerd/typeurl/v2 v2.2.0 +# github.com/containerd/typeurl/v2 v2.2.1 ## explicit; go 1.21 github.com/containerd/typeurl/v2 # github.com/containerd/zfs/v2 v2.0.0-rc.0