mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-05 07:27:21 +00:00
cmd/kube-controller-manager
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user