mirror of https://github.com/k3s-io/k3s
Merge pull request #26007 from smarterclayton/watch_opt
Automatic merge from submit-queue Additional optimizations to the encode/decode paths Builds on top of #25983 with a number of other optimizations.pull/6/head
commit
e543bd6452
|
@ -32,6 +32,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/watch/versioned"
|
||||
)
|
||||
|
||||
const importPrefix = "k8s.io/kubernetes/pkg/api"
|
||||
|
@ -233,6 +234,17 @@ func addVersionsToScheme(externalVersions ...unversioned.GroupVersion) {
|
|||
case *v1.Endpoints:
|
||||
return true, v1.Convert_api_Endpoints_To_v1_Endpoints(a, b, s)
|
||||
}
|
||||
|
||||
case *versioned.Event:
|
||||
switch b := objB.(type) {
|
||||
case *versioned.InternalEvent:
|
||||
return true, versioned.Convert_versioned_Event_to_versioned_InternalEvent(a, b, s)
|
||||
}
|
||||
case *versioned.InternalEvent:
|
||||
switch b := objB.(type) {
|
||||
case *versioned.Event:
|
||||
return true, versioned.Convert_versioned_InternalEvent_to_versioned_Event(a, b, s)
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
|
|
@ -57,11 +57,11 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) {
|
|||
kind := gvk.Kind
|
||||
if len(kind) == 0 {
|
||||
// TODO: this is wrong
|
||||
gvk, err := Scheme.ObjectKind(obj)
|
||||
gvks, _, err := Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kind = gvk.Kind
|
||||
kind = gvks[0].Kind
|
||||
}
|
||||
|
||||
// if the object referenced is actually persisted, we can also get version from meta
|
||||
|
|
|
@ -40,7 +40,7 @@ func TestGetReference(t *testing.T) {
|
|||
// when vendoring kube, if you don't force the set of registered versions (like this hack/test-go.sh does)
|
||||
// then you run into trouble because the types aren't registered in the scheme by anything. This does the
|
||||
// register manually to allow unit test execution
|
||||
if _, err := Scheme.ObjectKind(&Pod{}); err != nil {
|
||||
if _, _, err := Scheme.ObjectKinds(&Pod{}); err != nil {
|
||||
AddToScheme(Scheme)
|
||||
}
|
||||
|
||||
|
|
|
@ -112,11 +112,11 @@ func objectMetaAndKind(typer runtime.ObjectTyper, obj runtime.Object) (*api.Obje
|
|||
if err != nil {
|
||||
return nil, unversioned.GroupVersionKind{}, errors.NewInternalError(err)
|
||||
}
|
||||
kind, err := typer.ObjectKind(obj)
|
||||
kinds, _, err := typer.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, unversioned.GroupVersionKind{}, errors.NewInternalError(err)
|
||||
}
|
||||
return objectMeta, kind, nil
|
||||
return objectMeta, kinds[0], nil
|
||||
}
|
||||
|
||||
// NamespaceScopedStrategy has a method to tell if the object must be in a namespace.
|
||||
|
|
|
@ -37,7 +37,7 @@ import (
|
|||
|
||||
func init() {
|
||||
codecsToTest = append(codecsToTest, func(version unversioned.GroupVersion, item runtime.Object) (runtime.Codec, error) {
|
||||
s := protobuf.NewSerializer(api.Scheme, runtime.ObjectTyperToTyper(api.Scheme), "application/arbitrary.content.type")
|
||||
s := protobuf.NewSerializer(api.Scheme, api.Scheme, "application/arbitrary.content.type")
|
||||
return api.Codecs.CodecForVersions(s, s, testapi.ExternalGroupVersions(), nil), nil
|
||||
})
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ func BenchmarkEncodeProtobufGeneratedMarshal(b *testing.B) {
|
|||
func BenchmarkDecodeCodecToInternalProtobuf(b *testing.B) {
|
||||
items := benchmarkItems()
|
||||
width := len(items)
|
||||
s := protobuf.NewSerializer(api.Scheme, runtime.ObjectTyperToTyper(api.Scheme), "application/arbitrary.content.type")
|
||||
s := protobuf.NewSerializer(api.Scheme, api.Scheme, "application/arbitrary.content.type")
|
||||
encoder := api.Codecs.EncoderForVersion(s, v1.SchemeGroupVersion)
|
||||
var encoded [][]byte
|
||||
for i := range items {
|
||||
|
|
|
@ -365,10 +365,11 @@ func ExternalGroupVersions() []unversioned.GroupVersion {
|
|||
|
||||
// Get codec based on runtime.Object
|
||||
func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) {
|
||||
kind, err := api.Scheme.ObjectKind(obj)
|
||||
kinds, _, err := api.Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected encoding error: %v", err)
|
||||
}
|
||||
kind := kinds[0]
|
||||
|
||||
for _, group := range Groups {
|
||||
if group.GroupVersion().Group != kind.Group {
|
||||
|
|
|
@ -195,6 +195,8 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source)
|
|||
randomQuantity := func() resource.Quantity {
|
||||
var q resource.Quantity
|
||||
c.Fuzz(&q)
|
||||
// precalc the string for benchmarking purposes
|
||||
_ = q.String()
|
||||
return q
|
||||
}
|
||||
q.Limits = make(api.ResourceList)
|
||||
|
|
|
@ -118,7 +118,7 @@ func (a *APIInstaller) getResourceKind(path string, storage rest.Storage) (unver
|
|||
}
|
||||
|
||||
object := storage.New()
|
||||
fqKinds, err := a.group.Typer.ObjectKinds(object)
|
||||
fqKinds, _, err := a.group.Typer.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
}
|
||||
|
@ -233,8 +233,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||
var versionedList interface{}
|
||||
if isLister {
|
||||
list := lister.NewList()
|
||||
listGVK, err := a.group.Typer.ObjectKind(list)
|
||||
versionedListPtr, err := a.group.Creater.New(a.group.GroupVersion.WithKind(listGVK.Kind))
|
||||
listGVKs, _, err := a.group.Typer.ObjectKinds(list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
versionedListPtr, err := a.group.Creater.New(a.group.GroupVersion.WithKind(listGVKs[0].Kind))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -272,10 +275,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||
)
|
||||
if isGetterWithOptions {
|
||||
getOptions, getSubpath, _ = getterWithOptions.NewGetOptions()
|
||||
getOptionsInternalKind, err = a.group.Typer.ObjectKind(getOptions)
|
||||
getOptionsInternalKinds, _, err := a.group.Typer.ObjectKinds(getOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
getOptionsInternalKind = getOptionsInternalKinds[0]
|
||||
versionedGetOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(getOptionsInternalKind.Kind))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -300,12 +304,16 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||
if isConnecter {
|
||||
connectOptions, connectSubpath, _ = connecter.NewConnectOptions()
|
||||
if connectOptions != nil {
|
||||
connectOptionsInternalKind, err = a.group.Typer.ObjectKind(connectOptions)
|
||||
connectOptionsInternalKinds, _, err := a.group.Typer.ObjectKinds(connectOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
connectOptionsInternalKind = connectOptionsInternalKinds[0]
|
||||
versionedConnectOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(connectOptionsInternalKind.Kind))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,18 +398,26 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||
|
||||
resourcePath := namespacedPath
|
||||
resourceParams := namespaceParams
|
||||
itemPathPrefix := gpath.Join(a.prefix, scope.ParamName()) + "/"
|
||||
itemPath := namespacedPath + "/{name}"
|
||||
itemPathMiddle := "/" + resource + "/"
|
||||
nameParams := append(namespaceParams, nameParam)
|
||||
proxyParams := append(nameParams, pathParam)
|
||||
itemPathSuffix := ""
|
||||
if hasSubresource {
|
||||
itemPath = itemPath + "/" + subresource
|
||||
itemPathSuffix = "/" + subresource
|
||||
itemPath = itemPath + itemPathSuffix
|
||||
resourcePath = itemPath
|
||||
resourceParams = nameParams
|
||||
}
|
||||
apiResource.Name = path
|
||||
apiResource.Namespaced = true
|
||||
apiResource.Kind = resourceKind
|
||||
namer := scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), false}
|
||||
|
||||
itemPathFn := func(name, namespace string) string {
|
||||
return itemPathPrefix + namespace + itemPathMiddle + name + itemPathSuffix
|
||||
}
|
||||
namer := scopeNaming{scope, a.group.Linker, itemPathFn, false}
|
||||
|
||||
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister)
|
||||
actions = appendIf(actions, action{"POST", resourcePath, resourceParams, namer}, isCreater)
|
||||
|
@ -430,7 +446,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||
// For ex: LIST all pods in all namespaces by sending a LIST request at /api/apiVersion/pods.
|
||||
// TODO: more strongly type whether a resource allows these actions on "all namespaces" (bulk delete)
|
||||
if !hasSubresource {
|
||||
namer = scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), true}
|
||||
namer = scopeNaming{scope, a.group.Linker, itemPathFn, true}
|
||||
actions = appendIf(actions, action{"LIST", resource, params, namer}, isLister)
|
||||
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer}, allowWatchList)
|
||||
}
|
||||
|
@ -776,7 +792,7 @@ func (n rootScopeNaming) ObjectName(obj runtime.Object) (namespace, name string,
|
|||
type scopeNaming struct {
|
||||
scope meta.RESTScope
|
||||
runtime.SelfLinker
|
||||
itemPath string
|
||||
itemPathFn func(name, namespace string) string
|
||||
allNamespaces bool
|
||||
}
|
||||
|
||||
|
@ -823,9 +839,8 @@ func (n scopeNaming) GenerateLink(req *restful.Request, obj runtime.Object) (pat
|
|||
if len(name) == 0 {
|
||||
return "", "", errEmptyName
|
||||
}
|
||||
path = strings.Replace(n.itemPath, "{name}", name, 1)
|
||||
path = strings.Replace(path, "{"+n.scope.ArgumentName()+"}", namespace, 1)
|
||||
return path, "", nil
|
||||
|
||||
return n.itemPathFn(name, namespace), "", nil
|
||||
}
|
||||
|
||||
// GenerateListLink returns the appropriate path and query to locate a list by its canonical path.
|
||||
|
|
|
@ -36,7 +36,9 @@ func TestScopeNamingGenerateLink(t *testing.T) {
|
|||
s := scopeNaming{
|
||||
meta.RESTScopeNamespace,
|
||||
selfLinker,
|
||||
"/api/v1/namespaces/{namespace}/services/{name}",
|
||||
func(name, namespace string) string {
|
||||
return "/api/v1/namespaces/" + namespace + "/services/" + name
|
||||
},
|
||||
true,
|
||||
}
|
||||
service := &api.Service{
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
gpath "path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -975,10 +974,11 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
|
|||
|
||||
// transformDecodeError adds additional information when a decode fails.
|
||||
func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime.Object, gvk *unversioned.GroupVersionKind, body []byte) error {
|
||||
objGVK, err := typer.ObjectKind(into)
|
||||
objGVKs, _, err := typer.ObjectKinds(into)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
objGVK := objGVKs[0]
|
||||
if gvk != nil && len(gvk.Kind) > 0 {
|
||||
return errors.NewBadRequest(fmt.Sprintf("%s in version %q cannot be handled as a %s: %v", gvk.Kind, gvk.Version, objGVK.Kind, baseErr))
|
||||
}
|
||||
|
@ -997,7 +997,7 @@ func setSelfLink(obj runtime.Object, req *restful.Request, namer ScopeNamer) err
|
|||
|
||||
newURL := *req.Request.URL
|
||||
// use only canonical paths
|
||||
newURL.Path = gpath.Clean(path)
|
||||
newURL.Path = path
|
||||
newURL.RawQuery = query
|
||||
newURL.Fragment = ""
|
||||
|
||||
|
|
|
@ -167,18 +167,22 @@ func (s *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
w.WriteHeader(http.StatusOK)
|
||||
flusher.Flush()
|
||||
|
||||
var unknown runtime.Unknown
|
||||
internalEvent := &versioned.InternalEvent{}
|
||||
buf := &bytes.Buffer{}
|
||||
ch := s.watching.ResultChan()
|
||||
for {
|
||||
select {
|
||||
case <-cn.CloseNotify():
|
||||
return
|
||||
case <-timeoutCh:
|
||||
return
|
||||
case event, ok := <-s.watching.ResultChan():
|
||||
case event, ok := <-ch:
|
||||
if !ok {
|
||||
// End of results.
|
||||
return
|
||||
}
|
||||
|
||||
obj := event.Object
|
||||
s.fixup(obj)
|
||||
if err := s.embeddedEncoder.EncodeToStream(obj, buf); err != nil {
|
||||
|
@ -186,12 +190,15 @@ func (s *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
utilruntime.HandleError(fmt.Errorf("unable to encode watch object: %v", err))
|
||||
return
|
||||
}
|
||||
event.Object = &runtime.Unknown{
|
||||
Raw: buf.Bytes(),
|
||||
// ContentType is not required here because we are defaulting to the serializer
|
||||
// type
|
||||
}
|
||||
if err := e.Encode((*versioned.InternalEvent)(&event)); err != nil {
|
||||
|
||||
// ContentType is not required here because we are defaulting to the serializer
|
||||
// type
|
||||
unknown.Raw = buf.Bytes()
|
||||
event.Object = &unknown
|
||||
|
||||
// the internal event will be versioned by the encoder
|
||||
*internalEvent = versioned.InternalEvent(event)
|
||||
if err := e.Encode(internalEvent); err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("unable to encode watch object: %v (%#v)", err, e))
|
||||
// client disconnect.
|
||||
return
|
||||
|
@ -208,14 +215,18 @@ func (s *WatchServer) HandleWS(ws *websocket.Conn) {
|
|||
defer ws.Close()
|
||||
done := make(chan struct{})
|
||||
go wsstream.IgnoreReceives(ws, 0)
|
||||
|
||||
var unknown runtime.Unknown
|
||||
internalEvent := &versioned.InternalEvent{}
|
||||
buf := &bytes.Buffer{}
|
||||
streamBuf := &bytes.Buffer{}
|
||||
ch := s.watching.ResultChan()
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
s.watching.Stop()
|
||||
return
|
||||
case event, ok := <-s.watching.ResultChan():
|
||||
case event, ok := <-ch:
|
||||
if !ok {
|
||||
// End of results.
|
||||
return
|
||||
|
@ -227,14 +238,15 @@ func (s *WatchServer) HandleWS(ws *websocket.Conn) {
|
|||
utilruntime.HandleError(fmt.Errorf("unable to encode watch object: %v", err))
|
||||
return
|
||||
}
|
||||
event.Object = &runtime.Unknown{
|
||||
Raw: buf.Bytes(),
|
||||
// ContentType is not required here because we are defaulting to the serializer
|
||||
// type
|
||||
}
|
||||
|
||||
// ContentType is not required here because we are defaulting to the serializer
|
||||
// type
|
||||
unknown.Raw = buf.Bytes()
|
||||
event.Object = &unknown
|
||||
|
||||
// the internal event will be versioned by the encoder
|
||||
internalEvent := versioned.InternalEvent(event)
|
||||
if err := s.encoder.EncodeToStream(&internalEvent, streamBuf); err != nil {
|
||||
*internalEvent = versioned.InternalEvent(event)
|
||||
if err := s.encoder.EncodeToStream(internalEvent, streamBuf); err != nil {
|
||||
// encoding error
|
||||
utilruntime.HandleError(fmt.Errorf("unable to encode event: %v", err))
|
||||
s.watching.Stop()
|
||||
|
|
|
@ -561,6 +561,7 @@ func benchmarkItems() []api.Pod {
|
|||
items := make([]api.Pod, 3)
|
||||
for i := range items {
|
||||
apiObjectFuzzer.Fuzz(&items[i])
|
||||
items[i].Spec.InitContainers, items[i].Status.InitContainerStatuses = nil, nil
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
|
|
@ -210,11 +210,11 @@ func (o objects) Kind(kind unversioned.GroupVersionKind, name string) (runtime.O
|
|||
}
|
||||
|
||||
func (o objects) Add(obj runtime.Object) error {
|
||||
gvk, err := o.scheme.ObjectKind(obj)
|
||||
gvks, _, err := o.scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
kind := gvk.Kind
|
||||
kind := gvks[0].Kind
|
||||
|
||||
switch {
|
||||
case meta.IsListType(obj):
|
||||
|
|
|
@ -76,28 +76,15 @@ func NewObjectTyper(resources []*unversioned.APIResourceList) (runtime.ObjectTyp
|
|||
return ot, nil
|
||||
}
|
||||
|
||||
// ObjectKind returns the group,version,kind of the provided object,
|
||||
// or an error if the object in not *runtime.Unstructured or has no
|
||||
// group,version,kind information.
|
||||
func (ot *ObjectTyper) ObjectKind(obj runtime.Object) (unversioned.GroupVersionKind, error) {
|
||||
if _, ok := obj.(*runtime.Unstructured); !ok {
|
||||
return unversioned.GroupVersionKind{}, fmt.Errorf("type %T is invalid for dynamic object typer", obj)
|
||||
}
|
||||
|
||||
return obj.GetObjectKind().GroupVersionKind(), nil
|
||||
}
|
||||
|
||||
// ObjectKinds returns a slice of one element with the
|
||||
// group,version,kind of the provided object, or an error if the
|
||||
// object is not *runtime.Unstructured or has no group,version,kind
|
||||
// information.
|
||||
func (ot *ObjectTyper) ObjectKinds(obj runtime.Object) ([]unversioned.GroupVersionKind, error) {
|
||||
gvk, err := ot.ObjectKind(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (ot *ObjectTyper) ObjectKinds(obj runtime.Object) ([]unversioned.GroupVersionKind, bool, error) {
|
||||
if _, ok := obj.(*runtime.Unstructured); !ok {
|
||||
return nil, false, fmt.Errorf("type %T is invalid for dynamic object typer", obj)
|
||||
}
|
||||
|
||||
return []unversioned.GroupVersionKind{gvk}, nil
|
||||
return []unversioned.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil
|
||||
}
|
||||
|
||||
// Recognizes returns true if the provided group,version,kind was in
|
||||
|
@ -105,15 +92,3 @@ func (ot *ObjectTyper) ObjectKinds(obj runtime.Object) ([]unversioned.GroupVersi
|
|||
func (ot *ObjectTyper) Recognizes(gvk unversioned.GroupVersionKind) bool {
|
||||
return ot.registered[gvk]
|
||||
}
|
||||
|
||||
// IsUnversioned returns false always because *runtime.Unstructured
|
||||
// objects should always have group,version,kind information set. ok
|
||||
// will be true if the object's group,version,kind is registered.
|
||||
func (ot *ObjectTyper) IsUnversioned(obj runtime.Object) (unversioned bool, ok bool) {
|
||||
gvk, err := ot.ObjectKind(obj)
|
||||
if err != nil {
|
||||
return false, false
|
||||
}
|
||||
|
||||
return false, ot.registered[gvk]
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ var Versions = []string{"v1"}
|
|||
var Codec runtime.Codec
|
||||
|
||||
func init() {
|
||||
yamlSerializer := json.NewYAMLSerializer(json.DefaultMetaFactory, api.Scheme, runtime.ObjectTyperToTyper(api.Scheme))
|
||||
yamlSerializer := json.NewYAMLSerializer(json.DefaultMetaFactory, api.Scheme, api.Scheme)
|
||||
Codec = versioning.NewCodecForScheme(
|
||||
api.Scheme,
|
||||
yamlSerializer,
|
||||
|
|
|
@ -204,11 +204,11 @@ func (o objects) Kind(kind unversioned.GroupVersionKind, name string) (runtime.O
|
|||
}
|
||||
|
||||
func (o objects) Add(obj runtime.Object) error {
|
||||
gvk, err := o.scheme.ObjectKind(obj)
|
||||
gvks, _, err := o.scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
kind := gvk.Kind
|
||||
kind := gvks[0].Kind
|
||||
|
||||
switch {
|
||||
case meta.IsListType(obj):
|
||||
|
|
|
@ -224,11 +224,11 @@ func validateFields(a, b string) bool {
|
|||
|
||||
func (c *Client) body(t *testing.T, obj runtime.Object, raw *string) *string {
|
||||
if obj != nil {
|
||||
fqKind, err := api.Scheme.ObjectKind(obj)
|
||||
fqKinds, _, err := api.Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
}
|
||||
groupName := fqKind.GroupVersion().Group
|
||||
groupName := fqKinds[0].GroupVersion().Group
|
||||
if c.ResourceGroup != "" {
|
||||
groupName = c.ResourceGroup
|
||||
}
|
||||
|
|
|
@ -320,11 +320,11 @@ func NewAPIFactory() (*cmdutil.Factory, *testFactory, runtime.Codec) {
|
|||
}
|
||||
return c.Pods(t.Namespace).GetLogs(t.Name, opts), nil
|
||||
default:
|
||||
fqKind, err := api.Scheme.ObjectKind(object)
|
||||
fqKinds, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot get the logs from %v", fqKind)
|
||||
return nil, fmt.Errorf("cannot get the logs from %v", fqKinds[0])
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -238,7 +238,11 @@ func RunCreateSubcommand(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer,
|
|||
return err
|
||||
}
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
gvk, err := typer.ObjectKind(obj)
|
||||
gvks, _, err := typer.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gvk := gvks[0]
|
||||
mapping, err := mapper.RESTMapping(unversioned.GroupKind{Group: gvk.Group, Kind: gvk.Kind}, gvk.Version)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -221,8 +221,8 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg
|
|||
}
|
||||
newRc, ok = obj.(*api.ReplicationController)
|
||||
if !ok {
|
||||
if gvk, err := typer.ObjectKind(obj); err == nil {
|
||||
return cmdutil.UsageError(cmd, "%s contains a %v not a ReplicationController", filename, gvk)
|
||||
if gvks, _, err := typer.ObjectKinds(obj); err == nil {
|
||||
return cmdutil.UsageError(cmd, "%s contains a %v not a ReplicationController", filename, gvks[0])
|
||||
}
|
||||
glog.V(4).Infof("Object %#v is not a ReplicationController", obj)
|
||||
return cmdutil.UsageError(cmd, "%s does not specify a valid ReplicationController", filename)
|
||||
|
@ -377,11 +377,11 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg
|
|||
if outputFormat != "" {
|
||||
return f.PrintObject(cmd, mapper, newRc, out)
|
||||
}
|
||||
kind, err := api.Scheme.ObjectKind(newRc)
|
||||
kinds, _, err := api.Scheme.ObjectKinds(newRc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, res := meta.KindToResource(kind)
|
||||
_, res := meta.KindToResource(kinds[0])
|
||||
cmdutil.PrintSuccess(mapper, false, out, res.Resource, oldName, message)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -443,10 +443,11 @@ func createGeneratedObject(f *cmdutil.Factory, cmd *cobra.Command, generator kub
|
|||
}
|
||||
|
||||
mapper, typer := f.Object(cmdutil.GetIncludeThirdPartyAPIs(cmd))
|
||||
groupVersionKind, err := typer.ObjectKind(obj)
|
||||
groupVersionKinds, _, err := typer.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, "", nil, nil, err
|
||||
}
|
||||
groupVersionKind := groupVersionKinds[0]
|
||||
|
||||
if len(overrides) > 0 {
|
||||
codec := runtime.NewCodec(f.JSONEncoder(), f.Decoder(true))
|
||||
|
|
|
@ -427,11 +427,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
}
|
||||
return kubectl.MakeLabels(t.Spec.Selector.MatchLabels), nil
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", fmt.Errorf("cannot extract pod selector from %v", gvk)
|
||||
return "", fmt.Errorf("cannot extract pod selector from %v", gvks[0])
|
||||
}
|
||||
},
|
||||
PortsForObject: func(object runtime.Object) ([]string, error) {
|
||||
|
@ -448,11 +448,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
case *extensions.ReplicaSet:
|
||||
return getPorts(t.Spec.Template.Spec), nil
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot extract ports from %v", gvk)
|
||||
return nil, fmt.Errorf("cannot extract ports from %v", gvks[0])
|
||||
}
|
||||
},
|
||||
ProtocolsForObject: func(object runtime.Object) (map[string]string, error) {
|
||||
|
@ -469,11 +469,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
case *extensions.ReplicaSet:
|
||||
return getProtocols(t.Spec.Template.Spec), nil
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot extract protocols from %v", gvk)
|
||||
return nil, fmt.Errorf("cannot extract protocols from %v", gvks[0])
|
||||
}
|
||||
},
|
||||
LabelsForObject: func(object runtime.Object) (map[string]string, error) {
|
||||
|
@ -531,11 +531,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
return c.Pods(pod.Namespace).GetLogs(pod.Name, opts), nil
|
||||
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot get the logs from %v", gvk)
|
||||
return nil, fmt.Errorf("cannot get the logs from %v", gvks[0])
|
||||
}
|
||||
},
|
||||
PauseObject: func(object runtime.Object) (bool, error) {
|
||||
|
@ -553,11 +553,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
_, err := c.Extensions().Deployments(t.Namespace).Update(t)
|
||||
return false, err
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, fmt.Errorf("cannot pause %v", gvk)
|
||||
return false, fmt.Errorf("cannot pause %v", gvks[0])
|
||||
}
|
||||
},
|
||||
ResumeObject: func(object runtime.Object) (bool, error) {
|
||||
|
@ -575,11 +575,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
_, err := c.Extensions().Deployments(t.Namespace).Update(t)
|
||||
return false, err
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, fmt.Errorf("cannot resume %v", gvk)
|
||||
return false, fmt.Errorf("cannot resume %v", gvks[0])
|
||||
}
|
||||
},
|
||||
Scaler: func(mapping *meta.RESTMapping) (kubectl.Scaler, error) {
|
||||
|
@ -712,11 +712,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
case *api.Pod:
|
||||
return t, nil
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot attach to %v: not implemented", gvk)
|
||||
return nil, fmt.Errorf("cannot attach to %v: not implemented", gvks[0])
|
||||
}
|
||||
},
|
||||
// UpdatePodSpecForObject update the pod specification for the provided object
|
||||
|
@ -1101,12 +1101,12 @@ func DefaultClientConfig(flags *pflag.FlagSet) clientcmd.ClientConfig {
|
|||
|
||||
// PrintObject prints an api object given command line flags to modify the output format
|
||||
func (f *Factory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
|
||||
gvk, err := api.Scheme.ObjectKind(obj)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mapping, err := mapper.RESTMapping(gvk.GroupKind())
|
||||
mapping, err := mapper.RESTMapping(gvks[0].GroupKind())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
|
|||
// if the object cannot be introspected. Name and namespace will be set into Info
|
||||
// if the mapping's MetadataAccessor can retrieve them.
|
||||
func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []unversioned.GroupVersionKind) (*Info, error) {
|
||||
groupVersionKinds, err := m.ObjectKinds(obj)
|
||||
groupVersionKinds, _, err := m.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get type info from the object %q: %v", reflect.TypeOf(obj), err)
|
||||
}
|
||||
|
|
|
@ -251,7 +251,7 @@ func AsVersionedObjects(infos []*Info, version unversioned.GroupVersion, encoder
|
|||
// objects that are not part of api.Scheme must be converted to JSON
|
||||
// TODO: convert to map[string]interface{}, attach to runtime.Unknown?
|
||||
if !version.IsEmpty() {
|
||||
if _, err := api.Scheme.ObjectKind(info.Object); runtime.IsNotRegisteredError(err) {
|
||||
if _, _, err := api.Scheme.ObjectKinds(info.Object); runtime.IsNotRegisteredError(err) {
|
||||
// TODO: ideally this would encode to version, but we don't expose multiple codecs here.
|
||||
data, err := runtime.Encode(encoder, info.Object)
|
||||
if err != nil {
|
||||
|
|
|
@ -69,7 +69,8 @@ func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
|
|||
printer = &YAMLPrinter{}
|
||||
case "name":
|
||||
printer = &NamePrinter{
|
||||
Typer: runtime.ObjectTyperToTyper(api.Scheme),
|
||||
// TODO: this is wrong, these should be provided as an argument to GetPrinter
|
||||
Typer: api.Scheme,
|
||||
Decoder: api.Codecs.UniversalDecoder(),
|
||||
}
|
||||
case "template", "go-template":
|
||||
|
@ -203,14 +204,12 @@ func (p *VersionedPrinter) HandledResources() []string {
|
|||
// NamePrinter is an implementation of ResourcePrinter which outputs "resource/name" pair of an object.
|
||||
type NamePrinter struct {
|
||||
Decoder runtime.Decoder
|
||||
Typer runtime.Typer
|
||||
Typer runtime.ObjectTyper
|
||||
}
|
||||
|
||||
// PrintObj is an implementation of ResourcePrinter.PrintObj which decodes the object
|
||||
// and print "resource/name" pair. If the object is a List, print all items in it.
|
||||
func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||
gvk, _, _ := p.Typer.ObjectKind(obj)
|
||||
|
||||
if meta.IsListType(obj) {
|
||||
items, err := meta.ExtractList(obj)
|
||||
if err != nil {
|
||||
|
@ -236,10 +235,9 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
|||
}
|
||||
}
|
||||
|
||||
if gvk != nil {
|
||||
if gvks, _, err := p.Typer.ObjectKinds(obj); err == nil {
|
||||
// TODO: this is wrong, it assumes that meta knows about all Kinds - should take a RESTMapper
|
||||
_, resource := meta.KindToResource(*gvk)
|
||||
|
||||
_, resource := meta.KindToResource(gvks[0])
|
||||
fmt.Fprintf(w, "%s/%s\n", resource.Resource, name)
|
||||
} else {
|
||||
fmt.Fprintf(w, "<unknown>/%s\n", name)
|
||||
|
|
|
@ -466,7 +466,7 @@ func TestPrinters(t *testing.T) {
|
|||
"template2": templatePrinter2,
|
||||
"jsonpath": jsonpathPrinter,
|
||||
"name": &NamePrinter{
|
||||
Typer: runtime.ObjectTyperToTyper(api.Scheme),
|
||||
Typer: api.Scheme,
|
||||
Decoder: api.Codecs.UniversalDecoder(),
|
||||
},
|
||||
}
|
||||
|
|
|
@ -152,10 +152,11 @@ func (t *Tester) TestWatch(valid runtime.Object, labelsPass, labelsFail []labels
|
|||
// =============================================================================
|
||||
// get codec based on runtime.Object
|
||||
func getCodec(obj runtime.Object) (runtime.Codec, error) {
|
||||
fqKind, err := api.Scheme.ObjectKind(obj)
|
||||
fqKinds, _, err := api.Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected encoding error: %v", err)
|
||||
}
|
||||
fqKind := fqKinds[0]
|
||||
// TODO: caesarxuchao: we should detect which group an object belongs to
|
||||
// by using the version returned by Schem.ObjectVersionAndKind() once we
|
||||
// split the schemes for internal objects.
|
||||
|
|
|
@ -78,13 +78,13 @@ func EncodeOrDie(e Encoder, obj Object) string {
|
|||
|
||||
// UseOrCreateObject returns obj if the canonical ObjectKind returned by the provided typer matches gvk, or
|
||||
// invokes the ObjectCreator to instantiate a new gvk. Returns an error if the typer cannot find the object.
|
||||
func UseOrCreateObject(t Typer, c ObjectCreater, gvk unversioned.GroupVersionKind, obj Object) (Object, error) {
|
||||
func UseOrCreateObject(t ObjectTyper, c ObjectCreater, gvk unversioned.GroupVersionKind, obj Object) (Object, error) {
|
||||
if obj != nil {
|
||||
into, _, err := t.ObjectKind(obj)
|
||||
into, _, err := t.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if gvk == *into {
|
||||
if gvk == into[0] {
|
||||
return obj, nil
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ func (n NoopDecoder) Decode(data []byte, gvk *unversioned.GroupVersionKind, into
|
|||
// NewParameterCodec creates a ParameterCodec capable of transforming url values into versioned objects and back.
|
||||
func NewParameterCodec(scheme *Scheme) ParameterCodec {
|
||||
return ¶meterCodec{
|
||||
typer: ObjectTyperToTyper(scheme),
|
||||
typer: scheme,
|
||||
convertor: scheme,
|
||||
creator: scheme,
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ func NewParameterCodec(scheme *Scheme) ParameterCodec {
|
|||
|
||||
// parameterCodec implements conversion to and from query parameters and objects.
|
||||
type parameterCodec struct {
|
||||
typer Typer
|
||||
typer ObjectTyper
|
||||
convertor ObjectConvertor
|
||||
creator ObjectCreater
|
||||
}
|
||||
|
@ -137,10 +137,11 @@ func (c *parameterCodec) DecodeParameters(parameters url.Values, from unversione
|
|||
if len(parameters) == 0 {
|
||||
return nil
|
||||
}
|
||||
targetGVK, _, err := c.typer.ObjectKind(into)
|
||||
targetGVKs, _, err := c.typer.ObjectKinds(into)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
targetGVK := targetGVKs[0]
|
||||
if targetGVK.GroupVersion() == from {
|
||||
return c.convertor.Convert(¶meters, into)
|
||||
}
|
||||
|
@ -157,10 +158,11 @@ func (c *parameterCodec) DecodeParameters(parameters url.Values, from unversione
|
|||
// EncodeParameters converts the provided object into the to version, then converts that object to url.Values.
|
||||
// Returns an error if conversion is not possible.
|
||||
func (c *parameterCodec) EncodeParameters(obj Object, to unversioned.GroupVersion) (url.Values, error) {
|
||||
gvk, _, err := c.typer.ObjectKind(obj)
|
||||
gvks, _, err := c.typer.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gvk := gvks[0]
|
||||
if to != gvk.GroupVersion() {
|
||||
out, err := c.convertor.ConvertToVersion(obj, to)
|
||||
if err != nil {
|
||||
|
|
|
@ -26,28 +26,6 @@ import (
|
|||
"k8s.io/kubernetes/pkg/util/errors"
|
||||
)
|
||||
|
||||
type objectTyperToTyper struct {
|
||||
typer ObjectTyper
|
||||
}
|
||||
|
||||
func (t objectTyperToTyper) ObjectKind(obj Object) (*unversioned.GroupVersionKind, bool, error) {
|
||||
gvk, err := t.typer.ObjectKind(obj)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
unversionedType, ok := t.typer.IsUnversioned(obj)
|
||||
if !ok {
|
||||
// ObjectTyper violates its contract
|
||||
return nil, false, fmt.Errorf("typer returned a kind for %v, but then reported it was not in the scheme with IsUnversioned", reflect.TypeOf(obj))
|
||||
}
|
||||
return &gvk, unversionedType, nil
|
||||
}
|
||||
|
||||
// ObjectTyperToTyper casts the old typer interface to the new typer interface
|
||||
func ObjectTyperToTyper(typer ObjectTyper) Typer {
|
||||
return objectTyperToTyper{typer: typer}
|
||||
}
|
||||
|
||||
// unsafeObjectConvertor implements ObjectConvertor using the unsafe conversion path.
|
||||
type unsafeObjectConvertor struct {
|
||||
*Scheme
|
||||
|
@ -195,19 +173,9 @@ type MultiObjectTyper []ObjectTyper
|
|||
|
||||
var _ ObjectTyper = MultiObjectTyper{}
|
||||
|
||||
func (m MultiObjectTyper) ObjectKind(obj Object) (gvk unversioned.GroupVersionKind, err error) {
|
||||
func (m MultiObjectTyper) ObjectKinds(obj Object) (gvks []unversioned.GroupVersionKind, unversionedType bool, err error) {
|
||||
for _, t := range m {
|
||||
gvk, err = t.ObjectKind(obj)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m MultiObjectTyper) ObjectKinds(obj Object) (gvks []unversioned.GroupVersionKind, err error) {
|
||||
for _, t := range m {
|
||||
gvks, err = t.ObjectKinds(obj)
|
||||
gvks, unversionedType, err = t.ObjectKinds(obj)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
@ -224,15 +192,6 @@ func (m MultiObjectTyper) Recognizes(gvk unversioned.GroupVersionKind) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (m MultiObjectTyper) IsUnversioned(obj Object) (bool, bool) {
|
||||
for _, t := range m {
|
||||
if unversioned, ok := t.IsUnversioned(obj); ok {
|
||||
return unversioned, true
|
||||
}
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
// SetZeroValue would set the object of objPtr to zero value of its type.
|
||||
func SetZeroValue(objPtr Object) error {
|
||||
v, err := conversion.EnforcePtr(objPtr)
|
||||
|
|
|
@ -30,15 +30,6 @@ const (
|
|||
APIVersionInternal = "__internal"
|
||||
)
|
||||
|
||||
// Typer retrieves information about an object's group, version, and kind.
|
||||
type Typer interface {
|
||||
// ObjectKind returns the version and kind of the provided object, or an
|
||||
// error if the object is not recognized (IsNotRegisteredError will return true).
|
||||
// It returns whether the object is considered unversioned at the same time.
|
||||
// TODO: align the signature of ObjectTyper with this interface
|
||||
ObjectKind(Object) (*unversioned.GroupVersionKind, bool, error)
|
||||
}
|
||||
|
||||
type Encoder interface {
|
||||
// EncodeToStream writes an object to a stream. Override versions may be provided for each group
|
||||
// that enforce a certain versioning. Implementations may return errors if the versions are incompatible,
|
||||
|
@ -178,20 +169,14 @@ type ObjectConvertor interface {
|
|||
// ObjectTyper contains methods for extracting the APIVersion and Kind
|
||||
// of objects.
|
||||
type ObjectTyper interface {
|
||||
// ObjectKind returns the default group,version,kind of the provided object, or an
|
||||
// error if the object is not recognized (IsNotRegisteredError will return true).
|
||||
ObjectKind(Object) (unversioned.GroupVersionKind, error)
|
||||
// ObjectKinds returns the all possible group,version,kind of the provided object, or an
|
||||
// error if the object is not recognized (IsNotRegisteredError will return true).
|
||||
ObjectKinds(Object) ([]unversioned.GroupVersionKind, error)
|
||||
// ObjectKinds returns the all possible group,version,kind of the provided object, true if
|
||||
// the object is unversioned, or an error if the object is not recognized
|
||||
// (IsNotRegisteredError will return true).
|
||||
ObjectKinds(Object) ([]unversioned.GroupVersionKind, bool, error)
|
||||
// Recognizes returns true if the scheme is able to handle the provided version and kind,
|
||||
// or more precisely that the provided version is a possible conversion or decoding
|
||||
// target.
|
||||
Recognizes(gvk unversioned.GroupVersionKind) bool
|
||||
// IsUnversioned returns true if the provided object is considered unversioned and thus
|
||||
// should have Version and Group suppressed in the output. If the object is not recognized
|
||||
// in the scheme, ok is false.
|
||||
IsUnversioned(Object) (unversioned bool, ok bool)
|
||||
}
|
||||
|
||||
// ObjectCreater contains methods for instantiating an object by kind and version.
|
||||
|
|
|
@ -211,31 +211,32 @@ func (s *Scheme) KnownTypes(gv unversioned.GroupVersion) map[string]reflect.Type
|
|||
return types
|
||||
}
|
||||
|
||||
// ObjectKind returns the group,version,kind of the go object,
|
||||
// or an error if it's not a pointer or is unregistered.
|
||||
func (s *Scheme) ObjectKind(obj Object) (unversioned.GroupVersionKind, error) {
|
||||
gvks, err := s.ObjectKinds(obj)
|
||||
// ObjectKind returns the group,version,kind of the go object and true if this object
|
||||
// is considered unversioned, or an error if it's not a pointer or is unregistered.
|
||||
func (s *Scheme) ObjectKind(obj Object) (unversioned.GroupVersionKind, bool, error) {
|
||||
gvks, unversionedType, err := s.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
return unversioned.GroupVersionKind{}, false, err
|
||||
}
|
||||
return gvks[0], nil
|
||||
return gvks[0], unversionedType, nil
|
||||
}
|
||||
|
||||
// ObjectKinds returns all possible group,version,kind of the go object,
|
||||
// or an error if it's not a pointer or is unregistered.
|
||||
func (s *Scheme) ObjectKinds(obj Object) ([]unversioned.GroupVersionKind, error) {
|
||||
// ObjectKinds returns all possible group,version,kind of the go object, true if the
|
||||
// object is considered unversioned, or an error if it's not a pointer or is unregistered.
|
||||
func (s *Scheme) ObjectKinds(obj Object) ([]unversioned.GroupVersionKind, bool, error) {
|
||||
v, err := conversion.EnforcePtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, false, err
|
||||
}
|
||||
t := v.Type()
|
||||
|
||||
gvks, ok := s.typeToGVK[t]
|
||||
if !ok {
|
||||
return nil, ¬RegisteredErr{t: t}
|
||||
return nil, false, ¬RegisteredErr{t: t}
|
||||
}
|
||||
_, unversionedType := s.unversionedTypes[t]
|
||||
|
||||
return gvks, nil
|
||||
return gvks, unversionedType, nil
|
||||
}
|
||||
|
||||
// Recognizes returns true if the scheme is able to handle the provided group,version,kind
|
||||
|
@ -439,13 +440,13 @@ func (s *Scheme) Convert(in, out interface{}) error {
|
|||
inVersion := unversioned.GroupVersion{Group: "unknown", Version: "unknown"}
|
||||
outVersion := unversioned.GroupVersion{Group: "unknown", Version: "unknown"}
|
||||
if inObj, ok := in.(Object); ok {
|
||||
if gvk, err := s.ObjectKind(inObj); err == nil {
|
||||
inVersion = gvk.GroupVersion()
|
||||
if gvks, _, err := s.ObjectKinds(inObj); err == nil {
|
||||
inVersion = gvks[0].GroupVersion()
|
||||
}
|
||||
}
|
||||
if outObj, ok := out.(Object); ok {
|
||||
if gvk, err := s.ObjectKind(outObj); err == nil {
|
||||
outVersion = gvk.GroupVersion()
|
||||
if gvks, _, err := s.ObjectKinds(outObj); err == nil {
|
||||
outVersion = gvks[0].GroupVersion()
|
||||
}
|
||||
}
|
||||
flags, meta := s.generateConvertMeta(inVersion, outVersion, in)
|
||||
|
@ -504,7 +505,7 @@ func (s *Scheme) ConvertToVersion(in Object, outVersion unversioned.GroupVersion
|
|||
|
||||
outKind := outVersion.WithKind(kind.Kind)
|
||||
|
||||
inKind, err := s.ObjectKind(in)
|
||||
inKinds, _, err := s.ObjectKinds(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -514,7 +515,7 @@ func (s *Scheme) ConvertToVersion(in Object, outVersion unversioned.GroupVersion
|
|||
return nil, err
|
||||
}
|
||||
|
||||
flags, meta := s.generateConvertMeta(inKind.GroupVersion(), outVersion, in)
|
||||
flags, meta := s.generateConvertMeta(inKinds[0].GroupVersion(), outVersion, in)
|
||||
if err := s.converter.Convert(in, out, flags, meta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -603,8 +604,11 @@ func setTargetVersion(obj Object, raw *Scheme, gv unversioned.GroupVersion) {
|
|||
obj.GetObjectKind().SetGroupVersionKind(unversioned.GroupVersionKind{})
|
||||
return
|
||||
}
|
||||
gvk, _ := raw.ObjectKind(obj)
|
||||
obj.GetObjectKind().SetGroupVersionKind(unversioned.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: gvk.Kind})
|
||||
if gvks, _, _ := raw.ObjectKinds(obj); len(gvks) > 0 {
|
||||
obj.GetObjectKind().SetGroupVersionKind(unversioned.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: gvks[0].Kind})
|
||||
} else {
|
||||
obj.GetObjectKind().SetGroupVersionKind(unversioned.GroupVersionKind{Group: gv.Group, Version: gv.Version})
|
||||
}
|
||||
}
|
||||
|
||||
// setTargetKind sets the kind on an object, taking into account whether the target kind is the internal version.
|
||||
|
|
|
@ -354,10 +354,11 @@ func TestUnversionedTypes(t *testing.T) {
|
|||
t.Fatalf("type not unversioned and in scheme: %t %t", unv, ok)
|
||||
}
|
||||
|
||||
kind, err := scheme.ObjectKind(&InternalSimple{})
|
||||
kinds, _, err := scheme.ObjectKinds(&InternalSimple{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kind := kinds[0]
|
||||
if kind != externalGV.WithKind("InternalSimple") {
|
||||
t.Fatalf("unexpected: %#v", kind)
|
||||
}
|
||||
|
|
|
@ -58,9 +58,9 @@ type serializerType struct {
|
|||
}
|
||||
|
||||
func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory) []serializerType {
|
||||
jsonSerializer := json.NewSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme), false)
|
||||
jsonPrettySerializer := json.NewSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme), true)
|
||||
yamlSerializer := json.NewYAMLSerializer(mf, scheme, runtime.ObjectTyperToTyper(scheme))
|
||||
jsonSerializer := json.NewSerializer(mf, scheme, scheme, false)
|
||||
jsonPrettySerializer := json.NewSerializer(mf, scheme, scheme, true)
|
||||
yamlSerializer := json.NewYAMLSerializer(mf, scheme, scheme)
|
||||
|
||||
serializers := []serializerType{
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ import (
|
|||
|
||||
// NewSerializer creates a JSON serializer that handles encoding versioned objects into the proper JSON form. If typer
|
||||
// is not nil, the object has the group, version, and kind fields set.
|
||||
func NewSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.Typer, pretty bool) *Serializer {
|
||||
func NewSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, pretty bool) *Serializer {
|
||||
return &Serializer{
|
||||
meta: meta,
|
||||
creater: creater,
|
||||
|
@ -44,7 +44,7 @@ func NewSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtim
|
|||
// NewYAMLSerializer creates a YAML serializer that handles encoding versioned objects into the proper YAML form. If typer
|
||||
// is not nil, the object has the group, version, and kind fields set. This serializer supports only the subset of YAML that
|
||||
// matches JSON, and will error if constructs are used that do not serialize to JSON.
|
||||
func NewYAMLSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.Typer) *Serializer {
|
||||
func NewYAMLSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper) *Serializer {
|
||||
return &Serializer{
|
||||
meta: meta,
|
||||
creater: creater,
|
||||
|
@ -56,7 +56,7 @@ func NewYAMLSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer ru
|
|||
type Serializer struct {
|
||||
meta MetaFactory
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.Typer
|
||||
typer runtime.ObjectTyper
|
||||
yaml bool
|
||||
pretty bool
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi
|
|||
}
|
||||
|
||||
if into != nil {
|
||||
typed, _, err := s.typer.ObjectKind(into)
|
||||
types, _, err := s.typer.ObjectKinds(into)
|
||||
switch {
|
||||
case runtime.IsNotRegisteredError(err):
|
||||
if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(into); err != nil {
|
||||
|
@ -126,6 +126,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi
|
|||
case err != nil:
|
||||
return nil, actual, err
|
||||
default:
|
||||
typed := types[0]
|
||||
if len(actual.Kind) == 0 {
|
||||
actual.Kind = typed.Kind
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func (d *testDecodable) GroupVersionKind() unversioned.GroupVersionKind {
|
|||
func TestDecode(t *testing.T) {
|
||||
testCases := []struct {
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.Typer
|
||||
typer runtime.ObjectTyper
|
||||
yaml bool
|
||||
pretty bool
|
||||
|
||||
|
@ -260,6 +260,13 @@ type mockTyper struct {
|
|||
err error
|
||||
}
|
||||
|
||||
func (t *mockTyper) ObjectKind(obj runtime.Object) (*unversioned.GroupVersionKind, bool, error) {
|
||||
return t.gvk, false, t.err
|
||||
func (t *mockTyper) ObjectKinds(obj runtime.Object) ([]unversioned.GroupVersionKind, bool, error) {
|
||||
if t.gvk == nil {
|
||||
return nil, false, t.err
|
||||
}
|
||||
return []unversioned.GroupVersionKind{*t.gvk}, false, t.err
|
||||
}
|
||||
|
||||
func (t *mockTyper) Recognizes(_ unversioned.GroupVersionKind) bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ func IsNotMarshalable(err error) bool {
|
|||
// as-is (any type info passed with the object will be used).
|
||||
//
|
||||
// This encoding scheme is experimental, and is subject to change at any time.
|
||||
func NewSerializer(creater runtime.ObjectCreater, typer runtime.Typer, defaultContentType string) *Serializer {
|
||||
func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, defaultContentType string) *Serializer {
|
||||
return &Serializer{
|
||||
prefix: protoEncodingPrefix,
|
||||
creater: creater,
|
||||
|
@ -71,7 +71,7 @@ func NewSerializer(creater runtime.ObjectCreater, typer runtime.Typer, defaultCo
|
|||
type Serializer struct {
|
||||
prefix []byte
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.Typer
|
||||
typer runtime.ObjectTyper
|
||||
contentType string
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi
|
|||
}
|
||||
|
||||
if into != nil {
|
||||
typed, _, err := s.typer.ObjectKind(into)
|
||||
types, _, err := s.typer.ObjectKinds(into)
|
||||
switch {
|
||||
case runtime.IsNotRegisteredError(err):
|
||||
pb, ok := into.(proto.Message)
|
||||
|
@ -145,12 +145,12 @@ func (s *Serializer) Decode(originalData []byte, gvk *unversioned.GroupVersionKi
|
|||
case err != nil:
|
||||
return nil, &actual, err
|
||||
default:
|
||||
copyKindDefaults(&actual, typed)
|
||||
copyKindDefaults(&actual, &types[0])
|
||||
// if the result of defaulting did not set a version or group, ensure that at least group is set
|
||||
// (copyKindDefaults will not assign Group if version is already set). This guarantees that the group
|
||||
// of into is set if there is no better information from the caller or object.
|
||||
if len(actual.Version) == 0 && len(actual.Group) == 0 {
|
||||
actual.Group = typed.Group
|
||||
actual.Group = types[0].Group
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ func estimateUnknownSize(unk *runtime.Unknown, byteSize uint64) uint64 {
|
|||
// encoded object, and thus is not self describing (callers must know what type is being described in order to decode).
|
||||
//
|
||||
// This encoding scheme is experimental, and is subject to change at any time.
|
||||
func NewRawSerializer(creater runtime.ObjectCreater, typer runtime.Typer, defaultContentType string) *RawSerializer {
|
||||
func NewRawSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, defaultContentType string) *RawSerializer {
|
||||
return &RawSerializer{
|
||||
creater: creater,
|
||||
typer: typer,
|
||||
|
@ -289,7 +289,7 @@ func NewRawSerializer(creater runtime.ObjectCreater, typer runtime.Typer, defaul
|
|||
// type).
|
||||
type RawSerializer struct {
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.Typer
|
||||
typer runtime.ObjectTyper
|
||||
contentType string
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,7 @@ func (s *RawSerializer) Decode(originalData []byte, gvk *unversioned.GroupVersio
|
|||
return intoUnknown, actual, nil
|
||||
}
|
||||
|
||||
typed, _, err := s.typer.ObjectKind(into)
|
||||
types, _, err := s.typer.ObjectKinds(into)
|
||||
switch {
|
||||
case runtime.IsNotRegisteredError(err):
|
||||
pb, ok := into.(proto.Message)
|
||||
|
@ -351,12 +351,12 @@ func (s *RawSerializer) Decode(originalData []byte, gvk *unversioned.GroupVersio
|
|||
case err != nil:
|
||||
return nil, actual, err
|
||||
default:
|
||||
copyKindDefaults(actual, typed)
|
||||
copyKindDefaults(actual, &types[0])
|
||||
// if the result of defaulting did not set a version or group, ensure that at least group is set
|
||||
// (copyKindDefaults will not assign Group if version is already set). This guarantees that the group
|
||||
// of into is set if there is no better information from the caller or object.
|
||||
if len(actual.Version) == 0 && len(actual.Group) == 0 {
|
||||
actual.Group = typed.Group
|
||||
actual.Group = types[0].Group
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,7 +371,7 @@ func (s *RawSerializer) Decode(originalData []byte, gvk *unversioned.GroupVersio
|
|||
}
|
||||
|
||||
// unmarshalToObject is the common code between decode in the raw and normal serializer.
|
||||
func unmarshalToObject(typer runtime.Typer, creater runtime.ObjectCreater, actual *unversioned.GroupVersionKind, into runtime.Object, data []byte) (runtime.Object, *unversioned.GroupVersionKind, error) {
|
||||
func unmarshalToObject(typer runtime.ObjectTyper, creater runtime.ObjectCreater, actual *unversioned.GroupVersionKind, into runtime.Object, data []byte) (runtime.Object, *unversioned.GroupVersionKind, error) {
|
||||
// use the target if necessary
|
||||
obj, err := runtime.UseOrCreateObject(typer, creater, *actual, into)
|
||||
if err != nil {
|
||||
|
|
|
@ -323,7 +323,7 @@ func TestDecodeObjects(t *testing.T) {
|
|||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
s := protobuf.NewSerializer(api.Scheme, runtime.ObjectTyperToTyper(api.Scheme), "application/protobuf")
|
||||
s := protobuf.NewSerializer(api.Scheme, api.Scheme, "application/protobuf")
|
||||
obj, err := runtime.Decode(s, test.data)
|
||||
|
||||
switch {
|
||||
|
|
|
@ -31,8 +31,8 @@ const (
|
|||
)
|
||||
|
||||
func protobufSerializer(scheme *runtime.Scheme) (serializerType, bool) {
|
||||
serializer := protobuf.NewSerializer(scheme, runtime.ObjectTyperToTyper(scheme), contentTypeProtobuf)
|
||||
raw := protobuf.NewRawSerializer(scheme, runtime.ObjectTyperToTyper(scheme), contentTypeProtobuf)
|
||||
serializer := protobuf.NewSerializer(scheme, scheme, contentTypeProtobuf)
|
||||
raw := protobuf.NewRawSerializer(scheme, scheme, contentTypeProtobuf)
|
||||
return serializerType{
|
||||
AcceptContentTypes: []string{contentTypeProtobuf},
|
||||
ContentType: contentTypeProtobuf,
|
||||
|
|
|
@ -32,8 +32,8 @@ func TestRecognizer(t *testing.T) {
|
|||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(unversioned.GroupVersion{Version: "v1"}, &A{})
|
||||
d := NewDecoder(
|
||||
json.NewSerializer(json.DefaultMetaFactory, s, runtime.ObjectTyperToTyper(s), false),
|
||||
json.NewYAMLSerializer(json.DefaultMetaFactory, s, runtime.ObjectTyperToTyper(s)),
|
||||
json.NewSerializer(json.DefaultMetaFactory, s, s, false),
|
||||
json.NewYAMLSerializer(json.DefaultMetaFactory, s, s),
|
||||
)
|
||||
out, _, err := d.Decode([]byte(`
|
||||
kind: A
|
||||
|
|
|
@ -71,7 +71,7 @@ func NewCodecForScheme(
|
|||
encodeVersion []unversioned.GroupVersion,
|
||||
decodeVersion []unversioned.GroupVersion,
|
||||
) runtime.Codec {
|
||||
return NewCodec(encoder, decoder, runtime.UnsafeObjectConvertor(scheme), scheme, scheme, runtime.ObjectTyperToTyper(scheme), encodeVersion, decodeVersion)
|
||||
return NewCodec(encoder, decoder, runtime.UnsafeObjectConvertor(scheme), scheme, scheme, scheme, encodeVersion, decodeVersion)
|
||||
}
|
||||
|
||||
// NewCodec takes objects in their internal versions and converts them to external versions before
|
||||
|
@ -83,7 +83,7 @@ func NewCodec(
|
|||
convertor runtime.ObjectConvertor,
|
||||
creater runtime.ObjectCreater,
|
||||
copier runtime.ObjectCopier,
|
||||
typer runtime.Typer,
|
||||
typer runtime.ObjectTyper,
|
||||
encodeVersion []unversioned.GroupVersion,
|
||||
decodeVersion []unversioned.GroupVersion,
|
||||
) runtime.Codec {
|
||||
|
@ -104,6 +104,11 @@ func NewCodec(
|
|||
}
|
||||
internal.encodeVersion[v.Group] = v
|
||||
}
|
||||
if len(internal.encodeVersion) == 1 {
|
||||
for _, v := range internal.encodeVersion {
|
||||
internal.preferredEncodeVersion = []unversioned.GroupVersion{v}
|
||||
}
|
||||
}
|
||||
}
|
||||
if decodeVersion != nil {
|
||||
internal.decodeVersion = make(map[string]unversioned.GroupVersion)
|
||||
|
@ -125,10 +130,12 @@ type codec struct {
|
|||
convertor runtime.ObjectConvertor
|
||||
creater runtime.ObjectCreater
|
||||
copier runtime.ObjectCopier
|
||||
typer runtime.Typer
|
||||
typer runtime.ObjectTyper
|
||||
|
||||
encodeVersion map[string]unversioned.GroupVersion
|
||||
decodeVersion map[string]unversioned.GroupVersion
|
||||
|
||||
preferredEncodeVersion []unversioned.GroupVersion
|
||||
}
|
||||
|
||||
// Decode attempts a decode of the object, then tries to convert it to the internal version. If into is provided and the decoding is
|
||||
|
@ -221,15 +228,16 @@ func (c *codec) EncodeToStream(obj runtime.Object, w io.Writer, overrides ...unv
|
|||
if _, ok := obj.(*runtime.Unknown); ok {
|
||||
return c.encoder.EncodeToStream(obj, w, overrides...)
|
||||
}
|
||||
gvk, isUnversioned, err := c.typer.ObjectKind(obj)
|
||||
gvks, isUnversioned, err := c.typer.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gvk := gvks[0]
|
||||
|
||||
if (c.encodeVersion == nil && len(overrides) == 0) || isUnversioned {
|
||||
objectKind := obj.GetObjectKind()
|
||||
old := objectKind.GroupVersionKind()
|
||||
objectKind.SetGroupVersionKind(*gvk)
|
||||
objectKind.SetGroupVersionKind(gvk)
|
||||
err = c.encoder.EncodeToStream(obj, w, overrides...)
|
||||
objectKind.SetGroupVersionKind(old)
|
||||
return err
|
||||
|
@ -248,13 +256,16 @@ func (c *codec) EncodeToStream(obj runtime.Object, w io.Writer, overrides ...unv
|
|||
}
|
||||
|
||||
// attempt a conversion to the sole encode version
|
||||
if !ok && len(c.encodeVersion) == 1 {
|
||||
if !ok && c.preferredEncodeVersion != nil {
|
||||
ok = true
|
||||
for _, v := range c.encodeVersion {
|
||||
targetGV = v
|
||||
targetGV = c.preferredEncodeVersion[0]
|
||||
if len(overrides) > 0 {
|
||||
// ensure the target override is first
|
||||
overrides = promoteOrPrependGroupVersion(targetGV, overrides)
|
||||
} else {
|
||||
// avoids allocating a new array for each call to EncodeToVersion
|
||||
overrides = c.preferredEncodeVersion
|
||||
}
|
||||
// ensure the target override is first
|
||||
overrides = promoteOrPrependGroupVersion(targetGV, overrides)
|
||||
}
|
||||
|
||||
// if no fallback is available, error
|
||||
|
|
|
@ -49,7 +49,7 @@ func TestDecode(t *testing.T) {
|
|||
convertor runtime.ObjectConvertor
|
||||
creater runtime.ObjectCreater
|
||||
copier runtime.ObjectCopier
|
||||
typer runtime.Typer
|
||||
typer runtime.ObjectTyper
|
||||
yaml bool
|
||||
pretty bool
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
type lengthDelimitedFrameWriter struct {
|
||||
w io.Writer
|
||||
h [4]byte
|
||||
}
|
||||
|
||||
func NewLengthDelimitedFrameWriter(w io.Writer) io.Writer {
|
||||
|
@ -34,13 +35,12 @@ func NewLengthDelimitedFrameWriter(w io.Writer) io.Writer {
|
|||
// Write writes a single frame to the nested writer, prepending it with the length in
|
||||
// in bytes of data (as a 4 byte, bigendian uint32).
|
||||
func (w *lengthDelimitedFrameWriter) Write(data []byte) (int, error) {
|
||||
header := [4]byte{}
|
||||
binary.BigEndian.PutUint32(header[:], uint32(len(data)))
|
||||
n, err := w.w.Write(header[:])
|
||||
binary.BigEndian.PutUint32(w.h[:], uint32(len(data)))
|
||||
n, err := w.w.Write(w.h[:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if n != len(header) {
|
||||
if n != len(w.h) {
|
||||
return 0, io.ErrShortWrite
|
||||
}
|
||||
return w.w.Write(data)
|
||||
|
|
|
@ -42,7 +42,7 @@ var Versions = []string{"v1"}
|
|||
var Codec runtime.Codec
|
||||
|
||||
func init() {
|
||||
jsonSerializer := json.NewSerializer(json.DefaultMetaFactory, api.Scheme, runtime.ObjectTyperToTyper(api.Scheme), true)
|
||||
jsonSerializer := json.NewSerializer(json.DefaultMetaFactory, api.Scheme, api.Scheme, true)
|
||||
Codec = versioning.NewCodecForScheme(
|
||||
api.Scheme,
|
||||
jsonSerializer,
|
||||
|
|
|
@ -59,9 +59,9 @@ func (s *wrappedSerializer) UniversalDeserializer() runtime.Decoder {
|
|||
}
|
||||
|
||||
func (s *wrappedSerializer) EncoderForVersion(encoder runtime.Encoder, gv unversioned.GroupVersion) runtime.Encoder {
|
||||
return versioning.NewCodec(encoder, nil, s.scheme, s.scheme, s.scheme, runtime.ObjectTyperToTyper(s.scheme), []unversioned.GroupVersion{gv}, nil)
|
||||
return versioning.NewCodec(encoder, nil, s.scheme, s.scheme, s.scheme, s.scheme, []unversioned.GroupVersion{gv}, nil)
|
||||
}
|
||||
|
||||
func (s *wrappedSerializer) DecoderToVersion(decoder runtime.Decoder, gv unversioned.GroupVersion) runtime.Decoder {
|
||||
return versioning.NewCodec(nil, decoder, s.scheme, s.scheme, s.scheme, runtime.ObjectTyperToTyper(s.scheme), nil, []unversioned.GroupVersion{gv})
|
||||
return versioning.NewCodec(nil, decoder, s.scheme, s.scheme, s.scheme, s.scheme, nil, []unversioned.GroupVersion{gv})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue