Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
f6a186b1
Commit
f6a186b1
authored
Feb 14, 2017
by
Andy Goldstein
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switch statefulset controller to shared informers
parent
eef16cf1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
174 additions
and
135 deletions
+174
-135
apps.go
cmd/kube-controller-manager/app/apps.go
+2
-3
BUILD
pkg/controller/statefulset/BUILD
+12
-4
stateful_pod_control.go
pkg/controller/statefulset/stateful_pod_control.go
+62
-57
stateful_pod_control_test.go
pkg/controller/statefulset/stateful_pod_control_test.go
+0
-0
stateful_set.go
pkg/controller/statefulset/stateful_set.go
+48
-45
stateful_set_control.go
pkg/controller/statefulset/stateful_set_control.go
+23
-4
stateful_set_control_test.go
pkg/controller/statefulset/stateful_set_control_test.go
+0
-0
stateful_set_test.go
pkg/controller/statefulset/stateful_set_test.go
+16
-10
stateful_set_utils.go
pkg/controller/statefulset/stateful_set_utils.go
+1
-1
stateful_set_utils_test.go
pkg/controller/statefulset/stateful_set_utils_test.go
+3
-3
examples.go
test/e2e/examples.go
+3
-4
BUILD
test/e2e/framework/BUILD
+1
-0
statefulset_utils.go
test/e2e/framework/statefulset_utils.go
+3
-4
No files found.
cmd/kube-controller-manager/app/apps.go
View file @
f6a186b1
...
@@ -29,11 +29,10 @@ func startStatefulSetController(ctx ControllerContext) (bool, error) {
...
@@ -29,11 +29,10 @@ func startStatefulSetController(ctx ControllerContext) (bool, error) {
if
!
ctx
.
AvailableResources
[
schema
.
GroupVersionResource
{
Group
:
"apps"
,
Version
:
"v1beta1"
,
Resource
:
"statefulsets"
}]
{
if
!
ctx
.
AvailableResources
[
schema
.
GroupVersionResource
{
Group
:
"apps"
,
Version
:
"v1beta1"
,
Resource
:
"statefulsets"
}]
{
return
false
,
nil
return
false
,
nil
}
}
resyncPeriod
:=
ResyncPeriod
(
&
ctx
.
Options
)()
go
statefulset
.
NewStatefulSetController
(
go
statefulset
.
NewStatefulSetController
(
ctx
.
InformerFactory
.
Pods
()
.
Informer
(),
ctx
.
NewInformerFactory
.
Core
()
.
V1
()
.
Pods
(),
ctx
.
NewInformerFactory
.
Apps
()
.
V1beta1
()
.
StatefulSets
(),
ctx
.
ClientBuilder
.
ClientOrDie
(
"statefulset-controller"
),
ctx
.
ClientBuilder
.
ClientOrDie
(
"statefulset-controller"
),
resyncPeriod
,
)
.
Run
(
1
,
ctx
.
Stop
)
)
.
Run
(
1
,
ctx
.
Stop
)
return
true
,
nil
return
true
,
nil
}
}
pkg/controller/statefulset/BUILD
View file @
f6a186b1
...
@@ -23,17 +23,20 @@ go_library(
...
@@ -23,17 +23,20 @@ go_library(
"//pkg/api/v1/pod:go_default_library",
"//pkg/api/v1/pod:go_default_library",
"//pkg/apis/apps/v1beta1:go_default_library",
"//pkg/apis/apps/v1beta1:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/legacylisters:go_default_library",
"//pkg/client/informers/informers_generated/externalversions/apps/v1beta1:go_default_library",
"//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library",
"//pkg/client/listers/apps/v1beta1:go_default_library",
"//pkg/client/listers/core/v1:go_default_library",
"//pkg/client/retry:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/controller:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/errors",
"//vendor:k8s.io/apimachinery/pkg/util/errors",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apimachinery/pkg/util/wait",
"//vendor:k8s.io/apimachinery/pkg/watch",
"//vendor:k8s.io/client-go/kubernetes/typed/core/v1",
"//vendor:k8s.io/client-go/kubernetes/typed/core/v1",
"//vendor:k8s.io/client-go/pkg/api",
"//vendor:k8s.io/client-go/pkg/api/v1",
"//vendor:k8s.io/client-go/pkg/api/v1",
"//vendor:k8s.io/client-go/tools/cache",
"//vendor:k8s.io/client-go/tools/cache",
"//vendor:k8s.io/client-go/tools/record",
"//vendor:k8s.io/client-go/tools/record",
...
@@ -56,17 +59,22 @@ go_test(
...
@@ -56,17 +59,22 @@ go_test(
"//pkg/api/v1/pod:go_default_library",
"//pkg/api/v1/pod:go_default_library",
"//pkg/apis/apps/v1beta1:go_default_library",
"//pkg/apis/apps/v1beta1:go_default_library",
"//pkg/client/clientset_generated/clientset/fake:go_default_library",
"//pkg/client/clientset_generated/clientset/fake:go_default_library",
"//pkg/client/informers/informers_generated/externalversions:go_default_library",
"//pkg/client/informers/informers_generated/externalversions/apps/v1beta1:go_default_library",
"//pkg/client/informers/informers_generated/externalversions/core/v1:go_default_library",
"//pkg/client/legacylisters:go_default_library",
"//pkg/client/legacylisters:go_default_library",
"//pkg/client/listers/apps/v1beta1:go_default_library",
"//pkg/client/listers/core/v1:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/controller:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/api/resource",
"//vendor:k8s.io/apimachinery/pkg/api/resource",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/client-go/testing",
"//vendor:k8s.io/client-go/testing",
"//vendor:k8s.io/client-go/tools/cache",
"//vendor:k8s.io/client-go/tools/cache",
"//vendor:k8s.io/client-go/tools/record",
"//vendor:k8s.io/client-go/tools/record",
"//vendor:k8s.io/client-go/util/workqueue",
],
],
)
)
...
...
pkg/controller/statefulset/stateful_pod_control.go
View file @
f6a186b1
...
@@ -23,11 +23,15 @@ import (
...
@@ -23,11 +23,15 @@ import (
apierrors
"k8s.io/apimachinery/pkg/api/errors"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
errorutils
"k8s.io/apimachinery/pkg/util/errors"
errorutils
"k8s.io/apimachinery/pkg/util/errors"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/pkg/api"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
appslisters
"k8s.io/kubernetes/pkg/client/listers/apps/v1beta1"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/kubernetes/pkg/client/retry"
)
)
// StatefulPodControlInterface defines the interface that StatefulSetController uses to create, update, and delete Pods,
// StatefulPodControlInterface defines the interface that StatefulSetController uses to create, update, and delete Pods,
...
@@ -52,15 +56,17 @@ type StatefulPodControlInterface interface {
...
@@ -52,15 +56,17 @@ type StatefulPodControlInterface interface {
UpdateStatefulSetReplicas
(
set
*
apps
.
StatefulSet
,
replicas
int32
)
error
UpdateStatefulSetReplicas
(
set
*
apps
.
StatefulSet
,
replicas
int32
)
error
}
}
func
NewRealStatefulPodControl
(
client
clientset
.
Interface
,
recorder
record
.
EventRecorder
)
StatefulPodControlInterface
{
func
NewRealStatefulPodControl
(
client
clientset
.
Interface
,
setLister
appslisters
.
StatefulSetLister
,
podLister
corelisters
.
PodLister
,
recorder
record
.
EventRecorder
)
StatefulPodControlInterface
{
return
&
realStatefulPodControl
{
client
,
recorder
}
return
&
realStatefulPodControl
{
client
,
setLister
,
podLister
,
recorder
}
}
}
// realStatefulPodControl implements StatefulPodControlInterface using a clientset.Interface to communicate with the
// realStatefulPodControl implements StatefulPodControlInterface using a clientset.Interface to communicate with the
// API server. The struct is package private as the internal details are irrelevant to importing packages.
// API server. The struct is package private as the internal details are irrelevant to importing packages.
type
realStatefulPodControl
struct
{
type
realStatefulPodControl
struct
{
client
clientset
.
Interface
client
clientset
.
Interface
recorder
record
.
EventRecorder
setLister
appslisters
.
StatefulSetLister
podLister
corelisters
.
PodLister
recorder
record
.
EventRecorder
}
}
func
(
spc
*
realStatefulPodControl
)
CreateStatefulPod
(
set
*
apps
.
StatefulSet
,
pod
*
v1
.
Pod
)
error
{
func
(
spc
*
realStatefulPodControl
)
CreateStatefulPod
(
set
*
apps
.
StatefulSet
,
pod
*
v1
.
Pod
)
error
{
...
@@ -80,54 +86,56 @@ func (spc *realStatefulPodControl) CreateStatefulPod(set *apps.StatefulSet, pod
...
@@ -80,54 +86,56 @@ func (spc *realStatefulPodControl) CreateStatefulPod(set *apps.StatefulSet, pod
}
}
func
(
spc
*
realStatefulPodControl
)
UpdateStatefulPod
(
set
*
apps
.
StatefulSet
,
pod
*
v1
.
Pod
)
error
{
func
(
spc
*
realStatefulPodControl
)
UpdateStatefulPod
(
set
*
apps
.
StatefulSet
,
pod
*
v1
.
Pod
)
error
{
// we make a copy of the Pod on the stack and mutate the copy
attemptedUpdate
:=
false
// we copy back to pod to notify the caller of successful mutation
obj
,
err
:=
api
.
Scheme
.
Copy
(
pod
)
err
:=
retry
.
RetryOnConflict
(
retry
.
DefaultBackoff
,
func
()
error
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"unable to copy pod: %v"
,
err
)
}
podCopy
:=
obj
.
(
*
v1
.
Pod
)
for
attempt
:=
0
;
attempt
<
maxUpdateRetries
;
attempt
++
{
// assume the Pod is consistent
// assume the Pod is consistent
consistent
:=
true
consistent
:=
true
// if the Pod does not conform to it
'
s identity, update the identity and dirty the Pod
// if the Pod does not conform to its identity, update the identity and dirty the Pod
if
!
identityMatches
(
set
,
pod
Copy
)
{
if
!
identityMatches
(
set
,
pod
)
{
updateIdentity
(
set
,
pod
Copy
)
updateIdentity
(
set
,
pod
)
consistent
=
false
consistent
=
false
}
}
// if the Pod does not conform to the StatefulSet's storage requirements, update the Pod's PVC's,
// if the Pod does not conform to the StatefulSet's storage requirements, update the Pod's PVC's,
// dirty the Pod, and create any missing PVCs
// dirty the Pod, and create any missing PVCs
if
!
storageMatches
(
set
,
pod
Copy
)
{
if
!
storageMatches
(
set
,
pod
)
{
updateStorage
(
set
,
pod
Copy
)
updateStorage
(
set
,
pod
)
consistent
=
false
consistent
=
false
if
err
:=
spc
.
createPersistentVolumeClaims
(
set
,
pod
Copy
);
err
!=
nil
{
if
err
:=
spc
.
createPersistentVolumeClaims
(
set
,
pod
);
err
!=
nil
{
spc
.
recordPodEvent
(
"update"
,
set
,
pod
,
err
)
spc
.
recordPodEvent
(
"update"
,
set
,
pod
,
err
)
return
err
return
err
}
}
}
}
// if the Pod is not dirty do nothing
// if the Pod is not dirty do nothing
if
consistent
{
if
consistent
{
*
pod
=
*
podCopy
return
nil
return
nil
}
}
attemptedUpdate
=
true
// commit the update, retrying on conflicts
// commit the update, retrying on conflicts
_
,
err
=
spc
.
client
.
Core
()
.
Pods
(
set
.
Namespace
)
.
Update
(
podCopy
)
_
,
err
:=
spc
.
client
.
Core
()
.
Pods
(
set
.
Namespace
)
.
Update
(
pod
)
if
!
apierrors
.
IsConflict
(
err
)
{
if
err
==
nil
{
if
err
==
nil
{
return
nil
*
pod
=
*
podCopy
}
spc
.
recordPodEvent
(
"update"
,
set
,
pod
,
err
)
return
err
}
}
conflicting
,
err
:=
spc
.
client
.
Core
()
.
Pods
(
set
.
Namespace
)
.
Get
(
podCopy
.
Name
,
metav1
.
GetOptions
{})
updateErr
:=
err
if
err
!=
nil
{
spc
.
recordPodEvent
(
"update"
,
set
,
podCopy
,
err
)
if
updated
,
err
:=
spc
.
podLister
.
Pods
(
set
.
Namespace
)
.
Get
(
pod
.
Name
);
err
==
nil
{
return
err
// make a copy so we don't mutate the shared cache
if
copy
,
err
:=
api
.
Scheme
.
DeepCopy
(
updated
);
err
==
nil
{
pod
=
copy
.
(
*
v1
.
Pod
)
}
else
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"error copying updated Pod: %v"
,
err
))
}
}
else
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"error getting updated Pod %s/%s from lister: %v"
,
set
.
Namespace
,
pod
.
Name
,
err
))
}
}
*
podCopy
=
*
conflicting
return
updateErr
})
if
attemptedUpdate
{
spc
.
recordPodEvent
(
"update"
,
set
,
pod
,
err
)
}
}
spc
.
recordPodEvent
(
"update"
,
set
,
pod
,
updateConflictError
)
return
err
return
updateConflictError
}
}
func
(
spc
*
realStatefulPodControl
)
DeleteStatefulPod
(
set
*
apps
.
StatefulSet
,
pod
*
v1
.
Pod
)
error
{
func
(
spc
*
realStatefulPodControl
)
DeleteStatefulPod
(
set
*
apps
.
StatefulSet
,
pod
*
v1
.
Pod
)
error
{
...
@@ -137,31 +145,28 @@ func (spc *realStatefulPodControl) DeleteStatefulPod(set *apps.StatefulSet, pod
...
@@ -137,31 +145,28 @@ func (spc *realStatefulPodControl) DeleteStatefulPod(set *apps.StatefulSet, pod
}
}
func
(
spc
*
realStatefulPodControl
)
UpdateStatefulSetReplicas
(
set
*
apps
.
StatefulSet
,
replicas
int32
)
error
{
func
(
spc
*
realStatefulPodControl
)
UpdateStatefulSetReplicas
(
set
*
apps
.
StatefulSet
,
replicas
int32
)
error
{
if
set
.
Status
.
Replicas
==
replicas
{
return
retry
.
RetryOnConflict
(
retry
.
DefaultBackoff
,
func
()
error
{
return
nil
set
.
Status
.
Replicas
=
replicas
}
_
,
err
:=
spc
.
client
.
Apps
()
.
StatefulSets
(
set
.
Namespace
)
.
UpdateStatus
(
set
)
obj
,
err
:=
api
.
Scheme
.
Copy
(
set
)
if
err
==
nil
{
if
err
!=
nil
{
return
nil
return
fmt
.
Errorf
(
"unable to copy set: %v"
,
err
)
}
setCopy
:=
obj
.
(
*
apps
.
StatefulSet
)
setCopy
.
Status
.
Replicas
=
replicas
for
attempt
:=
0
;
attempt
<
maxUpdateRetries
;
attempt
++
{
_
,
err
:=
spc
.
client
.
Apps
()
.
StatefulSets
(
setCopy
.
Namespace
)
.
UpdateStatus
(
setCopy
)
if
!
apierrors
.
IsConflict
(
err
)
{
if
err
==
nil
{
*
set
=
*
setCopy
}
return
err
}
}
conflicting
,
err
:=
spc
.
client
.
Apps
()
.
StatefulSets
(
setCopy
.
Namespace
)
.
Get
(
setCopy
.
Name
,
metav1
.
GetOptions
{})
if
err
!=
nil
{
updateErr
:=
err
return
err
if
updated
,
err
:=
spc
.
setLister
.
StatefulSets
(
set
.
Namespace
)
.
Get
(
set
.
Name
);
err
==
nil
{
// make a copy so we don't mutate the shared cache
if
copy
,
err
:=
api
.
Scheme
.
DeepCopy
(
updated
);
err
==
nil
{
set
=
copy
.
(
*
apps
.
StatefulSet
)
}
else
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"error copying updated StatefulSet: %v"
,
err
))
}
}
else
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"error getting updated StatefulSet %s/%s from lister: %v"
,
set
.
Namespace
,
set
.
Name
,
err
))
}
}
conflicting
.
Status
.
Replicas
=
setCopy
.
Status
.
Replicas
*
setCopy
=
*
conflicting
return
updateErr
}
})
return
updateConflictError
}
}
// recordPodEvent records an event for verb applied to a Pod in a StatefulSet. If err is nil the generated event will
// recordPodEvent records an event for verb applied to a Pod in a StatefulSet. If err is nil the generated event will
...
...
pkg/controller/statefulset/stateful_pod_control_test.go
View file @
f6a186b1
This diff is collapsed.
Click to expand it.
pkg/controller/statefulset/stateful_set.go
View file @
f6a186b1
...
@@ -22,23 +22,23 @@ import (
...
@@ -22,23 +22,23 @@ import (
"sort"
"sort"
"time"
"time"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
v1core
"k8s.io/client-go/kubernetes/typed/core/v1"
v1core
"k8s.io/client-go/kubernetes/typed/core/v1"
clientv1
"k8s.io/client-go/pkg/api/v1"
clientv1
"k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/legacylisters"
appsinformers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions/apps/v1beta1"
coreinformers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions/core/v1"
"k8s.io/apimachinery/pkg/runtime"
appslisters
"k8s.io/kubernetes/pkg/client/listers/apps/v1beta1"
utilruntime
"k8s.io/apimachinery/pkg/util/runtime"
corelisters
"k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/util/workqueue"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/controller"
"github.com/golang/glog"
"github.com/golang/glog"
...
@@ -56,20 +56,24 @@ type StatefulSetController struct {
...
@@ -56,20 +56,24 @@ type StatefulSetController struct {
// control returns an interface capable of syncing a stateful set.
// control returns an interface capable of syncing a stateful set.
// Abstracted out for testing.
// Abstracted out for testing.
control
StatefulSetControlInterface
control
StatefulSetControlInterface
// pod
Store is a cache of watched pods.
// pod
Lister is able to list/get pods from a shared informer's store
pod
Store
listers
.
StoreTo
PodLister
pod
Lister
corelisters
.
PodLister
// pod
StoreSynced returns true if the pod store has synced at least once.
// pod
ListerSynced returns true if the pod shared informer has synced at least once
pod
Store
Synced
cache
.
InformerSynced
pod
Lister
Synced
cache
.
InformerSynced
//
A store of StatefulSets, populated by setController.
//
setLister is able to list/get stateful sets from a shared informer's store
set
Store
listers
.
StoreTo
StatefulSetLister
set
Lister
appslisters
.
StatefulSetLister
//
Watches changes to all StatefulSets.
//
setListerSynced returns true if the stateful set shared informer has synced at least once
set
Controller
cache
.
Controller
set
ListerSynced
cache
.
InformerSynced
// StatefulSets that need to be synced.
// StatefulSets that need to be synced.
queue
workqueue
.
RateLimitingInterface
queue
workqueue
.
RateLimitingInterface
}
}
// NewStatefulSetController creates a new statefulset controller.
// NewStatefulSetController creates a new statefulset controller.
func
NewStatefulSetController
(
podInformer
cache
.
SharedIndexInformer
,
kubeClient
clientset
.
Interface
,
resyncPeriod
time
.
Duration
)
*
StatefulSetController
{
func
NewStatefulSetController
(
podInformer
coreinformers
.
PodInformer
,
setInformer
appsinformers
.
StatefulSetInformer
,
kubeClient
clientset
.
Interface
,
)
*
StatefulSetController
{
eventBroadcaster
:=
record
.
NewBroadcaster
()
eventBroadcaster
:=
record
.
NewBroadcaster
()
eventBroadcaster
.
StartLogging
(
glog
.
Infof
)
eventBroadcaster
.
StartLogging
(
glog
.
Infof
)
eventBroadcaster
.
StartRecordingToSink
(
&
v1core
.
EventSinkImpl
{
Interface
:
v1core
.
New
(
kubeClient
.
Core
()
.
RESTClient
())
.
Events
(
""
)})
eventBroadcaster
.
StartRecordingToSink
(
&
v1core
.
EventSinkImpl
{
Interface
:
v1core
.
New
(
kubeClient
.
Core
()
.
RESTClient
())
.
Events
(
""
)})
...
@@ -77,11 +81,11 @@ func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient
...
@@ -77,11 +81,11 @@ func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient
ssc
:=
&
StatefulSetController
{
ssc
:=
&
StatefulSetController
{
kubeClient
:
kubeClient
,
kubeClient
:
kubeClient
,
control
:
NewDefaultStatefulSetControl
(
NewRealStatefulPodControl
(
kubeClient
,
recorder
)),
control
:
NewDefaultStatefulSetControl
(
NewRealStatefulPodControl
(
kubeClient
,
setInformer
.
Lister
(),
podInformer
.
Lister
(),
recorder
)),
queue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"statefulset"
),
queue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"statefulset"
),
}
}
podInformer
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
podInformer
.
Informer
()
.
AddEventHandler
(
cache
.
ResourceEventHandlerFuncs
{
// lookup the statefulset and enqueue
// lookup the statefulset and enqueue
AddFunc
:
ssc
.
addPod
,
AddFunc
:
ssc
.
addPod
,
// lookup current and old statefulset if labels changed
// lookup current and old statefulset if labels changed
...
@@ -89,19 +93,10 @@ func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient
...
@@ -89,19 +93,10 @@ func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient
// lookup statefulset accounting for deletion tombstones
// lookup statefulset accounting for deletion tombstones
DeleteFunc
:
ssc
.
deletePod
,
DeleteFunc
:
ssc
.
deletePod
,
})
})
ssc
.
podStore
.
Indexer
=
podInformer
.
GetIndexer
()
ssc
.
podLister
=
podInformer
.
Lister
()
ssc
.
podListerSynced
=
podInformer
.
Informer
()
.
HasSynced
ssc
.
setStore
.
Store
,
ssc
.
setController
=
cache
.
NewInformer
(
setInformer
.
Informer
()
.
AddEventHandlerWithResyncPeriod
(
&
cache
.
ListWatch
{
ListFunc
:
func
(
options
metav1
.
ListOptions
)
(
runtime
.
Object
,
error
)
{
return
ssc
.
kubeClient
.
Apps
()
.
StatefulSets
(
v1
.
NamespaceAll
)
.
List
(
options
)
},
WatchFunc
:
func
(
options
metav1
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
ssc
.
kubeClient
.
Apps
()
.
StatefulSets
(
v1
.
NamespaceAll
)
.
Watch
(
options
)
},
},
&
apps
.
StatefulSet
{},
statefulSetResyncPeriod
,
cache
.
ResourceEventHandlerFuncs
{
cache
.
ResourceEventHandlerFuncs
{
AddFunc
:
ssc
.
enqueueStatefulSet
,
AddFunc
:
ssc
.
enqueueStatefulSet
,
UpdateFunc
:
func
(
old
,
cur
interface
{})
{
UpdateFunc
:
func
(
old
,
cur
interface
{})
{
...
@@ -114,9 +109,12 @@ func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient
...
@@ -114,9 +109,12 @@ func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient
},
},
DeleteFunc
:
ssc
.
enqueueStatefulSet
,
DeleteFunc
:
ssc
.
enqueueStatefulSet
,
},
},
statefulSetResyncPeriod
,
)
)
ssc
.
setLister
=
setInformer
.
Lister
()
ssc
.
setListerSynced
=
setInformer
.
Informer
()
.
HasSynced
// TODO: Watch volumes
// TODO: Watch volumes
ssc
.
podStoreSynced
=
podInformer
.
GetController
()
.
HasSynced
return
ssc
return
ssc
}
}
...
@@ -124,18 +122,20 @@ func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient
...
@@ -124,18 +122,20 @@ func NewStatefulSetController(podInformer cache.SharedIndexInformer, kubeClient
func
(
ssc
*
StatefulSetController
)
Run
(
workers
int
,
stopCh
<-
chan
struct
{})
{
func
(
ssc
*
StatefulSetController
)
Run
(
workers
int
,
stopCh
<-
chan
struct
{})
{
defer
utilruntime
.
HandleCrash
()
defer
utilruntime
.
HandleCrash
()
defer
ssc
.
queue
.
ShutDown
()
defer
ssc
.
queue
.
ShutDown
()
glog
.
Infof
(
"Starting statefulset controller"
)
glog
.
Infof
(
"Starting statefulset controller"
)
if
!
cache
.
WaitForCacheSync
(
stopCh
,
ssc
.
podStoreSynced
)
{
if
!
cache
.
WaitForCacheSync
(
stopCh
,
ssc
.
podListerSynced
,
ssc
.
setListerSynced
)
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"timed out waiting for caches to sync"
))
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"timed out waiting for caches to sync"
))
return
return
}
}
go
ssc
.
setController
.
Run
(
stopCh
)
for
i
:=
0
;
i
<
workers
;
i
++
{
for
i
:=
0
;
i
<
workers
;
i
++
{
go
wait
.
Until
(
ssc
.
worker
,
time
.
Second
,
stopCh
)
go
wait
.
Until
(
ssc
.
worker
,
time
.
Second
,
stopCh
)
}
}
<-
stopCh
<-
stopCh
glog
.
Infof
(
"Shutting down statefulset controller"
)
glog
.
Infof
(
"Shutting down statefulset controller"
)
}
}
// addPod adds the statefulset for the pod to the sync queue
// addPod adds the statefulset for the pod to the sync queue
...
@@ -204,12 +204,12 @@ func (ssc *StatefulSetController) getPodsForStatefulSet(set *apps.StatefulSet) (
...
@@ -204,12 +204,12 @@ func (ssc *StatefulSetController) getPodsForStatefulSet(set *apps.StatefulSet) (
if
err
!=
nil
{
if
err
!=
nil
{
return
[]
*
v1
.
Pod
{},
err
return
[]
*
v1
.
Pod
{},
err
}
}
return
ssc
.
pod
Store
.
Pods
(
set
.
Namespace
)
.
List
(
sel
)
return
ssc
.
pod
Lister
.
Pods
(
set
.
Namespace
)
.
List
(
sel
)
}
}
// getStatefulSetForPod returns the StatefulSet managing the given pod.
// getStatefulSetForPod returns the StatefulSet managing the given pod.
func
(
ssc
*
StatefulSetController
)
getStatefulSetForPod
(
pod
*
v1
.
Pod
)
*
apps
.
StatefulSet
{
func
(
ssc
*
StatefulSetController
)
getStatefulSetForPod
(
pod
*
v1
.
Pod
)
*
apps
.
StatefulSet
{
sets
,
err
:=
ssc
.
set
Store
.
GetPodStatefulSets
(
pod
)
sets
,
err
:=
ssc
.
set
Lister
.
GetPodStatefulSets
(
pod
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
V
(
4
)
.
Infof
(
"No StatefulSets found for pod %v, StatefulSet controller will avoid syncing"
,
pod
.
Name
)
glog
.
V
(
4
)
.
Infof
(
"No StatefulSets found for pod %v, StatefulSet controller will avoid syncing"
,
pod
.
Name
)
return
nil
return
nil
...
@@ -225,14 +225,14 @@ func (ssc *StatefulSetController) getStatefulSetForPod(pod *v1.Pod) *apps.Statef
...
@@ -225,14 +225,14 @@ func (ssc *StatefulSetController) getStatefulSetForPod(pod *v1.Pod) *apps.Statef
sort
.
Sort
(
overlappingStatefulSets
(
sets
))
sort
.
Sort
(
overlappingStatefulSets
(
sets
))
// return the first created set for which pod is a member
// return the first created set for which pod is a member
for
i
:=
range
sets
{
for
i
:=
range
sets
{
if
isMemberOf
(
&
sets
[
i
],
pod
)
{
if
isMemberOf
(
sets
[
i
],
pod
)
{
return
&
sets
[
i
]
return
sets
[
i
]
}
}
}
}
glog
.
V
(
4
)
.
Infof
(
"No StatefulSets found for pod %v, StatefulSet controller will avoid syncing"
,
pod
.
Name
)
glog
.
V
(
4
)
.
Infof
(
"No StatefulSets found for pod %v, StatefulSet controller will avoid syncing"
,
pod
.
Name
)
return
nil
return
nil
}
}
return
&
sets
[
0
]
return
sets
[
0
]
}
}
...
@@ -276,8 +276,12 @@ func (ssc *StatefulSetController) sync(key string) error {
...
@@ -276,8 +276,12 @@ func (ssc *StatefulSetController) sync(key string) error {
glog
.
V
(
4
)
.
Infof
(
"Finished syncing statefulset %q (%v)"
,
key
,
time
.
Now
()
.
Sub
(
startTime
))
glog
.
V
(
4
)
.
Infof
(
"Finished syncing statefulset %q (%v)"
,
key
,
time
.
Now
()
.
Sub
(
startTime
))
}()
}()
obj
,
exists
,
err
:=
ssc
.
setStore
.
Store
.
GetByKey
(
key
)
namespace
,
name
,
err
:=
cache
.
SplitMetaNamespaceKey
(
key
)
if
!
exists
{
if
err
!=
nil
{
return
err
}
set
,
err
:=
ssc
.
setLister
.
StatefulSets
(
namespace
)
.
Get
(
name
)
if
errors
.
IsNotFound
(
err
)
{
glog
.
Infof
(
"StatefulSet has been deleted %v"
,
key
)
glog
.
Infof
(
"StatefulSet has been deleted %v"
,
key
)
return
nil
return
nil
}
}
...
@@ -286,13 +290,12 @@ func (ssc *StatefulSetController) sync(key string) error {
...
@@ -286,13 +290,12 @@ func (ssc *StatefulSetController) sync(key string) error {
return
err
return
err
}
}
set
:=
*
obj
.
(
*
apps
.
StatefulSet
)
pods
,
err
:=
ssc
.
getPodsForStatefulSet
(
set
)
pods
,
err
:=
ssc
.
getPodsForStatefulSet
(
&
set
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
return
ssc
.
syncStatefulSet
(
&
set
,
pods
)
return
ssc
.
syncStatefulSet
(
set
,
pods
)
}
}
// syncStatefulSet syncs a tuple of (statefulset, []*v1.Pod).
// syncStatefulSet syncs a tuple of (statefulset, []*v1.Pod).
...
...
pkg/controller/statefulset/stateful_set_control.go
View file @
f6a186b1
...
@@ -17,8 +17,10 @@ limitations under the License.
...
@@ -17,8 +17,10 @@ limitations under the License.
package
statefulset
package
statefulset
import
(
import
(
"fmt"
"sort"
"sort"
"k8s.io/client-go/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
...
@@ -97,8 +99,16 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
...
@@ -97,8 +99,16 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
sort
.
Sort
(
ascendingOrdinal
(
condemned
))
sort
.
Sort
(
ascendingOrdinal
(
condemned
))
// if the current number of replicas has changed update the statefulSets replicas
// if the current number of replicas has changed update the statefulSets replicas
if
err
:=
ssc
.
podControl
.
UpdateStatefulSetReplicas
(
set
,
int32
(
ready
));
err
!=
nil
{
if
set
.
Status
.
Replicas
!=
int32
(
ready
)
{
return
err
obj
,
err
:=
api
.
Scheme
.
Copy
(
set
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"unable to copy set: %v"
,
err
)
}
set
=
obj
.
(
*
apps
.
StatefulSet
)
if
err
:=
ssc
.
podControl
.
UpdateStatefulSetReplicas
(
set
,
int32
(
ready
));
err
!=
nil
{
return
err
}
}
}
// Examine each replica with respect to its ordinal
// Examine each replica with respect to its ordinal
...
@@ -123,8 +133,17 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
...
@@ -123,8 +133,17 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *apps.StatefulSet, p
set
.
Name
,
replicas
[
i
]
.
Name
)
set
.
Name
,
replicas
[
i
]
.
Name
)
return
nil
return
nil
}
}
// Enforce the StatefulSet invariants,
// Enforce the StatefulSet invariants
if
err
:=
ssc
.
podControl
.
UpdateStatefulPod
(
set
,
replicas
[
i
]);
err
!=
nil
{
if
identityMatches
(
set
,
replicas
[
i
])
&&
storageMatches
(
set
,
replicas
[
i
])
{
continue
}
// Make a deep copy so we don't mutate the shared cache
copy
,
err
:=
api
.
Scheme
.
DeepCopy
(
replicas
[
i
])
if
err
!=
nil
{
return
err
}
replica
:=
copy
.
(
*
v1
.
Pod
)
if
err
:=
ssc
.
podControl
.
UpdateStatefulPod
(
set
,
replica
);
err
!=
nil
{
return
err
return
err
}
}
}
}
...
...
pkg/controller/statefulset/stateful_set_control_test.go
View file @
f6a186b1
This diff is collapsed.
Click to expand it.
pkg/controller/statefulset/stateful_set_test.go
View file @
f6a186b1
...
@@ -24,13 +24,16 @@ import (
...
@@ -24,13 +24,16 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake"
informers
"k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/controller"
)
)
func
alwaysReady
()
bool
{
return
true
}
func
TestStatefulSetControllerCreates
(
t
*
testing
.
T
)
{
func
TestStatefulSetControllerCreates
(
t
*
testing
.
T
)
{
ssc
,
spc
:=
newFakeStatefulSetController
()
ssc
,
spc
:=
newFakeStatefulSetController
()
set
:=
newStatefulSet
(
3
)
set
:=
newStatefulSet
(
3
)
...
@@ -343,15 +346,18 @@ func TestStatefulSetControllerGetStatefulSetForPodOverlapping(t *testing.T) {
...
@@ -343,15 +346,18 @@ func TestStatefulSetControllerGetStatefulSetForPodOverlapping(t *testing.T) {
}
}
func
newFakeStatefulSetController
()
(
*
StatefulSetController
,
*
fakeStatefulPodControl
)
{
func
newFakeStatefulSetController
()
(
*
StatefulSetController
,
*
fakeStatefulPodControl
)
{
fpc
:=
newFakeStatefulPodControl
()
client
:=
fake
.
NewSimpleClientset
()
ssc
:=
&
StatefulSetController
{
informerFactory
:=
informers
.
NewSharedInformerFactory
(
client
,
controller
.
NoResyncPeriodFunc
())
kubeClient
:
nil
,
fpc
:=
newFakeStatefulPodControl
(
informerFactory
.
Core
()
.
V1
()
.
Pods
(),
informerFactory
.
Apps
()
.
V1beta1
()
.
StatefulSets
())
podStoreSynced
:
func
()
bool
{
return
true
},
ssc
:=
NewStatefulSetController
(
setStore
:
fpc
.
setsLister
,
informerFactory
.
Core
()
.
V1
()
.
Pods
(),
podStore
:
fpc
.
podsLister
,
informerFactory
.
Apps
()
.
V1beta1
()
.
StatefulSets
(),
control
:
NewDefaultStatefulSetControl
(
fpc
),
client
,
queue
:
workqueue
.
NewNamedRateLimitingQueue
(
workqueue
.
DefaultControllerRateLimiter
(),
"statefulset"
),
)
}
ssc
.
podListerSynced
=
alwaysReady
ssc
.
setListerSynced
=
alwaysReady
ssc
.
control
=
NewDefaultStatefulSetControl
(
fpc
)
return
ssc
,
fpc
return
ssc
,
fpc
}
}
...
...
pkg/controller/statefulset/stateful_set_utils.go
View file @
f6a186b1
...
@@ -38,7 +38,7 @@ var updateConflictError = fmt.Errorf("aborting update after %d attempts", maxUpd
...
@@ -38,7 +38,7 @@ var updateConflictError = fmt.Errorf("aborting update after %d attempts", maxUpd
// overlappingStatefulSets sorts a list of StatefulSets by creation timestamp, using their names as a tie breaker.
// overlappingStatefulSets sorts a list of StatefulSets by creation timestamp, using their names as a tie breaker.
// Generally used to tie break between StatefulSets that have overlapping selectors.
// Generally used to tie break between StatefulSets that have overlapping selectors.
type
overlappingStatefulSets
[]
apps
.
StatefulSet
type
overlappingStatefulSets
[]
*
apps
.
StatefulSet
func
(
o
overlappingStatefulSets
)
Len
()
int
{
return
len
(
o
)
}
func
(
o
overlappingStatefulSets
)
Len
()
int
{
return
len
(
o
)
}
...
...
pkg/controller/statefulset/stateful_set_utils_test.go
View file @
f6a186b1
...
@@ -251,10 +251,10 @@ func TestAscendingOrdinal(t *testing.T) {
...
@@ -251,10 +251,10 @@ func TestAscendingOrdinal(t *testing.T) {
}
}
func
TestOverlappingStatefulSets
(
t
*
testing
.
T
)
{
func
TestOverlappingStatefulSets
(
t
*
testing
.
T
)
{
sets
:=
make
([]
apps
.
StatefulSet
,
10
)
sets
:=
make
([]
*
apps
.
StatefulSet
,
10
)
perm
:=
rand
.
Perm
(
10
)
perm
:=
rand
.
Perm
(
10
)
for
i
,
v
:=
range
perm
{
for
i
,
v
:=
range
perm
{
sets
[
i
]
=
*
newStatefulSet
(
10
)
sets
[
i
]
=
newStatefulSet
(
10
)
sets
[
i
]
.
CreationTimestamp
=
metav1
.
NewTime
(
sets
[
i
]
.
CreationTimestamp
.
Add
(
time
.
Duration
(
v
)
*
time
.
Second
))
sets
[
i
]
.
CreationTimestamp
=
metav1
.
NewTime
(
sets
[
i
]
.
CreationTimestamp
.
Add
(
time
.
Duration
(
v
)
*
time
.
Second
))
}
}
sort
.
Sort
(
overlappingStatefulSets
(
sets
))
sort
.
Sort
(
overlappingStatefulSets
(
sets
))
...
@@ -262,7 +262,7 @@ func TestOverlappingStatefulSets(t *testing.T) {
...
@@ -262,7 +262,7 @@ func TestOverlappingStatefulSets(t *testing.T) {
t
.
Error
(
"ascendingOrdinal fails to sort Pods"
)
t
.
Error
(
"ascendingOrdinal fails to sort Pods"
)
}
}
for
i
,
v
:=
range
perm
{
for
i
,
v
:=
range
perm
{
sets
[
i
]
=
*
newStatefulSet
(
10
)
sets
[
i
]
=
newStatefulSet
(
10
)
sets
[
i
]
.
Name
=
strconv
.
FormatInt
(
int64
(
v
),
10
)
sets
[
i
]
.
Name
=
strconv
.
FormatInt
(
int64
(
v
),
10
)
}
}
sort
.
Sort
(
overlappingStatefulSets
(
sets
))
sort
.
Sort
(
overlappingStatefulSets
(
sets
))
...
...
test/e2e/examples.go
View file @
f6a186b1
...
@@ -264,20 +264,19 @@ var _ = framework.KubeDescribe("[Feature:Example]", func() {
...
@@ -264,20 +264,19 @@ var _ = framework.KubeDescribe("[Feature:Example]", func() {
framework
.
KubeDescribe
(
"CassandraStatefulSet"
,
func
()
{
framework
.
KubeDescribe
(
"CassandraStatefulSet"
,
func
()
{
It
(
"should create statefulset"
,
func
()
{
It
(
"should create statefulset"
,
func
()
{
mkpath
:=
func
(
file
string
)
string
{
mkpath
:=
func
(
file
string
)
string
{
return
filepath
.
Join
(
framework
.
TestContext
.
RepoRoot
,
"examples/storage/cassandra"
,
file
)
return
filepath
.
Join
(
"examples/storage/cassandra"
,
file
)
}
}
serviceYaml
:=
mkpath
(
"cassandra-service.yaml"
)
serviceYaml
:=
mkpath
(
"cassandra-service.yaml"
)
nsFlag
:=
fmt
.
Sprintf
(
"--namespace=%v"
,
ns
)
nsFlag
:=
fmt
.
Sprintf
(
"--namespace=%v"
,
ns
)
// have to change dns prefix because of the dynamic namespace
// have to change dns prefix because of the dynamic namespace
input
,
err
:=
ioutil
.
ReadFile
(
mkpath
(
"cassandra-statefulset.yaml"
))
input
:=
generated
.
ReadOrDie
(
mkpath
(
"cassandra-statefulset.yaml"
))
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
output
:=
strings
.
Replace
(
string
(
input
),
"cassandra-0.cassandra.default.svc.cluster.local"
,
"cassandra-0.cassandra."
+
ns
+
".svc.cluster.local"
,
-
1
)
output
:=
strings
.
Replace
(
string
(
input
),
"cassandra-0.cassandra.default.svc.cluster.local"
,
"cassandra-0.cassandra."
+
ns
+
".svc.cluster.local"
,
-
1
)
statefulsetYaml
:=
"/tmp/cassandra-statefulset.yaml"
statefulsetYaml
:=
"/tmp/cassandra-statefulset.yaml"
err
=
ioutil
.
WriteFile
(
statefulsetYaml
,
[]
byte
(
output
),
0644
)
err
:
=
ioutil
.
WriteFile
(
statefulsetYaml
,
[]
byte
(
output
),
0644
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
By
(
"Starting the cassandra service"
)
By
(
"Starting the cassandra service"
)
...
...
test/e2e/framework/BUILD
View file @
f6a186b1
...
@@ -71,6 +71,7 @@ go_library(
...
@@ -71,6 +71,7 @@ go_library(
"//pkg/util/version:go_default_library",
"//pkg/util/version:go_default_library",
"//plugin/pkg/scheduler/algorithm/predicates:go_default_library",
"//plugin/pkg/scheduler/algorithm/predicates:go_default_library",
"//plugin/pkg/scheduler/schedulercache:go_default_library",
"//plugin/pkg/scheduler/schedulercache:go_default_library",
"//test/e2e/generated:go_default_library",
"//test/e2e/perftype:go_default_library",
"//test/e2e/perftype:go_default_library",
"//test/utils:go_default_library",
"//test/utils:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:github.com/golang/glog",
...
...
test/e2e/framework/statefulset_utils.go
View file @
f6a186b1
...
@@ -18,7 +18,6 @@ package framework
...
@@ -18,7 +18,6 @@ package framework
import
(
import
(
"fmt"
"fmt"
"io/ioutil"
"path/filepath"
"path/filepath"
"strconv"
"strconv"
"strings"
"strings"
...
@@ -38,6 +37,7 @@ import (
...
@@ -38,6 +37,7 @@ import (
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
apps
"k8s.io/kubernetes/pkg/apis/apps/v1beta1"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/test/e2e/generated"
)
)
const
(
const
(
...
@@ -70,8 +70,7 @@ func CreateStatefulSetService(name string, labels map[string]string) *v1.Service
...
@@ -70,8 +70,7 @@ func CreateStatefulSetService(name string, labels map[string]string) *v1.Service
func
StatefulSetFromManifest
(
fileName
,
ns
string
)
*
apps
.
StatefulSet
{
func
StatefulSetFromManifest
(
fileName
,
ns
string
)
*
apps
.
StatefulSet
{
var
ss
apps
.
StatefulSet
var
ss
apps
.
StatefulSet
Logf
(
"Parsing statefulset from %v"
,
fileName
)
Logf
(
"Parsing statefulset from %v"
,
fileName
)
data
,
err
:=
ioutil
.
ReadFile
(
fileName
)
data
:=
generated
.
ReadOrDie
(
fileName
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
json
,
err
:=
utilyaml
.
ToJSON
(
data
)
json
,
err
:=
utilyaml
.
ToJSON
(
data
)
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
Expect
(
err
)
.
NotTo
(
HaveOccurred
())
...
@@ -99,7 +98,7 @@ func NewStatefulSetTester(c clientset.Interface) *StatefulSetTester {
...
@@ -99,7 +98,7 @@ func NewStatefulSetTester(c clientset.Interface) *StatefulSetTester {
// CreateStatefulSet creates a StatefulSet from the manifest at manifestPath in the Namespace ns using kubectl create.
// CreateStatefulSet creates a StatefulSet from the manifest at manifestPath in the Namespace ns using kubectl create.
func
(
s
*
StatefulSetTester
)
CreateStatefulSet
(
manifestPath
,
ns
string
)
*
apps
.
StatefulSet
{
func
(
s
*
StatefulSetTester
)
CreateStatefulSet
(
manifestPath
,
ns
string
)
*
apps
.
StatefulSet
{
mkpath
:=
func
(
file
string
)
string
{
mkpath
:=
func
(
file
string
)
string
{
return
filepath
.
Join
(
TestContext
.
RepoRoot
,
manifestPath
,
file
)
return
filepath
.
Join
(
manifestPath
,
file
)
}
}
ss
:=
StatefulSetFromManifest
(
mkpath
(
"statefulset.yaml"
),
ns
)
ss
:=
StatefulSetFromManifest
(
mkpath
(
"statefulset.yaml"
),
ns
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment