mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 03:38:15 +00:00 
			
		
		
		
	only store typeMeta and objectMeta in the gc store
This commit is contained in:
		@@ -51,6 +51,7 @@ import (
 | 
			
		||||
	endpointcontroller "k8s.io/kubernetes/pkg/controller/endpoint"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/framework/informers"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/garbagecollector"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/job"
 | 
			
		||||
	namespacecontroller "k8s.io/kubernetes/pkg/controller/namespace"
 | 
			
		||||
	nodecontroller "k8s.io/kubernetes/pkg/controller/node"
 | 
			
		||||
@@ -69,6 +70,7 @@ import (
 | 
			
		||||
	persistentvolumecontroller "k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/healthz"
 | 
			
		||||
	quotainstall "k8s.io/kubernetes/pkg/quota/install"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime/serializer"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/serviceaccount"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/configz"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/crypto"
 | 
			
		||||
@@ -495,8 +497,12 @@ func StartControllers(s *options.CMServer, kubeClient *client.Client, kubeconfig
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			glog.Fatalf("Failed to get supported resources from server: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		clientPool := dynamic.NewClientPool(restclient.AddUserAgent(kubeconfig, "generic-garbage-collector"), dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
		garbageCollector, err := garbagecollector.NewGarbageCollector(clientPool, groupVersionResources)
 | 
			
		||||
		config := restclient.AddUserAgent(kubeconfig, "generic-garbage-collector")
 | 
			
		||||
		config.ContentConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: metaonly.NewMetadataCodecFactory()}
 | 
			
		||||
		metaOnlyClientPool := dynamic.NewClientPool(config, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
		config.ContentConfig.NegotiatedSerializer = nil
 | 
			
		||||
		clientPool := dynamic.NewClientPool(config, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
		garbageCollector, err := garbagecollector.NewGarbageCollector(metaOnlyClientPool, clientPool, groupVersionResources)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			glog.Errorf("Failed to start the generic garbage collector: %v", err)
 | 
			
		||||
		} else {
 | 
			
		||||
 
 | 
			
		||||
@@ -1911,6 +1911,7 @@ func TestDeleteWithOptions(t *testing.T) {
 | 
			
		||||
	if simpleStorage.deleted != ID {
 | 
			
		||||
		t.Errorf("Unexpected delete: %s, expected %s", simpleStorage.deleted, ID)
 | 
			
		||||
	}
 | 
			
		||||
	simpleStorage.deleteOptions.GetObjectKind().SetGroupVersionKind(unversioned.GroupVersionKind{})
 | 
			
		||||
	if !api.Semantic.DeepEqual(simpleStorage.deleteOptions, item) {
 | 
			
		||||
		t.Errorf("unexpected delete options: %s", diff.ObjectDiff(simpleStorage.deleteOptions, item))
 | 
			
		||||
	}
 | 
			
		||||
@@ -2700,6 +2701,7 @@ func TestCreate(t *testing.T) {
 | 
			
		||||
		t.Errorf("unexpected error: %v %#v", err, response)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	itemOut.GetObjectKind().SetGroupVersionKind(unversioned.GroupVersionKind{})
 | 
			
		||||
	if !reflect.DeepEqual(&itemOut, simple) {
 | 
			
		||||
		t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simple, string(body))
 | 
			
		||||
	}
 | 
			
		||||
@@ -2769,6 +2771,7 @@ func TestCreateYAML(t *testing.T) {
 | 
			
		||||
		t.Fatalf("unexpected error: %v %#v", err, response)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	itemOut.GetObjectKind().SetGroupVersionKind(unversioned.GroupVersionKind{})
 | 
			
		||||
	if !reflect.DeepEqual(&itemOut, simple) {
 | 
			
		||||
		t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simple, string(body))
 | 
			
		||||
	}
 | 
			
		||||
@@ -2827,6 +2830,7 @@ func TestCreateInNamespace(t *testing.T) {
 | 
			
		||||
		t.Fatalf("unexpected error: %v\n%s", err, data)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	itemOut.GetObjectKind().SetGroupVersionKind(unversioned.GroupVersionKind{})
 | 
			
		||||
	if !reflect.DeepEqual(&itemOut, simple) {
 | 
			
		||||
		t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simple, string(body))
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -54,13 +54,9 @@ func NewClient(conf *restclient.Config) (*Client, error) {
 | 
			
		||||
	confCopy := *conf
 | 
			
		||||
	conf = &confCopy
 | 
			
		||||
 | 
			
		||||
	codec := dynamicCodec{}
 | 
			
		||||
 | 
			
		||||
	// TODO: it's questionable that this should be using anything other than unstructured schema and JSON
 | 
			
		||||
	conf.ContentType = runtime.ContentTypeJSON
 | 
			
		||||
	conf.AcceptContentTypes = runtime.ContentTypeJSON
 | 
			
		||||
	streamingInfo, _ := api.Codecs.StreamingSerializerForMediaType("application/json;stream=watch", nil)
 | 
			
		||||
	conf.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec}, streamingInfo)
 | 
			
		||||
 | 
			
		||||
	if conf.APIPath == "" {
 | 
			
		||||
		conf.APIPath = "/api"
 | 
			
		||||
@@ -69,6 +65,10 @@ func NewClient(conf *restclient.Config) (*Client, error) {
 | 
			
		||||
	if len(conf.UserAgent) == 0 {
 | 
			
		||||
		conf.UserAgent = restclient.DefaultKubernetesUserAgent()
 | 
			
		||||
	}
 | 
			
		||||
	if conf.NegotiatedSerializer == nil {
 | 
			
		||||
		streamingInfo, _ := api.Codecs.StreamingSerializerForMediaType("application/json;stream=watch", nil)
 | 
			
		||||
		conf.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: dynamicCodec{}}, streamingInfo)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cl, err := restclient.RESTClientFor(conf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -119,19 +119,17 @@ type ResourceClient struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// List returns a list of objects for this resource.
 | 
			
		||||
func (rc *ResourceClient) List(opts runtime.Object) (*runtime.UnstructuredList, error) {
 | 
			
		||||
	result := new(runtime.UnstructuredList)
 | 
			
		||||
func (rc *ResourceClient) List(opts runtime.Object) (runtime.Object, error) {
 | 
			
		||||
	parameterEncoder := rc.parameterCodec
 | 
			
		||||
	if parameterEncoder == nil {
 | 
			
		||||
		parameterEncoder = defaultParameterEncoder
 | 
			
		||||
	}
 | 
			
		||||
	err := rc.cl.Get().
 | 
			
		||||
	return rc.cl.Get().
 | 
			
		||||
		NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
 | 
			
		||||
		Resource(rc.resource.Name).
 | 
			
		||||
		VersionedParams(opts, parameterEncoder).
 | 
			
		||||
		Do().
 | 
			
		||||
		Into(result)
 | 
			
		||||
	return result, err
 | 
			
		||||
		Get()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get gets the resource with the specified name.
 | 
			
		||||
 
 | 
			
		||||
@@ -19,8 +19,11 @@ package dynamic
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/unversioned"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/client/restclient"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime/serializer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ClientPool manages a pool of dynamic clients.
 | 
			
		||||
@@ -77,6 +80,12 @@ func (c *clientPoolImpl) ClientForGroupVersion(groupVersion unversioned.GroupVer
 | 
			
		||||
 | 
			
		||||
	// we need to make a client
 | 
			
		||||
	conf.GroupVersion = &groupVersion
 | 
			
		||||
 | 
			
		||||
	if conf.NegotiatedSerializer == nil {
 | 
			
		||||
		streamingInfo, _ := api.Codecs.StreamingSerializerForMediaType("application/json;stream=watch", nil)
 | 
			
		||||
		conf.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: dynamicCodec{}}, streamingInfo)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dynamicClient, err := NewClient(conf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/client/cache"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/client/typed/dynamic"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/framework"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/types"
 | 
			
		||||
	utilerrors "k8s.io/kubernetes/pkg/util/errors"
 | 
			
		||||
@@ -154,6 +155,7 @@ func (p *Propagator) addDependentToOwners(n *node, owners []metatypes.OwnerRefer
 | 
			
		||||
				dependentsLock: &sync.RWMutex{},
 | 
			
		||||
				dependents:     make(map[*node]struct{}),
 | 
			
		||||
			}
 | 
			
		||||
			glog.V(6).Infof("add virtual node.identity: %s\n\n", ownerNode.identity)
 | 
			
		||||
			p.uidToNode.Write(ownerNode)
 | 
			
		||||
			p.gc.dirtyQueue.Add(ownerNode)
 | 
			
		||||
		}
 | 
			
		||||
@@ -427,6 +429,11 @@ func (p *Propagator) processEvent() {
 | 
			
		||||
// DeleteOptions.OrphanDependents=true.
 | 
			
		||||
type GarbageCollector struct {
 | 
			
		||||
	restMapper meta.RESTMapper
 | 
			
		||||
	// metaOnlyClientPool uses a special codec, which removes fields except for
 | 
			
		||||
	// apiVersion, kind, and metadata during decoding.
 | 
			
		||||
	metaOnlyClientPool dynamic.ClientPool
 | 
			
		||||
	// clientPool uses the regular dynamicCodec. We need it to update
 | 
			
		||||
	// finalizers. It can be removed if we support patching finalizers.
 | 
			
		||||
	clientPool  dynamic.ClientPool
 | 
			
		||||
	dirtyQueue  *workqueue.Type
 | 
			
		||||
	orphanQueue *workqueue.Type
 | 
			
		||||
@@ -434,8 +441,6 @@ type GarbageCollector struct {
 | 
			
		||||
	propagator  *Propagator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: make special List and Watch function that removes fields other than
 | 
			
		||||
// ObjectMeta.
 | 
			
		||||
func gcListWatcher(client *dynamic.Client, resource unversioned.GroupVersionResource) *cache.ListWatch {
 | 
			
		||||
	return &cache.ListWatch{
 | 
			
		||||
		ListFunc: func(options api.ListOptions) (runtime.Object, error) {
 | 
			
		||||
@@ -461,14 +466,21 @@ func gcListWatcher(client *dynamic.Client, resource unversioned.GroupVersionReso
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func monitorFor(p *Propagator, clientPool dynamic.ClientPool, resource unversioned.GroupVersionResource) (monitor, error) {
 | 
			
		||||
func monitorFor(p *Propagator, clientPool dynamic.ClientPool, resource unversioned.GroupVersionResource, kind unversioned.GroupVersionKind) (monitor, error) {
 | 
			
		||||
	// TODO: consider store in one storage.
 | 
			
		||||
	glog.V(6).Infof("create storage for resource %s", resource)
 | 
			
		||||
	var monitor monitor
 | 
			
		||||
	client, err := clientPool.ClientForGroupVersion(resource.GroupVersion())
 | 
			
		||||
	client, err := p.gc.metaOnlyClientPool.ClientForGroupVersion(resource.GroupVersion())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return monitor, err
 | 
			
		||||
	}
 | 
			
		||||
	setObjectTypeMeta := func(obj interface{}) {
 | 
			
		||||
		runtimeObject, ok := obj.(runtime.Object)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			utilruntime.HandleError(fmt.Errorf("expected runtime.Object, got %#v", obj))
 | 
			
		||||
		}
 | 
			
		||||
		runtimeObject.GetObjectKind().SetGroupVersionKind(kind)
 | 
			
		||||
	}
 | 
			
		||||
	monitor.store, monitor.controller = framework.NewInformer(
 | 
			
		||||
		gcListWatcher(client, resource),
 | 
			
		||||
		nil,
 | 
			
		||||
@@ -476,6 +488,7 @@ func monitorFor(p *Propagator, clientPool dynamic.ClientPool, resource unversion
 | 
			
		||||
		framework.ResourceEventHandlerFuncs{
 | 
			
		||||
			// add the event to the propagator's eventQueue.
 | 
			
		||||
			AddFunc: func(obj interface{}) {
 | 
			
		||||
				setObjectTypeMeta(obj)
 | 
			
		||||
				event := event{
 | 
			
		||||
					eventType: addEvent,
 | 
			
		||||
					obj:       obj,
 | 
			
		||||
@@ -483,6 +496,8 @@ func monitorFor(p *Propagator, clientPool dynamic.ClientPool, resource unversion
 | 
			
		||||
				p.eventQueue.Add(event)
 | 
			
		||||
			},
 | 
			
		||||
			UpdateFunc: func(oldObj, newObj interface{}) {
 | 
			
		||||
				setObjectTypeMeta(newObj)
 | 
			
		||||
				setObjectTypeMeta(oldObj)
 | 
			
		||||
				event := event{updateEvent, newObj, oldObj}
 | 
			
		||||
				p.eventQueue.Add(event)
 | 
			
		||||
			},
 | 
			
		||||
@@ -491,6 +506,7 @@ func monitorFor(p *Propagator, clientPool dynamic.ClientPool, resource unversion
 | 
			
		||||
				if deletedFinalStateUnknown, ok := obj.(cache.DeletedFinalStateUnknown); ok {
 | 
			
		||||
					obj = deletedFinalStateUnknown.Obj
 | 
			
		||||
				}
 | 
			
		||||
				setObjectTypeMeta(obj)
 | 
			
		||||
				event := event{
 | 
			
		||||
					eventType: deleteEvent,
 | 
			
		||||
					obj:       obj,
 | 
			
		||||
@@ -511,8 +527,9 @@ var ignoredResources = map[unversioned.GroupVersionResource]struct{}{
 | 
			
		||||
	unversioned.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1beta1", Resource: "subjectaccessreviews"}: {},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewGarbageCollector(clientPool dynamic.ClientPool, resources []unversioned.GroupVersionResource) (*GarbageCollector, error) {
 | 
			
		||||
func NewGarbageCollector(metaOnlyClientPool dynamic.ClientPool, clientPool dynamic.ClientPool, resources []unversioned.GroupVersionResource) (*GarbageCollector, error) {
 | 
			
		||||
	gc := &GarbageCollector{
 | 
			
		||||
		metaOnlyClientPool: metaOnlyClientPool,
 | 
			
		||||
		clientPool:         clientPool,
 | 
			
		||||
		dirtyQueue:         workqueue.New(),
 | 
			
		||||
		orphanQueue:        workqueue.New(),
 | 
			
		||||
@@ -532,7 +549,11 @@ func NewGarbageCollector(clientPool dynamic.ClientPool, resources []unversioned.
 | 
			
		||||
			glog.V(6).Infof("ignore resource %#v", resource)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		monitor, err := monitorFor(gc.propagator, gc.clientPool, resource)
 | 
			
		||||
		kind, err := gc.restMapper.KindFor(resource)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		monitor, err := monitorFor(gc.propagator, gc.clientPool, resource, kind)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
@@ -549,7 +570,7 @@ func (gc *GarbageCollector) worker() {
 | 
			
		||||
	defer gc.dirtyQueue.Done(key)
 | 
			
		||||
	err := gc.processItem(key.(*node))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		utilruntime.HandleError(fmt.Errorf("Error syncing item %v: %v", key, err))
 | 
			
		||||
		utilruntime.HandleError(fmt.Errorf("Error syncing item %#v: %v", key, err))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -623,6 +644,20 @@ func objectReferenceToUnstructured(ref objectReference) *runtime.Unstructured {
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func objectReferenceToMetadataOnlyObject(ref objectReference) *metaonly.MetadataOnlyObject {
 | 
			
		||||
	return &metaonly.MetadataOnlyObject{
 | 
			
		||||
		TypeMeta: unversioned.TypeMeta{
 | 
			
		||||
			APIVersion: ref.APIVersion,
 | 
			
		||||
			Kind:       ref.Kind,
 | 
			
		||||
		},
 | 
			
		||||
		ObjectMeta: v1.ObjectMeta{
 | 
			
		||||
			Namespace: ref.Namespace,
 | 
			
		||||
			UID:       ref.UID,
 | 
			
		||||
			Name:      ref.Name,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (gc *GarbageCollector) processItem(item *node) error {
 | 
			
		||||
	// Get the latest item from the API server
 | 
			
		||||
	latest, err := gc.getObject(item.identity)
 | 
			
		||||
@@ -634,15 +669,22 @@ func (gc *GarbageCollector) processItem(item *node) error {
 | 
			
		||||
			glog.V(6).Infof("item %v not found, generating a virtual delete event", item.identity)
 | 
			
		||||
			event := event{
 | 
			
		||||
				eventType: deleteEvent,
 | 
			
		||||
				obj:       objectReferenceToUnstructured(item.identity),
 | 
			
		||||
				obj:       objectReferenceToMetadataOnlyObject(item.identity),
 | 
			
		||||
			}
 | 
			
		||||
			glog.V(6).Infof("generating virtual delete event for %s\n\n", event.obj)
 | 
			
		||||
			gc.propagator.eventQueue.Add(event)
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if latest.GetUID() != item.identity.UID {
 | 
			
		||||
		glog.V(6).Infof("UID doesn't match, item %v not found, ignore it", item.identity)
 | 
			
		||||
		glog.V(6).Infof("UID doesn't match, item %v not found, generating a virtual delete event", item.identity)
 | 
			
		||||
		event := event{
 | 
			
		||||
			eventType: deleteEvent,
 | 
			
		||||
			obj:       objectReferenceToMetadataOnlyObject(item.identity),
 | 
			
		||||
		}
 | 
			
		||||
		glog.V(6).Infof("generating virtual delete event for %s\n\n", event.obj)
 | 
			
		||||
		gc.propagator.eventQueue.Add(event)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	ownerReferences := latest.GetOwnerReferences()
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,8 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	_ "k8s.io/kubernetes/pkg/api/install"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime/serializer"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
@@ -39,9 +41,13 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestNewGarbageCollector(t *testing.T) {
 | 
			
		||||
	clientPool := dynamic.NewClientPool(&restclient.Config{}, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	config := &restclient.Config{}
 | 
			
		||||
	config.ContentConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: metaonly.NewMetadataCodecFactory()}
 | 
			
		||||
	metaOnlyClientPool := dynamic.NewClientPool(config, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	config.ContentConfig.NegotiatedSerializer = nil
 | 
			
		||||
	clientPool := dynamic.NewClientPool(config, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	podResource := []unversioned.GroupVersionResource{{Version: "v1", Resource: "pods"}}
 | 
			
		||||
	gc, err := NewGarbageCollector(clientPool, podResource)
 | 
			
		||||
	gc, err := NewGarbageCollector(metaOnlyClientPool, clientPool, podResource)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -141,8 +147,11 @@ func TestProcessItem(t *testing.T) {
 | 
			
		||||
	podResource := []unversioned.GroupVersionResource{{Version: "v1", Resource: "pods"}}
 | 
			
		||||
	srv, clientConfig := testServerAndClientConfig(testHandler.ServeHTTP)
 | 
			
		||||
	defer srv.Close()
 | 
			
		||||
	clientConfig.ContentConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: metaonly.NewMetadataCodecFactory()}
 | 
			
		||||
	metaOnlyClientPool := dynamic.NewClientPool(clientConfig, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	clientConfig.ContentConfig.NegotiatedSerializer = nil
 | 
			
		||||
	clientPool := dynamic.NewClientPool(clientConfig, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	gc, err := NewGarbageCollector(clientPool, podResource)
 | 
			
		||||
	gc, err := NewGarbageCollector(metaOnlyClientPool, clientPool, podResource)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -293,9 +302,13 @@ func TestProcessEvent(t *testing.T) {
 | 
			
		||||
// TestDependentsRace relies on golang's data race detector to check if there is
 | 
			
		||||
// data race among in the dependents field.
 | 
			
		||||
func TestDependentsRace(t *testing.T) {
 | 
			
		||||
	clientPool := dynamic.NewClientPool(&restclient.Config{}, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	config := &restclient.Config{}
 | 
			
		||||
	config.ContentConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: metaonly.NewMetadataCodecFactory()}
 | 
			
		||||
	metaOnlyClientPool := dynamic.NewClientPool(config, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	config.ContentConfig.NegotiatedSerializer = nil
 | 
			
		||||
	clientPool := dynamic.NewClientPool(config, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	podResource := []unversioned.GroupVersionResource{{Version: "v1", Resource: "pods"}}
 | 
			
		||||
	gc, err := NewGarbageCollector(clientPool, podResource)
 | 
			
		||||
	gc, err := NewGarbageCollector(metaOnlyClientPool, clientPool, podResource)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								pkg/controller/garbagecollector/metaonly/metaonly.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								pkg/controller/garbagecollector/metaonly/metaonly.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes 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 metaonly
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/unversioned"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime/serializer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (obj *MetadataOnlyObject) GetObjectKind() unversioned.ObjectKind     { return obj }
 | 
			
		||||
func (obj *MetadataOnlyObjectList) GetObjectKind() unversioned.ObjectKind { return obj }
 | 
			
		||||
 | 
			
		||||
type metaOnlyJSONScheme struct{}
 | 
			
		||||
 | 
			
		||||
// This function can be extended to mapping different gvk to different MetadataOnlyObject,
 | 
			
		||||
// which embedded with different version of ObjectMeta. Currently the system
 | 
			
		||||
// only supports v1.ObjectMeta.
 | 
			
		||||
func gvkToMetadataOnlyObject(gvk unversioned.GroupVersionKind) runtime.Object {
 | 
			
		||||
	if strings.HasSuffix(gvk.Kind, "List") {
 | 
			
		||||
		return &MetadataOnlyObjectList{}
 | 
			
		||||
	} else {
 | 
			
		||||
		return &MetadataOnlyObject{}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMetadataCodecFactory() serializer.CodecFactory {
 | 
			
		||||
	// populating another scheme from api.Scheme, registering every kind with
 | 
			
		||||
	// MetadataOnlyObject (or MetadataOnlyObjectList).
 | 
			
		||||
	scheme := runtime.NewScheme()
 | 
			
		||||
	allTypes := api.Scheme.AllKnownTypes()
 | 
			
		||||
	for kind := range allTypes {
 | 
			
		||||
		if kind.Version == runtime.APIVersionInternal {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		metaOnlyObject := gvkToMetadataOnlyObject(kind)
 | 
			
		||||
		scheme.AddKnownTypeWithName(kind, metaOnlyObject)
 | 
			
		||||
	}
 | 
			
		||||
	scheme.AddUnversionedTypes(api.Unversioned, &unversioned.Status{})
 | 
			
		||||
	return serializer.NewCodecFactory(scheme)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String converts a MetadataOnlyObject to a human-readable string.
 | 
			
		||||
func (metaOnly MetadataOnlyObject) String() string {
 | 
			
		||||
	return fmt.Sprintf("%s/%s, name: %s, DeletionTimestamp:%v", metaOnly.TypeMeta.APIVersion, metaOnly.TypeMeta.Kind, metaOnly.ObjectMeta.Name, metaOnly.ObjectMeta.DeletionTimestamp)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										163
									
								
								pkg/controller/garbagecollector/metaonly/metaonly_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								pkg/controller/garbagecollector/metaonly/metaonly_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes 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 metaonly
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	_ "k8s.io/kubernetes/pkg/api/install"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/meta"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/unversioned"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime/serializer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getPod() *v1.Pod {
 | 
			
		||||
	return &v1.Pod{
 | 
			
		||||
		TypeMeta: unversioned.TypeMeta{
 | 
			
		||||
			Kind:       "Pod",
 | 
			
		||||
			APIVersion: "v1",
 | 
			
		||||
		},
 | 
			
		||||
		ObjectMeta: v1.ObjectMeta{
 | 
			
		||||
			Name: "pod",
 | 
			
		||||
			OwnerReferences: []v1.OwnerReference{
 | 
			
		||||
				{UID: "1234"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		Spec: v1.PodSpec{
 | 
			
		||||
			Containers: []v1.Container{
 | 
			
		||||
				{
 | 
			
		||||
					Name:  "fake-name",
 | 
			
		||||
					Image: "fakeimage",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getPodJson(t *testing.T) []byte {
 | 
			
		||||
	data, err := json.Marshal(getPod())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	return data
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getPodListJson(t *testing.T) []byte {
 | 
			
		||||
	data, err := json.Marshal(&v1.PodList{
 | 
			
		||||
		TypeMeta: unversioned.TypeMeta{
 | 
			
		||||
			Kind:       "PodList",
 | 
			
		||||
			APIVersion: "v1",
 | 
			
		||||
		},
 | 
			
		||||
		Items: []v1.Pod{
 | 
			
		||||
			*getPod(),
 | 
			
		||||
			*getPod(),
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	return data
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func verfiyMetadata(description string, t *testing.T, in *MetadataOnlyObject) {
 | 
			
		||||
	pod := getPod()
 | 
			
		||||
	if e, a := pod.ObjectMeta, in.ObjectMeta; !reflect.DeepEqual(e, a) {
 | 
			
		||||
		t.Errorf("%s: expected %#v, got %#v", description, e, a)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDecodeToMetadataOnlyObject(t *testing.T) {
 | 
			
		||||
	data := getPodJson(t)
 | 
			
		||||
	cf := serializer.DirectCodecFactory{CodecFactory: NewMetadataCodecFactory()}
 | 
			
		||||
	serializer, ok := cf.SerializerForMediaType(runtime.ContentTypeJSON, nil)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		t.Fatalf("expected to get a JSON serializer")
 | 
			
		||||
	}
 | 
			
		||||
	codec := cf.DecoderToVersion(serializer, unversioned.GroupVersion{Group: "SOMEGROUP", Version: "SOMEVERSION"})
 | 
			
		||||
	// decode with into
 | 
			
		||||
	into := &MetadataOnlyObject{}
 | 
			
		||||
	ret, _, err := codec.Decode(data, nil, into)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	metaOnly, ok := ret.(*MetadataOnlyObject)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		t.Fatalf("expected ret to be *runtime.MetadataOnlyObject")
 | 
			
		||||
	}
 | 
			
		||||
	verfiyMetadata("check returned metaonly with into", t, metaOnly)
 | 
			
		||||
	verfiyMetadata("check into", t, into)
 | 
			
		||||
	// decode without into
 | 
			
		||||
	ret, _, err = codec.Decode(data, nil, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	metaOnly, ok = ret.(*MetadataOnlyObject)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		t.Fatalf("expected ret to be *runtime.MetadataOnlyObject")
 | 
			
		||||
	}
 | 
			
		||||
	verfiyMetadata("check returned metaonly without into", t, metaOnly)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func verifyListMetadata(t *testing.T, metaOnlyList *MetadataOnlyObjectList) {
 | 
			
		||||
	items, err := meta.ExtractList(metaOnlyList)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	for _, item := range items {
 | 
			
		||||
		metaOnly, ok := item.(*MetadataOnlyObject)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			t.Fatalf("expected item to be *MetadataOnlyObject")
 | 
			
		||||
		}
 | 
			
		||||
		verfiyMetadata("check list", t, metaOnly)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDecodeToMetadataOnlyObjectList(t *testing.T) {
 | 
			
		||||
	data := getPodListJson(t)
 | 
			
		||||
	cf := serializer.DirectCodecFactory{CodecFactory: NewMetadataCodecFactory()}
 | 
			
		||||
	serializer, ok := cf.SerializerForMediaType(runtime.ContentTypeJSON, nil)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		t.Fatalf("expected to get a JSON serializer")
 | 
			
		||||
	}
 | 
			
		||||
	codec := cf.DecoderToVersion(serializer, unversioned.GroupVersion{Group: "SOMEGROUP", Version: "SOMEVERSION"})
 | 
			
		||||
	// decode with into
 | 
			
		||||
	into := &MetadataOnlyObjectList{}
 | 
			
		||||
	ret, _, err := codec.Decode(data, nil, into)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	metaOnlyList, ok := ret.(*MetadataOnlyObjectList)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		t.Fatalf("expected ret to be *runtime.UnstructuredList")
 | 
			
		||||
	}
 | 
			
		||||
	verifyListMetadata(t, metaOnlyList)
 | 
			
		||||
	verifyListMetadata(t, into)
 | 
			
		||||
	// decode without into
 | 
			
		||||
	ret, _, err = codec.Decode(data, nil, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	metaOnlyList, ok = ret.(*MetadataOnlyObjectList)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		t.Fatalf("expected ret to be *runtime.UnstructuredList")
 | 
			
		||||
	}
 | 
			
		||||
	verifyListMetadata(t, metaOnlyList)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										794
									
								
								pkg/controller/garbagecollector/metaonly/types.generated.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										794
									
								
								pkg/controller/garbagecollector/metaonly/types.generated.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,794 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes 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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// ************************************************************
 | 
			
		||||
// DO NOT EDIT.
 | 
			
		||||
// THIS FILE IS AUTO-GENERATED BY codecgen.
 | 
			
		||||
// ************************************************************
 | 
			
		||||
 | 
			
		||||
package metaonly
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	codec1978 "github.com/ugorji/go/codec"
 | 
			
		||||
	pkg1_unversioned "k8s.io/kubernetes/pkg/api/unversioned"
 | 
			
		||||
	pkg2_v1 "k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
	pkg3_types "k8s.io/kubernetes/pkg/types"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	time "time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// ----- content types ----
 | 
			
		||||
	codecSelferC_UTF81234 = 1
 | 
			
		||||
	codecSelferC_RAW1234  = 0
 | 
			
		||||
	// ----- value types used ----
 | 
			
		||||
	codecSelferValueTypeArray1234 = 10
 | 
			
		||||
	codecSelferValueTypeMap1234   = 9
 | 
			
		||||
	// ----- containerStateValues ----
 | 
			
		||||
	codecSelfer_containerMapKey1234    = 2
 | 
			
		||||
	codecSelfer_containerMapValue1234  = 3
 | 
			
		||||
	codecSelfer_containerMapEnd1234    = 4
 | 
			
		||||
	codecSelfer_containerArrayElem1234 = 6
 | 
			
		||||
	codecSelfer_containerArrayEnd1234  = 7
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	codecSelferBitsize1234                         = uint8(reflect.TypeOf(uint(0)).Bits())
 | 
			
		||||
	codecSelferOnlyMapOrArrayEncodeToStructErr1234 = errors.New(`only encoded map or array can be decoded into a struct`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type codecSelfer1234 struct{}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if codec1978.GenVersion != 5 {
 | 
			
		||||
		_, file, _, _ := runtime.Caller(0)
 | 
			
		||||
		err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v",
 | 
			
		||||
			5, codec1978.GenVersion, file)
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	if false { // reference the types, but skip this branch at build/run time
 | 
			
		||||
		var v0 pkg1_unversioned.TypeMeta
 | 
			
		||||
		var v1 pkg2_v1.ObjectMeta
 | 
			
		||||
		var v2 pkg3_types.UID
 | 
			
		||||
		var v3 time.Time
 | 
			
		||||
		_, _, _, _ = v0, v1, v2, v3
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *MetadataOnlyObject) CodecEncodeSelf(e *codec1978.Encoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperEncoder(e)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	if x == nil {
 | 
			
		||||
		r.EncodeNil()
 | 
			
		||||
	} else {
 | 
			
		||||
		yym1 := z.EncBinary()
 | 
			
		||||
		_ = yym1
 | 
			
		||||
		if false {
 | 
			
		||||
		} else if z.HasExtensions() && z.EncExt(x) {
 | 
			
		||||
		} else {
 | 
			
		||||
			yysep2 := !z.EncBinary()
 | 
			
		||||
			yy2arr2 := z.EncBasicHandle().StructToArray
 | 
			
		||||
			var yyq2 [3]bool
 | 
			
		||||
			_, _, _ = yysep2, yyq2, yy2arr2
 | 
			
		||||
			const yyr2 bool = false
 | 
			
		||||
			yyq2[0] = true
 | 
			
		||||
			yyq2[1] = x.Kind != ""
 | 
			
		||||
			yyq2[2] = x.APIVersion != ""
 | 
			
		||||
			var yynn2 int
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				r.EncodeArrayStart(3)
 | 
			
		||||
			} else {
 | 
			
		||||
				yynn2 = 0
 | 
			
		||||
				for _, b := range yyq2 {
 | 
			
		||||
					if b {
 | 
			
		||||
						yynn2++
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				r.EncodeMapStart(yynn2)
 | 
			
		||||
				yynn2 = 0
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
				if yyq2[0] {
 | 
			
		||||
					yy4 := &x.ObjectMeta
 | 
			
		||||
					yy4.CodecEncodeSelf(e)
 | 
			
		||||
				} else {
 | 
			
		||||
					r.EncodeNil()
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if yyq2[0] {
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, string("metadata"))
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
					yy6 := &x.ObjectMeta
 | 
			
		||||
					yy6.CodecEncodeSelf(e)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
				if yyq2[1] {
 | 
			
		||||
					yym9 := z.EncBinary()
 | 
			
		||||
					_ = yym9
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, "")
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if yyq2[1] {
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, string("kind"))
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
					yym10 := z.EncBinary()
 | 
			
		||||
					_ = yym10
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
				if yyq2[2] {
 | 
			
		||||
					yym12 := z.EncBinary()
 | 
			
		||||
					_ = yym12
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, "")
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if yyq2[2] {
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, string("apiVersion"))
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
					yym13 := z.EncBinary()
 | 
			
		||||
					_ = yym13
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
			} else {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerMapEnd1234)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *MetadataOnlyObject) CodecDecodeSelf(d *codec1978.Decoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperDecoder(d)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	yym1 := z.DecBinary()
 | 
			
		||||
	_ = yym1
 | 
			
		||||
	if false {
 | 
			
		||||
	} else if z.HasExtensions() && z.DecExt(x) {
 | 
			
		||||
	} else {
 | 
			
		||||
		yyct2 := r.ContainerType()
 | 
			
		||||
		if yyct2 == codecSelferValueTypeMap1234 {
 | 
			
		||||
			yyl2 := r.ReadMapStart()
 | 
			
		||||
			if yyl2 == 0 {
 | 
			
		||||
				z.DecSendContainerState(codecSelfer_containerMapEnd1234)
 | 
			
		||||
			} else {
 | 
			
		||||
				x.codecDecodeSelfFromMap(yyl2, d)
 | 
			
		||||
			}
 | 
			
		||||
		} else if yyct2 == codecSelferValueTypeArray1234 {
 | 
			
		||||
			yyl2 := r.ReadArrayStart()
 | 
			
		||||
			if yyl2 == 0 {
 | 
			
		||||
				z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
			} else {
 | 
			
		||||
				x.codecDecodeSelfFromArray(yyl2, d)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *MetadataOnlyObject) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperDecoder(d)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
 | 
			
		||||
	_ = yys3Slc
 | 
			
		||||
	var yyhl3 bool = l >= 0
 | 
			
		||||
	for yyj3 := 0; ; yyj3++ {
 | 
			
		||||
		if yyhl3 {
 | 
			
		||||
			if yyj3 >= l {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if r.CheckBreak() {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
		yys3Slc = r.DecodeBytes(yys3Slc, true, true)
 | 
			
		||||
		yys3 := string(yys3Slc)
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
		switch yys3 {
 | 
			
		||||
		case "metadata":
 | 
			
		||||
			if r.TryDecodeAsNil() {
 | 
			
		||||
				x.ObjectMeta = pkg2_v1.ObjectMeta{}
 | 
			
		||||
			} else {
 | 
			
		||||
				yyv4 := &x.ObjectMeta
 | 
			
		||||
				yyv4.CodecDecodeSelf(d)
 | 
			
		||||
			}
 | 
			
		||||
		case "kind":
 | 
			
		||||
			if r.TryDecodeAsNil() {
 | 
			
		||||
				x.Kind = ""
 | 
			
		||||
			} else {
 | 
			
		||||
				x.Kind = string(r.DecodeString())
 | 
			
		||||
			}
 | 
			
		||||
		case "apiVersion":
 | 
			
		||||
			if r.TryDecodeAsNil() {
 | 
			
		||||
				x.APIVersion = ""
 | 
			
		||||
			} else {
 | 
			
		||||
				x.APIVersion = string(r.DecodeString())
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			z.DecStructFieldNotFound(-1, yys3)
 | 
			
		||||
		} // end switch yys3
 | 
			
		||||
	} // end for yyj3
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerMapEnd1234)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *MetadataOnlyObject) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperDecoder(d)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	var yyj7 int
 | 
			
		||||
	var yyb7 bool
 | 
			
		||||
	var yyhl7 bool = l >= 0
 | 
			
		||||
	yyj7++
 | 
			
		||||
	if yyhl7 {
 | 
			
		||||
		yyb7 = yyj7 > l
 | 
			
		||||
	} else {
 | 
			
		||||
		yyb7 = r.CheckBreak()
 | 
			
		||||
	}
 | 
			
		||||
	if yyb7 {
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
	if r.TryDecodeAsNil() {
 | 
			
		||||
		x.ObjectMeta = pkg2_v1.ObjectMeta{}
 | 
			
		||||
	} else {
 | 
			
		||||
		yyv8 := &x.ObjectMeta
 | 
			
		||||
		yyv8.CodecDecodeSelf(d)
 | 
			
		||||
	}
 | 
			
		||||
	yyj7++
 | 
			
		||||
	if yyhl7 {
 | 
			
		||||
		yyb7 = yyj7 > l
 | 
			
		||||
	} else {
 | 
			
		||||
		yyb7 = r.CheckBreak()
 | 
			
		||||
	}
 | 
			
		||||
	if yyb7 {
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
	if r.TryDecodeAsNil() {
 | 
			
		||||
		x.Kind = ""
 | 
			
		||||
	} else {
 | 
			
		||||
		x.Kind = string(r.DecodeString())
 | 
			
		||||
	}
 | 
			
		||||
	yyj7++
 | 
			
		||||
	if yyhl7 {
 | 
			
		||||
		yyb7 = yyj7 > l
 | 
			
		||||
	} else {
 | 
			
		||||
		yyb7 = r.CheckBreak()
 | 
			
		||||
	}
 | 
			
		||||
	if yyb7 {
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
	if r.TryDecodeAsNil() {
 | 
			
		||||
		x.APIVersion = ""
 | 
			
		||||
	} else {
 | 
			
		||||
		x.APIVersion = string(r.DecodeString())
 | 
			
		||||
	}
 | 
			
		||||
	for {
 | 
			
		||||
		yyj7++
 | 
			
		||||
		if yyhl7 {
 | 
			
		||||
			yyb7 = yyj7 > l
 | 
			
		||||
		} else {
 | 
			
		||||
			yyb7 = r.CheckBreak()
 | 
			
		||||
		}
 | 
			
		||||
		if yyb7 {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
		z.DecStructFieldNotFound(yyj7-1, "")
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *MetadataOnlyObjectList) CodecEncodeSelf(e *codec1978.Encoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperEncoder(e)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	if x == nil {
 | 
			
		||||
		r.EncodeNil()
 | 
			
		||||
	} else {
 | 
			
		||||
		yym1 := z.EncBinary()
 | 
			
		||||
		_ = yym1
 | 
			
		||||
		if false {
 | 
			
		||||
		} else if z.HasExtensions() && z.EncExt(x) {
 | 
			
		||||
		} else {
 | 
			
		||||
			yysep2 := !z.EncBinary()
 | 
			
		||||
			yy2arr2 := z.EncBasicHandle().StructToArray
 | 
			
		||||
			var yyq2 [4]bool
 | 
			
		||||
			_, _, _ = yysep2, yyq2, yy2arr2
 | 
			
		||||
			const yyr2 bool = false
 | 
			
		||||
			yyq2[0] = true
 | 
			
		||||
			yyq2[2] = x.Kind != ""
 | 
			
		||||
			yyq2[3] = x.APIVersion != ""
 | 
			
		||||
			var yynn2 int
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				r.EncodeArrayStart(4)
 | 
			
		||||
			} else {
 | 
			
		||||
				yynn2 = 1
 | 
			
		||||
				for _, b := range yyq2 {
 | 
			
		||||
					if b {
 | 
			
		||||
						yynn2++
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				r.EncodeMapStart(yynn2)
 | 
			
		||||
				yynn2 = 0
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
				if yyq2[0] {
 | 
			
		||||
					yy4 := &x.ListMeta
 | 
			
		||||
					yym5 := z.EncBinary()
 | 
			
		||||
					_ = yym5
 | 
			
		||||
					if false {
 | 
			
		||||
					} else if z.HasExtensions() && z.EncExt(yy4) {
 | 
			
		||||
					} else {
 | 
			
		||||
						z.EncFallback(yy4)
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					r.EncodeNil()
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if yyq2[0] {
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, string("metadata"))
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
					yy6 := &x.ListMeta
 | 
			
		||||
					yym7 := z.EncBinary()
 | 
			
		||||
					_ = yym7
 | 
			
		||||
					if false {
 | 
			
		||||
					} else if z.HasExtensions() && z.EncExt(yy6) {
 | 
			
		||||
					} else {
 | 
			
		||||
						z.EncFallback(yy6)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
				if x.Items == nil {
 | 
			
		||||
					r.EncodeNil()
 | 
			
		||||
				} else {
 | 
			
		||||
					yym9 := z.EncBinary()
 | 
			
		||||
					_ = yym9
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						h.encSliceMetadataOnlyObject(([]MetadataOnlyObject)(x.Items), e)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
				r.EncodeString(codecSelferC_UTF81234, string("items"))
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
				if x.Items == nil {
 | 
			
		||||
					r.EncodeNil()
 | 
			
		||||
				} else {
 | 
			
		||||
					yym10 := z.EncBinary()
 | 
			
		||||
					_ = yym10
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						h.encSliceMetadataOnlyObject(([]MetadataOnlyObject)(x.Items), e)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
				if yyq2[2] {
 | 
			
		||||
					yym12 := z.EncBinary()
 | 
			
		||||
					_ = yym12
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, "")
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if yyq2[2] {
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, string("kind"))
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
					yym13 := z.EncBinary()
 | 
			
		||||
					_ = yym13
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
				if yyq2[3] {
 | 
			
		||||
					yym15 := z.EncBinary()
 | 
			
		||||
					_ = yym15
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, "")
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if yyq2[3] {
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
					r.EncodeString(codecSelferC_UTF81234, string("apiVersion"))
 | 
			
		||||
					z.EncSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
					yym16 := z.EncBinary()
 | 
			
		||||
					_ = yym16
 | 
			
		||||
					if false {
 | 
			
		||||
					} else {
 | 
			
		||||
						r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if yyr2 || yy2arr2 {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
			} else {
 | 
			
		||||
				z.EncSendContainerState(codecSelfer_containerMapEnd1234)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *MetadataOnlyObjectList) CodecDecodeSelf(d *codec1978.Decoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperDecoder(d)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	yym1 := z.DecBinary()
 | 
			
		||||
	_ = yym1
 | 
			
		||||
	if false {
 | 
			
		||||
	} else if z.HasExtensions() && z.DecExt(x) {
 | 
			
		||||
	} else {
 | 
			
		||||
		yyct2 := r.ContainerType()
 | 
			
		||||
		if yyct2 == codecSelferValueTypeMap1234 {
 | 
			
		||||
			yyl2 := r.ReadMapStart()
 | 
			
		||||
			if yyl2 == 0 {
 | 
			
		||||
				z.DecSendContainerState(codecSelfer_containerMapEnd1234)
 | 
			
		||||
			} else {
 | 
			
		||||
				x.codecDecodeSelfFromMap(yyl2, d)
 | 
			
		||||
			}
 | 
			
		||||
		} else if yyct2 == codecSelferValueTypeArray1234 {
 | 
			
		||||
			yyl2 := r.ReadArrayStart()
 | 
			
		||||
			if yyl2 == 0 {
 | 
			
		||||
				z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
			} else {
 | 
			
		||||
				x.codecDecodeSelfFromArray(yyl2, d)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *MetadataOnlyObjectList) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperDecoder(d)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	var yys3Slc = z.DecScratchBuffer() // default slice to decode into
 | 
			
		||||
	_ = yys3Slc
 | 
			
		||||
	var yyhl3 bool = l >= 0
 | 
			
		||||
	for yyj3 := 0; ; yyj3++ {
 | 
			
		||||
		if yyhl3 {
 | 
			
		||||
			if yyj3 >= l {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if r.CheckBreak() {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerMapKey1234)
 | 
			
		||||
		yys3Slc = r.DecodeBytes(yys3Slc, true, true)
 | 
			
		||||
		yys3 := string(yys3Slc)
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerMapValue1234)
 | 
			
		||||
		switch yys3 {
 | 
			
		||||
		case "metadata":
 | 
			
		||||
			if r.TryDecodeAsNil() {
 | 
			
		||||
				x.ListMeta = pkg1_unversioned.ListMeta{}
 | 
			
		||||
			} else {
 | 
			
		||||
				yyv4 := &x.ListMeta
 | 
			
		||||
				yym5 := z.DecBinary()
 | 
			
		||||
				_ = yym5
 | 
			
		||||
				if false {
 | 
			
		||||
				} else if z.HasExtensions() && z.DecExt(yyv4) {
 | 
			
		||||
				} else {
 | 
			
		||||
					z.DecFallback(yyv4, false)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		case "items":
 | 
			
		||||
			if r.TryDecodeAsNil() {
 | 
			
		||||
				x.Items = nil
 | 
			
		||||
			} else {
 | 
			
		||||
				yyv6 := &x.Items
 | 
			
		||||
				yym7 := z.DecBinary()
 | 
			
		||||
				_ = yym7
 | 
			
		||||
				if false {
 | 
			
		||||
				} else {
 | 
			
		||||
					h.decSliceMetadataOnlyObject((*[]MetadataOnlyObject)(yyv6), d)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		case "kind":
 | 
			
		||||
			if r.TryDecodeAsNil() {
 | 
			
		||||
				x.Kind = ""
 | 
			
		||||
			} else {
 | 
			
		||||
				x.Kind = string(r.DecodeString())
 | 
			
		||||
			}
 | 
			
		||||
		case "apiVersion":
 | 
			
		||||
			if r.TryDecodeAsNil() {
 | 
			
		||||
				x.APIVersion = ""
 | 
			
		||||
			} else {
 | 
			
		||||
				x.APIVersion = string(r.DecodeString())
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			z.DecStructFieldNotFound(-1, yys3)
 | 
			
		||||
		} // end switch yys3
 | 
			
		||||
	} // end for yyj3
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerMapEnd1234)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *MetadataOnlyObjectList) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperDecoder(d)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	var yyj10 int
 | 
			
		||||
	var yyb10 bool
 | 
			
		||||
	var yyhl10 bool = l >= 0
 | 
			
		||||
	yyj10++
 | 
			
		||||
	if yyhl10 {
 | 
			
		||||
		yyb10 = yyj10 > l
 | 
			
		||||
	} else {
 | 
			
		||||
		yyb10 = r.CheckBreak()
 | 
			
		||||
	}
 | 
			
		||||
	if yyb10 {
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
	if r.TryDecodeAsNil() {
 | 
			
		||||
		x.ListMeta = pkg1_unversioned.ListMeta{}
 | 
			
		||||
	} else {
 | 
			
		||||
		yyv11 := &x.ListMeta
 | 
			
		||||
		yym12 := z.DecBinary()
 | 
			
		||||
		_ = yym12
 | 
			
		||||
		if false {
 | 
			
		||||
		} else if z.HasExtensions() && z.DecExt(yyv11) {
 | 
			
		||||
		} else {
 | 
			
		||||
			z.DecFallback(yyv11, false)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	yyj10++
 | 
			
		||||
	if yyhl10 {
 | 
			
		||||
		yyb10 = yyj10 > l
 | 
			
		||||
	} else {
 | 
			
		||||
		yyb10 = r.CheckBreak()
 | 
			
		||||
	}
 | 
			
		||||
	if yyb10 {
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
	if r.TryDecodeAsNil() {
 | 
			
		||||
		x.Items = nil
 | 
			
		||||
	} else {
 | 
			
		||||
		yyv13 := &x.Items
 | 
			
		||||
		yym14 := z.DecBinary()
 | 
			
		||||
		_ = yym14
 | 
			
		||||
		if false {
 | 
			
		||||
		} else {
 | 
			
		||||
			h.decSliceMetadataOnlyObject((*[]MetadataOnlyObject)(yyv13), d)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	yyj10++
 | 
			
		||||
	if yyhl10 {
 | 
			
		||||
		yyb10 = yyj10 > l
 | 
			
		||||
	} else {
 | 
			
		||||
		yyb10 = r.CheckBreak()
 | 
			
		||||
	}
 | 
			
		||||
	if yyb10 {
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
	if r.TryDecodeAsNil() {
 | 
			
		||||
		x.Kind = ""
 | 
			
		||||
	} else {
 | 
			
		||||
		x.Kind = string(r.DecodeString())
 | 
			
		||||
	}
 | 
			
		||||
	yyj10++
 | 
			
		||||
	if yyhl10 {
 | 
			
		||||
		yyb10 = yyj10 > l
 | 
			
		||||
	} else {
 | 
			
		||||
		yyb10 = r.CheckBreak()
 | 
			
		||||
	}
 | 
			
		||||
	if yyb10 {
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
	if r.TryDecodeAsNil() {
 | 
			
		||||
		x.APIVersion = ""
 | 
			
		||||
	} else {
 | 
			
		||||
		x.APIVersion = string(r.DecodeString())
 | 
			
		||||
	}
 | 
			
		||||
	for {
 | 
			
		||||
		yyj10++
 | 
			
		||||
		if yyhl10 {
 | 
			
		||||
			yyb10 = yyj10 > l
 | 
			
		||||
		} else {
 | 
			
		||||
			yyb10 = r.CheckBreak()
 | 
			
		||||
		}
 | 
			
		||||
		if yyb10 {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		z.DecSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
		z.DecStructFieldNotFound(yyj10-1, "")
 | 
			
		||||
	}
 | 
			
		||||
	z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x codecSelfer1234) encSliceMetadataOnlyObject(v []MetadataOnlyObject, e *codec1978.Encoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperEncoder(e)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
	r.EncodeArrayStart(len(v))
 | 
			
		||||
	for _, yyv1 := range v {
 | 
			
		||||
		z.EncSendContainerState(codecSelfer_containerArrayElem1234)
 | 
			
		||||
		yy2 := &yyv1
 | 
			
		||||
		yy2.CodecEncodeSelf(e)
 | 
			
		||||
	}
 | 
			
		||||
	z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x codecSelfer1234) decSliceMetadataOnlyObject(v *[]MetadataOnlyObject, d *codec1978.Decoder) {
 | 
			
		||||
	var h codecSelfer1234
 | 
			
		||||
	z, r := codec1978.GenHelperDecoder(d)
 | 
			
		||||
	_, _, _ = h, z, r
 | 
			
		||||
 | 
			
		||||
	yyv1 := *v
 | 
			
		||||
	yyh1, yyl1 := z.DecSliceHelperStart()
 | 
			
		||||
	var yyc1 bool
 | 
			
		||||
	_ = yyc1
 | 
			
		||||
	if yyl1 == 0 {
 | 
			
		||||
		if yyv1 == nil {
 | 
			
		||||
			yyv1 = []MetadataOnlyObject{}
 | 
			
		||||
			yyc1 = true
 | 
			
		||||
		} else if len(yyv1) != 0 {
 | 
			
		||||
			yyv1 = yyv1[:0]
 | 
			
		||||
			yyc1 = true
 | 
			
		||||
		}
 | 
			
		||||
	} else if yyl1 > 0 {
 | 
			
		||||
		var yyrr1, yyrl1 int
 | 
			
		||||
		var yyrt1 bool
 | 
			
		||||
		_, _ = yyrl1, yyrt1
 | 
			
		||||
		yyrr1 = yyl1 // len(yyv1)
 | 
			
		||||
		if yyl1 > cap(yyv1) {
 | 
			
		||||
 | 
			
		||||
			yyrg1 := len(yyv1) > 0
 | 
			
		||||
			yyv21 := yyv1
 | 
			
		||||
			yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 240)
 | 
			
		||||
			if yyrt1 {
 | 
			
		||||
				if yyrl1 <= cap(yyv1) {
 | 
			
		||||
					yyv1 = yyv1[:yyrl1]
 | 
			
		||||
				} else {
 | 
			
		||||
					yyv1 = make([]MetadataOnlyObject, yyrl1)
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				yyv1 = make([]MetadataOnlyObject, yyrl1)
 | 
			
		||||
			}
 | 
			
		||||
			yyc1 = true
 | 
			
		||||
			yyrr1 = len(yyv1)
 | 
			
		||||
			if yyrg1 {
 | 
			
		||||
				copy(yyv1, yyv21)
 | 
			
		||||
			}
 | 
			
		||||
		} else if yyl1 != len(yyv1) {
 | 
			
		||||
			yyv1 = yyv1[:yyl1]
 | 
			
		||||
			yyc1 = true
 | 
			
		||||
		}
 | 
			
		||||
		yyj1 := 0
 | 
			
		||||
		for ; yyj1 < yyrr1; yyj1++ {
 | 
			
		||||
			yyh1.ElemContainerState(yyj1)
 | 
			
		||||
			if r.TryDecodeAsNil() {
 | 
			
		||||
				yyv1[yyj1] = MetadataOnlyObject{}
 | 
			
		||||
			} else {
 | 
			
		||||
				yyv2 := &yyv1[yyj1]
 | 
			
		||||
				yyv2.CodecDecodeSelf(d)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		if yyrt1 {
 | 
			
		||||
			for ; yyj1 < yyl1; yyj1++ {
 | 
			
		||||
				yyv1 = append(yyv1, MetadataOnlyObject{})
 | 
			
		||||
				yyh1.ElemContainerState(yyj1)
 | 
			
		||||
				if r.TryDecodeAsNil() {
 | 
			
		||||
					yyv1[yyj1] = MetadataOnlyObject{}
 | 
			
		||||
				} else {
 | 
			
		||||
					yyv3 := &yyv1[yyj1]
 | 
			
		||||
					yyv3.CodecDecodeSelf(d)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
		yyj1 := 0
 | 
			
		||||
		for ; !r.CheckBreak(); yyj1++ {
 | 
			
		||||
 | 
			
		||||
			if yyj1 >= len(yyv1) {
 | 
			
		||||
				yyv1 = append(yyv1, MetadataOnlyObject{}) // var yyz1 MetadataOnlyObject
 | 
			
		||||
				yyc1 = true
 | 
			
		||||
			}
 | 
			
		||||
			yyh1.ElemContainerState(yyj1)
 | 
			
		||||
			if yyj1 < len(yyv1) {
 | 
			
		||||
				if r.TryDecodeAsNil() {
 | 
			
		||||
					yyv1[yyj1] = MetadataOnlyObject{}
 | 
			
		||||
				} else {
 | 
			
		||||
					yyv4 := &yyv1[yyj1]
 | 
			
		||||
					yyv4.CodecDecodeSelf(d)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			} else {
 | 
			
		||||
				z.DecSwallow()
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		if yyj1 < len(yyv1) {
 | 
			
		||||
			yyv1 = yyv1[:yyj1]
 | 
			
		||||
			yyc1 = true
 | 
			
		||||
		} else if yyj1 == 0 && yyv1 == nil {
 | 
			
		||||
			yyv1 = []MetadataOnlyObject{}
 | 
			
		||||
			yyc1 = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	yyh1.End()
 | 
			
		||||
	if yyc1 {
 | 
			
		||||
		*v = yyv1
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								pkg/controller/garbagecollector/metaonly/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								pkg/controller/garbagecollector/metaonly/types.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes 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 metaonly
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/unversioned"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MetadataOnlyObject allows decoding only the apiVersion, kind, and metadata fields of
 | 
			
		||||
// JSON data.
 | 
			
		||||
// TODO: enable meta-only decoding for protobuf.
 | 
			
		||||
type MetadataOnlyObject struct {
 | 
			
		||||
	unversioned.TypeMeta `json:",inline"`
 | 
			
		||||
	v1.ObjectMeta        `json:"metadata,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MetadataOnlyObjectList allows decoding from JSON data only the typemeta and metadata of
 | 
			
		||||
// a list, and those of the enclosing objects.
 | 
			
		||||
// TODO: enable meta-only decoding for protobuf.
 | 
			
		||||
type MetadataOnlyObjectList struct {
 | 
			
		||||
	unversioned.TypeMeta `json:",inline"`
 | 
			
		||||
	unversioned.ListMeta `json:"metadata,omitempty"`
 | 
			
		||||
 | 
			
		||||
	Items []MetadataOnlyObject `json:"items"`
 | 
			
		||||
}
 | 
			
		||||
@@ -272,7 +272,7 @@ func (f *fakeActionHandler) ServeHTTP(response http.ResponseWriter, request *htt
 | 
			
		||||
	f.actions = append(f.actions, fakeAction{method: request.Method, path: request.URL.Path})
 | 
			
		||||
	response.Header().Set("Content-Type", runtime.ContentTypeJSON)
 | 
			
		||||
	response.WriteHeader(f.statusCode)
 | 
			
		||||
	response.Write([]byte("{\"kind\": \"List\"}"))
 | 
			
		||||
	response.Write([]byte("{\"kind\": \"List\",\"items\":null}"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// testGroupVersionResources returns a mocked up set of resources across different api groups for testing namespace controller.
 | 
			
		||||
 
 | 
			
		||||
@@ -195,8 +195,12 @@ func listCollection(
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	apiResource := unversioned.APIResource{Name: gvr.Resource, Namespaced: true}
 | 
			
		||||
	unstructuredList, err := dynamicClient.Resource(&apiResource, namespace).List(&v1.ListOptions{})
 | 
			
		||||
	obj, err := dynamicClient.Resource(&apiResource, namespace).List(&v1.ListOptions{})
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		unstructuredList, ok := obj.(*runtime.UnstructuredList)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return nil, false, fmt.Errorf("resource: %s, expected *runtime.UnstructuredList, got %#v", apiResource.Name, obj)
 | 
			
		||||
		}
 | 
			
		||||
		return unstructuredList, true, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -80,14 +80,16 @@ func EncodeOrDie(e Encoder, obj Object) string {
 | 
			
		||||
// invokes the ObjectCreator to instantiate a new gvk. Returns an error if the typer cannot find the object.
 | 
			
		||||
func UseOrCreateObject(t ObjectTyper, c ObjectCreater, gvk unversioned.GroupVersionKind, obj Object) (Object, error) {
 | 
			
		||||
	if obj != nil {
 | 
			
		||||
		into, _, err := t.ObjectKinds(obj)
 | 
			
		||||
		kinds, _, err := t.ObjectKinds(obj)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		if gvk == into[0] {
 | 
			
		||||
		for _, kind := range kinds {
 | 
			
		||||
			if gvk == kind {
 | 
			
		||||
				return obj, nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return c.New(gvk)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -211,6 +211,11 @@ func (s *Scheme) KnownTypes(gv unversioned.GroupVersion) map[string]reflect.Type
 | 
			
		||||
	return types
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AllKnownTypes returns the all known types.
 | 
			
		||||
func (s *Scheme) AllKnownTypes() map[unversioned.GroupVersionKind]reflect.Type {
 | 
			
		||||
	return s.gvkToType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -95,6 +95,7 @@ func (s unstructuredJSONScheme) decode(data []byte) (Object, error) {
 | 
			
		||||
	err := s.decodeToUnstructured(data, unstruct)
 | 
			
		||||
	return unstruct, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s unstructuredJSONScheme) decodeInto(data []byte, obj Object) error {
 | 
			
		||||
	switch x := obj.(type) {
 | 
			
		||||
	case *Unstructured:
 | 
			
		||||
 
 | 
			
		||||
@@ -92,7 +92,11 @@ func TestDynamicClient(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check dynamic list
 | 
			
		||||
	unstructuredList, err := dynamicClient.Resource(&resource, ns.Name).List(&v1.ListOptions{})
 | 
			
		||||
	obj, err := dynamicClient.Resource(&resource, ns.Name).List(&v1.ListOptions{})
 | 
			
		||||
	unstructuredList, ok := obj.(*runtime.UnstructuredList)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		t.Fatalf("expected *runtime.UnstructuredList, got %#v", obj)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("unexpected error when listing pods: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,9 @@ import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/client/restclient"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/client/typed/dynamic"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/garbagecollector"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/registry/generic/registry"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime/serializer"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/types"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/wait"
 | 
			
		||||
	"k8s.io/kubernetes/test/integration/framework"
 | 
			
		||||
@@ -127,8 +129,12 @@ func setup(t *testing.T) (*httptest.Server, *garbagecollector.GarbageCollector,
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("Failed to get supported resources from server: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	clientPool := dynamic.NewClientPool(&restclient.Config{Host: s.URL}, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	gc, err := garbagecollector.NewGarbageCollector(clientPool, groupVersionResources)
 | 
			
		||||
	config := &restclient.Config{Host: s.URL}
 | 
			
		||||
	config.ContentConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: metaonly.NewMetadataCodecFactory()}
 | 
			
		||||
	metaOnlyClientPool := dynamic.NewClientPool(config, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	config.ContentConfig.NegotiatedSerializer = nil
 | 
			
		||||
	clientPool := dynamic.NewClientPool(config, dynamic.LegacyAPIPathResolverFunc)
 | 
			
		||||
	gc, err := garbagecollector.NewGarbageCollector(metaOnlyClientPool, clientPool, groupVersionResources)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("Failed to create garbage collector")
 | 
			
		||||
	}
 | 
			
		||||
@@ -215,7 +221,7 @@ func TestCascadingDeletion(t *testing.T) {
 | 
			
		||||
	// sometimes the deletion of the RC takes long time to be observed by
 | 
			
		||||
	// the gc, so wait for the garbage collector to observe the deletion of
 | 
			
		||||
	// the toBeDeletedRC
 | 
			
		||||
	if err := wait.Poll(10*time.Second, 120*time.Second, func() (bool, error) {
 | 
			
		||||
	if err := wait.Poll(10*time.Second, 60*time.Second, func() (bool, error) {
 | 
			
		||||
		return !gc.GraphHasUID([]types.UID{toBeDeletedRC.ObjectMeta.UID}), nil
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user