cmd/kube-controller-manager

This commit is contained in:
Chao Xu
2016-11-18 12:50:17 -08:00
parent 48536eaef9
commit 7eeb71f698
109 changed files with 4380 additions and 4153 deletions

View File

@@ -19,10 +19,10 @@ package namespace
import (
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/cache"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
"k8s.io/kubernetes/pkg/client/typed/dynamic"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/runtime"
@@ -52,7 +52,7 @@ type NamespaceController struct {
// opCache is a cache to remember if a particular operation is not supported to aid dynamic client.
opCache *operationNotSupportedCache
// finalizerToken is the finalizer token managed by this controller
finalizerToken api.FinalizerName
finalizerToken v1.FinalizerName
}
// NewNamespaceController creates a new NamespaceController
@@ -61,7 +61,7 @@ func NewNamespaceController(
clientPool dynamic.ClientPool,
groupVersionResourcesFn func() ([]unversioned.GroupVersionResource, error),
resyncPeriod time.Duration,
finalizerToken api.FinalizerName) *NamespaceController {
finalizerToken v1.FinalizerName) *NamespaceController {
// the namespace deletion code looks at the discovery document to enumerate the set of resources on the server.
// it then finds all namespaced resources, and in response to namespace deletion, will call delete on all of them.
@@ -98,22 +98,22 @@ func NewNamespaceController(
// configure the backing store/controller
store, controller := cache.NewInformer(
&cache.ListWatch{
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
return kubeClient.Core().Namespaces().List(options)
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
return kubeClient.Core().Namespaces().Watch(options)
},
},
&api.Namespace{},
&v1.Namespace{},
resyncPeriod,
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
namespace := obj.(*api.Namespace)
namespace := obj.(*v1.Namespace)
namespaceController.enqueueNamespace(namespace)
},
UpdateFunc: func(oldObj, newObj interface{}) {
namespace := newObj.(*api.Namespace)
namespace := newObj.(*v1.Namespace)
namespaceController.enqueueNamespace(namespace)
},
},
@@ -125,7 +125,7 @@ func NewNamespaceController(
}
// enqueueNamespace adds an object to the controller work queue
// obj could be an *api.Namespace, or a DeletionFinalStateUnknown item.
// obj could be an *v1.Namespace, or a DeletionFinalStateUnknown item.
func (nm *NamespaceController) enqueueNamespace(obj interface{}) {
key, err := controller.KeyFunc(obj)
if err != nil {
@@ -190,7 +190,7 @@ func (nm *NamespaceController) syncNamespaceFromKey(key string) (err error) {
nm.queue.Add(key)
return err
}
namespace := obj.(*api.Namespace)
namespace := obj.(*v1.Namespace)
return syncNamespace(nm.kubeClient, nm.clientPool, nm.opCache, nm.groupVersionResourcesFn, namespace, nm.finalizerToken)
}

View File

@@ -28,9 +28,10 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apimachinery/registered"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/testing/core"
"k8s.io/kubernetes/pkg/client/typed/dynamic"
@@ -39,15 +40,15 @@ import (
)
func TestFinalized(t *testing.T) {
testNamespace := &api.Namespace{
Spec: api.NamespaceSpec{
Finalizers: []api.FinalizerName{"a", "b"},
testNamespace := &v1.Namespace{
Spec: v1.NamespaceSpec{
Finalizers: []v1.FinalizerName{"a", "b"},
},
}
if finalized(testNamespace) {
t.Errorf("Unexpected result, namespace is not finalized")
}
testNamespace.Spec.Finalizers = []api.FinalizerName{}
testNamespace.Spec.Finalizers = []v1.FinalizerName{}
if !finalized(testNamespace) {
t.Errorf("Expected object to be finalized")
}
@@ -55,16 +56,16 @@ func TestFinalized(t *testing.T) {
func TestFinalizeNamespaceFunc(t *testing.T) {
mockClient := &fake.Clientset{}
testNamespace := &api.Namespace{
ObjectMeta: api.ObjectMeta{
testNamespace := &v1.Namespace{
ObjectMeta: v1.ObjectMeta{
Name: "test",
ResourceVersion: "1",
},
Spec: api.NamespaceSpec{
Finalizers: []api.FinalizerName{"kubernetes", "other"},
Spec: v1.NamespaceSpec{
Finalizers: []v1.FinalizerName{"kubernetes", "other"},
},
}
finalizeNamespace(mockClient, testNamespace, api.FinalizerKubernetes)
finalizeNamespace(mockClient, testNamespace, v1.FinalizerKubernetes)
actions := mockClient.Actions()
if len(actions) != 1 {
t.Errorf("Expected 1 mock client action, but got %v", len(actions))
@@ -72,7 +73,7 @@ func TestFinalizeNamespaceFunc(t *testing.T) {
if !actions[0].Matches("create", "namespaces") || actions[0].GetSubresource() != "finalize" {
t.Errorf("Expected finalize-namespace action %v", actions[0])
}
finalizers := actions[0].(core.CreateAction).GetObject().(*api.Namespace).Spec.Finalizers
finalizers := actions[0].(core.CreateAction).GetObject().(*v1.Namespace).Spec.Finalizers
if len(finalizers) != 1 {
t.Errorf("There should be a single finalizer remaining")
}
@@ -84,28 +85,28 @@ func TestFinalizeNamespaceFunc(t *testing.T) {
func testSyncNamespaceThatIsTerminating(t *testing.T, versions *unversioned.APIVersions) {
now := unversioned.Now()
namespaceName := "test"
testNamespacePendingFinalize := &api.Namespace{
ObjectMeta: api.ObjectMeta{
testNamespacePendingFinalize := &v1.Namespace{
ObjectMeta: v1.ObjectMeta{
Name: namespaceName,
ResourceVersion: "1",
DeletionTimestamp: &now,
},
Spec: api.NamespaceSpec{
Finalizers: []api.FinalizerName{"kubernetes"},
Spec: v1.NamespaceSpec{
Finalizers: []v1.FinalizerName{"kubernetes"},
},
Status: api.NamespaceStatus{
Phase: api.NamespaceTerminating,
Status: v1.NamespaceStatus{
Phase: v1.NamespaceTerminating,
},
}
testNamespaceFinalizeComplete := &api.Namespace{
ObjectMeta: api.ObjectMeta{
testNamespaceFinalizeComplete := &v1.Namespace{
ObjectMeta: v1.ObjectMeta{
Name: namespaceName,
ResourceVersion: "1",
DeletionTimestamp: &now,
},
Spec: api.NamespaceSpec{},
Status: api.NamespaceStatus{
Phase: api.NamespaceTerminating,
Spec: v1.NamespaceSpec{},
Status: v1.NamespaceStatus{
Phase: v1.NamespaceTerminating,
},
}
@@ -126,7 +127,7 @@ func testSyncNamespaceThatIsTerminating(t *testing.T, versions *unversioned.APIV
}
scenarios := map[string]struct {
testNamespace *api.Namespace
testNamespace *v1.Namespace
kubeClientActionSet sets.String
dynamicClientActionSet sets.String
gvrError error
@@ -172,7 +173,7 @@ func testSyncNamespaceThatIsTerminating(t *testing.T, versions *unversioned.APIV
return groupVersionResources, nil
}
err := syncNamespace(mockClient, clientPool, &operationNotSupportedCache{m: make(map[operationKey]bool)}, fn, testInput.testNamespace, api.FinalizerKubernetes)
err := syncNamespace(mockClient, clientPool, &operationNotSupportedCache{m: make(map[operationKey]bool)}, fn, testInput.testNamespace, v1.FinalizerKubernetes)
if err != nil {
t.Errorf("scenario %s - Unexpected error when synching namespace %v", scenario, err)
}
@@ -202,14 +203,14 @@ func testSyncNamespaceThatIsTerminating(t *testing.T, versions *unversioned.APIV
func TestRetryOnConflictError(t *testing.T) {
mockClient := &fake.Clientset{}
numTries := 0
retryOnce := func(kubeClient clientset.Interface, namespace *api.Namespace) (*api.Namespace, error) {
retryOnce := func(kubeClient clientset.Interface, namespace *v1.Namespace) (*v1.Namespace, error) {
numTries++
if numTries <= 1 {
return namespace, errors.NewConflict(api.Resource("namespaces"), namespace.Name, fmt.Errorf("ERROR!"))
}
return namespace, nil
}
namespace := &api.Namespace{}
namespace := &v1.Namespace{}
_, err := retryOnConflictError(mockClient, namespace, retryOnce)
if err != nil {
t.Errorf("Unexpected error %v", err)
@@ -229,22 +230,22 @@ func TestSyncNamespaceThatIsTerminatingV1Beta1(t *testing.T) {
func TestSyncNamespaceThatIsActive(t *testing.T) {
mockClient := &fake.Clientset{}
testNamespace := &api.Namespace{
ObjectMeta: api.ObjectMeta{
testNamespace := &v1.Namespace{
ObjectMeta: v1.ObjectMeta{
Name: "test",
ResourceVersion: "1",
},
Spec: api.NamespaceSpec{
Finalizers: []api.FinalizerName{"kubernetes"},
Spec: v1.NamespaceSpec{
Finalizers: []v1.FinalizerName{"kubernetes"},
},
Status: api.NamespaceStatus{
Phase: api.NamespaceActive,
Status: v1.NamespaceStatus{
Phase: v1.NamespaceActive,
},
}
fn := func() ([]unversioned.GroupVersionResource, error) {
return testGroupVersionResources(), nil
}
err := syncNamespace(mockClient, nil, &operationNotSupportedCache{m: make(map[operationKey]bool)}, fn, testNamespace, api.FinalizerKubernetes)
err := syncNamespace(mockClient, nil, &operationNotSupportedCache{m: make(map[operationKey]bool)}, fn, testNamespace, v1.FinalizerKubernetes)
if err != nil {
t.Errorf("Unexpected error when synching namespace %v", err)
}

View File

@@ -22,11 +22,10 @@ import (
"sync"
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
"k8s.io/kubernetes/pkg/client/typed/dynamic"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets"
@@ -80,12 +79,12 @@ func (o *operationNotSupportedCache) setNotSupported(key operationKey) {
}
// updateNamespaceFunc is a function that makes an update to a namespace
type updateNamespaceFunc func(kubeClient clientset.Interface, namespace *api.Namespace) (*api.Namespace, error)
type updateNamespaceFunc func(kubeClient clientset.Interface, namespace *v1.Namespace) (*v1.Namespace, error)
// retryOnConflictError retries the specified fn if there was a conflict error
// it will return an error if the UID for an object changes across retry operations.
// TODO RetryOnConflict should be a generic concept in client code
func retryOnConflictError(kubeClient clientset.Interface, namespace *api.Namespace, fn updateNamespaceFunc) (result *api.Namespace, err error) {
func retryOnConflictError(kubeClient clientset.Interface, namespace *v1.Namespace, fn updateNamespaceFunc) (result *v1.Namespace, err error) {
latestNamespace := namespace
for {
result, err = fn(kubeClient, latestNamespace)
@@ -107,32 +106,32 @@ func retryOnConflictError(kubeClient clientset.Interface, namespace *api.Namespa
}
// updateNamespaceStatusFunc will verify that the status of the namespace is correct
func updateNamespaceStatusFunc(kubeClient clientset.Interface, namespace *api.Namespace) (*api.Namespace, error) {
if namespace.DeletionTimestamp.IsZero() || namespace.Status.Phase == api.NamespaceTerminating {
func updateNamespaceStatusFunc(kubeClient clientset.Interface, namespace *v1.Namespace) (*v1.Namespace, error) {
if namespace.DeletionTimestamp.IsZero() || namespace.Status.Phase == v1.NamespaceTerminating {
return namespace, nil
}
newNamespace := api.Namespace{}
newNamespace := v1.Namespace{}
newNamespace.ObjectMeta = namespace.ObjectMeta
newNamespace.Status = namespace.Status
newNamespace.Status.Phase = api.NamespaceTerminating
newNamespace.Status.Phase = v1.NamespaceTerminating
return kubeClient.Core().Namespaces().UpdateStatus(&newNamespace)
}
// finalized returns true if the namespace.Spec.Finalizers is an empty list
func finalized(namespace *api.Namespace) bool {
func finalized(namespace *v1.Namespace) bool {
return len(namespace.Spec.Finalizers) == 0
}
// finalizeNamespaceFunc returns a function that knows how to finalize a namespace for specified token.
func finalizeNamespaceFunc(finalizerToken api.FinalizerName) updateNamespaceFunc {
return func(kubeClient clientset.Interface, namespace *api.Namespace) (*api.Namespace, error) {
func finalizeNamespaceFunc(finalizerToken v1.FinalizerName) updateNamespaceFunc {
return func(kubeClient clientset.Interface, namespace *v1.Namespace) (*v1.Namespace, error) {
return finalizeNamespace(kubeClient, namespace, finalizerToken)
}
}
// finalizeNamespace removes the specified finalizerToken and finalizes the namespace
func finalizeNamespace(kubeClient clientset.Interface, namespace *api.Namespace, finalizerToken api.FinalizerName) (*api.Namespace, error) {
namespaceFinalize := api.Namespace{}
func finalizeNamespace(kubeClient clientset.Interface, namespace *v1.Namespace, finalizerToken v1.FinalizerName) (*v1.Namespace, error) {
namespaceFinalize := v1.Namespace{}
namespaceFinalize.ObjectMeta = namespace.ObjectMeta
namespaceFinalize.Spec = namespace.Spec
finalizerSet := sets.NewString()
@@ -141,9 +140,9 @@ func finalizeNamespace(kubeClient clientset.Interface, namespace *api.Namespace,
finalizerSet.Insert(string(namespace.Spec.Finalizers[i]))
}
}
namespaceFinalize.Spec.Finalizers = make([]api.FinalizerName, 0, len(finalizerSet))
namespaceFinalize.Spec.Finalizers = make([]v1.FinalizerName, 0, len(finalizerSet))
for _, value := range finalizerSet.List() {
namespaceFinalize.Spec.Finalizers = append(namespaceFinalize.Spec.Finalizers, api.FinalizerName(value))
namespaceFinalize.Spec.Finalizers = append(namespaceFinalize.Spec.Finalizers, v1.FinalizerName(value))
}
namespace, err := kubeClient.Core().Namespaces().Finalize(&namespaceFinalize)
if err != nil {
@@ -372,8 +371,8 @@ func syncNamespace(
clientPool dynamic.ClientPool,
opCache *operationNotSupportedCache,
groupVersionResourcesFn func() ([]unversioned.GroupVersionResource, error),
namespace *api.Namespace,
finalizerToken api.FinalizerName,
namespace *v1.Namespace,
finalizerToken v1.FinalizerName,
) error {
if namespace.DeletionTimestamp == nil {
return nil
@@ -409,10 +408,10 @@ func syncNamespace(
// if the namespace is already finalized, delete it
if finalized(namespace) {
var opts *api.DeleteOptions
var opts *v1.DeleteOptions
uid := namespace.UID
if len(uid) > 0 {
opts = &api.DeleteOptions{Preconditions: &api.Preconditions{UID: &uid}}
opts = &v1.DeleteOptions{Preconditions: &v1.Preconditions{UID: &uid}}
}
err = kubeClient.Core().Namespaces().Delete(namespace.Name, opts)
if err != nil && !errors.IsNotFound(err) {
@@ -483,14 +482,14 @@ func estimateGracefulTermination(kubeClient clientset.Interface, groupVersionRes
func estimateGracefulTerminationForPods(kubeClient clientset.Interface, ns string) (int64, error) {
glog.V(5).Infof("namespace controller - estimateGracefulTerminationForPods - namespace %s", ns)
estimate := int64(0)
items, err := kubeClient.Core().Pods(ns).List(api.ListOptions{})
items, err := kubeClient.Core().Pods(ns).List(v1.ListOptions{})
if err != nil {
return estimate, err
}
for i := range items.Items {
// filter out terminal pods
phase := items.Items[i].Status.Phase
if api.PodSucceeded == phase || api.PodFailed == phase {
if v1.PodSucceeded == phase || v1.PodFailed == phase {
continue
}
if items.Items[i].Spec.TerminationGracePeriodSeconds != nil {