mirror of https://github.com/openkruise/kruise.git
Promote Advacned StatefulSet to v1beta1 (#423)
This commit is contained in:
parent
ffb3f87eec
commit
dbe481e5d0
14
Makefile
14
Makefile
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
# Image URL to use all building/pushing image targets
|
||||
IMG ?= openkruise/kruise-manager:test
|
||||
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
|
||||
CRD_OPTIONS ?= "crd:trivialVersions=true"
|
||||
# Produce CRDs that work for API servers that supports v1beta1 CRD and conversion, requires k8s 1.13 or later.
|
||||
CRD_OPTIONS ?= "crd"
|
||||
|
||||
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
|
||||
ifeq (,$(shell go env GOBIN))
|
||||
|
|
@ -69,18 +69,18 @@ docker-push:
|
|||
# find or download controller-gen
|
||||
# download controller-gen if necessary
|
||||
controller-gen:
|
||||
ifeq (, $(shell which controller-gen-kruise))
|
||||
ifeq (, $(shell which controller-gen-kruise-2))
|
||||
@{ \
|
||||
set -e ;\
|
||||
CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
|
||||
cd $$CONTROLLER_GEN_TMP_DIR ;\
|
||||
go mod init tmp ;\
|
||||
echo "replace sigs.k8s.io/controller-tools => github.com/openkruise/controller-tools v0.2.9-kruise" >> go.mod ;\
|
||||
echo "replace sigs.k8s.io/controller-tools => github.com/openkruise/controller-tools v0.2.9-kruise.2" >> go.mod ;\
|
||||
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.9 ;\
|
||||
rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
|
||||
mv $(GOPATH)/bin/controller-gen $(GOPATH)/bin/controller-gen-kruise ;\
|
||||
mv $(GOPATH)/bin/controller-gen $(GOPATH)/bin/controller-gen-kruise-2 ;\
|
||||
}
|
||||
CONTROLLER_GEN=$(GOPATH)/bin/controller-gen-kruise
|
||||
CONTROLLER_GEN=$(GOPATH)/bin/controller-gen-kruise-2
|
||||
else
|
||||
CONTROLLER_GEN=$(shell which controller-gen-kruise)
|
||||
CONTROLLER_GEN=$(shell which controller-gen-kruise-2)
|
||||
endif
|
||||
|
|
|
|||
3
PROJECT
3
PROJECT
|
|
@ -26,4 +26,7 @@ resources:
|
|||
- group: apps
|
||||
kind: ImagePullJob
|
||||
version: v1alpha1
|
||||
- group: apps
|
||||
kind: StatefulSet
|
||||
version: v1beta1
|
||||
version: "2"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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 apis
|
||||
|
||||
import (
|
||||
"github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register the types with the Scheme so the components can map objects to GroupVersionKinds and back
|
||||
AddToSchemes = append(AddToSchemes, v1beta1.SchemeBuilder.AddToScheme)
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
|
||||
// +kubebuilder:object:generate=true
|
||||
package pub
|
||||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
package pub
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
package pub
|
||||
|
||||
const (
|
||||
LifecycleStateKey = "lifecycle.apps.kruise.io/state"
|
||||
|
|
@ -14,9 +14,11 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
package pub
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
|
@ -53,3 +55,34 @@ type UpdatePriorityWeightTerm struct {
|
|||
// MatchSelector is used to select by pod's labels.
|
||||
MatchSelector metav1.LabelSelector `json:"matchSelector"`
|
||||
}
|
||||
|
||||
// FieldsValidation checks invalid fields in UpdatePriorityStrategy.
|
||||
func (strategy *UpdatePriorityStrategy) FieldsValidation() error {
|
||||
if strategy == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(strategy.WeightPriority) > 0 && len(strategy.OrderPriority) > 0 {
|
||||
return fmt.Errorf("only one of weightPriority and orderPriority can be used")
|
||||
}
|
||||
|
||||
for _, w := range strategy.WeightPriority {
|
||||
if w.Weight < 0 || w.Weight > 100 {
|
||||
return fmt.Errorf("weight must be valid number in the range 1-100")
|
||||
}
|
||||
if w.MatchSelector.Size() == 0 {
|
||||
return fmt.Errorf("selector can not be empty")
|
||||
}
|
||||
if _, err := metav1.LabelSelectorAsSelector(&w.MatchSelector); err != nil {
|
||||
return fmt.Errorf("invalid selector %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, o := range strategy.OrderPriority {
|
||||
if len(o.OrderedKey) == 0 {
|
||||
return fmt.Errorf("order key can not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package pub
|
||||
|
||||
import ()
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InPlaceUpdateContainerStatus) DeepCopyInto(out *InPlaceUpdateContainerStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InPlaceUpdateContainerStatus.
|
||||
func (in *InPlaceUpdateContainerStatus) DeepCopy() *InPlaceUpdateContainerStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InPlaceUpdateContainerStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InPlaceUpdateState) DeepCopyInto(out *InPlaceUpdateState) {
|
||||
*out = *in
|
||||
in.UpdateTimestamp.DeepCopyInto(&out.UpdateTimestamp)
|
||||
if in.LastContainerStatuses != nil {
|
||||
in, out := &in.LastContainerStatuses, &out.LastContainerStatuses
|
||||
*out = make(map[string]InPlaceUpdateContainerStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InPlaceUpdateState.
|
||||
func (in *InPlaceUpdateState) DeepCopy() *InPlaceUpdateState {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InPlaceUpdateState)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InPlaceUpdateStrategy) DeepCopyInto(out *InPlaceUpdateStrategy) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InPlaceUpdateStrategy.
|
||||
func (in *InPlaceUpdateStrategy) DeepCopy() *InPlaceUpdateStrategy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InPlaceUpdateStrategy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Lifecycle) DeepCopyInto(out *Lifecycle) {
|
||||
*out = *in
|
||||
if in.PreDelete != nil {
|
||||
in, out := &in.PreDelete, &out.PreDelete
|
||||
*out = new(LifecycleHook)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.InPlaceUpdate != nil {
|
||||
in, out := &in.InPlaceUpdate, &out.InPlaceUpdate
|
||||
*out = new(LifecycleHook)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Lifecycle.
|
||||
func (in *Lifecycle) DeepCopy() *Lifecycle {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Lifecycle)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LifecycleHook) DeepCopyInto(out *LifecycleHook) {
|
||||
*out = *in
|
||||
if in.LabelsHandler != nil {
|
||||
in, out := &in.LabelsHandler, &out.LabelsHandler
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.FinalizersHandler != nil {
|
||||
in, out := &in.FinalizersHandler, &out.FinalizersHandler
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LifecycleHook.
|
||||
func (in *LifecycleHook) DeepCopy() *LifecycleHook {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LifecycleHook)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdatePriorityOrderTerm) DeepCopyInto(out *UpdatePriorityOrderTerm) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdatePriorityOrderTerm.
|
||||
func (in *UpdatePriorityOrderTerm) DeepCopy() *UpdatePriorityOrderTerm {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdatePriorityOrderTerm)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdatePriorityStrategy) DeepCopyInto(out *UpdatePriorityStrategy) {
|
||||
*out = *in
|
||||
if in.OrderPriority != nil {
|
||||
in, out := &in.OrderPriority, &out.OrderPriority
|
||||
*out = make([]UpdatePriorityOrderTerm, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.WeightPriority != nil {
|
||||
in, out := &in.WeightPriority, &out.WeightPriority
|
||||
*out = make([]UpdatePriorityWeightTerm, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdatePriorityStrategy.
|
||||
func (in *UpdatePriorityStrategy) DeepCopy() *UpdatePriorityStrategy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdatePriorityStrategy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdatePriorityWeightTerm) DeepCopyInto(out *UpdatePriorityWeightTerm) {
|
||||
*out = *in
|
||||
in.MatchSelector.DeepCopyInto(&out.MatchSelector)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdatePriorityWeightTerm.
|
||||
func (in *UpdatePriorityWeightTerm) DeepCopy() *UpdatePriorityWeightTerm {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdatePriorityWeightTerm)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
|
@ -17,6 +17,9 @@ limitations under the License.
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
|
@ -71,7 +74,7 @@ type CloneSetSpec struct {
|
|||
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
|
||||
|
||||
// Lifecycle defines the lifecycle hooks for Pods pre-delete, in-place update.
|
||||
Lifecycle *Lifecycle `json:"lifecycle,omitempty"`
|
||||
Lifecycle *appspub.Lifecycle `json:"lifecycle,omitempty"`
|
||||
}
|
||||
|
||||
// CloneSetScaleStrategy defines strategies for pods scale.
|
||||
|
|
@ -106,14 +109,14 @@ type CloneSetUpdateStrategy struct {
|
|||
Paused bool `json:"paused,omitempty"`
|
||||
// Priorities are the rules for calculating the priority of updating pods.
|
||||
// Each pod to be updated, will pass through these terms and get a sum of weights.
|
||||
PriorityStrategy *UpdatePriorityStrategy `json:"priorityStrategy,omitempty"`
|
||||
PriorityStrategy *appspub.UpdatePriorityStrategy `json:"priorityStrategy,omitempty"`
|
||||
// ScatterStrategy defines the scatter rules to make pods been scattered when update.
|
||||
// This will avoid pods with the same key-value to be updated in one batch.
|
||||
// - Note that pods will be scattered after priority sort. So, although priority strategy and scatter strategy can be applied together, we suggest to use either one of them.
|
||||
// - If scatterStrategy is used, we suggest to just use one term. Otherwise, the update order can be hard to understand.
|
||||
ScatterStrategy CloneSetUpdateScatterStrategy `json:"scatterStrategy,omitempty"`
|
||||
// InPlaceUpdateStrategy contains strategies for in-place update.
|
||||
InPlaceUpdateStrategy *InPlaceUpdateStrategy `json:"inPlaceUpdateStrategy,omitempty"`
|
||||
InPlaceUpdateStrategy *appspub.InPlaceUpdateStrategy `json:"inPlaceUpdateStrategy,omitempty"`
|
||||
}
|
||||
|
||||
// CloneSetUpdateStrategyType defines strategies for pods in-place update.
|
||||
|
|
@ -148,6 +151,28 @@ type CloneSetUpdateScatterTerm struct {
|
|||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// FieldsValidation checks invalid fields in CloneSetUpdateScatterStrategy.
|
||||
func (strategy CloneSetUpdateScatterStrategy) FieldsValidation() error {
|
||||
if len(strategy) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
m := make(map[string]struct{}, len(strategy))
|
||||
for _, term := range strategy {
|
||||
if term.Key == "" {
|
||||
return fmt.Errorf("key should not be empty")
|
||||
}
|
||||
id := term.Key + ":" + term.Value
|
||||
if _, ok := m[id]; !ok {
|
||||
m[id] = struct{}{}
|
||||
} else {
|
||||
return fmt.Errorf("duplicated key=%v value=%v", term.Key, term.Value)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloneSetStatus defines the observed state of CloneSet
|
||||
type CloneSetStatus struct {
|
||||
// ObservedGeneration is the most recent generation observed for this CloneSet. It corresponds to the
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
|
@ -210,7 +211,7 @@ func SetDefaultsCloneSet(obj *CloneSet) {
|
|||
obj.Spec.UpdateStrategy.Type = RecreateCloneSetUpdateStrategyType
|
||||
case InPlaceIfPossibleCloneSetUpdateStrategyType, InPlaceOnlyCloneSetUpdateStrategyType:
|
||||
if obj.Spec.UpdateStrategy.InPlaceUpdateStrategy == nil {
|
||||
obj.Spec.UpdateStrategy.InPlaceUpdateStrategy = &InPlaceUpdateStrategy{}
|
||||
obj.Spec.UpdateStrategy.InPlaceUpdateStrategy = &appspub.InPlaceUpdateStrategy{}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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 v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/conversion"
|
||||
)
|
||||
|
||||
func (sts *StatefulSet) ConvertTo(dst conversion.Hub) error {
|
||||
switch t := dst.(type) {
|
||||
case *v1beta1.StatefulSet:
|
||||
stsv1beta1 := dst.(*v1beta1.StatefulSet)
|
||||
stsv1beta1.ObjectMeta = sts.ObjectMeta
|
||||
|
||||
// spec
|
||||
stsv1beta1.Spec = v1beta1.StatefulSetSpec{
|
||||
Replicas: sts.Spec.Replicas,
|
||||
Selector: sts.Spec.Selector,
|
||||
Template: sts.Spec.Template,
|
||||
VolumeClaimTemplates: sts.Spec.VolumeClaimTemplates,
|
||||
ServiceName: sts.Spec.ServiceName,
|
||||
PodManagementPolicy: sts.Spec.PodManagementPolicy,
|
||||
UpdateStrategy: v1beta1.StatefulSetUpdateStrategy{
|
||||
Type: sts.Spec.UpdateStrategy.Type,
|
||||
},
|
||||
RevisionHistoryLimit: sts.Spec.RevisionHistoryLimit,
|
||||
}
|
||||
if sts.Spec.UpdateStrategy.RollingUpdate != nil {
|
||||
stsv1beta1.Spec.UpdateStrategy.RollingUpdate = &v1beta1.RollingUpdateStatefulSetStrategy{
|
||||
Partition: sts.Spec.UpdateStrategy.RollingUpdate.Partition,
|
||||
MaxUnavailable: sts.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable,
|
||||
PodUpdatePolicy: v1beta1.PodUpdateStrategyType(sts.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy),
|
||||
Paused: sts.Spec.UpdateStrategy.RollingUpdate.Paused,
|
||||
InPlaceUpdateStrategy: sts.Spec.UpdateStrategy.RollingUpdate.InPlaceUpdateStrategy,
|
||||
MinReadySeconds: sts.Spec.UpdateStrategy.RollingUpdate.MinReadySeconds,
|
||||
}
|
||||
if sts.Spec.UpdateStrategy.RollingUpdate.UnorderedUpdate != nil {
|
||||
stsv1beta1.Spec.UpdateStrategy.RollingUpdate.UnorderedUpdate = &v1beta1.UnorderedUpdateStrategy{
|
||||
PriorityStrategy: sts.Spec.UpdateStrategy.RollingUpdate.UnorderedUpdate.PriorityStrategy,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// status
|
||||
stsv1beta1.Status = v1beta1.StatefulSetStatus{
|
||||
ObservedGeneration: sts.Status.ObservedGeneration,
|
||||
Replicas: sts.Status.Replicas,
|
||||
ReadyReplicas: sts.Status.ReadyReplicas,
|
||||
AvailableReplicas: sts.Status.AvailableReplicas,
|
||||
CurrentReplicas: sts.Status.CurrentReplicas,
|
||||
UpdatedReplicas: sts.Status.UpdatedReplicas,
|
||||
CurrentRevision: sts.Status.CurrentRevision,
|
||||
UpdateRevision: sts.Status.UpdateRevision,
|
||||
CollisionCount: sts.Status.CollisionCount,
|
||||
Conditions: sts.Status.Conditions,
|
||||
LabelSelector: sts.Status.LabelSelector,
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported type %v", t)
|
||||
}
|
||||
}
|
||||
|
||||
func (sts *StatefulSet) ConvertFrom(src conversion.Hub) error {
|
||||
switch t := src.(type) {
|
||||
case *v1beta1.StatefulSet:
|
||||
stsv1beta1 := src.(*v1beta1.StatefulSet)
|
||||
sts.ObjectMeta = stsv1beta1.ObjectMeta
|
||||
|
||||
// spec
|
||||
sts.Spec = StatefulSetSpec{
|
||||
Replicas: stsv1beta1.Spec.Replicas,
|
||||
Selector: stsv1beta1.Spec.Selector,
|
||||
Template: stsv1beta1.Spec.Template,
|
||||
VolumeClaimTemplates: stsv1beta1.Spec.VolumeClaimTemplates,
|
||||
ServiceName: stsv1beta1.Spec.ServiceName,
|
||||
PodManagementPolicy: stsv1beta1.Spec.PodManagementPolicy,
|
||||
UpdateStrategy: StatefulSetUpdateStrategy{
|
||||
Type: stsv1beta1.Spec.UpdateStrategy.Type,
|
||||
},
|
||||
RevisionHistoryLimit: stsv1beta1.Spec.RevisionHistoryLimit,
|
||||
}
|
||||
if stsv1beta1.Spec.UpdateStrategy.RollingUpdate != nil {
|
||||
sts.Spec.UpdateStrategy.RollingUpdate = &RollingUpdateStatefulSetStrategy{
|
||||
Partition: stsv1beta1.Spec.UpdateStrategy.RollingUpdate.Partition,
|
||||
MaxUnavailable: stsv1beta1.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable,
|
||||
PodUpdatePolicy: PodUpdateStrategyType(stsv1beta1.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy),
|
||||
Paused: stsv1beta1.Spec.UpdateStrategy.RollingUpdate.Paused,
|
||||
InPlaceUpdateStrategy: stsv1beta1.Spec.UpdateStrategy.RollingUpdate.InPlaceUpdateStrategy,
|
||||
MinReadySeconds: stsv1beta1.Spec.UpdateStrategy.RollingUpdate.MinReadySeconds,
|
||||
}
|
||||
if stsv1beta1.Spec.UpdateStrategy.RollingUpdate.UnorderedUpdate != nil {
|
||||
sts.Spec.UpdateStrategy.RollingUpdate.UnorderedUpdate = &UnorderedUpdateStrategy{
|
||||
PriorityStrategy: stsv1beta1.Spec.UpdateStrategy.RollingUpdate.UnorderedUpdate.PriorityStrategy,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// status
|
||||
sts.Status = StatefulSetStatus{
|
||||
ObservedGeneration: stsv1beta1.Status.ObservedGeneration,
|
||||
Replicas: stsv1beta1.Status.Replicas,
|
||||
ReadyReplicas: stsv1beta1.Status.ReadyReplicas,
|
||||
AvailableReplicas: stsv1beta1.Status.AvailableReplicas,
|
||||
CurrentReplicas: stsv1beta1.Status.CurrentReplicas,
|
||||
UpdatedReplicas: stsv1beta1.Status.UpdatedReplicas,
|
||||
CurrentRevision: stsv1beta1.Status.CurrentRevision,
|
||||
UpdateRevision: stsv1beta1.Status.UpdateRevision,
|
||||
CollisionCount: stsv1beta1.Status.CollisionCount,
|
||||
Conditions: stsv1beta1.Status.Conditions,
|
||||
LabelSelector: stsv1beta1.Status.LabelSelector,
|
||||
}
|
||||
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unsupported type %v", t)
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -72,7 +73,7 @@ type RollingUpdateStatefulSetStrategy struct {
|
|||
UnorderedUpdate *UnorderedUpdateStrategy `json:"unorderedUpdate,omitempty"`
|
||||
// InPlaceUpdateStrategy contains strategies for in-place update.
|
||||
// +optional
|
||||
InPlaceUpdateStrategy *InPlaceUpdateStrategy `json:"inPlaceUpdateStrategy,omitempty"`
|
||||
InPlaceUpdateStrategy *appspub.InPlaceUpdateStrategy `json:"inPlaceUpdateStrategy,omitempty"`
|
||||
// MinReadySeconds indicates how long will the pod be considered ready after it's updated.
|
||||
// MinReadySeconds works with both OrderedReady and Parallel podManagementPolicy.
|
||||
// It affects the pod scale up speed when the podManagementPolicy is set to be OrderedReady.
|
||||
|
|
@ -87,7 +88,7 @@ type UnorderedUpdateStrategy struct {
|
|||
// Priorities are the rules for calculating the priority of updating pods.
|
||||
// Each pod to be updated, will pass through these terms and get a sum of weights.
|
||||
// +optional
|
||||
PriorityStrategy *UpdatePriorityStrategy `json:"priorityStrategy,omitempty"`
|
||||
PriorityStrategy *appspub.UpdatePriorityStrategy `json:"priorityStrategy,omitempty"`
|
||||
}
|
||||
|
||||
// PodUpdateStrategyType is a string enumeration type that enumerates
|
||||
|
|
|
|||
|
|
@ -94,17 +94,20 @@ type SubsetTemplate struct {
|
|||
|
||||
// StatefulSetTemplateSpec defines the subset template of StatefulSet.
|
||||
type StatefulSetTemplateSpec struct {
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec appsv1.StatefulSetSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// AdvancedStatefulSetTemplateSpec defines the subset template of AdvancedStatefulSet.
|
||||
type AdvancedStatefulSetTemplateSpec struct {
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec StatefulSetSpec `json:"spec"`
|
||||
}
|
||||
|
||||
type CloneSetTemplateSpec struct {
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
Spec CloneSetSpec `json:"spec"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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 v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// FieldsValidation checks invalid fields in UpdatePriorityStrategy.
|
||||
func (strategy *UpdatePriorityStrategy) FieldsValidation() error {
|
||||
if strategy == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(strategy.WeightPriority) > 0 && len(strategy.OrderPriority) > 0 {
|
||||
return fmt.Errorf("only one of weightPriority and orderPriority can be used")
|
||||
}
|
||||
|
||||
for _, w := range strategy.WeightPriority {
|
||||
if w.Weight < 0 || w.Weight > 100 {
|
||||
return fmt.Errorf("weight must be valid number in the range 1-100")
|
||||
}
|
||||
if w.MatchSelector.Size() == 0 {
|
||||
return fmt.Errorf("selector can not be empty")
|
||||
}
|
||||
if _, err := metav1.LabelSelectorAsSelector(&w.MatchSelector); err != nil {
|
||||
return fmt.Errorf("invalid selector %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, o := range strategy.OrderPriority {
|
||||
if len(o.OrderedKey) == 0 {
|
||||
return fmt.Errorf("order key can not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FieldsValidation checks invalid fields in CloneSetUpdateScatterStrategy.
|
||||
func (strategy CloneSetUpdateScatterStrategy) FieldsValidation() error {
|
||||
if len(strategy) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
m := make(map[string]struct{}, len(strategy))
|
||||
for _, term := range strategy {
|
||||
if term.Key == "" {
|
||||
return fmt.Errorf("key should not be empty")
|
||||
}
|
||||
id := term.Key + ":" + term.Value
|
||||
if _, ok := m[id]; !ok {
|
||||
m[id] = struct{}{}
|
||||
} else {
|
||||
return fmt.Errorf("duplicated key=%v value=%v", term.Key, term.Value)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ limitations under the License.
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
"github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -282,7 +283,7 @@ func (in *CloneSetSpec) DeepCopyInto(out *CloneSetSpec) {
|
|||
}
|
||||
if in.Lifecycle != nil {
|
||||
in, out := &in.Lifecycle, &out.Lifecycle
|
||||
*out = new(Lifecycle)
|
||||
*out = new(pub.Lifecycle)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
|
@ -395,7 +396,7 @@ func (in *CloneSetUpdateStrategy) DeepCopyInto(out *CloneSetUpdateStrategy) {
|
|||
}
|
||||
if in.PriorityStrategy != nil {
|
||||
in, out := &in.PriorityStrategy, &out.PriorityStrategy
|
||||
*out = new(UpdatePriorityStrategy)
|
||||
*out = new(pub.UpdatePriorityStrategy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ScatterStrategy != nil {
|
||||
|
|
@ -405,7 +406,7 @@ func (in *CloneSetUpdateStrategy) DeepCopyInto(out *CloneSetUpdateStrategy) {
|
|||
}
|
||||
if in.InPlaceUpdateStrategy != nil {
|
||||
in, out := &in.InPlaceUpdateStrategy, &out.InPlaceUpdateStrategy
|
||||
*out = new(InPlaceUpdateStrategy)
|
||||
*out = new(pub.InPlaceUpdateStrategy)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
|
@ -873,59 +874,6 @@ func (in *ImageTagStatus) DeepCopy() *ImageTagStatus {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InPlaceUpdateContainerStatus) DeepCopyInto(out *InPlaceUpdateContainerStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InPlaceUpdateContainerStatus.
|
||||
func (in *InPlaceUpdateContainerStatus) DeepCopy() *InPlaceUpdateContainerStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InPlaceUpdateContainerStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InPlaceUpdateState) DeepCopyInto(out *InPlaceUpdateState) {
|
||||
*out = *in
|
||||
in.UpdateTimestamp.DeepCopyInto(&out.UpdateTimestamp)
|
||||
if in.LastContainerStatuses != nil {
|
||||
in, out := &in.LastContainerStatuses, &out.LastContainerStatuses
|
||||
*out = make(map[string]InPlaceUpdateContainerStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InPlaceUpdateState.
|
||||
func (in *InPlaceUpdateState) DeepCopy() *InPlaceUpdateState {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InPlaceUpdateState)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InPlaceUpdateStrategy) DeepCopyInto(out *InPlaceUpdateStrategy) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InPlaceUpdateStrategy.
|
||||
func (in *InPlaceUpdateStrategy) DeepCopy() *InPlaceUpdateStrategy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InPlaceUpdateStrategy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *JobCondition) DeepCopyInto(out *JobCondition) {
|
||||
*out = *in
|
||||
|
|
@ -943,58 +891,6 @@ func (in *JobCondition) DeepCopy() *JobCondition {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Lifecycle) DeepCopyInto(out *Lifecycle) {
|
||||
*out = *in
|
||||
if in.PreDelete != nil {
|
||||
in, out := &in.PreDelete, &out.PreDelete
|
||||
*out = new(LifecycleHook)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.InPlaceUpdate != nil {
|
||||
in, out := &in.InPlaceUpdate, &out.InPlaceUpdate
|
||||
*out = new(LifecycleHook)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Lifecycle.
|
||||
func (in *Lifecycle) DeepCopy() *Lifecycle {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Lifecycle)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LifecycleHook) DeepCopyInto(out *LifecycleHook) {
|
||||
*out = *in
|
||||
if in.LabelsHandler != nil {
|
||||
in, out := &in.LabelsHandler, &out.LabelsHandler
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.FinalizersHandler != nil {
|
||||
in, out := &in.FinalizersHandler, &out.FinalizersHandler
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LifecycleHook.
|
||||
func (in *LifecycleHook) DeepCopy() *LifecycleHook {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LifecycleHook)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManualUpdate) DeepCopyInto(out *ManualUpdate) {
|
||||
*out = *in
|
||||
|
|
@ -1266,7 +1162,7 @@ func (in *RollingUpdateStatefulSetStrategy) DeepCopyInto(out *RollingUpdateState
|
|||
}
|
||||
if in.InPlaceUpdateStrategy != nil {
|
||||
in, out := &in.InPlaceUpdateStrategy, &out.InPlaceUpdateStrategy
|
||||
*out = new(InPlaceUpdateStrategy)
|
||||
*out = new(pub.InPlaceUpdateStrategy)
|
||||
**out = **in
|
||||
}
|
||||
if in.MinReadySeconds != nil {
|
||||
|
|
@ -1868,7 +1764,7 @@ func (in *UnorderedUpdateStrategy) DeepCopyInto(out *UnorderedUpdateStrategy) {
|
|||
*out = *in
|
||||
if in.PriorityStrategy != nil {
|
||||
in, out := &in.PriorityStrategy, &out.PriorityStrategy
|
||||
*out = new(UpdatePriorityStrategy)
|
||||
*out = new(pub.UpdatePriorityStrategy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
|
@ -1883,64 +1779,6 @@ func (in *UnorderedUpdateStrategy) DeepCopy() *UnorderedUpdateStrategy {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdatePriorityOrderTerm) DeepCopyInto(out *UpdatePriorityOrderTerm) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdatePriorityOrderTerm.
|
||||
func (in *UpdatePriorityOrderTerm) DeepCopy() *UpdatePriorityOrderTerm {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdatePriorityOrderTerm)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdatePriorityStrategy) DeepCopyInto(out *UpdatePriorityStrategy) {
|
||||
*out = *in
|
||||
if in.OrderPriority != nil {
|
||||
in, out := &in.OrderPriority, &out.OrderPriority
|
||||
*out = make([]UpdatePriorityOrderTerm, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.WeightPriority != nil {
|
||||
in, out := &in.WeightPriority, &out.WeightPriority
|
||||
*out = make([]UpdatePriorityWeightTerm, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdatePriorityStrategy.
|
||||
func (in *UpdatePriorityStrategy) DeepCopy() *UpdatePriorityStrategy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdatePriorityStrategy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdatePriorityWeightTerm) DeepCopyInto(out *UpdatePriorityWeightTerm) {
|
||||
*out = *in
|
||||
in.MatchSelector.DeepCopyInto(&out.MatchSelector)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdatePriorityWeightTerm.
|
||||
func (in *UpdatePriorityWeightTerm) DeepCopy() *UpdatePriorityWeightTerm {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UpdatePriorityWeightTerm)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UpdateStatus) DeepCopyInto(out *UpdateStatus) {
|
||||
*out = *in
|
||||
|
|
|
|||
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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 v1beta1
|
||||
|
||||
import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
v1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
// SetDefaults_StatefulSet set default values for StatefulSet.
|
||||
func SetDefaultsStatefulSet(obj *StatefulSet) {
|
||||
if len(obj.Spec.PodManagementPolicy) == 0 {
|
||||
obj.Spec.PodManagementPolicy = appsv1.OrderedReadyPodManagement
|
||||
}
|
||||
|
||||
if obj.Spec.UpdateStrategy.Type == "" {
|
||||
obj.Spec.UpdateStrategy.Type = appsv1.RollingUpdateStatefulSetStrategyType
|
||||
|
||||
// UpdateStrategy.RollingUpdate will take default values below.
|
||||
obj.Spec.UpdateStrategy.RollingUpdate = &RollingUpdateStatefulSetStrategy{}
|
||||
}
|
||||
|
||||
if obj.Spec.UpdateStrategy.Type == appsv1.RollingUpdateStatefulSetStrategyType {
|
||||
if obj.Spec.UpdateStrategy.RollingUpdate == nil {
|
||||
obj.Spec.UpdateStrategy.RollingUpdate = &RollingUpdateStatefulSetStrategy{}
|
||||
}
|
||||
if obj.Spec.UpdateStrategy.RollingUpdate.Partition == nil {
|
||||
obj.Spec.UpdateStrategy.RollingUpdate.Partition = utilpointer.Int32Ptr(0)
|
||||
}
|
||||
if obj.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable == nil {
|
||||
maxUnavailable := intstr.FromInt(1)
|
||||
obj.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable = &maxUnavailable
|
||||
}
|
||||
if obj.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy == "" {
|
||||
obj.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy = RecreatePodUpdateStrategyType
|
||||
}
|
||||
if obj.Spec.UpdateStrategy.RollingUpdate.MinReadySeconds == nil {
|
||||
obj.Spec.UpdateStrategy.RollingUpdate.MinReadySeconds = utilpointer.Int32Ptr(0)
|
||||
}
|
||||
}
|
||||
|
||||
if obj.Spec.Replicas == nil {
|
||||
obj.Spec.Replicas = utilpointer.Int32Ptr(1)
|
||||
}
|
||||
if obj.Spec.RevisionHistoryLimit == nil {
|
||||
obj.Spec.RevisionHistoryLimit = utilpointer.Int32Ptr(10)
|
||||
}
|
||||
|
||||
SetDefaultPodSpec(&obj.Spec.Template.Spec)
|
||||
for i := range obj.Spec.VolumeClaimTemplates {
|
||||
a := &obj.Spec.VolumeClaimTemplates[i]
|
||||
v1.SetDefaults_PersistentVolumeClaim(a)
|
||||
v1.SetDefaults_ResourceList(&a.Spec.Resources.Limits)
|
||||
v1.SetDefaults_ResourceList(&a.Spec.Resources.Requests)
|
||||
v1.SetDefaults_ResourceList(&a.Status.Capacity)
|
||||
}
|
||||
}
|
||||
|
||||
// SetDefaultPodSpec sets default pod spec
|
||||
func SetDefaultPodSpec(in *corev1.PodSpec) {
|
||||
v1.SetDefaults_PodSpec(in)
|
||||
for i := range in.Volumes {
|
||||
a := &in.Volumes[i]
|
||||
v1.SetDefaults_Volume(a)
|
||||
if a.VolumeSource.HostPath != nil {
|
||||
v1.SetDefaults_HostPathVolumeSource(a.VolumeSource.HostPath)
|
||||
}
|
||||
if a.VolumeSource.Secret != nil {
|
||||
v1.SetDefaults_SecretVolumeSource(a.VolumeSource.Secret)
|
||||
}
|
||||
if a.VolumeSource.ISCSI != nil {
|
||||
v1.SetDefaults_ISCSIVolumeSource(a.VolumeSource.ISCSI)
|
||||
}
|
||||
if a.VolumeSource.RBD != nil {
|
||||
v1.SetDefaults_RBDVolumeSource(a.VolumeSource.RBD)
|
||||
}
|
||||
if a.VolumeSource.DownwardAPI != nil {
|
||||
v1.SetDefaults_DownwardAPIVolumeSource(a.VolumeSource.DownwardAPI)
|
||||
for j := range a.VolumeSource.DownwardAPI.Items {
|
||||
b := &a.VolumeSource.DownwardAPI.Items[j]
|
||||
if b.FieldRef != nil {
|
||||
v1.SetDefaults_ObjectFieldSelector(b.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.VolumeSource.ConfigMap != nil {
|
||||
v1.SetDefaults_ConfigMapVolumeSource(a.VolumeSource.ConfigMap)
|
||||
}
|
||||
if a.VolumeSource.AzureDisk != nil {
|
||||
v1.SetDefaults_AzureDiskVolumeSource(a.VolumeSource.AzureDisk)
|
||||
}
|
||||
if a.VolumeSource.Projected != nil {
|
||||
v1.SetDefaults_ProjectedVolumeSource(a.VolumeSource.Projected)
|
||||
for j := range a.VolumeSource.Projected.Sources {
|
||||
b := &a.VolumeSource.Projected.Sources[j]
|
||||
if b.DownwardAPI != nil {
|
||||
for k := range b.DownwardAPI.Items {
|
||||
c := &b.DownwardAPI.Items[k]
|
||||
if c.FieldRef != nil {
|
||||
v1.SetDefaults_ObjectFieldSelector(c.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
if b.ServiceAccountToken != nil {
|
||||
v1.SetDefaults_ServiceAccountTokenProjection(b.ServiceAccountToken)
|
||||
}
|
||||
}
|
||||
}
|
||||
if a.VolumeSource.ScaleIO != nil {
|
||||
v1.SetDefaults_ScaleIOVolumeSource(a.VolumeSource.ScaleIO)
|
||||
}
|
||||
}
|
||||
for i := range in.InitContainers {
|
||||
a := &in.InitContainers[i]
|
||||
v1.SetDefaults_Container(a)
|
||||
for j := range a.Ports {
|
||||
b := &a.Ports[j]
|
||||
v1.SetDefaults_ContainerPort(b)
|
||||
}
|
||||
for j := range a.Env {
|
||||
b := &a.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
v1.SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
v1.SetDefaults_ResourceList(&a.Resources.Limits)
|
||||
v1.SetDefaults_ResourceList(&a.Resources.Requests)
|
||||
if a.LivenessProbe != nil {
|
||||
v1.SetDefaults_Probe(a.LivenessProbe)
|
||||
if a.LivenessProbe.Handler.HTTPGet != nil {
|
||||
v1.SetDefaults_HTTPGetAction(a.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.ReadinessProbe != nil {
|
||||
v1.SetDefaults_Probe(a.ReadinessProbe)
|
||||
if a.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
v1.SetDefaults_HTTPGetAction(a.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle != nil {
|
||||
if a.Lifecycle.PostStart != nil {
|
||||
if a.Lifecycle.PostStart.HTTPGet != nil {
|
||||
v1.SetDefaults_HTTPGetAction(a.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle.PreStop != nil {
|
||||
if a.Lifecycle.PreStop.HTTPGet != nil {
|
||||
v1.SetDefaults_HTTPGetAction(a.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range in.Containers {
|
||||
a := &in.Containers[i]
|
||||
// For in-place update, we set default imagePullPolicy to Always
|
||||
if a.ImagePullPolicy == "" {
|
||||
a.ImagePullPolicy = corev1.PullAlways
|
||||
}
|
||||
v1.SetDefaults_Container(a)
|
||||
for j := range a.Ports {
|
||||
b := &a.Ports[j]
|
||||
v1.SetDefaults_ContainerPort(b)
|
||||
}
|
||||
for j := range a.Env {
|
||||
b := &a.Env[j]
|
||||
if b.ValueFrom != nil {
|
||||
if b.ValueFrom.FieldRef != nil {
|
||||
v1.SetDefaults_ObjectFieldSelector(b.ValueFrom.FieldRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
v1.SetDefaults_ResourceList(&a.Resources.Limits)
|
||||
v1.SetDefaults_ResourceList(&a.Resources.Requests)
|
||||
if a.LivenessProbe != nil {
|
||||
v1.SetDefaults_Probe(a.LivenessProbe)
|
||||
if a.LivenessProbe.Handler.HTTPGet != nil {
|
||||
v1.SetDefaults_HTTPGetAction(a.LivenessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.ReadinessProbe != nil {
|
||||
v1.SetDefaults_Probe(a.ReadinessProbe)
|
||||
if a.ReadinessProbe.Handler.HTTPGet != nil {
|
||||
v1.SetDefaults_HTTPGetAction(a.ReadinessProbe.Handler.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle != nil {
|
||||
if a.Lifecycle.PostStart != nil {
|
||||
if a.Lifecycle.PostStart.HTTPGet != nil {
|
||||
v1.SetDefaults_HTTPGetAction(a.Lifecycle.PostStart.HTTPGet)
|
||||
}
|
||||
}
|
||||
if a.Lifecycle.PreStop != nil {
|
||||
if a.Lifecycle.PreStop.HTTPGet != nil {
|
||||
v1.SetDefaults_HTTPGetAction(a.Lifecycle.PreStop.HTTPGet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
|
||||
// +groupName=apps.kruise.io
|
||||
package v1beta1
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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 v1beta1 contains API Schema definitions for the apps v1beta1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=apps.kruise.io
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "apps.kruise.io", Version: "v1beta1"}
|
||||
|
||||
SchemeGroupVersion = GroupVersion
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Resource is required by pkg/client/listers/...
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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 v1beta1
|
||||
|
||||
func (*StatefulSet) Hub() {}
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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 v1beta1
|
||||
|
||||
import (
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
const (
|
||||
// MaxMinReadySeconds is the max value of MinReadySeconds
|
||||
MaxMinReadySeconds = 300
|
||||
)
|
||||
|
||||
// StatefulSetUpdateStrategy indicates the strategy that the StatefulSet
|
||||
// controller will use to perform updates. It includes any additional parameters
|
||||
// necessary to perform the update for the indicated strategy.
|
||||
type StatefulSetUpdateStrategy struct {
|
||||
// Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
// Default is RollingUpdate.
|
||||
// +optional
|
||||
Type apps.StatefulSetUpdateStrategyType `json:"type,omitempty"`
|
||||
// RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType.
|
||||
// +optional
|
||||
RollingUpdate *RollingUpdateStatefulSetStrategy `json:"rollingUpdate,omitempty"`
|
||||
}
|
||||
|
||||
// RollingUpdateStatefulSetStrategy is used to communicate parameter for RollingUpdateStatefulSetStrategyType.
|
||||
type RollingUpdateStatefulSetStrategy struct {
|
||||
// Partition indicates the ordinal at which the StatefulSet should be partitioned by default.
|
||||
// But if unorderedUpdate has been set:
|
||||
// - Partition indicates the number of pods with non-updated revisions when rolling update.
|
||||
// - It means controller will update $(replicas - partition) number of pod.
|
||||
// Default value is 0.
|
||||
// +optional
|
||||
Partition *int32 `json:"partition,omitempty"`
|
||||
// The maximum number of pods that can be unavailable during the update.
|
||||
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
|
||||
// Absolute number is calculated from percentage by rounding down.
|
||||
// Also, maxUnavailable can just be allowed to work with Parallel podManagementPolicy.
|
||||
// Defaults to 1.
|
||||
// +optional
|
||||
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`
|
||||
// PodUpdatePolicy indicates how pods should be updated
|
||||
// Default value is "ReCreate"
|
||||
// +optional
|
||||
PodUpdatePolicy PodUpdateStrategyType `json:"podUpdatePolicy,omitempty"`
|
||||
// Paused indicates that the StatefulSet is paused.
|
||||
// Default value is false
|
||||
// +optional
|
||||
Paused bool `json:"paused,omitempty"`
|
||||
// UnorderedUpdate contains strategies for non-ordered update.
|
||||
// If it is not nil, pods will be updated with non-ordered sequence.
|
||||
// Noted that UnorderedUpdate can only be allowed to work with Parallel podManagementPolicy
|
||||
// +optional
|
||||
UnorderedUpdate *UnorderedUpdateStrategy `json:"unorderedUpdate,omitempty"`
|
||||
// InPlaceUpdateStrategy contains strategies for in-place update.
|
||||
// +optional
|
||||
InPlaceUpdateStrategy *appspub.InPlaceUpdateStrategy `json:"inPlaceUpdateStrategy,omitempty"`
|
||||
// MinReadySeconds indicates how long will the pod be considered ready after it's updated.
|
||||
// MinReadySeconds works with both OrderedReady and Parallel podManagementPolicy.
|
||||
// It affects the pod scale up speed when the podManagementPolicy is set to be OrderedReady.
|
||||
// Combined with MaxUnavailable, it affects the pod update speed regardless of podManagementPolicy.
|
||||
// Default value is 0, max is 300.
|
||||
// +optional
|
||||
MinReadySeconds *int32 `json:"minReadySeconds,omitempty"`
|
||||
}
|
||||
|
||||
// UnorderedUpdateStrategy defines strategies for non-ordered update.
|
||||
type UnorderedUpdateStrategy struct {
|
||||
// Priorities are the rules for calculating the priority of updating pods.
|
||||
// Each pod to be updated, will pass through these terms and get a sum of weights.
|
||||
// +optional
|
||||
PriorityStrategy *appspub.UpdatePriorityStrategy `json:"priorityStrategy,omitempty"`
|
||||
}
|
||||
|
||||
// PodUpdateStrategyType is a string enumeration type that enumerates
|
||||
// all possible ways we can update a Pod when updating application
|
||||
type PodUpdateStrategyType string
|
||||
|
||||
const (
|
||||
// RecreatePodUpdateStrategyType indicates that we always delete Pod and create new Pod
|
||||
// during Pod update, which is the default behavior
|
||||
RecreatePodUpdateStrategyType PodUpdateStrategyType = "ReCreate"
|
||||
// InPlaceIfPossiblePodUpdateStrategyType indicates that we try to in-place update Pod instead of
|
||||
// recreating Pod when possible. Currently, only image update of pod spec is allowed. Any other changes to the pod
|
||||
// spec will fall back to ReCreate PodUpdateStrategyType where pod will be recreated.
|
||||
InPlaceIfPossiblePodUpdateStrategyType PodUpdateStrategyType = "InPlaceIfPossible"
|
||||
// InPlaceOnlyPodUpdateStrategyType indicates that we will in-place update Pod instead of
|
||||
// recreating pod. Currently we only allow image update for pod spec. Any other changes to the pod spec will be
|
||||
// rejected by kube-apiserver
|
||||
InPlaceOnlyPodUpdateStrategyType PodUpdateStrategyType = "InPlaceOnly"
|
||||
)
|
||||
|
||||
// StatefulSetSpec defines the desired state of StatefulSet
|
||||
type StatefulSetSpec struct {
|
||||
// replicas is the desired number of replicas of the given Template.
|
||||
// These are replicas in the sense that they are instantiations of the
|
||||
// same Template, but individual replicas also have a consistent identity.
|
||||
// If unspecified, defaults to 1.
|
||||
// TODO: Consider a rename of this field.
|
||||
// +optional
|
||||
Replicas *int32 `json:"replicas,omitempty"`
|
||||
|
||||
// selector is a label query over pods that should match the replica count.
|
||||
// It must match the pod template's labels.
|
||||
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
|
||||
Selector *metav1.LabelSelector `json:"selector"`
|
||||
|
||||
// template is the object that describes the pod that will be created if
|
||||
// insufficient replicas are detected. Each pod stamped out by the StatefulSet
|
||||
// will fulfill this Template, but have a unique identity from the rest
|
||||
// of the StatefulSet.
|
||||
Template v1.PodTemplateSpec `json:"template"`
|
||||
|
||||
// volumeClaimTemplates is a list of claims that pods are allowed to reference.
|
||||
// The StatefulSet controller is responsible for mapping network identities to
|
||||
// claims in a way that maintains the identity of a pod. Every claim in
|
||||
// this list must have at least one matching (by name) volumeMount in one
|
||||
// container in the template. A claim in this list takes precedence over
|
||||
// any volumes in the template, with the same name.
|
||||
// TODO: Define the behavior if a claim already exists with the same name.
|
||||
// +optional
|
||||
VolumeClaimTemplates []v1.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"`
|
||||
|
||||
// serviceName is the name of the service that governs this StatefulSet.
|
||||
// This service must exist before the StatefulSet, and is responsible for
|
||||
// the network identity of the set. Pods get DNS/hostnames that follow the
|
||||
// pattern: pod-specific-string.serviceName.default.svc.cluster.local
|
||||
// where "pod-specific-string" is managed by the StatefulSet controller.
|
||||
ServiceName string `json:"serviceName,omitempty"`
|
||||
|
||||
// podManagementPolicy controls how pods are created during initial scale up,
|
||||
// when replacing pods on nodes, or when scaling down. The default policy is
|
||||
// `OrderedReady`, where pods are created in increasing order (pod-0, then
|
||||
// pod-1, etc) and the controller will wait until each pod is ready before
|
||||
// continuing. When scaling down, the pods are removed in the opposite order.
|
||||
// The alternative policy is `Parallel` which will create pods in parallel
|
||||
// to match the desired scale without waiting, and on scale down will delete
|
||||
// all pods at once.
|
||||
// +optional
|
||||
PodManagementPolicy apps.PodManagementPolicyType `json:"podManagementPolicy,omitempty"`
|
||||
|
||||
// updateStrategy indicates the StatefulSetUpdateStrategy that will be
|
||||
// employed to update Pods in the StatefulSet when a revision is made to
|
||||
// Template.
|
||||
UpdateStrategy StatefulSetUpdateStrategy `json:"updateStrategy,omitempty"`
|
||||
|
||||
// revisionHistoryLimit is the maximum number of revisions that will
|
||||
// be maintained in the StatefulSet's revision history. The revision history
|
||||
// consists of all revisions not represented by a currently applied
|
||||
// StatefulSetSpec version. The default value is 10.
|
||||
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
|
||||
}
|
||||
|
||||
// StatefulSetStatus defines the observed state of StatefulSet
|
||||
type StatefulSetStatus struct {
|
||||
// observedGeneration is the most recent generation observed for this StatefulSet. It corresponds to the
|
||||
// StatefulSet's generation, which is updated on mutation by the API Server.
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// replicas is the number of Pods created by the StatefulSet controller.
|
||||
Replicas int32 `json:"replicas"`
|
||||
|
||||
// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.
|
||||
ReadyReplicas int32 `json:"readyReplicas"`
|
||||
|
||||
// AvailableReplicas is the number of Pods created by the StatefulSet controller that have been ready for
|
||||
//minReadySeconds.
|
||||
AvailableReplicas int32 `json:"availableReplicas"`
|
||||
|
||||
// currentReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by currentRevision.
|
||||
CurrentReplicas int32 `json:"currentReplicas"`
|
||||
|
||||
// updatedReplicas is the number of Pods created by the StatefulSet controller from the StatefulSet version
|
||||
// indicated by updateRevision.
|
||||
UpdatedReplicas int32 `json:"updatedReplicas"`
|
||||
|
||||
// currentRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the
|
||||
// sequence [0,currentReplicas).
|
||||
CurrentRevision string `json:"currentRevision,omitempty"`
|
||||
|
||||
// updateRevision, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
|
||||
// [replicas-updatedReplicas,replicas)
|
||||
UpdateRevision string `json:"updateRevision,omitempty"`
|
||||
|
||||
// collisionCount is the count of hash collisions for the StatefulSet. The StatefulSet controller
|
||||
// uses this field as a collision avoidance mechanism when it needs to create the name for the
|
||||
// newest ControllerRevision.
|
||||
// +optional
|
||||
CollisionCount *int32 `json:"collisionCount,omitempty"`
|
||||
|
||||
// Represents the latest available observations of a statefulset's current state.
|
||||
// +optional
|
||||
// +patchMergeKey=type
|
||||
// +patchStrategy=merge
|
||||
Conditions []apps.StatefulSetCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
|
||||
// LabelSelector is label selectors for query over pods that should match the replica count used by HPA.
|
||||
LabelSelector string `json:"labelSelector,omitempty"`
|
||||
}
|
||||
|
||||
// These are valid conditions of a statefulset.
|
||||
const (
|
||||
FailedCreatePod apps.StatefulSetConditionType = "FailedCreatePod"
|
||||
FailedUpdatePod apps.StatefulSetConditionType = "FailedUpdatePod"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.labelSelector
|
||||
// +kubebuilder:resource:shortName=sts;asts
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.labelSelector
|
||||
// +kubebuilder:printcolumn:name="DESIRED",type="integer",JSONPath=".spec.replicas",description="The desired number of pods."
|
||||
// +kubebuilder:printcolumn:name="CURRENT",type="integer",JSONPath=".status.replicas",description="The number of currently all pods."
|
||||
// +kubebuilder:printcolumn:name="UPDATED",type="integer",JSONPath=".status.updatedReplicas",description="The number of pods updated."
|
||||
// +kubebuilder:printcolumn:name="READY",type="integer",JSONPath=".status.readyReplicas",description="The number of pods ready."
|
||||
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp",description="CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC."
|
||||
|
||||
// StatefulSet is the Schema for the statefulsets API
|
||||
type StatefulSet struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec StatefulSetSpec `json:"spec,omitempty"`
|
||||
Status StatefulSetStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// StatefulSetList contains a list of StatefulSet
|
||||
type StatefulSetList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []StatefulSet `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&StatefulSet{}, &StatefulSetList{})
|
||||
}
|
||||
|
|
@ -0,0 +1,235 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RollingUpdateStatefulSetStrategy) DeepCopyInto(out *RollingUpdateStatefulSetStrategy) {
|
||||
*out = *in
|
||||
if in.Partition != nil {
|
||||
in, out := &in.Partition, &out.Partition
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.MaxUnavailable != nil {
|
||||
in, out := &in.MaxUnavailable, &out.MaxUnavailable
|
||||
*out = new(intstr.IntOrString)
|
||||
**out = **in
|
||||
}
|
||||
if in.UnorderedUpdate != nil {
|
||||
in, out := &in.UnorderedUpdate, &out.UnorderedUpdate
|
||||
*out = new(UnorderedUpdateStrategy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.InPlaceUpdateStrategy != nil {
|
||||
in, out := &in.InPlaceUpdateStrategy, &out.InPlaceUpdateStrategy
|
||||
*out = new(pub.InPlaceUpdateStrategy)
|
||||
**out = **in
|
||||
}
|
||||
if in.MinReadySeconds != nil {
|
||||
in, out := &in.MinReadySeconds, &out.MinReadySeconds
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdateStatefulSetStrategy.
|
||||
func (in *RollingUpdateStatefulSetStrategy) DeepCopy() *RollingUpdateStatefulSetStrategy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RollingUpdateStatefulSetStrategy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatefulSet) DeepCopyInto(out *StatefulSet) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSet.
|
||||
func (in *StatefulSet) DeepCopy() *StatefulSet {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatefulSet)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *StatefulSet) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatefulSetList) DeepCopyInto(out *StatefulSetList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]StatefulSet, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetList.
|
||||
func (in *StatefulSetList) DeepCopy() *StatefulSetList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatefulSetList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *StatefulSetList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatefulSetSpec) DeepCopyInto(out *StatefulSetSpec) {
|
||||
*out = *in
|
||||
if in.Replicas != nil {
|
||||
in, out := &in.Replicas, &out.Replicas
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(v1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Template.DeepCopyInto(&out.Template)
|
||||
if in.VolumeClaimTemplates != nil {
|
||||
in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates
|
||||
*out = make([]corev1.PersistentVolumeClaim, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.UpdateStrategy.DeepCopyInto(&out.UpdateStrategy)
|
||||
if in.RevisionHistoryLimit != nil {
|
||||
in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetSpec.
|
||||
func (in *StatefulSetSpec) DeepCopy() *StatefulSetSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatefulSetSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatefulSetStatus) DeepCopyInto(out *StatefulSetStatus) {
|
||||
*out = *in
|
||||
if in.CollisionCount != nil {
|
||||
in, out := &in.CollisionCount, &out.CollisionCount
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]appsv1.StatefulSetCondition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetStatus.
|
||||
func (in *StatefulSetStatus) DeepCopy() *StatefulSetStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatefulSetStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StatefulSetUpdateStrategy) DeepCopyInto(out *StatefulSetUpdateStrategy) {
|
||||
*out = *in
|
||||
if in.RollingUpdate != nil {
|
||||
in, out := &in.RollingUpdate, &out.RollingUpdate
|
||||
*out = new(RollingUpdateStatefulSetStrategy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatefulSetUpdateStrategy.
|
||||
func (in *StatefulSetUpdateStrategy) DeepCopy() *StatefulSetUpdateStrategy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StatefulSetUpdateStrategy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *UnorderedUpdateStrategy) DeepCopyInto(out *UnorderedUpdateStrategy) {
|
||||
*out = *in
|
||||
if in.PriorityStrategy != nil {
|
||||
in, out := &in.PriorityStrategy, &out.PriorityStrategy
|
||||
*out = new(pub.UpdatePriorityStrategy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnorderedUpdateStrategy.
|
||||
func (in *UnorderedUpdateStrategy) DeepCopy() *UnorderedUpdateStrategy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(UnorderedUpdateStrategy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
apiVersion: v1
|
||||
name: kruise
|
||||
description: Helm chart for all kruise-manager components
|
||||
version: 0.7.0
|
||||
appVersion: 0.7.0
|
||||
icon: http://openkruise.io/img/kruise_white.png
|
||||
keywords:
|
||||
- kubernetes
|
||||
- kruise
|
||||
- workload
|
||||
- statefulset
|
||||
- sidecar
|
||||
- job
|
||||
- deployment
|
||||
home: https://openkruise.io
|
||||
sources:
|
||||
- https://github.com/openkruise/kruise
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# Kruise
|
||||
|
||||
## Install
|
||||
|
||||
Install with Helm 3:
|
||||
|
||||
Note that Kruise v0.7+ will only support Kubernetes 1.13+ and 1.13/1.14 must enable `CustomResourceWebhookConversion` feature-gate.
|
||||
|
||||
If your Kubernetes version is lower than 1.15, you'll need Helm v3.1.0+ that has the flag --disable-openapi-validation.
|
||||
|
||||
```bash
|
||||
# Kubernetes 1.13 and 1.14
|
||||
helm install kruise https://github.com/openkruise/kruise/releases/download/v0.7.0/kruise-chart.tgz --disable-openapi-validation
|
||||
# Kubernetes 1.15 and newer versions
|
||||
helm install kruise https://github.com/openkruise/kruise/releases/download/v0.7.0/kruise-chart.tgz
|
||||
```
|
||||
|
||||
you will see follow:
|
||||
|
||||
```
|
||||
NAME: kruise
|
||||
LAST DEPLOYED: Mon Jan 6 14:47:48 2020
|
||||
NAMESPACE: default
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
```
|
||||
|
||||
## Uninstall
|
||||
|
||||
```bash
|
||||
$ helm delete kruise
|
||||
release "kruise" uninstalled
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The following table lists the configurable parameters of the kruise chart and their default values.
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| ----------------------------------------- | ------------------------------------------------------------ | ----------------------------- |
|
||||
| `log.level` | Log level that kruise-manager printed | `4` |
|
||||
| `revisionHistoryLimit` | Limit of revision history | `3` |
|
||||
| `manager.replicas` | Replicas of kruise-controller-manager deployment | `2` |
|
||||
| `manager.image.repository` | Repository for kruise-manager image | `openkruise/kruise-manager` |
|
||||
| `manager.image.tag` | Tag for kruise-manager image | `v0.6.1` |
|
||||
| `manager.resources.limits.cpu` | CPU resource limit of kruise-manager container | `100m` |
|
||||
| `manager.resources.limits.memory` | Memory resource limit of kruise-manager container | `256Mi` |
|
||||
| `manager.resources.requests.cpu` | CPU resource request of kruise-manager container | `100m` |
|
||||
| `manager.resources.requests.memory` | Memory resource request of kruise-manager container | `256Mi` |
|
||||
| `manager.metrics.addr` | Addr of metrics served | `localhost` |
|
||||
| `manager.metrics.port` | Port of metrics served | `8080` |
|
||||
| `manager.webhook.port` | Port of webhook served | `9443` |
|
||||
| `manager.custom_resource_enable` | Custom resources enabled by kruise-manager | `""(empty means all enabled)` |
|
||||
| `manager.allowPrivileged` | Allow privileged for workloads template | `false` |
|
||||
| `spec.nodeAffinity` | Node affinity policy for kruise-manager pod | `{}` |
|
||||
| `spec.nodeSelector` | Node labels for kruise-manager pod | `{}` |
|
||||
| `spec.tolerations` | Tolerations for kruise-manager pod | `[]` |
|
||||
| `webhookConfiguration.failurePolicy.pods` | The failurePolicy for pods in mutating webhook configuration | `Ignore` |
|
||||
|
||||
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
||||
|
||||
```bash
|
||||
# helm install kruise https://github.com/openkruise/kruise/releases/download/v0.7.0/kruise-chart.tgz --set manager.log.level=5,manager.custom_resource_enable="CloneSet\,SidecarSet"
|
||||
```
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "kruise.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "kruise.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "kruise.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.9
|
||||
creationTimestamp: null
|
||||
name: broadcastjobs.apps.kruise.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .status.desired
|
||||
description: The desired number of pods. This is typically equal to the number
|
||||
of nodes satisfied to run pods.
|
||||
name: Desired
|
||||
type: integer
|
||||
- JSONPath: .status.active
|
||||
description: The number of actively running pods.
|
||||
name: Active
|
||||
type: integer
|
||||
- JSONPath: .status.succeeded
|
||||
description: The number of pods which reached phase Succeeded.
|
||||
name: Succeeded
|
||||
type: integer
|
||||
- JSONPath: .status.failed
|
||||
description: The number of pods which reached phase Failed.
|
||||
name: Failed
|
||||
type: integer
|
||||
- JSONPath: .metadata.creationTimestamp
|
||||
description: CreationTimestamp is a timestamp representing the server time when
|
||||
this object was created. It is not guaranteed to be set in happens-before order
|
||||
across separate operations. Clients may not set this value. It is represented
|
||||
in RFC3339 form and is in UTC.
|
||||
name: AGE
|
||||
type: date
|
||||
group: apps.kruise.io
|
||||
names:
|
||||
kind: BroadcastJob
|
||||
listKind: BroadcastJobList
|
||||
plural: broadcastjobs
|
||||
shortNames:
|
||||
- bcj
|
||||
singular: broadcastjob
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: BroadcastJob is the Schema for the broadcastjobs API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: BroadcastJobSpec defines the desired state of BroadcastJob
|
||||
properties:
|
||||
completionPolicy:
|
||||
description: CompletionPolicy indicates the completion policy of the
|
||||
job. Default is Always CompletionPolicyType
|
||||
properties:
|
||||
activeDeadlineSeconds:
|
||||
description: ActiveDeadlineSeconds specifies the duration in seconds
|
||||
relative to the startTime that the job may be active before the
|
||||
system tries to terminate it; value must be positive integer.
|
||||
Only works for Always type.
|
||||
format: int64
|
||||
type: integer
|
||||
ttlSecondsAfterFinished:
|
||||
description: ttlSecondsAfterFinished limits the lifetime of a Job
|
||||
that has finished execution (either Complete or Failed). If this
|
||||
field is set, ttlSecondsAfterFinished after the Job finishes,
|
||||
it is eligible to be automatically deleted. When the Job is being
|
||||
deleted, its lifecycle guarantees (e.g. finalizers) will be honored.
|
||||
If this field is unset, the Job won't be automatically deleted.
|
||||
If this field is set to zero, the Job becomes eligible to be deleted
|
||||
immediately after it finishes. This field is alpha-level and is
|
||||
only honored by servers that enable the TTLAfterFinished feature.
|
||||
Only works for Always type
|
||||
format: int32
|
||||
type: integer
|
||||
type:
|
||||
description: Type indicates the type of the CompletionPolicy Default
|
||||
is Always
|
||||
type: string
|
||||
type: object
|
||||
failurePolicy:
|
||||
description: FailurePolicy indicates the behavior of the job, when failed
|
||||
pod is found.
|
||||
properties:
|
||||
restartLimit:
|
||||
description: RestartLimit specifies the number of retries before
|
||||
marking the pod failed.
|
||||
format: int32
|
||||
type: integer
|
||||
type:
|
||||
description: Type indicates the type of FailurePolicyType.
|
||||
type: string
|
||||
type: object
|
||||
parallelism:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Parallelism specifies the maximum desired number of pods
|
||||
the job should run at any given time. The actual number of pods running
|
||||
in steady state will be less than this number when the work left to
|
||||
do is less than max parallelism. Not setting this value means no limit.
|
||||
x-kubernetes-int-or-string: true
|
||||
paused:
|
||||
description: Paused will pause the job.
|
||||
type: boolean
|
||||
template:
|
||||
description: Template describes the pod that will be created when executing
|
||||
a job.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
status:
|
||||
description: BroadcastJobStatus defines the observed state of BroadcastJob
|
||||
properties:
|
||||
active:
|
||||
description: The number of actively running pods.
|
||||
format: int32
|
||||
type: integer
|
||||
completionTime:
|
||||
description: Represents time when the job was completed. It is not guaranteed
|
||||
to be set in happens-before order across separate operations. It is
|
||||
represented in RFC3339 form and is in UTC.
|
||||
format: date-time
|
||||
type: string
|
||||
conditions:
|
||||
description: The latest available observations of an object's current
|
||||
state.
|
||||
items:
|
||||
description: JobCondition describes current state of a job.
|
||||
properties:
|
||||
lastProbeTime:
|
||||
description: Last time the condition was checked.
|
||||
format: date-time
|
||||
type: string
|
||||
lastTransitionTime:
|
||||
description: Last time the condition transit from one status to
|
||||
another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: Human readable message indicating details about last
|
||||
transition.
|
||||
type: string
|
||||
reason:
|
||||
description: (brief) reason for the condition's last transition.
|
||||
type: string
|
||||
status:
|
||||
description: Status of the condition, one of True, False, Unknown.
|
||||
type: string
|
||||
type:
|
||||
description: Type of job condition, Complete or Failed.
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
desired:
|
||||
description: The desired number of pods, this is typically equal to
|
||||
the number of nodes satisfied to run pods.
|
||||
format: int32
|
||||
type: integer
|
||||
failed:
|
||||
description: The number of pods which reached phase Failed.
|
||||
format: int32
|
||||
type: integer
|
||||
phase:
|
||||
description: The phase of the job.
|
||||
type: string
|
||||
startTime:
|
||||
description: Represents time when the job was acknowledged by the job
|
||||
controller. It is not guaranteed to be set in happens-before order
|
||||
across separate operations. It is represented in RFC3339 form and
|
||||
is in UTC.
|
||||
format: date-time
|
||||
type: string
|
||||
succeeded:
|
||||
description: The number of pods which reached phase Succeeded.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
type: object
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
|
@ -0,0 +1,455 @@
|
|||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.9
|
||||
creationTimestamp: null
|
||||
name: clonesets.apps.kruise.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .spec.replicas
|
||||
description: The desired number of pods.
|
||||
name: DESIRED
|
||||
type: integer
|
||||
- JSONPath: .status.updatedReplicas
|
||||
description: The number of pods updated.
|
||||
name: UPDATED
|
||||
type: integer
|
||||
- JSONPath: .status.updatedReadyReplicas
|
||||
description: The number of pods updated and ready.
|
||||
name: UPDATED_READY
|
||||
type: integer
|
||||
- JSONPath: .status.readyReplicas
|
||||
description: The number of pods ready.
|
||||
name: READY
|
||||
type: integer
|
||||
- JSONPath: .status.replicas
|
||||
description: The number of currently all pods.
|
||||
name: TOTAL
|
||||
type: integer
|
||||
- JSONPath: .metadata.creationTimestamp
|
||||
description: CreationTimestamp is a timestamp representing the server time when
|
||||
this object was created. It is not guaranteed to be set in happens-before order
|
||||
across separate operations. Clients may not set this value. It is represented
|
||||
in RFC3339 form and is in UTC.
|
||||
name: AGE
|
||||
type: date
|
||||
group: apps.kruise.io
|
||||
names:
|
||||
kind: CloneSet
|
||||
listKind: CloneSetList
|
||||
plural: clonesets
|
||||
shortNames:
|
||||
- clone
|
||||
singular: cloneset
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
scale:
|
||||
labelSelectorPath: .status.labelSelector
|
||||
specReplicasPath: .spec.replicas
|
||||
statusReplicasPath: .status.replicas
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: CloneSet is the Schema for the clonesets API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: CloneSetSpec defines the desired state of CloneSet
|
||||
properties:
|
||||
lifecycle:
|
||||
description: Lifecycle defines the lifecycle hooks for Pods pre-delete,
|
||||
in-place update.
|
||||
properties:
|
||||
inPlaceUpdate:
|
||||
description: InPlaceUpdate is the hook before Pod to update and
|
||||
after Pod has been updated.
|
||||
properties:
|
||||
finalizersHandler:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
labelsHandler:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
preDelete:
|
||||
description: PreDelete is the hook before Pod to be deleted.
|
||||
properties:
|
||||
finalizersHandler:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
labelsHandler:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
minReadySeconds:
|
||||
description: Minimum number of seconds for which a newly created pod
|
||||
should be ready without any of its container crashing, for it to be
|
||||
considered available. Defaults to 0 (pod will be considered available
|
||||
as soon as it is ready)
|
||||
format: int32
|
||||
type: integer
|
||||
replicas:
|
||||
description: Replicas is the desired number of replicas of the given
|
||||
Template. These are replicas in the sense that they are instantiations
|
||||
of the same Template. If unspecified, defaults to 1.
|
||||
format: int32
|
||||
type: integer
|
||||
revisionHistoryLimit:
|
||||
description: RevisionHistoryLimit is the maximum number of revisions
|
||||
that will be maintained in the CloneSet's revision history. The revision
|
||||
history consists of all revisions not represented by a currently applied
|
||||
CloneSetSpec version. The default value is 10.
|
||||
format: int32
|
||||
type: integer
|
||||
scaleStrategy:
|
||||
description: ScaleStrategy indicates the ScaleStrategy that will be
|
||||
employed to create and delete Pods in the CloneSet.
|
||||
properties:
|
||||
podsToDelete:
|
||||
description: PodsToDelete is the names of Pod should be deleted.
|
||||
Note that this list will be truncated for non-existing pod names.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
selector:
|
||||
description: 'Selector is a label query over pods that should match
|
||||
the replica count. It must match the pod template''s labels. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors'
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains
|
||||
values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a
|
||||
set of values. Valid operators are In, NotIn, Exists and
|
||||
DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator
|
||||
is In or NotIn, the values array must be non-empty. If the
|
||||
operator is Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator is
|
||||
"In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
template:
|
||||
description: Template describes the pods that will be created.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: UpdateStrategy indicates the UpdateStrategy that will be
|
||||
employed to update Pods in the CloneSet when a revision is made to
|
||||
Template.
|
||||
properties:
|
||||
inPlaceUpdateStrategy:
|
||||
description: InPlaceUpdateStrategy contains strategies for in-place
|
||||
update.
|
||||
properties:
|
||||
gracePeriodSeconds:
|
||||
description: GracePeriodSeconds is the timespan between set
|
||||
Pod status to not-ready and update images in Pod spec when
|
||||
in-place update a Pod.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
maxSurge:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'The maximum number of pods that can be scheduled above
|
||||
the desired replicas during the update. Value can be an absolute
|
||||
number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute
|
||||
number is calculated from percentage by rounding up. Defaults
|
||||
to 0.'
|
||||
x-kubernetes-int-or-string: true
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'The maximum number of pods that can be unavailable
|
||||
during the update. Value can be an absolute number (ex: 5) or
|
||||
a percentage of desired pods (ex: 10%). Absolute number is calculated
|
||||
from percentage by rounding up by default. When maxSurge > 0,
|
||||
absolute number is calculated from percentage by rounding down.
|
||||
Defaults to 20%.'
|
||||
x-kubernetes-int-or-string: true
|
||||
partition:
|
||||
description: Partition is the desired number of pods in old revisions.
|
||||
It means when partition is set during pods updating, (replicas
|
||||
- partition) number of pods will be updated. Default value is
|
||||
0.
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused indicates that the CloneSet is paused. Default
|
||||
value is false
|
||||
type: boolean
|
||||
priorityStrategy:
|
||||
description: Priorities are the rules for calculating the priority
|
||||
of updating pods. Each pod to be updated, will pass through these
|
||||
terms and get a sum of weights.
|
||||
properties:
|
||||
orderPriority:
|
||||
description: 'Order priority terms, pods will be sorted by the
|
||||
value of orderedKey. For example: ``` orderPriority: - orderedKey:
|
||||
key1 - orderedKey: key2 ``` First, all pods which have key1
|
||||
in labels will be sorted by the value of key1. Then, the left
|
||||
pods which have no key1 but have key2 in labels will be sorted
|
||||
by the value of key2 and put behind those pods have key1.'
|
||||
items:
|
||||
description: UpdatePriorityOrder defines order priority.
|
||||
properties:
|
||||
orderedKey:
|
||||
description: Calculate priority by value of this key.
|
||||
Values of this key, will be sorted by GetInt(val). GetInt
|
||||
method will find the last int in value, such as getting
|
||||
5 in value '5', getting 10 in value 'sts-10'.
|
||||
type: string
|
||||
required:
|
||||
- orderedKey
|
||||
type: object
|
||||
type: array
|
||||
weightPriority:
|
||||
description: Weight priority terms, pods will be sorted by the
|
||||
sum of all terms weight.
|
||||
items:
|
||||
description: UpdatePriorityWeightTerm defines weight priority.
|
||||
properties:
|
||||
matchSelector:
|
||||
description: MatchSelector is used to select by pod's
|
||||
labels.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In,
|
||||
NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values
|
||||
array must be non-empty. If the operator is
|
||||
Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a
|
||||
strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field
|
||||
is "key", the operator is "In", and the values array
|
||||
contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
weight:
|
||||
description: Weight associated with matching the corresponding
|
||||
matchExpressions, in the range 1-100.
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- matchSelector
|
||||
- weight
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
scatterStrategy:
|
||||
description: ScatterStrategy defines the scatter rules to make pods
|
||||
been scattered when update. This will avoid pods with the same
|
||||
key-value to be updated in one batch. - Note that pods will be
|
||||
scattered after priority sort. So, although priority strategy
|
||||
and scatter strategy can be applied together, we suggest to use
|
||||
either one of them. - If scatterStrategy is used, we suggest to
|
||||
just use one term. Otherwise, the update order can be hard to
|
||||
understand.
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- value
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
description: Type indicates the type of the CloneSetUpdateStrategy.
|
||||
Default is ReCreate.
|
||||
type: string
|
||||
type: object
|
||||
volumeClaimTemplates:
|
||||
description: VolumeClaimTemplates is a list of claims that pods are
|
||||
allowed to reference. Note that PVC will be deleted when its pod has
|
||||
been deleted.
|
||||
items:
|
||||
description: PersistentVolumeClaim is a user's request for and claim
|
||||
to a persistent volume
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- selector
|
||||
- template
|
||||
type: object
|
||||
status:
|
||||
description: CloneSetStatus defines the observed state of CloneSet
|
||||
properties:
|
||||
availableReplicas:
|
||||
description: AvailableReplicas is the number of Pods created by the
|
||||
CloneSet controller that have a Ready Condition for at least minReadySeconds.
|
||||
format: int32
|
||||
type: integer
|
||||
collisionCount:
|
||||
description: CollisionCount is the count of hash collisions for the
|
||||
CloneSet. The CloneSet controller uses this field as a collision avoidance
|
||||
mechanism when it needs to create the name for the newest ControllerRevision.
|
||||
format: int32
|
||||
type: integer
|
||||
conditions:
|
||||
description: Conditions represents the latest available observations
|
||||
of a CloneSet's current state.
|
||||
items:
|
||||
description: CloneSetCondition describes the state of a CloneSet at
|
||||
a certain point.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: Last time the condition transitioned from one status
|
||||
to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A human readable message indicating details about
|
||||
the transition.
|
||||
type: string
|
||||
reason:
|
||||
description: The reason for the condition's last transition.
|
||||
type: string
|
||||
status:
|
||||
description: Status of the condition, one of True, False, Unknown.
|
||||
type: string
|
||||
type:
|
||||
description: Type of CloneSet condition.
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
labelSelector:
|
||||
description: LabelSelector is label selectors for query over pods that
|
||||
should match the replica count used by HPA.
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: ObservedGeneration is the most recent generation observed
|
||||
for this CloneSet. It corresponds to the CloneSet's generation, which
|
||||
is updated on mutation by the API Server.
|
||||
format: int64
|
||||
type: integer
|
||||
readyReplicas:
|
||||
description: ReadyReplicas is the number of Pods created by the CloneSet
|
||||
controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
replicas:
|
||||
description: Replicas is the number of Pods created by the CloneSet
|
||||
controller.
|
||||
format: int32
|
||||
type: integer
|
||||
updateRevision:
|
||||
description: UpdateRevision, if not empty, indicates the latest revision
|
||||
of the CloneSet.
|
||||
type: string
|
||||
updatedReadyReplicas:
|
||||
description: UpdatedReadyReplicas is the number of Pods created by the
|
||||
CloneSet controller from the CloneSet version indicated by updateRevision
|
||||
and have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
updatedReplicas:
|
||||
description: UpdatedReplicas is the number of Pods created by the CloneSet
|
||||
controller from the CloneSet version indicated by updateRevision.
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- availableReplicas
|
||||
- readyReplicas
|
||||
- replicas
|
||||
- updatedReadyReplicas
|
||||
- updatedReplicas
|
||||
type: object
|
||||
type: object
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
|
@ -0,0 +1,353 @@
|
|||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.9
|
||||
creationTimestamp: null
|
||||
name: daemonsets.apps.kruise.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .status.desiredNumberScheduled
|
||||
description: The desired number of pods.
|
||||
name: DesiredNumber
|
||||
type: integer
|
||||
- JSONPath: .status.currentNumberScheduled
|
||||
description: The current number of pods.
|
||||
name: CurrentNumber
|
||||
type: integer
|
||||
- JSONPath: .status.updatedNumberScheduled
|
||||
description: The updated number of pods.
|
||||
name: UpdatedNumberScheduled
|
||||
type: integer
|
||||
- JSONPath: .metadata.creationTimestamp
|
||||
description: CreationTimestamp is a timestamp representing the server time when
|
||||
this object was created. It is not guaranteed to be set in happens-before order
|
||||
across separate operations. Clients may not set this value. It is represented
|
||||
in RFC3339 form and is in UTC.
|
||||
name: AGE
|
||||
type: date
|
||||
group: apps.kruise.io
|
||||
names:
|
||||
kind: DaemonSet
|
||||
listKind: DaemonSetList
|
||||
plural: daemonsets
|
||||
shortNames:
|
||||
- daemon
|
||||
singular: daemonset
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: DaemonSet is the Schema for the daemonsets API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: DaemonSetSpec defines the desired state of DaemonSet
|
||||
properties:
|
||||
burstReplicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: BurstReplicas is a rate limiter for booting pods on a lot
|
||||
of pods. The default value is 250
|
||||
x-kubernetes-int-or-string: true
|
||||
minReadySeconds:
|
||||
description: The minimum number of seconds for which a newly created
|
||||
DaemonSet pod should be ready without any of its container crashing,
|
||||
for it to be considered available. Defaults to 0 (pod will be considered
|
||||
available as soon as it is ready).
|
||||
format: int32
|
||||
type: integer
|
||||
revisionHistoryLimit:
|
||||
description: The number of old history to retain to allow rollback.
|
||||
This is a pointer to distinguish between explicit zero and not specified.
|
||||
Defaults to 10.
|
||||
format: int32
|
||||
type: integer
|
||||
selector:
|
||||
description: 'A label query over pods that are managed by the daemon
|
||||
set. Must match in order to be controlled. It must match the pod template''s
|
||||
labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors'
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains
|
||||
values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a
|
||||
set of values. Valid operators are In, NotIn, Exists and
|
||||
DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator
|
||||
is In or NotIn, the values array must be non-empty. If the
|
||||
operator is Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator is
|
||||
"In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
template:
|
||||
description: 'An object that describes the pod that will be created.
|
||||
The DaemonSet will create exactly one copy of this pod on every node
|
||||
that matches the template''s node selector (or on every node if no
|
||||
node selector is specified). More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template'
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: An update strategy to replace existing DaemonSet pods with
|
||||
new pods.
|
||||
properties:
|
||||
rollingUpdate:
|
||||
description: Rolling update config params. Present only if type
|
||||
= "RollingUpdate".
|
||||
properties:
|
||||
maxSurge:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'Only when type=SurgingRollingUpdateType, it works.
|
||||
The maximum number of DaemonSet pods that can be scheduled
|
||||
above the desired number of pods during the update. Value
|
||||
can be an absolute number (ex: 5) or a percentage of the total
|
||||
number of DaemonSet pods at the start of the update (ex: 10%).
|
||||
The absolute number is calculated from the percentage by rounding
|
||||
up. This cannot be 0. The default value is 1. Example: when
|
||||
this is set to 30%, at most 30% of the total number of nodes
|
||||
that should be running the daemon pod (i.e. status.desiredNumberScheduled)
|
||||
can have 2 pods running at any given time. The update starts
|
||||
by starting replacements for at most 30% of those DaemonSet
|
||||
pods. Once the new pods are available it then stops the existing
|
||||
pods before proceeding onto other DaemonSet pods, thus ensuring
|
||||
that at most 130% of the desired final number of DaemonSet pods
|
||||
are running at all times during the update.'
|
||||
x-kubernetes-int-or-string: true
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'The maximum number of DaemonSet pods that can
|
||||
be unavailable during the update. Value can be an absolute
|
||||
number (ex: 5) or a percentage of total number of DaemonSet
|
||||
pods at the start of the update (ex: 10%). Absolute number
|
||||
is calculated from percentage by rounding up. This cannot
|
||||
be 0. Default value is 1. Example: when this is set to 30%,
|
||||
at most 30% of the total number of nodes that should be running
|
||||
the daemon pod (i.e. status.desiredNumberScheduled) can have
|
||||
their pods stopped for an update at any given time. The update
|
||||
starts by stopping at most 30% of those DaemonSet pods and
|
||||
then brings up new DaemonSet pods in their place. Once the
|
||||
new pods are available, it then proceeds onto other DaemonSet
|
||||
pods, thus ensuring that at least 70% of original number of
|
||||
DaemonSet pods are available at all times during the update.'
|
||||
x-kubernetes-int-or-string: true
|
||||
partition:
|
||||
description: The number of DaemonSet pods remained to be old
|
||||
version. Default value is 0. Maximum value is status.DesiredNumberScheduled,
|
||||
which means no pod will be updated.
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Indicates that the daemon set is paused and will
|
||||
not be processed by the daemon set controller.
|
||||
type: boolean
|
||||
rollingUpdateType:
|
||||
description: Type is to specify which kind of rollingUpdate.
|
||||
type: string
|
||||
selector:
|
||||
description: A label query over nodes that are managed by the
|
||||
daemon set RollingUpdate. Must match in order to be controlled.
|
||||
It must match the node's labels.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty. This
|
||||
array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
type:
|
||||
description: Type of daemon set update. Can be "RollingUpdate" or
|
||||
"OnDelete". Default is RollingUpdate.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- selector
|
||||
- template
|
||||
type: object
|
||||
status:
|
||||
description: DaemonSetStatus defines the observed state of DaemonSet
|
||||
properties:
|
||||
collisionCount:
|
||||
description: Count of hash collisions for the DaemonSet. The DaemonSet
|
||||
controller uses this field as a collision avoidance mechanism when
|
||||
it needs to create the name for the newest ControllerRevision.
|
||||
format: int32
|
||||
type: integer
|
||||
conditions:
|
||||
description: Represents the latest available observations of a DaemonSet's
|
||||
current state.
|
||||
items:
|
||||
description: DaemonSetCondition describes the state of a DaemonSet
|
||||
at a certain point.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: Last time the condition transitioned from one status
|
||||
to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A human readable message indicating details about
|
||||
the transition.
|
||||
type: string
|
||||
reason:
|
||||
description: The reason for the condition's last transition.
|
||||
type: string
|
||||
status:
|
||||
description: Status of the condition, one of True, False, Unknown.
|
||||
type: string
|
||||
type:
|
||||
description: Type of DaemonSet condition.
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
currentNumberScheduled:
|
||||
description: 'The number of nodes that are running at least 1 daemon
|
||||
pod and are supposed to run the daemon pod. More info: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/'
|
||||
format: int32
|
||||
type: integer
|
||||
daemonSetHash:
|
||||
description: DaemonSetHash is the controller-revision-hash, which represents
|
||||
the latest version of the DaemonSet.
|
||||
type: string
|
||||
desiredNumberScheduled:
|
||||
description: 'The total number of nodes that should be running the daemon
|
||||
pod (including nodes correctly running the daemon pod). More info:
|
||||
https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/'
|
||||
format: int32
|
||||
type: integer
|
||||
numberAvailable:
|
||||
description: The number of nodes that should be running the daemon pod
|
||||
and have one or more of the daemon pod running and available (ready
|
||||
for at least spec.minReadySeconds)
|
||||
format: int32
|
||||
type: integer
|
||||
numberMisscheduled:
|
||||
description: 'The number of nodes that are running the daemon pod, but
|
||||
are not supposed to run the daemon pod. More info: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/'
|
||||
format: int32
|
||||
type: integer
|
||||
numberReady:
|
||||
description: The number of nodes that should be running the daemon pod
|
||||
and have one or more of the daemon pod running and ready.
|
||||
format: int32
|
||||
type: integer
|
||||
numberUnavailable:
|
||||
description: The number of nodes that should be running the daemon pod
|
||||
and have none of the daemon pod running and available (ready for at
|
||||
least spec.minReadySeconds)
|
||||
format: int32
|
||||
type: integer
|
||||
observedGeneration:
|
||||
description: The most recent generation observed by the daemon set controller.
|
||||
format: int64
|
||||
type: integer
|
||||
updatedNumberScheduled:
|
||||
description: The total number of nodes that are running updated daemon
|
||||
pod
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentNumberScheduled
|
||||
- daemonSetHash
|
||||
- desiredNumberScheduled
|
||||
- numberMisscheduled
|
||||
- numberReady
|
||||
- updatedNumberScheduled
|
||||
type: object
|
||||
type: object
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.9
|
||||
creationTimestamp: null
|
||||
name: sidecarsets.apps.kruise.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .status.matchedPods
|
||||
description: The number of pods matched.
|
||||
name: MATCHED
|
||||
type: integer
|
||||
- JSONPath: .status.updatedPods
|
||||
description: The number of pods matched and updated.
|
||||
name: UPDATED
|
||||
type: integer
|
||||
- JSONPath: .status.readyPods
|
||||
description: The number of pods matched and ready.
|
||||
name: READY
|
||||
type: integer
|
||||
- JSONPath: .metadata.creationTimestamp
|
||||
description: CreationTimestamp is a timestamp representing the server time when
|
||||
this object was created. It is not guaranteed to be set in happens-before order
|
||||
across separate operations. Clients may not set this value. It is represented
|
||||
in RFC3339 form and is in UTC.
|
||||
name: AGE
|
||||
type: date
|
||||
group: apps.kruise.io
|
||||
names:
|
||||
kind: SidecarSet
|
||||
listKind: SidecarSetList
|
||||
plural: sidecarsets
|
||||
singular: sidecarset
|
||||
scope: Cluster
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: SidecarSet is the Schema for the sidecarsets API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: SidecarSetSpec defines the desired state of SidecarSet
|
||||
properties:
|
||||
containers:
|
||||
description: Containers is the list of sidecar containers to be injected
|
||||
into the selected pod
|
||||
items:
|
||||
description: SidecarContainer defines the container of Sidecar
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
initContainers:
|
||||
description: Containers is the list of init containers to be injected
|
||||
into the selected pod We will inject those containers by their name
|
||||
in ascending order We only inject init containers when a new pod is
|
||||
created, it does not apply to any existing pod
|
||||
items:
|
||||
description: SidecarContainer defines the container of Sidecar
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
paused:
|
||||
description: Paused indicates that the sidecarset is paused and will
|
||||
not be processed by the sidecarset controller.
|
||||
type: boolean
|
||||
selector:
|
||||
description: selector is a label query over pods that should be injected
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains
|
||||
values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a
|
||||
set of values. Valid operators are In, NotIn, Exists and
|
||||
DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator
|
||||
is In or NotIn, the values array must be non-empty. If the
|
||||
operator is Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator is
|
||||
"In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
strategy:
|
||||
description: The sidecarset strategy to use to replace existing pods
|
||||
with new ones.
|
||||
properties:
|
||||
rollingUpdate:
|
||||
description: RollingUpdateSidecarSet is used to communicate parameter
|
||||
properties:
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
x-kubernetes-int-or-string: true
|
||||
type: object
|
||||
type: object
|
||||
volumes:
|
||||
description: List of volumes that can be mounted by sidecar containers
|
||||
items:
|
||||
description: Volume represents a named volume in a pod that may be
|
||||
accessed by any container in the pod.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
type: object
|
||||
status:
|
||||
description: SidecarSetStatus defines the observed state of SidecarSet
|
||||
properties:
|
||||
matchedPods:
|
||||
description: matchedPods is the number of Pods whose labels are matched
|
||||
with this SidecarSet's selector and are created after sidecarset creates
|
||||
format: int32
|
||||
type: integer
|
||||
observedGeneration:
|
||||
description: observedGeneration is the most recent generation observed
|
||||
for this SidecarSet. It corresponds to the SidecarSet's generation,
|
||||
which is updated on mutation by the API Server.
|
||||
format: int64
|
||||
type: integer
|
||||
readyPods:
|
||||
description: readyPods is the number of matched Pods that have a ready
|
||||
condition
|
||||
format: int32
|
||||
type: integer
|
||||
updatedPods:
|
||||
description: updatedPods is the number of matched Pods that are injected
|
||||
with the latest SidecarSet's containers
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- matchedPods
|
||||
- readyPods
|
||||
- updatedPods
|
||||
type: object
|
||||
type: object
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
|
@ -0,0 +1,433 @@
|
|||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.9
|
||||
creationTimestamp: null
|
||||
name: statefulsets.apps.kruise.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .spec.replicas
|
||||
description: The desired number of pods.
|
||||
name: DESIRED
|
||||
type: integer
|
||||
- JSONPath: .status.replicas
|
||||
description: The number of currently all pods.
|
||||
name: CURRENT
|
||||
type: integer
|
||||
- JSONPath: .status.updatedReplicas
|
||||
description: The number of pods updated.
|
||||
name: UPDATED
|
||||
type: integer
|
||||
- JSONPath: .status.readyReplicas
|
||||
description: The number of pods ready.
|
||||
name: READY
|
||||
type: integer
|
||||
- JSONPath: .metadata.creationTimestamp
|
||||
description: CreationTimestamp is a timestamp representing the server time when
|
||||
this object was created. It is not guaranteed to be set in happens-before order
|
||||
across separate operations. Clients may not set this value. It is represented
|
||||
in RFC3339 form and is in UTC.
|
||||
name: AGE
|
||||
type: date
|
||||
group: apps.kruise.io
|
||||
names:
|
||||
kind: StatefulSet
|
||||
listKind: StatefulSetList
|
||||
plural: statefulsets
|
||||
shortNames:
|
||||
- sts
|
||||
- asts
|
||||
singular: statefulset
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
scale:
|
||||
labelSelectorPath: .status.labelSelector
|
||||
specReplicasPath: .spec.replicas
|
||||
statusReplicasPath: .status.replicas
|
||||
status: {}
|
||||
conversion:
|
||||
strategy: Webhook
|
||||
webhookClientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
namespace: kruise-system
|
||||
name: kruise-webhook-service
|
||||
path: /convert
|
||||
preserveUnknownFields: false
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: StatefulSet is the Schema for the statefulsets API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: StatefulSetSpec defines the desired state of StatefulSet
|
||||
properties:
|
||||
podManagementPolicy:
|
||||
description: podManagementPolicy controls how pods are created during
|
||||
initial scale up, when replacing pods on nodes, or when scaling down.
|
||||
The default policy is `OrderedReady`, where pods are created in increasing
|
||||
order (pod-0, then pod-1, etc) and the controller will wait until
|
||||
each pod is ready before continuing. When scaling down, the pods are
|
||||
removed in the opposite order. The alternative policy is `Parallel`
|
||||
which will create pods in parallel to match the desired scale without
|
||||
waiting, and on scale down will delete all pods at once.
|
||||
type: string
|
||||
replicas:
|
||||
description: 'replicas is the desired number of replicas of the given
|
||||
Template. These are replicas in the sense that they are instantiations
|
||||
of the same Template, but individual replicas also have a consistent
|
||||
identity. If unspecified, defaults to 1. TODO: Consider a rename of
|
||||
this field.'
|
||||
format: int32
|
||||
type: integer
|
||||
revisionHistoryLimit:
|
||||
description: revisionHistoryLimit is the maximum number of revisions
|
||||
that will be maintained in the StatefulSet's revision history. The
|
||||
revision history consists of all revisions not represented by a currently
|
||||
applied StatefulSetSpec version. The default value is 10.
|
||||
format: int32
|
||||
type: integer
|
||||
selector:
|
||||
description: 'selector is a label query over pods that should match
|
||||
the replica count. It must match the pod template''s labels. More
|
||||
info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors'
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains
|
||||
values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a
|
||||
set of values. Valid operators are In, NotIn, Exists and
|
||||
DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator
|
||||
is In or NotIn, the values array must be non-empty. If the
|
||||
operator is Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator is
|
||||
"In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
serviceName:
|
||||
description: 'serviceName is the name of the service that governs this
|
||||
StatefulSet. This service must exist before the StatefulSet, and is
|
||||
responsible for the network identity of the set. Pods get DNS/hostnames
|
||||
that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local
|
||||
where "pod-specific-string" is managed by the StatefulSet controller.'
|
||||
type: string
|
||||
template:
|
||||
description: template is the object that describes the pod that will
|
||||
be created if insufficient replicas are detected. Each pod stamped
|
||||
out by the StatefulSet will fulfill this Template, but have a unique
|
||||
identity from the rest of the StatefulSet.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: updateStrategy indicates the StatefulSetUpdateStrategy
|
||||
that will be employed to update Pods in the StatefulSet when a revision
|
||||
is made to Template.
|
||||
properties:
|
||||
rollingUpdate:
|
||||
description: RollingUpdate is used to communicate parameters when
|
||||
Type is RollingUpdateStatefulSetStrategyType.
|
||||
properties:
|
||||
inPlaceUpdateStrategy:
|
||||
description: InPlaceUpdateStrategy contains strategies for in-place
|
||||
update.
|
||||
properties:
|
||||
gracePeriodSeconds:
|
||||
description: GracePeriodSeconds is the timespan between
|
||||
set Pod status to not-ready and update images in Pod spec
|
||||
when in-place update a Pod.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'The maximum number of pods that can be unavailable
|
||||
during the update. Value can be an absolute number (ex: 5)
|
||||
or a percentage of desired pods (ex: 10%). Absolute number
|
||||
is calculated from percentage by rounding down. Also, maxUnavailable
|
||||
can just be allowed to work with Parallel podManagementPolicy.
|
||||
Defaults to 1.'
|
||||
x-kubernetes-int-or-string: true
|
||||
minReadySeconds:
|
||||
description: MinReadySeconds indicates how long will the pod
|
||||
be considered ready after it's updated. MinReadySeconds works
|
||||
with both OrderedReady and Parallel podManagementPolicy. It
|
||||
affects the pod scale up speed when the podManagementPolicy
|
||||
is set to be OrderedReady. Combined with MaxUnavailable, it
|
||||
affects the pod update speed regardless of podManagementPolicy.
|
||||
Default value is 0, max is 300.
|
||||
format: int32
|
||||
type: integer
|
||||
partition:
|
||||
description: 'Partition indicates the ordinal at which the StatefulSet
|
||||
should be partitioned by default. But if unorderedUpdate has
|
||||
been set: - Partition indicates the number of pods with
|
||||
non-updated revisions when rolling update. - It means controller
|
||||
will update $(replicas - partition) number of pod. Default
|
||||
value is 0.'
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused indicates that the StatefulSet is paused.
|
||||
Default value is false
|
||||
type: boolean
|
||||
podUpdatePolicy:
|
||||
description: PodUpdatePolicy indicates how pods should be updated
|
||||
Default value is "ReCreate"
|
||||
type: string
|
||||
unorderedUpdate:
|
||||
description: UnorderedUpdate contains strategies for non-ordered
|
||||
update. If it is not nil, pods will be updated with non-ordered
|
||||
sequence. Noted that UnorderedUpdate can only be allowed to
|
||||
work with Parallel podManagementPolicy
|
||||
properties:
|
||||
priorityStrategy:
|
||||
description: Priorities are the rules for calculating the
|
||||
priority of updating pods. Each pod to be updated, will
|
||||
pass through these terms and get a sum of weights.
|
||||
properties:
|
||||
orderPriority:
|
||||
description: 'Order priority terms, pods will be sorted
|
||||
by the value of orderedKey. For example: ``` orderPriority:
|
||||
- orderedKey: key1 - orderedKey: key2 ``` First, all
|
||||
pods which have key1 in labels will be sorted by the
|
||||
value of key1. Then, the left pods which have no key1
|
||||
but have key2 in labels will be sorted by the value
|
||||
of key2 and put behind those pods have key1.'
|
||||
items:
|
||||
description: UpdatePriorityOrder defines order priority.
|
||||
properties:
|
||||
orderedKey:
|
||||
description: Calculate priority by value of this
|
||||
key. Values of this key, will be sorted by GetInt(val).
|
||||
GetInt method will find the last int in value,
|
||||
such as getting 5 in value '5', getting 10 in
|
||||
value 'sts-10'.
|
||||
type: string
|
||||
required:
|
||||
- orderedKey
|
||||
type: object
|
||||
type: array
|
||||
weightPriority:
|
||||
description: Weight priority terms, pods will be sorted
|
||||
by the sum of all terms weight.
|
||||
items:
|
||||
description: UpdatePriorityWeightTerm defines weight
|
||||
priority.
|
||||
properties:
|
||||
matchSelector:
|
||||
description: MatchSelector is used to select by
|
||||
pod's labels.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of
|
||||
label selector requirements. The requirements
|
||||
are ANDed.
|
||||
items:
|
||||
description: A label selector requirement
|
||||
is a selector that contains values, a
|
||||
key, and an operator that relates the
|
||||
key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that
|
||||
the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's
|
||||
relationship to a set of values. Valid
|
||||
operators are In, NotIn, Exists and
|
||||
DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string
|
||||
values. If the operator is In or NotIn,
|
||||
the values array must be non-empty.
|
||||
If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This
|
||||
array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value}
|
||||
pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions,
|
||||
whose key field is "key", the operator is
|
||||
"In", and the values array contains only
|
||||
"value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
weight:
|
||||
description: Weight associated with matching the
|
||||
corresponding matchExpressions, in the range
|
||||
1-100.
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- matchSelector
|
||||
- weight
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
type:
|
||||
description: Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
Default is RollingUpdate.
|
||||
type: string
|
||||
type: object
|
||||
volumeClaimTemplates:
|
||||
description: 'volumeClaimTemplates is a list of claims that pods are
|
||||
allowed to reference. The StatefulSet controller is responsible for
|
||||
mapping network identities to claims in a way that maintains the identity
|
||||
of a pod. Every claim in this list must have at least one matching
|
||||
(by name) volumeMount in one container in the template. A claim in
|
||||
this list takes precedence over any volumes in the template, with
|
||||
the same name. TODO: Define the behavior if a claim already exists
|
||||
with the same name.'
|
||||
items:
|
||||
description: PersistentVolumeClaim is a user's request for and claim
|
||||
to a persistent volume
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- selector
|
||||
- template
|
||||
type: object
|
||||
status:
|
||||
description: StatefulSetStatus defines the observed state of StatefulSet
|
||||
properties:
|
||||
availableReplicas:
|
||||
description: AvailableReplicas is the number of Pods created by the
|
||||
StatefulSet controller that have been ready for minReadySeconds.
|
||||
format: int32
|
||||
type: integer
|
||||
collisionCount:
|
||||
description: collisionCount is the count of hash collisions for the
|
||||
StatefulSet. The StatefulSet controller uses this field as a collision
|
||||
avoidance mechanism when it needs to create the name for the newest
|
||||
ControllerRevision.
|
||||
format: int32
|
||||
type: integer
|
||||
conditions:
|
||||
description: Represents the latest available observations of a statefulset's
|
||||
current state.
|
||||
items:
|
||||
description: StatefulSetCondition describes the state of a statefulset
|
||||
at a certain point.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
currentReplicas:
|
||||
description: currentReplicas is the number of Pods created by the StatefulSet
|
||||
controller from the StatefulSet version indicated by currentRevision.
|
||||
format: int32
|
||||
type: integer
|
||||
currentRevision:
|
||||
description: currentRevision, if not empty, indicates the version of
|
||||
the StatefulSet used to generate Pods in the sequence [0,currentReplicas).
|
||||
type: string
|
||||
labelSelector:
|
||||
description: LabelSelector is label selectors for query over pods that
|
||||
should match the replica count used by HPA.
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: observedGeneration is the most recent generation observed
|
||||
for this StatefulSet. It corresponds to the StatefulSet's generation,
|
||||
which is updated on mutation by the API Server.
|
||||
format: int64
|
||||
type: integer
|
||||
readyReplicas:
|
||||
description: readyReplicas is the number of Pods created by the StatefulSet
|
||||
controller that have a Ready Condition.
|
||||
format: int32
|
||||
type: integer
|
||||
replicas:
|
||||
description: replicas is the number of Pods created by the StatefulSet
|
||||
controller.
|
||||
format: int32
|
||||
type: integer
|
||||
updateRevision:
|
||||
description: updateRevision, if not empty, indicates the version of
|
||||
the StatefulSet used to generate Pods in the sequence [replicas-updatedReplicas,replicas)
|
||||
type: string
|
||||
updatedReplicas:
|
||||
description: updatedReplicas is the number of Pods created by the StatefulSet
|
||||
controller from the StatefulSet version indicated by updateRevision.
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- availableReplicas
|
||||
- currentReplicas
|
||||
- readyReplicas
|
||||
- replicas
|
||||
- updatedReplicas
|
||||
type: object
|
||||
type: object
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: false
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
|
@ -0,0 +1,949 @@
|
|||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.9
|
||||
creationTimestamp: null
|
||||
name: uniteddeployments.apps.kruise.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .spec.replicas
|
||||
description: The desired number of pods.
|
||||
name: DESIRED
|
||||
type: integer
|
||||
- JSONPath: .status.replicas
|
||||
description: The number of currently all pods.
|
||||
name: CURRENT
|
||||
type: integer
|
||||
- JSONPath: .status.updatedReplicas
|
||||
description: The number of pods updated.
|
||||
name: UPDATED
|
||||
type: integer
|
||||
- JSONPath: .status.readyReplicas
|
||||
description: The number of pods ready.
|
||||
name: READY
|
||||
type: integer
|
||||
- JSONPath: .metadata.creationTimestamp
|
||||
description: CreationTimestamp is a timestamp representing the server time when
|
||||
this object was created. It is not guaranteed to be set in happens-before order
|
||||
across separate operations. Clients may not set this value. It is represented
|
||||
in RFC3339 form and is in UTC.
|
||||
name: AGE
|
||||
type: date
|
||||
group: apps.kruise.io
|
||||
names:
|
||||
kind: UnitedDeployment
|
||||
listKind: UnitedDeploymentList
|
||||
plural: uniteddeployments
|
||||
shortNames:
|
||||
- ud
|
||||
singular: uniteddeployment
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
scale:
|
||||
labelSelectorPath: .status.selector
|
||||
specReplicasPath: .spec.replicas
|
||||
statusReplicasPath: .status.replicas
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: UnitedDeployment is the Schema for the uniteddeployments API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
of an object. Servers should convert recognized schemas to the latest
|
||||
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this
|
||||
object represents. Servers may infer this from the endpoint the client
|
||||
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: UnitedDeploymentSpec defines the desired state of UnitedDeployment.
|
||||
properties:
|
||||
replicas:
|
||||
description: Replicas is the total desired replicas of all the subsets.
|
||||
If unspecified, defaults to 1.
|
||||
format: int32
|
||||
type: integer
|
||||
revisionHistoryLimit:
|
||||
description: Indicates the number of histories to be conserved. If unspecified,
|
||||
defaults to 10.
|
||||
format: int32
|
||||
type: integer
|
||||
selector:
|
||||
description: Selector is a label query over pods that should match the
|
||||
replica count. It must match the pod template's labels.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains
|
||||
values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a
|
||||
set of values. Valid operators are In, NotIn, Exists and
|
||||
DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator
|
||||
is In or NotIn, the values array must be non-empty. If the
|
||||
operator is Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator is
|
||||
"In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
template:
|
||||
description: Template describes the subset that will be created.
|
||||
properties:
|
||||
advancedStatefulSetTemplate:
|
||||
description: AdvancedStatefulSet template
|
||||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
spec:
|
||||
description: StatefulSetSpec defines the desired state of StatefulSet
|
||||
properties:
|
||||
podManagementPolicy:
|
||||
description: podManagementPolicy controls how pods are created
|
||||
during initial scale up, when replacing pods on nodes,
|
||||
or when scaling down. The default policy is `OrderedReady`,
|
||||
where pods are created in increasing order (pod-0, then
|
||||
pod-1, etc) and the controller will wait until each pod
|
||||
is ready before continuing. When scaling down, the pods
|
||||
are removed in the opposite order. The alternative policy
|
||||
is `Parallel` which will create pods in parallel to match
|
||||
the desired scale without waiting, and on scale down will
|
||||
delete all pods at once.
|
||||
type: string
|
||||
replicas:
|
||||
description: 'replicas is the desired number of replicas
|
||||
of the given Template. These are replicas in the sense
|
||||
that they are instantiations of the same Template, but
|
||||
individual replicas also have a consistent identity. If
|
||||
unspecified, defaults to 1. TODO: Consider a rename of
|
||||
this field.'
|
||||
format: int32
|
||||
type: integer
|
||||
revisionHistoryLimit:
|
||||
description: revisionHistoryLimit is the maximum number
|
||||
of revisions that will be maintained in the StatefulSet's
|
||||
revision history. The revision history consists of all
|
||||
revisions not represented by a currently applied StatefulSetSpec
|
||||
version. The default value is 10.
|
||||
format: int32
|
||||
type: integer
|
||||
selector:
|
||||
description: 'selector is a label query over pods that should
|
||||
match the replica count. It must match the pod template''s
|
||||
labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors'
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In,
|
||||
NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists
|
||||
or DoesNotExist, the values array must be empty.
|
||||
This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field
|
||||
is "key", the operator is "In", and the values array
|
||||
contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
serviceName:
|
||||
description: 'serviceName is the name of the service that
|
||||
governs this StatefulSet. This service must exist before
|
||||
the StatefulSet, and is responsible for the network identity
|
||||
of the set. Pods get DNS/hostnames that follow the pattern:
|
||||
pod-specific-string.serviceName.default.svc.cluster.local
|
||||
where "pod-specific-string" is managed by the StatefulSet
|
||||
controller.'
|
||||
type: string
|
||||
template:
|
||||
description: template is the object that describes the pod
|
||||
that will be created if insufficient replicas are detected.
|
||||
Each pod stamped out by the StatefulSet will fulfill this
|
||||
Template, but have a unique identity from the rest of
|
||||
the StatefulSet.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: updateStrategy indicates the StatefulSetUpdateStrategy
|
||||
that will be employed to update Pods in the StatefulSet
|
||||
when a revision is made to Template.
|
||||
properties:
|
||||
rollingUpdate:
|
||||
description: RollingUpdate is used to communicate parameters
|
||||
when Type is RollingUpdateStatefulSetStrategyType.
|
||||
properties:
|
||||
inPlaceUpdateStrategy:
|
||||
description: InPlaceUpdateStrategy contains strategies
|
||||
for in-place update.
|
||||
properties:
|
||||
gracePeriodSeconds:
|
||||
description: GracePeriodSeconds is the timespan
|
||||
between set Pod status to not-ready and update
|
||||
images in Pod spec when in-place update a
|
||||
Pod.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'The maximum number of pods that can
|
||||
be unavailable during the update. Value can be
|
||||
an absolute number (ex: 5) or a percentage of
|
||||
desired pods (ex: 10%). Absolute number is calculated
|
||||
from percentage by rounding down. Also, maxUnavailable
|
||||
can just be allowed to work with Parallel podManagementPolicy.
|
||||
Defaults to 1.'
|
||||
x-kubernetes-int-or-string: true
|
||||
minReadySeconds:
|
||||
description: MinReadySeconds indicates how long
|
||||
will the pod be considered ready after it's updated.
|
||||
MinReadySeconds works with both OrderedReady and
|
||||
Parallel podManagementPolicy. It affects the pod
|
||||
scale up speed when the podManagementPolicy is
|
||||
set to be OrderedReady. Combined with MaxUnavailable,
|
||||
it affects the pod update speed regardless of
|
||||
podManagementPolicy. Default value is 0, max is
|
||||
300.
|
||||
format: int32
|
||||
type: integer
|
||||
partition:
|
||||
description: 'Partition indicates the ordinal at
|
||||
which the StatefulSet should be partitioned by
|
||||
default. But if unorderedUpdate has been set: -
|
||||
Partition indicates the number of pods with non-updated
|
||||
revisions when rolling update. - It means controller
|
||||
will update $(replicas - partition) number of
|
||||
pod. Default value is 0.'
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused indicates that the StatefulSet
|
||||
is paused. Default value is false
|
||||
type: boolean
|
||||
podUpdatePolicy:
|
||||
description: PodUpdatePolicy indicates how pods
|
||||
should be updated Default value is "ReCreate"
|
||||
type: string
|
||||
unorderedUpdate:
|
||||
description: UnorderedUpdate contains strategies
|
||||
for non-ordered update. If it is not nil, pods
|
||||
will be updated with non-ordered sequence. Noted
|
||||
that UnorderedUpdate can only be allowed to work
|
||||
with Parallel podManagementPolicy
|
||||
properties:
|
||||
priorityStrategy:
|
||||
description: Priorities are the rules for calculating
|
||||
the priority of updating pods. Each pod to
|
||||
be updated, will pass through these terms
|
||||
and get a sum of weights.
|
||||
properties:
|
||||
orderPriority:
|
||||
description: 'Order priority terms, pods
|
||||
will be sorted by the value of orderedKey.
|
||||
For example: ``` orderPriority: - orderedKey:
|
||||
key1 - orderedKey: key2 ``` First, all
|
||||
pods which have key1 in labels will be
|
||||
sorted by the value of key1. Then, the
|
||||
left pods which have no key1 but have
|
||||
key2 in labels will be sorted by the value
|
||||
of key2 and put behind those pods have
|
||||
key1.'
|
||||
items:
|
||||
description: UpdatePriorityOrder defines
|
||||
order priority.
|
||||
properties:
|
||||
orderedKey:
|
||||
description: Calculate priority by
|
||||
value of this key. Values of this
|
||||
key, will be sorted by GetInt(val).
|
||||
GetInt method will find the last
|
||||
int in value, such as getting 5
|
||||
in value '5', getting 10 in value
|
||||
'sts-10'.
|
||||
type: string
|
||||
required:
|
||||
- orderedKey
|
||||
type: object
|
||||
type: array
|
||||
weightPriority:
|
||||
description: Weight priority terms, pods
|
||||
will be sorted by the sum of all terms
|
||||
weight.
|
||||
items:
|
||||
description: UpdatePriorityWeightTerm
|
||||
defines weight priority.
|
||||
properties:
|
||||
matchSelector:
|
||||
description: MatchSelector is used
|
||||
to select by pod's labels.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions
|
||||
is a list of label selector
|
||||
requirements. The requirements
|
||||
are ANDed.
|
||||
items:
|
||||
description: A label selector
|
||||
requirement is a selector
|
||||
that contains values, a key,
|
||||
and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the
|
||||
label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents
|
||||
a key's relationship to
|
||||
a set of values. Valid
|
||||
operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an
|
||||
array of string values.
|
||||
If the operator is In
|
||||
or NotIn, the values array
|
||||
must be non-empty. If
|
||||
the operator is Exists
|
||||
or DoesNotExist, the values
|
||||
array must be empty. This
|
||||
array is replaced during
|
||||
a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a
|
||||
map of {key,value} pairs. A
|
||||
single {key,value} in the matchLabels
|
||||
map is equivalent to an element
|
||||
of matchExpressions, whose key
|
||||
field is "key", the operator
|
||||
is "In", and the values array
|
||||
contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
weight:
|
||||
description: Weight associated with
|
||||
matching the corresponding matchExpressions,
|
||||
in the range 1-100.
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- matchSelector
|
||||
- weight
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
type:
|
||||
description: Type indicates the type of the StatefulSetUpdateStrategy.
|
||||
Default is RollingUpdate.
|
||||
type: string
|
||||
type: object
|
||||
volumeClaimTemplates:
|
||||
description: 'volumeClaimTemplates is a list of claims that
|
||||
pods are allowed to reference. The StatefulSet controller
|
||||
is responsible for mapping network identities to claims
|
||||
in a way that maintains the identity of a pod. Every claim
|
||||
in this list must have at least one matching (by name)
|
||||
volumeMount in one container in the template. A claim
|
||||
in this list takes precedence over any volumes in the
|
||||
template, with the same name. TODO: Define the behavior
|
||||
if a claim already exists with the same name.'
|
||||
items:
|
||||
description: PersistentVolumeClaim is a user's request
|
||||
for and claim to a persistent volume
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- selector
|
||||
- template
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
cloneSetTemplate:
|
||||
description: CloneSet template
|
||||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
spec:
|
||||
description: CloneSetSpec defines the desired state of CloneSet
|
||||
properties:
|
||||
lifecycle:
|
||||
description: Lifecycle defines the lifecycle hooks for Pods
|
||||
pre-delete, in-place update.
|
||||
properties:
|
||||
inPlaceUpdate:
|
||||
description: InPlaceUpdate is the hook before Pod to
|
||||
update and after Pod has been updated.
|
||||
properties:
|
||||
finalizersHandler:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
labelsHandler:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
preDelete:
|
||||
description: PreDelete is the hook before Pod to be
|
||||
deleted.
|
||||
properties:
|
||||
finalizersHandler:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
labelsHandler:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
minReadySeconds:
|
||||
description: Minimum number of seconds for which a newly
|
||||
created pod should be ready without any of its container
|
||||
crashing, for it to be considered available. Defaults
|
||||
to 0 (pod will be considered available as soon as it is
|
||||
ready)
|
||||
format: int32
|
||||
type: integer
|
||||
replicas:
|
||||
description: Replicas is the desired number of replicas
|
||||
of the given Template. These are replicas in the sense
|
||||
that they are instantiations of the same Template. If
|
||||
unspecified, defaults to 1.
|
||||
format: int32
|
||||
type: integer
|
||||
revisionHistoryLimit:
|
||||
description: RevisionHistoryLimit is the maximum number
|
||||
of revisions that will be maintained in the CloneSet's
|
||||
revision history. The revision history consists of all
|
||||
revisions not represented by a currently applied CloneSetSpec
|
||||
version. The default value is 10.
|
||||
format: int32
|
||||
type: integer
|
||||
scaleStrategy:
|
||||
description: ScaleStrategy indicates the ScaleStrategy that
|
||||
will be employed to create and delete Pods in the CloneSet.
|
||||
properties:
|
||||
podsToDelete:
|
||||
description: PodsToDelete is the names of Pod should
|
||||
be deleted. Note that this list will be truncated
|
||||
for non-existing pod names.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
selector:
|
||||
description: 'Selector is a label query over pods that should
|
||||
match the replica count. It must match the pod template''s
|
||||
labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors'
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In,
|
||||
NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists
|
||||
or DoesNotExist, the values array must be empty.
|
||||
This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field
|
||||
is "key", the operator is "In", and the values array
|
||||
contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
template:
|
||||
description: Template describes the pods that will be created.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: UpdateStrategy indicates the UpdateStrategy
|
||||
that will be employed to update Pods in the CloneSet when
|
||||
a revision is made to Template.
|
||||
properties:
|
||||
inPlaceUpdateStrategy:
|
||||
description: InPlaceUpdateStrategy contains strategies
|
||||
for in-place update.
|
||||
properties:
|
||||
gracePeriodSeconds:
|
||||
description: GracePeriodSeconds is the timespan
|
||||
between set Pod status to not-ready and update
|
||||
images in Pod spec when in-place update a Pod.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
maxSurge:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'The maximum number of pods that can be
|
||||
scheduled above the desired replicas during the update.
|
||||
Value can be an absolute number (ex: 5) or a percentage
|
||||
of desired pods (ex: 10%). Absolute number is calculated
|
||||
from percentage by rounding up. Defaults to 0.'
|
||||
x-kubernetes-int-or-string: true
|
||||
maxUnavailable:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: 'The maximum number of pods that can be
|
||||
unavailable during the update. Value can be an absolute
|
||||
number (ex: 5) or a percentage of desired pods (ex:
|
||||
10%). Absolute number is calculated from percentage
|
||||
by rounding up by default. When maxSurge > 0, absolute
|
||||
number is calculated from percentage by rounding down.
|
||||
Defaults to 20%.'
|
||||
x-kubernetes-int-or-string: true
|
||||
partition:
|
||||
description: Partition is the desired number of pods
|
||||
in old revisions. It means when partition is set during
|
||||
pods updating, (replicas - partition) number of pods
|
||||
will be updated. Default value is 0.
|
||||
format: int32
|
||||
type: integer
|
||||
paused:
|
||||
description: Paused indicates that the CloneSet is paused.
|
||||
Default value is false
|
||||
type: boolean
|
||||
priorityStrategy:
|
||||
description: Priorities are the rules for calculating
|
||||
the priority of updating pods. Each pod to be updated,
|
||||
will pass through these terms and get a sum of weights.
|
||||
properties:
|
||||
orderPriority:
|
||||
description: 'Order priority terms, pods will be
|
||||
sorted by the value of orderedKey. For example:
|
||||
``` orderPriority: - orderedKey: key1 - orderedKey:
|
||||
key2 ``` First, all pods which have key1 in labels
|
||||
will be sorted by the value of key1. Then, the
|
||||
left pods which have no key1 but have key2 in
|
||||
labels will be sorted by the value of key2 and
|
||||
put behind those pods have key1.'
|
||||
items:
|
||||
description: UpdatePriorityOrder defines order
|
||||
priority.
|
||||
properties:
|
||||
orderedKey:
|
||||
description: Calculate priority by value of
|
||||
this key. Values of this key, will be sorted
|
||||
by GetInt(val). GetInt method will find
|
||||
the last int in value, such as getting 5
|
||||
in value '5', getting 10 in value 'sts-10'.
|
||||
type: string
|
||||
required:
|
||||
- orderedKey
|
||||
type: object
|
||||
type: array
|
||||
weightPriority:
|
||||
description: Weight priority terms, pods will be
|
||||
sorted by the sum of all terms weight.
|
||||
items:
|
||||
description: UpdatePriorityWeightTerm defines
|
||||
weight priority.
|
||||
properties:
|
||||
matchSelector:
|
||||
description: MatchSelector is used to select
|
||||
by pod's labels.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list
|
||||
of label selector requirements. The
|
||||
requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement
|
||||
is a selector that contains values,
|
||||
a key, and an operator that relates
|
||||
the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key
|
||||
that the selector applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents
|
||||
a key's relationship to a set
|
||||
of values. Valid operators are
|
||||
In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array
|
||||
of string values. If the operator
|
||||
is In or NotIn, the values array
|
||||
must be non-empty. If the operator
|
||||
is Exists or DoesNotExist, the
|
||||
values array must be empty. This
|
||||
array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value}
|
||||
pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions,
|
||||
whose key field is "key", the operator
|
||||
is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
weight:
|
||||
description: Weight associated with matching
|
||||
the corresponding matchExpressions, in the
|
||||
range 1-100.
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- matchSelector
|
||||
- weight
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
scatterStrategy:
|
||||
description: ScatterStrategy defines the scatter rules
|
||||
to make pods been scattered when update. This will
|
||||
avoid pods with the same key-value to be updated in
|
||||
one batch. - Note that pods will be scattered after
|
||||
priority sort. So, although priority strategy and
|
||||
scatter strategy can be applied together, we suggest
|
||||
to use either one of them. - If scatterStrategy is
|
||||
used, we suggest to just use one term. Otherwise,
|
||||
the update order can be hard to understand.
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
required:
|
||||
- key
|
||||
- value
|
||||
type: object
|
||||
type: array
|
||||
type:
|
||||
description: Type indicates the type of the CloneSetUpdateStrategy.
|
||||
Default is ReCreate.
|
||||
type: string
|
||||
type: object
|
||||
volumeClaimTemplates:
|
||||
description: VolumeClaimTemplates is a list of claims that
|
||||
pods are allowed to reference. Note that PVC will be deleted
|
||||
when its pod has been deleted.
|
||||
items:
|
||||
description: PersistentVolumeClaim is a user's request
|
||||
for and claim to a persistent volume
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- selector
|
||||
- template
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
statefulSetTemplate:
|
||||
description: StatefulSet template
|
||||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
spec:
|
||||
description: A StatefulSetSpec is the specification of a StatefulSet.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
type: object
|
||||
topology:
|
||||
description: Topology describes the pods distribution detail between
|
||||
each of subsets.
|
||||
properties:
|
||||
subsets:
|
||||
description: Contains the details of each subset. Each element in
|
||||
this array represents one subset which will be provisioned and
|
||||
managed by UnitedDeployment.
|
||||
items:
|
||||
description: Subset defines the detail of a subset.
|
||||
properties:
|
||||
name:
|
||||
description: Indicates subset name as a DNS_LABEL, which will
|
||||
be used to generate subset workload name prefix in the format
|
||||
'<deployment-name>-<subset-name>-'. Name should be unique
|
||||
between all of the subsets under one UnitedDeployment.
|
||||
type: string
|
||||
nodeSelectorTerm:
|
||||
description: Indicates the node selector to form the subset.
|
||||
Depending on the node selector, pods provisioned could be
|
||||
distributed across multiple groups of nodes. A subset's
|
||||
nodeSelectorTerm is not allowed to be updated.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
description: Indicates the number of the pod to be created
|
||||
under this subset. Replicas could also be percentage like
|
||||
'10%', which means 10% of UnitedDeployment replicas of pods
|
||||
will be distributed under this subset. If nil, the number
|
||||
of replicas in this subset is determined by controller.
|
||||
Controller will try to keep all the subsets with nil replicas
|
||||
have average pods.
|
||||
x-kubernetes-int-or-string: true
|
||||
tolerations:
|
||||
description: Indicates the tolerations the pods under this
|
||||
subset have. A subset's tolerations is not allowed to be
|
||||
updated.
|
||||
items:
|
||||
description: The pod this Toleration is attached to tolerates
|
||||
any taint that matches the triple <key,value,effect> using
|
||||
the matching operator <operator>.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
updateStrategy:
|
||||
description: UpdateStrategy indicates the strategy the UnitedDeployment
|
||||
use to preform the update, when template is changed.
|
||||
properties:
|
||||
manualUpdate:
|
||||
description: Includes all of the parameters a Manual update strategy
|
||||
needs.
|
||||
properties:
|
||||
partitions:
|
||||
additionalProperties:
|
||||
format: int32
|
||||
type: integer
|
||||
description: Indicates number of subset partition.
|
||||
type: object
|
||||
type: object
|
||||
type:
|
||||
description: Type of UnitedDeployment update strategy. Default is
|
||||
Manual.
|
||||
type: string
|
||||
type: object
|
||||
required:
|
||||
- selector
|
||||
type: object
|
||||
status:
|
||||
description: UnitedDeploymentStatus defines the observed state of UnitedDeployment.
|
||||
properties:
|
||||
collisionCount:
|
||||
description: Count of hash collisions for the UnitedDeployment. The
|
||||
UnitedDeployment controller uses this field as a collision avoidance
|
||||
mechanism when it needs to create the name for the newest ControllerRevision.
|
||||
format: int32
|
||||
type: integer
|
||||
conditions:
|
||||
description: Represents the latest available observations of a UnitedDeployment's
|
||||
current state.
|
||||
items:
|
||||
description: UnitedDeploymentCondition describes current state of
|
||||
a UnitedDeployment.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: Last time the condition transitioned from one status
|
||||
to another.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: A human readable message indicating details about
|
||||
the transition.
|
||||
type: string
|
||||
reason:
|
||||
description: The reason for the condition's last transition.
|
||||
type: string
|
||||
status:
|
||||
description: Status of the condition, one of True, False, Unknown.
|
||||
type: string
|
||||
type:
|
||||
description: Type of in place set condition.
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
currentRevision:
|
||||
description: CurrentRevision, if not empty, indicates the current version
|
||||
of the UnitedDeployment.
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: ObservedGeneration is the most recent generation observed
|
||||
for this UnitedDeployment. It corresponds to the UnitedDeployment's
|
||||
generation, which is updated on mutation by the API Server.
|
||||
format: int64
|
||||
type: integer
|
||||
readyReplicas:
|
||||
description: The number of ready replicas.
|
||||
format: int32
|
||||
type: integer
|
||||
replicas:
|
||||
description: Replicas is the most recently observed number of replicas.
|
||||
format: int32
|
||||
type: integer
|
||||
subsetReplicas:
|
||||
additionalProperties:
|
||||
format: int32
|
||||
type: integer
|
||||
description: Records the topology detail information of the replicas
|
||||
of each subset.
|
||||
type: object
|
||||
updateStatus:
|
||||
description: Records the information of update progress.
|
||||
properties:
|
||||
currentPartitions:
|
||||
additionalProperties:
|
||||
format: int32
|
||||
type: integer
|
||||
description: Records the current partition.
|
||||
type: object
|
||||
updatedRevision:
|
||||
description: Records the latest revision.
|
||||
type: string
|
||||
type: object
|
||||
updatedReadyReplicas:
|
||||
description: The number of ready current revision replicas for this
|
||||
UnitedDeployment.
|
||||
format: int32
|
||||
type: integer
|
||||
updatedReplicas:
|
||||
description: The number of pods in current version.
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- currentRevision
|
||||
- replicas
|
||||
- updatedReplicas
|
||||
type: object
|
||||
type: object
|
||||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
name: kruise-system
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
spec:
|
||||
ports:
|
||||
- port: 443
|
||||
targetPort: {{ .Values.manager.webhook.port }}
|
||||
selector:
|
||||
control-plane: controller-manager
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: kruise-webhook-certs
|
||||
namespace: kruise-system
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
name: kruise-controller-manager
|
||||
namespace: kruise-system
|
||||
spec:
|
||||
replicas: {{ .Values.manager.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
control-plane: controller-manager
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
control-plane: controller-manager
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- --enable-leader-election
|
||||
- --metrics-addr={{ .Values.manager.metrics.addr }}:{{ .Values.manager.metrics.port }}
|
||||
- --health-probe-addr=:{{ .Values.manager.healthProbe.port }}
|
||||
- --logtostderr=true
|
||||
- --v={{ .Values.manager.log.level }}
|
||||
{{- if .Values.manager.allowPrivileged }}
|
||||
- --allow-privileged=true
|
||||
{{- end }}
|
||||
command:
|
||||
- /manager
|
||||
image: {{ .Values.manager.image.repository }}:{{.Values.manager.image.tag}}
|
||||
imagePullPolicy: Always
|
||||
name: manager
|
||||
env:
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: WEBHOOK_PORT
|
||||
value: "{{ .Values.manager.webhook.port }}"
|
||||
- name: CUSTOM_RESOURCE_ENABLE
|
||||
value: {{ .Values.manager.custom_resource_enable }}
|
||||
- name: WEBHOOK_CONFIGURATION_FAILURE_POLICY_PODS
|
||||
value: {{ .Values.webhookConfiguration.failurePolicy.pods }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.manager.webhook.port }}
|
||||
name: webhook-server
|
||||
protocol: TCP
|
||||
- containerPort: {{ .Values.manager.metrics.port }}
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
- containerPort: {{ .Values.manager.healthProbe.port }}
|
||||
name: health
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: readyz
|
||||
port: {{ .Values.manager.healthProbe.port }}
|
||||
resources:
|
||||
{{- toYaml .Values.manager.resources | nindent 12 }}
|
||||
terminationGracePeriodSeconds: 10
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: control-plane
|
||||
operator: In
|
||||
values:
|
||||
- controller-manager
|
||||
topologyKey: kubernetes.io/hostname
|
||||
weight: 100
|
||||
{{- with .Values.spec.nodeAffinity }}
|
||||
nodeAffinity:
|
||||
{{ toYaml . | indent 10 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.spec.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{ toYaml .Values.spec.nodeSelector | indent 8 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.spec.tolerations }}
|
||||
tolerations:
|
||||
{{ toYaml .Values.spec.tolerations | indent 8 }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,316 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: kruise-leader-election-role
|
||||
namespace: kruise-system
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps/status
|
||||
verbs:
|
||||
- get
|
||||
- update
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: kruise-manager-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- admissionregistration.k8s.io
|
||||
resources:
|
||||
- mutatingwebhookconfigurations
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- admissionregistration.k8s.io
|
||||
resources:
|
||||
- validatingwebhookconfigurations
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- controllerrevisions
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- statefulsets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- statefulsets/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- broadcastjobs
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- broadcastjobs/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- clonesets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- clonesets/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- daemonsets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- daemonsets/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- sidecarsets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- sidecarsets/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- statefulsets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- statefulsets/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- uniteddeployments
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
resources:
|
||||
- uniteddeployments/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: kruise-leader-election-rolebinding
|
||||
namespace: kruise-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: kruise-leader-election-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: kruise-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: kruise-manager-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: kruise-manager-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: kruise-system
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
apiVersion: admissionregistration.k8s.io/v1beta1
|
||||
kind: MutatingWebhookConfiguration
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: kruise-mutating-webhook-configuration
|
||||
annotations:
|
||||
template: ""
|
||||
webhooks:
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /mutate-apps-kruise-io-v1alpha1-sidecarset
|
||||
failurePolicy: Fail
|
||||
name: msidecarset.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- sidecarsets
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /mutate-pod
|
||||
failurePolicy: {{ .Values.webhookConfiguration.failurePolicy.pods }}
|
||||
name: mpod.kb.io
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: control-plane
|
||||
operator: DoesNotExist
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- v1
|
||||
operations:
|
||||
- CREATE
|
||||
resources:
|
||||
- pods
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /mutate-apps-kruise-io-v1alpha1-broadcastjob
|
||||
failurePolicy: Fail
|
||||
name: mbroadcastjob.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- broadcastjobs
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /mutate-apps-kruise-io-v1alpha1-cloneset
|
||||
failurePolicy: Fail
|
||||
name: mcloneset.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- clonesets
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /mutate-apps-kruise-io-v1alpha1-daemonset
|
||||
failurePolicy: Fail
|
||||
name: mdaemonset.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- daemonsets
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /mutate-apps-kruise-io-statefulset
|
||||
failurePolicy: Fail
|
||||
name: mstatefulset.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- statefulsets
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /mutate-apps-kruise-io-v1alpha1-uniteddeployment
|
||||
failurePolicy: Fail
|
||||
name: muniteddeployment.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- uniteddeployments
|
||||
---
|
||||
apiVersion: admissionregistration.k8s.io/v1beta1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: kruise-validating-webhook-configuration
|
||||
annotations:
|
||||
template: ""
|
||||
webhooks:
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /validate-apps-kruise-io-v1alpha1-broadcastjob
|
||||
failurePolicy: Fail
|
||||
name: vbroadcastjob.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- broadcastjobs
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /validate-apps-kruise-io-v1alpha1-cloneset
|
||||
failurePolicy: Fail
|
||||
name: vcloneset.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- clonesets
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /validate-apps-kruise-io-v1alpha1-sidecarset
|
||||
failurePolicy: Fail
|
||||
name: vsidecarset.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- sidecarsets
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /validate-apps-kruise-io-statefulset
|
||||
failurePolicy: Fail
|
||||
name: vstatefulset.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- statefulsets
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: kruise-webhook-service
|
||||
namespace: kruise-system
|
||||
path: /validate-apps-kruise-io-v1alpha1-uniteddeployment
|
||||
failurePolicy: Fail
|
||||
name: vuniteddeployment.kb.io
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- uniteddeployments
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# Default values for kruise.
|
||||
|
||||
revisionHistoryLimit: 3
|
||||
|
||||
spec:
|
||||
nodeAffinity: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
|
||||
manager:
|
||||
# settings for log print
|
||||
log:
|
||||
# log level for kruise-manager
|
||||
level: "4"
|
||||
|
||||
replicas: 2
|
||||
image:
|
||||
repository: openkruise/kruise-manager
|
||||
tag: v0.7.0
|
||||
webhook:
|
||||
port: 9876
|
||||
|
||||
# resources of kruise-manager container
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
|
||||
metrics:
|
||||
addr: 0.0.0.0
|
||||
port: 8080
|
||||
|
||||
healthProbe:
|
||||
port: 8000
|
||||
|
||||
custom_resource_enable:
|
||||
|
||||
allowPrivileged: false
|
||||
|
||||
webhookConfiguration:
|
||||
failurePolicy:
|
||||
pods: Ignore
|
||||
|
|
@ -121,6 +121,7 @@ spec:
|
|||
description: Template describes the pod that will be created when executing
|
||||
a job.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- template
|
||||
type: object
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ spec:
|
|||
template:
|
||||
description: Template describes the pods that will be created.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: UpdateStrategy indicates the UpdateStrategy that will be
|
||||
employed to update Pods in the CloneSet when a revision is made to
|
||||
|
|
@ -348,6 +349,7 @@ spec:
|
|||
description: PersistentVolumeClaim is a user's request for and claim
|
||||
to a persistent volume
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- selector
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ spec:
|
|||
that matches the template''s node selector (or on every node if no
|
||||
node selector is specified). More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template'
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: An update strategy to replace existing DaemonSet pods with
|
||||
new pods.
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ spec:
|
|||
description: ObjectReference contains enough information
|
||||
to let you inspect or modify the referred object.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
pullPolicy:
|
||||
description: PullPolicy is an optional field to set parameters
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ spec:
|
|||
items:
|
||||
description: SidecarContainer defines the container of Sidecar
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
initContainers:
|
||||
description: Containers is the list of init containers to be injected
|
||||
|
|
@ -71,6 +72,7 @@ spec:
|
|||
items:
|
||||
description: SidecarContainer defines the container of Sidecar
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
paused:
|
||||
description: Paused indicates that the sidecarset is paused and will
|
||||
|
|
@ -139,6 +141,7 @@ spec:
|
|||
description: Volume represents a named volume in a pod that may be
|
||||
accessed by any container in the pod.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
type: object
|
||||
status:
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ spec:
|
|||
out by the StatefulSet will fulfill this Template, but have a unique
|
||||
identity from the rest of the StatefulSet.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: updateStrategy indicates the StatefulSetUpdateStrategy
|
||||
that will be employed to update Pods in the StatefulSet when a revision
|
||||
|
|
@ -331,6 +332,7 @@ spec:
|
|||
description: PersistentVolumeClaim is a user's request for and claim
|
||||
to a persistent volume
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- selector
|
||||
|
|
@ -358,6 +360,7 @@ spec:
|
|||
description: StatefulSetCondition describes the state of a statefulset
|
||||
at a certain point.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
currentReplicas:
|
||||
description: currentReplicas is the number of Pods created by the StatefulSet
|
||||
|
|
@ -408,6 +411,9 @@ spec:
|
|||
version: v1alpha1
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: false
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ spec:
|
|||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
spec:
|
||||
description: StatefulSetSpec defines the desired state of StatefulSet
|
||||
properties:
|
||||
|
|
@ -223,6 +224,7 @@ spec:
|
|||
Template, but have a unique identity from the rest of
|
||||
the StatefulSet.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: updateStrategy indicates the StatefulSetUpdateStrategy
|
||||
that will be employed to update Pods in the StatefulSet
|
||||
|
|
@ -429,6 +431,7 @@ spec:
|
|||
description: PersistentVolumeClaim is a user's request
|
||||
for and claim to a persistent volume
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- selector
|
||||
|
|
@ -442,6 +445,7 @@ spec:
|
|||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
spec:
|
||||
description: CloneSetSpec defines the desired state of CloneSet
|
||||
properties:
|
||||
|
|
@ -561,6 +565,7 @@ spec:
|
|||
template:
|
||||
description: Template describes the pods that will be created.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
updateStrategy:
|
||||
description: UpdateStrategy indicates the UpdateStrategy
|
||||
that will be employed to update Pods in the CloneSet when
|
||||
|
|
@ -744,6 +749,7 @@ spec:
|
|||
description: PersistentVolumeClaim is a user's request
|
||||
for and claim to a persistent volume
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- selector
|
||||
|
|
@ -757,9 +763,11 @@ spec:
|
|||
properties:
|
||||
metadata:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
spec:
|
||||
description: A StatefulSetSpec is the specification of a StatefulSet.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
|
|
@ -787,6 +795,7 @@ spec:
|
|||
distributed across multiple groups of nodes. A subset's
|
||||
nodeSelectorTerm is not allowed to be updated.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
replicas:
|
||||
anyOf:
|
||||
- type: integer
|
||||
|
|
@ -808,6 +817,7 @@ spec:
|
|||
any taint that matches the triple <key,value,effect> using
|
||||
the matching operator <operator>.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: array
|
||||
required:
|
||||
- name
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ patchesStrategicMerge:
|
|||
#- patches/webhook_in_clonesets.yaml
|
||||
#- patches/webhook_in_broadcastjobs.yaml
|
||||
#- patches/webhook_in_sidecarsets.yaml
|
||||
#- patches/webhook_in_statefulsets.yaml
|
||||
- patches/webhook_in_statefulsets.yaml
|
||||
#- patches/webhook_in_uniteddeployments.yaml
|
||||
#- patches/webhook_in_daemonsets.yaml
|
||||
#- patches/webhook_in_nodeimages.yaml
|
||||
|
|
|
|||
|
|
@ -8,10 +8,9 @@ spec:
|
|||
conversion:
|
||||
strategy: Webhook
|
||||
webhookClientConfig:
|
||||
# this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank,
|
||||
# but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager)
|
||||
caBundle: Cg==
|
||||
service:
|
||||
namespace: system
|
||||
name: webhook-service
|
||||
path: /convert
|
||||
preserveUnknownFields: false
|
||||
|
|
|
|||
|
|
@ -30,6 +30,16 @@ rules:
|
|||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: apps.kruise.io/v1beta1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: statefulset-sample
|
||||
spec:
|
||||
# Add fields here
|
||||
foo: bar
|
||||
|
|
@ -100,7 +100,7 @@ webhooks:
|
|||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /mutate-apps-kruise-io-v1alpha1-statefulset
|
||||
path: /mutate-apps-kruise-io-statefulset
|
||||
failurePolicy: Fail
|
||||
name: mstatefulset.kb.io
|
||||
rules:
|
||||
|
|
@ -108,6 +108,7 @@ webhooks:
|
|||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
|
|
@ -198,7 +199,7 @@ webhooks:
|
|||
service:
|
||||
name: webhook-service
|
||||
namespace: system
|
||||
path: /validate-apps-kruise-io-v1alpha1-statefulset
|
||||
path: /validate-apps-kruise-io-statefulset
|
||||
failurePolicy: Fail
|
||||
name: vstatefulset.kb.io
|
||||
rules:
|
||||
|
|
@ -206,6 +207,7 @@ webhooks:
|
|||
- apps.kruise.io
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -14,6 +14,7 @@ require (
|
|||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1
|
||||
k8s.io/api v0.17.7
|
||||
k8s.io/apiextensions-apiserver v0.17.7
|
||||
k8s.io/apimachinery v0.17.7
|
||||
k8s.io/apiserver v0.16.6
|
||||
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
|
||||
|
|
|
|||
13
main.go
13
main.go
|
|
@ -22,20 +22,21 @@ import (
|
|||
_ "net/http/pprof"
|
||||
"os"
|
||||
|
||||
"k8s.io/kubernetes/pkg/capabilities"
|
||||
|
||||
extclient "github.com/openkruise/kruise/pkg/client"
|
||||
"github.com/openkruise/kruise/pkg/util/fieldindex"
|
||||
"github.com/openkruise/kruise/pkg/webhook"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/klog/klogr"
|
||||
"k8s.io/kubernetes/pkg/capabilities"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
|
||||
extclient "github.com/openkruise/kruise/pkg/client"
|
||||
"github.com/openkruise/kruise/pkg/util/fieldindex"
|
||||
"github.com/openkruise/kruise/pkg/webhook"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/controller"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
|
@ -51,8 +52,10 @@ var (
|
|||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(scheme)
|
||||
_ = appsv1alpha1.AddToScheme(clientgoscheme.Scheme)
|
||||
_ = appsv1beta1.AddToScheme(clientgoscheme.Scheme)
|
||||
|
||||
_ = appsv1alpha1.AddToScheme(scheme)
|
||||
_ = appsv1beta1.AddToScheme(scheme)
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/pkg/client/clientset/versioned/typed/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/pkg/client/clientset/versioned/typed/apps/v1beta1"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||
|
|
@ -29,6 +30,7 @@ import (
|
|||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface
|
||||
AppsV1beta1() appsv1beta1.AppsV1beta1Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
|
|
@ -36,6 +38,7 @@ type Interface interface {
|
|||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
appsV1alpha1 *appsv1alpha1.AppsV1alpha1Client
|
||||
appsV1beta1 *appsv1beta1.AppsV1beta1Client
|
||||
}
|
||||
|
||||
// AppsV1alpha1 retrieves the AppsV1alpha1Client
|
||||
|
|
@ -43,6 +46,11 @@ func (c *Clientset) AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface {
|
|||
return c.appsV1alpha1
|
||||
}
|
||||
|
||||
// AppsV1beta1 retrieves the AppsV1beta1Client
|
||||
func (c *Clientset) AppsV1beta1() appsv1beta1.AppsV1beta1Interface {
|
||||
return c.appsV1beta1
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
if c == nil {
|
||||
|
|
@ -68,6 +76,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.appsV1beta1, err = appsv1beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
|
|
@ -81,6 +93,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
|||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var cs Clientset
|
||||
cs.appsV1alpha1 = appsv1alpha1.NewForConfigOrDie(c)
|
||||
cs.appsV1beta1 = appsv1beta1.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &cs
|
||||
|
|
@ -90,6 +103,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
|||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.appsV1alpha1 = appsv1alpha1.New(c)
|
||||
cs.appsV1beta1 = appsv1beta1.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import (
|
|||
clientset "github.com/openkruise/kruise/pkg/client/clientset/versioned"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/pkg/client/clientset/versioned/typed/apps/v1alpha1"
|
||||
fakeappsv1alpha1 "github.com/openkruise/kruise/pkg/client/clientset/versioned/typed/apps/v1alpha1/fake"
|
||||
appsv1beta1 "github.com/openkruise/kruise/pkg/client/clientset/versioned/typed/apps/v1beta1"
|
||||
fakeappsv1beta1 "github.com/openkruise/kruise/pkg/client/clientset/versioned/typed/apps/v1beta1/fake"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
|
|
@ -79,3 +81,8 @@ var _ clientset.Interface = &Clientset{}
|
|||
func (c *Clientset) AppsV1alpha1() appsv1alpha1.AppsV1alpha1Interface {
|
||||
return &fakeappsv1alpha1.FakeAppsV1alpha1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// AppsV1beta1 retrieves the AppsV1beta1Client
|
||||
func (c *Clientset) AppsV1beta1() appsv1beta1.AppsV1beta1Interface {
|
||||
return &fakeappsv1beta1.FakeAppsV1beta1{Fake: &c.Fake}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package fake
|
|||
|
||||
import (
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
|
@ -31,6 +32,7 @@ var codecs = serializer.NewCodecFactory(scheme)
|
|||
var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
appsv1alpha1.AddToScheme,
|
||||
appsv1beta1.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package scheme
|
|||
|
||||
import (
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
|
@ -31,6 +32,7 @@ var Codecs = serializer.NewCodecFactory(Scheme)
|
|||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
appsv1alpha1.AddToScheme,
|
||||
appsv1beta1.AddToScheme,
|
||||
}
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/client/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type AppsV1beta1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
StatefulSetsGetter
|
||||
}
|
||||
|
||||
// AppsV1beta1Client is used to interact with features provided by the apps.kruise.io group.
|
||||
type AppsV1beta1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *AppsV1beta1Client) StatefulSets(namespace string) StatefulSetInterface {
|
||||
return newStatefulSets(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new AppsV1beta1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*AppsV1beta1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AppsV1beta1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new AppsV1beta1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *AppsV1beta1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new AppsV1beta1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *AppsV1beta1Client {
|
||||
return &AppsV1beta1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1beta1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *AppsV1beta1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1beta1
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/openkruise/kruise/pkg/client/clientset/versioned/typed/apps/v1beta1"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeAppsV1beta1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeAppsV1beta1) StatefulSets(namespace string) v1beta1.StatefulSetInterface {
|
||||
return &FakeStatefulSets{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeAppsV1beta1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeStatefulSets implements StatefulSetInterface
|
||||
type FakeStatefulSets struct {
|
||||
Fake *FakeAppsV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var statefulsetsResource = schema.GroupVersionResource{Group: "apps.kruise.io", Version: "v1beta1", Resource: "statefulsets"}
|
||||
|
||||
var statefulsetsKind = schema.GroupVersionKind{Group: "apps.kruise.io", Version: "v1beta1", Kind: "StatefulSet"}
|
||||
|
||||
// Get takes name of the statefulSet, and returns the corresponding statefulSet object, and an error if there is any.
|
||||
func (c *FakeStatefulSets) Get(name string, options v1.GetOptions) (result *v1beta1.StatefulSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(statefulsetsResource, c.ns, name), &v1beta1.StatefulSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.StatefulSet), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of StatefulSets that match those selectors.
|
||||
func (c *FakeStatefulSets) List(opts v1.ListOptions) (result *v1beta1.StatefulSetList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(statefulsetsResource, statefulsetsKind, c.ns, opts), &v1beta1.StatefulSetList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.StatefulSetList{ListMeta: obj.(*v1beta1.StatefulSetList).ListMeta}
|
||||
for _, item := range obj.(*v1beta1.StatefulSetList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested statefulSets.
|
||||
func (c *FakeStatefulSets) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(statefulsetsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a statefulSet and creates it. Returns the server's representation of the statefulSet, and an error, if there is any.
|
||||
func (c *FakeStatefulSets) Create(statefulSet *v1beta1.StatefulSet) (result *v1beta1.StatefulSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(statefulsetsResource, c.ns, statefulSet), &v1beta1.StatefulSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.StatefulSet), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a statefulSet and updates it. Returns the server's representation of the statefulSet, and an error, if there is any.
|
||||
func (c *FakeStatefulSets) Update(statefulSet *v1beta1.StatefulSet) (result *v1beta1.StatefulSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(statefulsetsResource, c.ns, statefulSet), &v1beta1.StatefulSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.StatefulSet), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeStatefulSets) UpdateStatus(statefulSet *v1beta1.StatefulSet) (*v1beta1.StatefulSet, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(statefulsetsResource, "status", c.ns, statefulSet), &v1beta1.StatefulSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.StatefulSet), err
|
||||
}
|
||||
|
||||
// Delete takes name of the statefulSet and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeStatefulSets) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(statefulsetsResource, c.ns, name), &v1beta1.StatefulSet{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeStatefulSets) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(statefulsetsResource, c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.StatefulSetList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched statefulSet.
|
||||
func (c *FakeStatefulSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.StatefulSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(statefulsetsResource, c.ns, name, pt, data, subresources...), &v1beta1.StatefulSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.StatefulSet), err
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
type StatefulSetExpansion interface{}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
scheme "github.com/openkruise/kruise/pkg/client/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// StatefulSetsGetter has a method to return a StatefulSetInterface.
|
||||
// A group's client should implement this interface.
|
||||
type StatefulSetsGetter interface {
|
||||
StatefulSets(namespace string) StatefulSetInterface
|
||||
}
|
||||
|
||||
// StatefulSetInterface has methods to work with StatefulSet resources.
|
||||
type StatefulSetInterface interface {
|
||||
Create(*v1beta1.StatefulSet) (*v1beta1.StatefulSet, error)
|
||||
Update(*v1beta1.StatefulSet) (*v1beta1.StatefulSet, error)
|
||||
UpdateStatus(*v1beta1.StatefulSet) (*v1beta1.StatefulSet, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1beta1.StatefulSet, error)
|
||||
List(opts v1.ListOptions) (*v1beta1.StatefulSetList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.StatefulSet, err error)
|
||||
StatefulSetExpansion
|
||||
}
|
||||
|
||||
// statefulSets implements StatefulSetInterface
|
||||
type statefulSets struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newStatefulSets returns a StatefulSets
|
||||
func newStatefulSets(c *AppsV1beta1Client, namespace string) *statefulSets {
|
||||
return &statefulSets{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the statefulSet, and returns the corresponding statefulSet object, and an error if there is any.
|
||||
func (c *statefulSets) Get(name string, options v1.GetOptions) (result *v1beta1.StatefulSet, err error) {
|
||||
result = &v1beta1.StatefulSet{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of StatefulSets that match those selectors.
|
||||
func (c *statefulSets) List(opts v1.ListOptions) (result *v1beta1.StatefulSetList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.StatefulSetList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested statefulSets.
|
||||
func (c *statefulSets) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a statefulSet and creates it. Returns the server's representation of the statefulSet, and an error, if there is any.
|
||||
func (c *statefulSets) Create(statefulSet *v1beta1.StatefulSet) (result *v1beta1.StatefulSet, err error) {
|
||||
result = &v1beta1.StatefulSet{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
Body(statefulSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a statefulSet and updates it. Returns the server's representation of the statefulSet, and an error, if there is any.
|
||||
func (c *statefulSets) Update(statefulSet *v1beta1.StatefulSet) (result *v1beta1.StatefulSet, err error) {
|
||||
result = &v1beta1.StatefulSet{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
Name(statefulSet.Name).
|
||||
Body(statefulSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *statefulSets) UpdateStatus(statefulSet *v1beta1.StatefulSet) (result *v1beta1.StatefulSet, err error) {
|
||||
result = &v1beta1.StatefulSet{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
Name(statefulSet.Name).
|
||||
SubResource("status").
|
||||
Body(statefulSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the statefulSet and deletes it. Returns an error if one occurs.
|
||||
func (c *statefulSets) Delete(name string, options *v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *statefulSets) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOptions.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched statefulSet.
|
||||
func (c *statefulSets) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.StatefulSet, err error) {
|
||||
result = &v1beta1.StatefulSet{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("statefulsets").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ package apps
|
|||
|
||||
import (
|
||||
v1alpha1 "github.com/openkruise/kruise/pkg/client/informers/externalversions/apps/v1alpha1"
|
||||
v1beta1 "github.com/openkruise/kruise/pkg/client/informers/externalversions/apps/v1beta1"
|
||||
internalinterfaces "github.com/openkruise/kruise/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
|
|
@ -26,6 +27,8 @@ import (
|
|||
type Interface interface {
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
// V1beta1 provides access to shared informers for resources in V1beta1.
|
||||
V1beta1() v1beta1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
|
|
@ -43,3 +46,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
|||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
// V1beta1 returns a new v1beta1.Interface.
|
||||
func (g *group) V1beta1() v1beta1.Interface {
|
||||
return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/openkruise/kruise/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// StatefulSets returns a StatefulSetInformer.
|
||||
StatefulSets() StatefulSetInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// StatefulSets returns a StatefulSetInformer.
|
||||
func (v *version) StatefulSets() StatefulSetInformer {
|
||||
return &statefulSetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
versioned "github.com/openkruise/kruise/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/openkruise/kruise/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta1 "github.com/openkruise/kruise/pkg/client/listers/apps/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// StatefulSetInformer provides access to a shared informer and lister for
|
||||
// StatefulSets.
|
||||
type StatefulSetInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta1.StatefulSetLister
|
||||
}
|
||||
|
||||
type statefulSetInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewStatefulSetInformer constructs a new informer for StatefulSet type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewStatefulSetInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredStatefulSetInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredStatefulSetInformer constructs a new informer for StatefulSet type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredStatefulSetInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1beta1().StatefulSets(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1beta1().StatefulSets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta1.StatefulSet{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredStatefulSetInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta1.StatefulSet{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) Lister() v1beta1.StatefulSetLister {
|
||||
return v1beta1.NewStatefulSetLister(f.Informer().GetIndexer())
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
v1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
v1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
|
@ -69,6 +70,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
|||
case v1alpha1.SchemeGroupVersion.WithResource("uniteddeployments"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1alpha1().UnitedDeployments().Informer()}, nil
|
||||
|
||||
// Group=apps.kruise.io, Version=v1beta1
|
||||
case v1beta1.SchemeGroupVersion.WithResource("statefulsets"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Apps().V1beta1().StatefulSets().Informer()}, nil
|
||||
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no informer found for %v", resource)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
// StatefulSetListerExpansion allows custom methods to be added to
|
||||
// StatefulSetLister.
|
||||
type StatefulSetListerExpansion interface{}
|
||||
|
||||
// StatefulSetNamespaceListerExpansion allows custom methods to be added to
|
||||
// StatefulSetNamespaceLister.
|
||||
type StatefulSetNamespaceListerExpansion interface{}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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.
|
||||
*/
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// StatefulSetLister helps list StatefulSets.
|
||||
type StatefulSetLister interface {
|
||||
// List lists all StatefulSets in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1beta1.StatefulSet, err error)
|
||||
// StatefulSets returns an object that can list and get StatefulSets.
|
||||
StatefulSets(namespace string) StatefulSetNamespaceLister
|
||||
StatefulSetListerExpansion
|
||||
}
|
||||
|
||||
// statefulSetLister implements the StatefulSetLister interface.
|
||||
type statefulSetLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewStatefulSetLister returns a new StatefulSetLister.
|
||||
func NewStatefulSetLister(indexer cache.Indexer) StatefulSetLister {
|
||||
return &statefulSetLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all StatefulSets in the indexer.
|
||||
func (s *statefulSetLister) List(selector labels.Selector) (ret []*v1beta1.StatefulSet, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.StatefulSet))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// StatefulSets returns an object that can list and get StatefulSets.
|
||||
func (s *statefulSetLister) StatefulSets(namespace string) StatefulSetNamespaceLister {
|
||||
return statefulSetNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// StatefulSetNamespaceLister helps list and get StatefulSets.
|
||||
type StatefulSetNamespaceLister interface {
|
||||
// List lists all StatefulSets in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1beta1.StatefulSet, err error)
|
||||
// Get retrieves the StatefulSet from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1beta1.StatefulSet, error)
|
||||
StatefulSetNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// statefulSetNamespaceLister implements the StatefulSetNamespaceLister
|
||||
// interface.
|
||||
type statefulSetNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all StatefulSets in the indexer for a given namespace.
|
||||
func (s statefulSetNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.StatefulSet, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.StatefulSet))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the StatefulSet from the indexer for a given namespace and name.
|
||||
func (s statefulSetNamespaceLister) Get(name string) (*v1beta1.StatefulSet, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta1.Resource("statefulset"), name)
|
||||
}
|
||||
return obj.(*v1beta1.StatefulSet), nil
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
clonesetcore "github.com/openkruise/kruise/pkg/controller/cloneset/core"
|
||||
clonesetutils "github.com/openkruise/kruise/pkg/controller/cloneset/utils"
|
||||
|
|
@ -55,6 +56,7 @@ func (r *realControl) Manage(
|
|||
if updateCS.Spec.Replicas == nil {
|
||||
return false, fmt.Errorf("spec.Replicas is nil")
|
||||
}
|
||||
klog.Infof("DEBUG start scale for %v", util.DumpJSON(updateCS))
|
||||
|
||||
controllerKey := clonesetutils.GetControllerKey(updateCS)
|
||||
coreControl := clonesetcore.New(updateCS)
|
||||
|
|
@ -134,7 +136,7 @@ func (r *realControl) managePreparingDelete(cs *appsv1alpha1.CloneSet, pods, pod
|
|||
|
||||
klog.V(3).Infof("CloneSet %s patch pod %s lifecycle from PreparingDelete to Normal",
|
||||
clonesetutils.GetControllerKey(cs), pod.Name)
|
||||
if patched, err := lifecycle.PatchPodLifecycle(r, pod, appsv1alpha1.LifecycleStateNormal); err != nil {
|
||||
if patched, err := lifecycle.PatchPodLifecycle(r, pod, appspub.LifecycleStateNormal); err != nil {
|
||||
return modified, err
|
||||
} else if patched {
|
||||
modified = true
|
||||
|
|
@ -174,7 +176,7 @@ func (r *realControl) createPods(
|
|||
if pod.Labels[apps.ControllerRevisionHashLabelKey] == currentRevision {
|
||||
cs = currentCS
|
||||
}
|
||||
lifecycle.SetPodLifecycle(appsv1alpha1.LifecycleStateNormal)(pod)
|
||||
lifecycle.SetPodLifecycle(appspub.LifecycleStateNormal)(pod)
|
||||
|
||||
var createErr error
|
||||
if createErr = r.createOnePod(cs, pod, existingPVCNames); createErr != nil {
|
||||
|
|
@ -227,7 +229,7 @@ func (r *realControl) deletePods(cs *appsv1alpha1.CloneSet, podsToDelete []*v1.P
|
|||
var modified bool
|
||||
for _, pod := range podsToDelete {
|
||||
if cs.Spec.Lifecycle != nil && lifecycle.IsPodHooked(cs.Spec.Lifecycle.PreDelete, pod) {
|
||||
if patched, err := lifecycle.PatchPodLifecycle(r, pod, appsv1alpha1.LifecycleStatePreparingDelete); err != nil {
|
||||
if patched, err := lifecycle.PatchPodLifecycle(r, pod, appspub.LifecycleStatePreparingDelete); err != nil {
|
||||
return false, err
|
||||
} else if patched {
|
||||
klog.V(3).Infof("CloneSet %s scaling patch pod %s lifecycle to PreparingDelete",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"sort"
|
||||
"testing"
|
||||
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
clonesettest "github.com/openkruise/kruise/pkg/controller/cloneset/test"
|
||||
clonesetutils "github.com/openkruise/kruise/pkg/controller/cloneset/utils"
|
||||
|
|
@ -67,7 +68,7 @@ func TestCreatePods(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id1",
|
||||
apps.ControllerRevisionHashLabelKey: "revision-abc",
|
||||
"foo": "bar",
|
||||
appsv1alpha1.LifecycleStateKey: string(appsv1alpha1.LifecycleStateNormal),
|
||||
appspub.LifecycleStateKey: string(appspub.LifecycleStateNormal),
|
||||
},
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
|
|
@ -82,7 +83,7 @@ func TestCreatePods(t *testing.T) {
|
|||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "nginx",
|
||||
|
|
@ -123,7 +124,7 @@ func TestCreatePods(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id3",
|
||||
apps.ControllerRevisionHashLabelKey: "revision-xyz",
|
||||
"foo": "bar",
|
||||
appsv1alpha1.LifecycleStateKey: string(appsv1alpha1.LifecycleStateNormal),
|
||||
appspub.LifecycleStateKey: string(appspub.LifecycleStateNormal),
|
||||
},
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
|
|
@ -138,7 +139,7 @@ func TestCreatePods(t *testing.T) {
|
|||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "nginx",
|
||||
|
|
@ -180,7 +181,7 @@ func TestCreatePods(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id4",
|
||||
apps.ControllerRevisionHashLabelKey: "revision-xyz",
|
||||
"foo": "bar",
|
||||
appsv1alpha1.LifecycleStateKey: string(appsv1alpha1.LifecycleStateNormal),
|
||||
appspub.LifecycleStateKey: string(appspub.LifecycleStateNormal),
|
||||
},
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
|
|
@ -195,7 +196,7 @@ func TestCreatePods(t *testing.T) {
|
|||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "nginx",
|
||||
|
|
@ -237,11 +238,11 @@ func TestCreatePods(t *testing.T) {
|
|||
|
||||
for i := range expectedPods {
|
||||
appsv1alpha1.SetDefaultPod(&expectedPods[i])
|
||||
if v, ok := pods.Items[i].Annotations[appsv1alpha1.LifecycleTimestampKey]; ok {
|
||||
if v, ok := pods.Items[i].Annotations[appspub.LifecycleTimestampKey]; ok {
|
||||
if expectedPods[i].Annotations == nil {
|
||||
expectedPods[i].Annotations = make(map[string]string)
|
||||
}
|
||||
expectedPods[i].Annotations[appsv1alpha1.LifecycleTimestampKey] = v
|
||||
expectedPods[i].Annotations[appspub.LifecycleTimestampKey] = v
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package scale
|
|||
import (
|
||||
"sort"
|
||||
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
"github.com/openkruise/kruise/pkg/util/lifecycle"
|
||||
"github.com/openkruise/kruise/pkg/util/specifieddelete"
|
||||
|
|
@ -34,7 +35,7 @@ func getPlannedDeletedPods(cs *appsv1alpha1.CloneSet, pods []*v1.Pod) ([]*v1.Pod
|
|||
if isPodSpecifiedDelete(cs, pod) {
|
||||
podsSpecifiedToDelete = append(podsSpecifiedToDelete, pod)
|
||||
}
|
||||
if lifecycle.GetPodLifecycleState(pod) == appsv1alpha1.LifecycleStatePreparingDelete {
|
||||
if lifecycle.GetPodLifecycleState(pod) == appspub.LifecycleStatePreparingDelete {
|
||||
podsInPreDelete = append(podsInPreDelete, pod)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"sort"
|
||||
"time"
|
||||
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
clonesetcore "github.com/openkruise/kruise/pkg/controller/cloneset/core"
|
||||
clonesetutils "github.com/openkruise/kruise/pkg/controller/cloneset/utils"
|
||||
|
|
@ -97,7 +98,7 @@ func (c *realControl) Manage(cs *appsv1alpha1.CloneSet,
|
|||
|
||||
if clonesetutils.GetPodRevision(pods[i]) != updateRevision.Name {
|
||||
switch lifecycle.GetPodLifecycleState(pods[i]) {
|
||||
case appsv1alpha1.LifecycleStatePreparingDelete, appsv1alpha1.LifecycleStateUpdated:
|
||||
case appspub.LifecycleStatePreparingDelete, appspub.LifecycleStateUpdated:
|
||||
klog.V(3).Infof("CloneSet %s/%s find pod %s in state %s, so skip to update it",
|
||||
cs.Namespace, cs.Name, pods[i].Name, lifecycle.GetPodLifecycleState(pods[i]))
|
||||
default:
|
||||
|
|
@ -137,25 +138,25 @@ func (c *realControl) refreshPodState(cs *appsv1alpha1.CloneSet, coreControl clo
|
|||
return false, 0, res.RefreshErr
|
||||
}
|
||||
|
||||
var state appsv1alpha1.LifecycleStateType
|
||||
var state appspub.LifecycleStateType
|
||||
switch lifecycle.GetPodLifecycleState(pod) {
|
||||
case appsv1alpha1.LifecycleStateUpdating:
|
||||
case appspub.LifecycleStateUpdating:
|
||||
checkFunc := inplaceupdate.CheckInPlaceUpdateCompleted
|
||||
if opts != nil && opts.CustomizeCheckUpdateCompleted != nil {
|
||||
checkFunc = opts.CustomizeCheckUpdateCompleted
|
||||
}
|
||||
if checkFunc(pod) == nil {
|
||||
if cs.Spec.Lifecycle != nil && !lifecycle.IsPodHooked(cs.Spec.Lifecycle.InPlaceUpdate, pod) {
|
||||
state = appsv1alpha1.LifecycleStateUpdated
|
||||
state = appspub.LifecycleStateUpdated
|
||||
} else {
|
||||
state = appsv1alpha1.LifecycleStateNormal
|
||||
state = appspub.LifecycleStateNormal
|
||||
}
|
||||
}
|
||||
case appsv1alpha1.LifecycleStateUpdated:
|
||||
case appspub.LifecycleStateUpdated:
|
||||
if cs.Spec.Lifecycle == nil ||
|
||||
cs.Spec.Lifecycle.InPlaceUpdate == nil ||
|
||||
lifecycle.IsPodHooked(cs.Spec.Lifecycle.InPlaceUpdate, pod) {
|
||||
state = appsv1alpha1.LifecycleStateNormal
|
||||
state = appspub.LifecycleStateNormal
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,8 +187,8 @@ func sortUpdateIndexes(coreControl clonesetcore.Control, strategy appsv1alpha1.C
|
|||
|
||||
// PreparingUpdate first
|
||||
sort.Slice(waitUpdateIndexes, func(i, j int) bool {
|
||||
preparingUpdateI := lifecycle.GetPodLifecycleState(pods[waitUpdateIndexes[i]]) == appsv1alpha1.LifecycleStatePreparingUpdate
|
||||
preparingUpdateJ := lifecycle.GetPodLifecycleState(pods[waitUpdateIndexes[j]]) == appsv1alpha1.LifecycleStatePreparingUpdate
|
||||
preparingUpdateI := lifecycle.GetPodLifecycleState(pods[waitUpdateIndexes[i]]) == appspub.LifecycleStatePreparingUpdate
|
||||
preparingUpdateJ := lifecycle.GetPodLifecycleState(pods[waitUpdateIndexes[j]]) == appspub.LifecycleStatePreparingUpdate
|
||||
if preparingUpdateI != preparingUpdateJ {
|
||||
return preparingUpdateI
|
||||
}
|
||||
|
|
@ -238,7 +239,7 @@ func calculateUpdateCount(coreControl clonesetcore.Control, strategy appsv1alpha
|
|||
|
||||
func isPodReady(coreControl clonesetcore.Control, pod *v1.Pod, minReadySeconds int32) bool {
|
||||
state := lifecycle.GetPodLifecycleState(pod)
|
||||
if state != "" && state != appsv1alpha1.LifecycleStateNormal {
|
||||
if state != "" && state != appspub.LifecycleStateNormal {
|
||||
return false
|
||||
}
|
||||
return coreControl.IsPodUpdateReady(pod, minReadySeconds)
|
||||
|
|
@ -261,7 +262,7 @@ func (c *realControl) updatePod(cs *appsv1alpha1.CloneSet, coreControl clonesetc
|
|||
|
||||
if c.inplaceControl.CanUpdateInPlace(oldRevision, updateRevision, coreControl.GetUpdateOptions()) {
|
||||
if cs.Spec.Lifecycle != nil && lifecycle.IsPodHooked(cs.Spec.Lifecycle.InPlaceUpdate, pod) {
|
||||
if patched, err := lifecycle.PatchPodLifecycle(c, pod, appsv1alpha1.LifecycleStatePreparingUpdate); err != nil {
|
||||
if patched, err := lifecycle.PatchPodLifecycle(c, pod, appspub.LifecycleStatePreparingUpdate); err != nil {
|
||||
return 0, err
|
||||
} else if patched {
|
||||
clonesetutils.ResourceVersionExpectations.Expect(pod)
|
||||
|
|
@ -272,7 +273,7 @@ func (c *realControl) updatePod(cs *appsv1alpha1.CloneSet, coreControl clonesetc
|
|||
}
|
||||
|
||||
opts := coreControl.GetUpdateOptions()
|
||||
opts.AdditionalFuncs = append(opts.AdditionalFuncs, lifecycle.SetPodLifecycle(appsv1alpha1.LifecycleStateUpdating))
|
||||
opts.AdditionalFuncs = append(opts.AdditionalFuncs, lifecycle.SetPodLifecycle(appspub.LifecycleStateUpdating))
|
||||
res := c.inplaceControl.Update(pod, oldRevision, updateRevision, opts)
|
||||
if res.InPlaceUpdate {
|
||||
if res.UpdateErr == nil {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/openkruise/kruise/apis"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
clonesetcore "github.com/openkruise/kruise/pkg/controller/cloneset/core"
|
||||
"github.com/openkruise/kruise/pkg/util"
|
||||
|
|
@ -81,20 +82,20 @@ func TestMange(t *testing.T) {
|
|||
pods: []*v1.Pod{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod-0", Labels: map[string]string{apps.ControllerRevisionHashLabelKey: "rev-new"}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}}},
|
||||
Status: v1.PodStatus{Phase: v1.PodRunning, Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
}},
|
||||
},
|
||||
},
|
||||
expectedPods: []*v1.Pod{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod-0", Labels: map[string]string{apps.ControllerRevisionHashLabelKey: "rev-new"}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}}},
|
||||
Status: v1.PodStatus{Phase: v1.PodRunning, Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
|
@ -106,7 +107,7 @@ func TestMange(t *testing.T) {
|
|||
pods: []*v1.Pod{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod-0", Labels: map[string]string{apps.ControllerRevisionHashLabelKey: "rev-new"}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}}},
|
||||
Status: v1.PodStatus{Phase: v1.PodRunning, Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
}},
|
||||
|
|
@ -115,10 +116,10 @@ func TestMange(t *testing.T) {
|
|||
expectedPods: []*v1.Pod{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod-0", Labels: map[string]string{apps.ControllerRevisionHashLabelKey: "rev-new"}, ResourceVersion: "1"},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}}},
|
||||
Status: v1.PodStatus{Phase: v1.PodRunning, Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, LastTransitionTime: now, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, LastTransitionTime: now, Status: v1.ConditionTrue},
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
|
@ -136,10 +137,10 @@ func TestMange(t *testing.T) {
|
|||
apps.ControllerRevisionHashLabelKey: "rev-old",
|
||||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}}},
|
||||
Status: v1.PodStatus{Phase: v1.PodRunning, Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
|
@ -155,10 +156,10 @@ func TestMange(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
appsv1alpha1.SpecifiedDeleteKey: "true",
|
||||
}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}}},
|
||||
Spec: v1.PodSpec{ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}}},
|
||||
Status: v1.PodStatus{Phase: v1.PodRunning, Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
}},
|
||||
},
|
||||
},
|
||||
|
|
@ -191,14 +192,14 @@ func TestMange(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
}},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo1"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -217,14 +218,14 @@ func TestMange(t *testing.T) {
|
|||
appsv1alpha1.SpecifiedDeleteKey: "true",
|
||||
}},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo1"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -259,14 +260,14 @@ func TestMange(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
}},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo1"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -283,24 +284,24 @@ func TestMange(t *testing.T) {
|
|||
Labels: map[string]string{
|
||||
apps.ControllerRevisionHashLabelKey: "rev-new",
|
||||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
appsv1alpha1.LifecycleStateKey: string(appsv1alpha1.LifecycleStateUpdating),
|
||||
appspub.LifecycleStateKey: string(appspub.LifecycleStateUpdating),
|
||||
},
|
||||
Annotations: map[string]string{appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{
|
||||
Annotations: map[string]string{appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{
|
||||
Revision: "rev-new",
|
||||
UpdateTimestamp: now,
|
||||
LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
})},
|
||||
ResourceVersion: "2",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo2"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -316,7 +317,7 @@ func TestMange(t *testing.T) {
|
|||
name: "inplace update with grace period",
|
||||
cs: &appsv1alpha1.CloneSet{Spec: appsv1alpha1.CloneSetSpec{
|
||||
Replicas: getInt32Pointer(1),
|
||||
UpdateStrategy: appsv1alpha1.CloneSetUpdateStrategy{Type: appsv1alpha1.InPlaceIfPossibleCloneSetUpdateStrategyType, InPlaceUpdateStrategy: &appsv1alpha1.InPlaceUpdateStrategy{GracePeriodSeconds: 3630}},
|
||||
UpdateStrategy: appsv1alpha1.CloneSetUpdateStrategy{Type: appsv1alpha1.InPlaceIfPossibleCloneSetUpdateStrategyType, InPlaceUpdateStrategy: &appspub.InPlaceUpdateStrategy{GracePeriodSeconds: 3630}},
|
||||
}},
|
||||
updateRevision: &apps.ControllerRevision{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "rev-new"},
|
||||
|
|
@ -335,14 +336,14 @@ func TestMange(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
}},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo1"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -359,27 +360,27 @@ func TestMange(t *testing.T) {
|
|||
Labels: map[string]string{
|
||||
apps.ControllerRevisionHashLabelKey: "rev-new",
|
||||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
appsv1alpha1.LifecycleStateKey: string(appsv1alpha1.LifecycleStateUpdating),
|
||||
appspub.LifecycleStateKey: string(appspub.LifecycleStateUpdating),
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{
|
||||
Revision: "rev-new",
|
||||
UpdateTimestamp: now,
|
||||
LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
}),
|
||||
appsv1alpha1.InPlaceUpdateGraceKey: `{"revision":"rev-new","containerImages":{"c1":"foo2"},"graceSeconds":3630}`,
|
||||
appspub.InPlaceUpdateGraceKey: `{"revision":"rev-new","containerImages":{"c1":"foo2"},"graceSeconds":3630}`,
|
||||
},
|
||||
ResourceVersion: "2",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo1"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -395,7 +396,7 @@ func TestMange(t *testing.T) {
|
|||
name: "inplace update during grace period",
|
||||
cs: &appsv1alpha1.CloneSet{Spec: appsv1alpha1.CloneSetSpec{
|
||||
Replicas: getInt32Pointer(1),
|
||||
UpdateStrategy: appsv1alpha1.CloneSetUpdateStrategy{Type: appsv1alpha1.InPlaceIfPossibleCloneSetUpdateStrategyType, InPlaceUpdateStrategy: &appsv1alpha1.InPlaceUpdateStrategy{GracePeriodSeconds: 3630}},
|
||||
UpdateStrategy: appsv1alpha1.CloneSetUpdateStrategy{Type: appsv1alpha1.InPlaceIfPossibleCloneSetUpdateStrategyType, InPlaceUpdateStrategy: &appspub.InPlaceUpdateStrategy{GracePeriodSeconds: 3630}},
|
||||
}},
|
||||
updateRevision: &apps.ControllerRevision{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "rev-new"},
|
||||
|
|
@ -412,23 +413,23 @@ func TestMange(t *testing.T) {
|
|||
ObjectMeta: metav1.ObjectMeta{Name: "pod-0",
|
||||
Labels: map[string]string{apps.ControllerRevisionHashLabelKey: "rev-new", appsv1alpha1.CloneSetInstanceID: "id-0"},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{
|
||||
Revision: "rev-new",
|
||||
UpdateTimestamp: metav1.NewTime(now.Add(-time.Second * 10)),
|
||||
LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
}),
|
||||
appsv1alpha1.InPlaceUpdateGraceKey: `{"revision":"rev-new","containerImages":{"c1":"foo2"},"graceSeconds":3630}`,
|
||||
appspub.InPlaceUpdateGraceKey: `{"revision":"rev-new","containerImages":{"c1":"foo2"},"graceSeconds":3630}`,
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo1"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -447,23 +448,23 @@ func TestMange(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{
|
||||
Revision: "rev-new",
|
||||
UpdateTimestamp: metav1.NewTime(now.Add(-time.Second * 10)),
|
||||
LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
}),
|
||||
appsv1alpha1.InPlaceUpdateGraceKey: `{"revision":"rev-new","containerImages":{"c1":"foo2"},"graceSeconds":3630}`,
|
||||
appspub.InPlaceUpdateGraceKey: `{"revision":"rev-new","containerImages":{"c1":"foo2"},"graceSeconds":3630}`,
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo1"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -479,7 +480,7 @@ func TestMange(t *testing.T) {
|
|||
name: "inplace update continuously after grace period",
|
||||
cs: &appsv1alpha1.CloneSet{Spec: appsv1alpha1.CloneSetSpec{
|
||||
Replicas: getInt32Pointer(1),
|
||||
UpdateStrategy: appsv1alpha1.CloneSetUpdateStrategy{Type: appsv1alpha1.InPlaceIfPossibleCloneSetUpdateStrategyType, InPlaceUpdateStrategy: &appsv1alpha1.InPlaceUpdateStrategy{GracePeriodSeconds: 3630}},
|
||||
UpdateStrategy: appsv1alpha1.CloneSetUpdateStrategy{Type: appsv1alpha1.InPlaceIfPossibleCloneSetUpdateStrategyType, InPlaceUpdateStrategy: &appspub.InPlaceUpdateStrategy{GracePeriodSeconds: 3630}},
|
||||
}},
|
||||
updateRevision: &apps.ControllerRevision{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "rev-new"},
|
||||
|
|
@ -496,23 +497,23 @@ func TestMange(t *testing.T) {
|
|||
ObjectMeta: metav1.ObjectMeta{Name: "pod-0",
|
||||
Labels: map[string]string{apps.ControllerRevisionHashLabelKey: "rev-new", appsv1alpha1.CloneSetInstanceID: "id-0"},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{
|
||||
Revision: "rev-new",
|
||||
UpdateTimestamp: metav1.NewTime(now.Add(-time.Minute)),
|
||||
LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
}),
|
||||
appsv1alpha1.InPlaceUpdateGraceKey: `{"revision":"rev-new","containerImages":{"c1":"foo2"},"graceSeconds":3630}`,
|
||||
appspub.InPlaceUpdateGraceKey: `{"revision":"rev-new","containerImages":{"c1":"foo2"},"graceSeconds":3630}`,
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo1"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -531,23 +532,23 @@ func TestMange(t *testing.T) {
|
|||
appsv1alpha1.CloneSetInstanceID: "id-0",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{
|
||||
Revision: "rev-new",
|
||||
UpdateTimestamp: metav1.NewTime(now.Add(-time.Minute)),
|
||||
LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "image-id-xyz"}},
|
||||
}),
|
||||
},
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
Containers: []v1.Container{{Name: "c1", Image: "foo2"}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodReady, Status: v1.ConditionTrue},
|
||||
{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionFalse, Reason: "StartInPlaceUpdate", LastTransitionTime: now},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{{Name: "c1", ImageID: "image-id-xyz"}},
|
||||
},
|
||||
|
|
@ -589,11 +590,11 @@ func TestMange(t *testing.T) {
|
|||
t.Fatalf("Failed to test %s, get pod %s error: %v", mc.name, p.Name, err)
|
||||
}
|
||||
|
||||
if v, ok := gotPod.Annotations[appsv1alpha1.LifecycleTimestampKey]; ok {
|
||||
if v, ok := gotPod.Annotations[appspub.LifecycleTimestampKey]; ok {
|
||||
if p.Annotations == nil {
|
||||
p.Annotations = map[string]string{}
|
||||
}
|
||||
p.Annotations[appsv1alpha1.LifecycleTimestampKey] = v
|
||||
p.Annotations[appspub.LifecycleTimestampKey] = v
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(gotPod, p) {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
kruiseappslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
kruiseappslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1beta1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
errorutils "k8s.io/apimachinery/pkg/util/errors"
|
||||
|
|
@ -40,15 +40,15 @@ import (
|
|||
type StatefulPodControlInterface interface {
|
||||
// CreateStatefulPod create a Pod in a StatefulSet. Any PVCs necessary for the Pod are created prior to creating
|
||||
// the Pod. If the returned error is nil the Pod and its PVCs have been created.
|
||||
CreateStatefulPod(set *appsv1alpha1.StatefulSet, pod *v1.Pod) error
|
||||
CreateStatefulPod(set *appsv1beta1.StatefulSet, pod *v1.Pod) error
|
||||
// UpdateStatefulPod Updates a Pod in a StatefulSet. If the Pod already has the correct identity and stable
|
||||
// storage this method is a no-op. If the Pod must be mutated to conform to the Set, it is mutated and updated.
|
||||
// pod is an in-out parameter, and any updates made to the pod are reflected as mutations to this parameter. If
|
||||
// the create is successful, the returned error is nil.
|
||||
UpdateStatefulPod(set *appsv1alpha1.StatefulSet, pod *v1.Pod) error
|
||||
UpdateStatefulPod(set *appsv1beta1.StatefulSet, pod *v1.Pod) error
|
||||
// DeleteStatefulPod deletes a Pod in a StatefulSet. The pods PVCs are not deleted. If the delete is successful,
|
||||
// the returned error is nil.
|
||||
DeleteStatefulPod(set *appsv1alpha1.StatefulSet, pod *v1.Pod) error
|
||||
DeleteStatefulPod(set *appsv1beta1.StatefulSet, pod *v1.Pod) error
|
||||
}
|
||||
|
||||
// NewRealStatefulPodControl returns a new realStatefulPodControl
|
||||
|
|
@ -72,7 +72,7 @@ type realStatefulPodControl struct {
|
|||
recorder record.EventRecorder
|
||||
}
|
||||
|
||||
func (spc *realStatefulPodControl) CreateStatefulPod(set *appsv1alpha1.StatefulSet, pod *v1.Pod) error {
|
||||
func (spc *realStatefulPodControl) CreateStatefulPod(set *appsv1beta1.StatefulSet, pod *v1.Pod) error {
|
||||
// Create the Pod's PVCs prior to creating the Pod
|
||||
if err := spc.createPersistentVolumeClaims(set, pod); err != nil {
|
||||
spc.recordPodEvent("create", set, pod, err)
|
||||
|
|
@ -88,7 +88,7 @@ func (spc *realStatefulPodControl) CreateStatefulPod(set *appsv1alpha1.StatefulS
|
|||
return err
|
||||
}
|
||||
|
||||
func (spc *realStatefulPodControl) UpdateStatefulPod(set *appsv1alpha1.StatefulSet, pod *v1.Pod) error {
|
||||
func (spc *realStatefulPodControl) UpdateStatefulPod(set *appsv1beta1.StatefulSet, pod *v1.Pod) error {
|
||||
attemptedUpdate := false
|
||||
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
// assume the Pod is consistent
|
||||
|
|
@ -135,7 +135,7 @@ func (spc *realStatefulPodControl) UpdateStatefulPod(set *appsv1alpha1.StatefulS
|
|||
return err
|
||||
}
|
||||
|
||||
func (spc *realStatefulPodControl) DeleteStatefulPod(set *appsv1alpha1.StatefulSet, pod *v1.Pod) error {
|
||||
func (spc *realStatefulPodControl) DeleteStatefulPod(set *appsv1beta1.StatefulSet, pod *v1.Pod) error {
|
||||
err := spc.client.CoreV1().Pods(set.Namespace).Delete(pod.Name, nil)
|
||||
spc.recordPodEvent("delete", set, pod, err)
|
||||
return err
|
||||
|
|
@ -143,7 +143,7 @@ func (spc *realStatefulPodControl) DeleteStatefulPod(set *appsv1alpha1.StatefulS
|
|||
|
||||
// recordPodEvent records an event for verb applied to a Pod in a StatefulSet. If err is nil the generated event will
|
||||
// have a reason of v1.EventTypeNormal. If err is not nil the generated event will have a reason of v1.EventTypeWarning.
|
||||
func (spc *realStatefulPodControl) recordPodEvent(verb string, set *appsv1alpha1.StatefulSet, pod *v1.Pod, err error) {
|
||||
func (spc *realStatefulPodControl) recordPodEvent(verb string, set *appsv1beta1.StatefulSet, pod *v1.Pod, err error) {
|
||||
if err == nil {
|
||||
reason := fmt.Sprintf("Successful%s", strings.Title(verb))
|
||||
message := fmt.Sprintf("%s Pod %s in StatefulSet %s successful",
|
||||
|
|
@ -160,7 +160,7 @@ func (spc *realStatefulPodControl) recordPodEvent(verb string, set *appsv1alpha1
|
|||
// recordClaimEvent records an event for verb applied to the PersistentVolumeClaim of a Pod in a StatefulSet. If err is
|
||||
// nil the generated event will have a reason of v1.EventTypeNormal. If err is not nil the generated event will have a
|
||||
// reason of v1.EventTypeWarning.
|
||||
func (spc *realStatefulPodControl) recordClaimEvent(verb string, set *appsv1alpha1.StatefulSet, pod *v1.Pod, claim *v1.PersistentVolumeClaim, err error) {
|
||||
func (spc *realStatefulPodControl) recordClaimEvent(verb string, set *appsv1beta1.StatefulSet, pod *v1.Pod, claim *v1.PersistentVolumeClaim, err error) {
|
||||
if err == nil {
|
||||
reason := fmt.Sprintf("Successful%s", strings.Title(verb))
|
||||
message := fmt.Sprintf("%s Claim %s Pod %s in StatefulSet %s success",
|
||||
|
|
@ -178,7 +178,7 @@ func (spc *realStatefulPodControl) recordClaimEvent(verb string, set *appsv1alph
|
|||
// set. If all of the claims for Pod are successfully created, the returned error is nil. If creation fails, this method
|
||||
// may be called again until no error is returned, indicating the PersistentVolumeClaims for pod are consistent with
|
||||
// set's Spec.
|
||||
func (spc *realStatefulPodControl) createPersistentVolumeClaims(set *appsv1alpha1.StatefulSet, pod *v1.Pod) error {
|
||||
func (spc *realStatefulPodControl) createPersistentVolumeClaims(set *appsv1beta1.StatefulSet, pod *v1.Pod) error {
|
||||
var errs []error
|
||||
for _, claim := range getPersistentVolumeClaims(set, pod) {
|
||||
pvc, err := spc.pvcLister.PersistentVolumeClaims(claim.Namespace).Get(claim.Name)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/controller/history"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/util/inplaceupdate"
|
||||
)
|
||||
|
||||
|
|
@ -45,13 +45,13 @@ type ControlInterface interface {
|
|||
// If an implementation returns a non-nil error, the invocation will be retried using a rate-limited strategy.
|
||||
// Implementors should sink any errors that they do not wish to trigger a retry, and they may feel free to
|
||||
// exit exceptionally at any point provided they wish the update to be re-run at a later point in time.
|
||||
UpdateStatefulSet(set *appsv1alpha1.StatefulSet, pods []*v1.Pod) error
|
||||
UpdateStatefulSet(set *appsv1beta1.StatefulSet, pods []*v1.Pod) error
|
||||
// ListRevisions returns a array of the ControllerRevisions that represent the revisions of set. If the returned
|
||||
// error is nil, the returns slice of ControllerRevisions is valid.
|
||||
ListRevisions(set *appsv1alpha1.StatefulSet) ([]*apps.ControllerRevision, error)
|
||||
ListRevisions(set *appsv1beta1.StatefulSet) ([]*apps.ControllerRevision, error)
|
||||
// AdoptOrphanRevisions adopts any orphaned ControllerRevisions that match set's Selector. If all adoptions are
|
||||
// successful the returned error is nil.
|
||||
AdoptOrphanRevisions(set *appsv1alpha1.StatefulSet, revisions []*apps.ControllerRevision) error
|
||||
AdoptOrphanRevisions(set *appsv1beta1.StatefulSet, revisions []*apps.ControllerRevision) error
|
||||
}
|
||||
|
||||
// NewDefaultStatefulSetControl returns a new instance of the default implementation ControlInterface that
|
||||
|
|
@ -91,7 +91,7 @@ type defaultStatefulSetControl struct {
|
|||
// strategy allows these constraints to be relaxed - pods will be created and deleted eagerly and
|
||||
// in no particular order. Clients using the burst strategy should be careful to ensure they
|
||||
// understand the consistency implications of having unpredictable numbers of pods available.
|
||||
func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *appsv1alpha1.StatefulSet, pods []*v1.Pod) error {
|
||||
func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *appsv1beta1.StatefulSet, pods []*v1.Pod) error {
|
||||
|
||||
// list all revisions and sort them
|
||||
revisions, err := ssc.ListRevisions(set)
|
||||
|
|
@ -141,7 +141,7 @@ func (ssc *defaultStatefulSetControl) UpdateStatefulSet(set *appsv1alpha1.Statef
|
|||
return ssc.truncateHistory(set, pods, revisions, currentRevision, updateRevision)
|
||||
}
|
||||
|
||||
func (ssc *defaultStatefulSetControl) ListRevisions(set *appsv1alpha1.StatefulSet) ([]*apps.ControllerRevision, error) {
|
||||
func (ssc *defaultStatefulSetControl) ListRevisions(set *appsv1beta1.StatefulSet) ([]*apps.ControllerRevision, error) {
|
||||
selector, err := metav1.LabelSelectorAsSelector(set.Spec.Selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -150,7 +150,7 @@ func (ssc *defaultStatefulSetControl) ListRevisions(set *appsv1alpha1.StatefulSe
|
|||
}
|
||||
|
||||
func (ssc *defaultStatefulSetControl) AdoptOrphanRevisions(
|
||||
set *appsv1alpha1.StatefulSet,
|
||||
set *appsv1beta1.StatefulSet,
|
||||
revisions []*apps.ControllerRevision) error {
|
||||
for i := range revisions {
|
||||
adopted, err := ssc.controllerHistory.AdoptControllerRevision(set, controllerKind, revisions[i])
|
||||
|
|
@ -168,7 +168,7 @@ func (ssc *defaultStatefulSetControl) AdoptOrphanRevisions(
|
|||
// only RevisionHistoryLimit revisions remain. If the returned error is nil the operation was successful. This method
|
||||
// expects that revisions is sorted when supplied.
|
||||
func (ssc *defaultStatefulSetControl) truncateHistory(
|
||||
set *appsv1alpha1.StatefulSet,
|
||||
set *appsv1beta1.StatefulSet,
|
||||
pods []*v1.Pod,
|
||||
revisions []*apps.ControllerRevision,
|
||||
current *apps.ControllerRevision,
|
||||
|
|
@ -207,7 +207,7 @@ func (ssc *defaultStatefulSetControl) truncateHistory(
|
|||
// a new revision, or modify the Revision of an existing revision if an update to set is detected.
|
||||
// This method expects that revisions is sorted when supplied.
|
||||
func (ssc *defaultStatefulSetControl) getStatefulSetRevisions(
|
||||
set *appsv1alpha1.StatefulSet,
|
||||
set *appsv1beta1.StatefulSet,
|
||||
revisions []*apps.ControllerRevision) (*apps.ControllerRevision, *apps.ControllerRevision, int32, error) {
|
||||
var currentRevision, updateRevision *apps.ControllerRevision
|
||||
|
||||
|
|
@ -280,12 +280,12 @@ func (ssc *defaultStatefulSetControl) getStatefulSetRevisions(
|
|||
|
||||
// TODO (RZ): Break the below spaghetti code into smaller chucks with unit tests
|
||||
func (ssc *defaultStatefulSetControl) updateStatefulSet(
|
||||
set *appsv1alpha1.StatefulSet,
|
||||
set *appsv1beta1.StatefulSet,
|
||||
currentRevision *apps.ControllerRevision,
|
||||
updateRevision *apps.ControllerRevision,
|
||||
collisionCount int32,
|
||||
pods []*v1.Pod,
|
||||
revisions []*apps.ControllerRevision) (*appsv1alpha1.StatefulSetStatus, error) {
|
||||
revisions []*apps.ControllerRevision) (*appsv1beta1.StatefulSetStatus, error) {
|
||||
selector, err := metav1.LabelSelectorAsSelector(set.Spec.Selector)
|
||||
if err != nil {
|
||||
return set.Status.DeepCopy(), err
|
||||
|
|
@ -302,7 +302,7 @@ func (ssc *defaultStatefulSetControl) updateStatefulSet(
|
|||
}
|
||||
|
||||
// set the generation, and revisions in the returned status
|
||||
status := appsv1alpha1.StatefulSetStatus{}
|
||||
status := appsv1beta1.StatefulSetStatus{}
|
||||
status.ObservedGeneration = set.Generation
|
||||
status.CurrentRevision = currentRevision.Name
|
||||
status.UpdateRevision = updateRevision.Name
|
||||
|
|
@ -433,7 +433,7 @@ func (ssc *defaultStatefulSetControl) updateStatefulSet(
|
|||
if !isCreated(replicas[i]) {
|
||||
if err := ssc.podControl.CreateStatefulPod(set, replicas[i]); err != nil {
|
||||
msg := fmt.Sprintf("StatefulPodControl failed to create Pod error: %s", err)
|
||||
condition := NewStatefulsetCondition(appsv1alpha1.FailedCreatePod, v1.ConditionTrue, "", msg)
|
||||
condition := NewStatefulsetCondition(appsv1beta1.FailedCreatePod, v1.ConditionTrue, "", msg)
|
||||
SetStatefulsetCondition(&status, condition)
|
||||
return &status, err
|
||||
}
|
||||
|
|
@ -504,7 +504,7 @@ func (ssc *defaultStatefulSetControl) updateStatefulSet(
|
|||
replica := replicas[i].DeepCopy()
|
||||
if err := ssc.podControl.UpdateStatefulPod(updateSet, replica); err != nil {
|
||||
msg := fmt.Sprintf("StatefulPodControl failed to update Pod error: %s", err)
|
||||
condition := NewStatefulsetCondition(appsv1alpha1.FailedUpdatePod, v1.ConditionTrue, "", msg)
|
||||
condition := NewStatefulsetCondition(appsv1beta1.FailedUpdatePod, v1.ConditionTrue, "", msg)
|
||||
SetStatefulsetCondition(&status, condition)
|
||||
return &status, err
|
||||
}
|
||||
|
|
@ -590,7 +590,7 @@ func (ssc *defaultStatefulSetControl) updateStatefulSet(
|
|||
var unavailablePods []string
|
||||
updateIndexes := sortPodsToUpdate(set.Spec.UpdateStrategy.RollingUpdate, updateRevision.Name, replicas)
|
||||
klog.V(5).Infof("Prepare to update pods indexes %v for StatefulSet %s", updateIndexes, getStatefulSetKey(set))
|
||||
minWaitTime := appsv1alpha1.MaxMinReadySeconds * time.Second
|
||||
minWaitTime := appsv1beta1.MaxMinReadySeconds * time.Second
|
||||
// update pods in sequence
|
||||
for _, target := range updateIndexes {
|
||||
|
||||
|
|
@ -661,14 +661,14 @@ func (ssc *defaultStatefulSetControl) updateStatefulSet(
|
|||
}
|
||||
|
||||
func (ssc *defaultStatefulSetControl) inPlaceUpdatePod(
|
||||
set *appsv1alpha1.StatefulSet, pod *v1.Pod,
|
||||
set *appsv1beta1.StatefulSet, pod *v1.Pod,
|
||||
updateRevision *apps.ControllerRevision, revisions []*apps.ControllerRevision,
|
||||
) (bool, error) {
|
||||
if set.Spec.UpdateStrategy.RollingUpdate == nil {
|
||||
return false, nil
|
||||
}
|
||||
if set.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy != appsv1alpha1.InPlaceIfPossiblePodUpdateStrategyType &&
|
||||
set.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy != appsv1alpha1.InPlaceOnlyPodUpdateStrategyType {
|
||||
if set.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy != appsv1beta1.InPlaceIfPossiblePodUpdateStrategyType &&
|
||||
set.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy != appsv1beta1.InPlaceOnlyPodUpdateStrategyType {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
|
@ -703,8 +703,8 @@ func (ssc *defaultStatefulSetControl) inPlaceUpdatePod(
|
|||
// mutated to indicate completion. If status is semantically equivalent to set's Status no update is performed. If the
|
||||
// returned error is nil, the update is successful.
|
||||
func (ssc *defaultStatefulSetControl) updateStatefulSetStatus(
|
||||
set *appsv1alpha1.StatefulSet,
|
||||
status *appsv1alpha1.StatefulSetStatus) error {
|
||||
set *appsv1beta1.StatefulSet,
|
||||
status *appsv1beta1.StatefulSetStatus) error {
|
||||
|
||||
// complete any in progress rolling update if necessary
|
||||
completeRollingUpdate(set, status)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -20,9 +20,9 @@ package statefulset
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
clientset "github.com/openkruise/kruise/pkg/client/clientset/versioned"
|
||||
appslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1alpha1"
|
||||
appslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1beta1"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/util/retry"
|
||||
)
|
||||
|
|
@ -32,7 +32,7 @@ import (
|
|||
type StatusUpdaterInterface interface {
|
||||
// UpdateStatefulSetStatus sets the set's Status to status. Implementations are required to retry on conflicts,
|
||||
// but fail on other errors. If the returned error is nil set's Status has been successfully set to status.
|
||||
UpdateStatefulSetStatus(set *appsv1alpha1.StatefulSet, status *appsv1alpha1.StatefulSetStatus) error
|
||||
UpdateStatefulSetStatus(set *appsv1beta1.StatefulSet, status *appsv1beta1.StatefulSetStatus) error
|
||||
}
|
||||
|
||||
// NewRealStatefulSetStatusUpdater returns a StatusUpdaterInterface that updates the Status of a StatefulSet,
|
||||
|
|
@ -49,12 +49,12 @@ type realStatefulSetStatusUpdater struct {
|
|||
}
|
||||
|
||||
func (ssu *realStatefulSetStatusUpdater) UpdateStatefulSetStatus(
|
||||
set *appsv1alpha1.StatefulSet,
|
||||
status *appsv1alpha1.StatefulSetStatus) error {
|
||||
set *appsv1beta1.StatefulSet,
|
||||
status *appsv1beta1.StatefulSetStatus) error {
|
||||
// don't wait due to limited number of clients, but backoff after the default number of steps
|
||||
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
set.Status = *status
|
||||
_, updateErr := ssu.client.AppsV1alpha1().StatefulSets(set.Namespace).UpdateStatus(set)
|
||||
_, updateErr := ssu.client.AppsV1beta1().StatefulSets(set.Namespace).UpdateStatus(set)
|
||||
if updateErr == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import (
|
|||
"errors"
|
||||
"testing"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/client/clientset/versioned/fake"
|
||||
kruiseappslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1alpha1"
|
||||
kruiseappslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1beta1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
core "k8s.io/client-go/testing"
|
||||
|
|
@ -32,7 +32,7 @@ import (
|
|||
|
||||
func TestStatefulSetUpdaterUpdatesSetStatus(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := appsv1alpha1.StatefulSetStatus{ObservedGeneration: 1, Replicas: 2}
|
||||
status := appsv1beta1.StatefulSetStatus{ObservedGeneration: 1, Replicas: 2}
|
||||
fakeClient := &fake.Clientset{}
|
||||
updater := NewRealStatefulSetStatusUpdater(fakeClient, nil)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
|
|
@ -49,12 +49,12 @@ func TestStatefulSetUpdaterUpdatesSetStatus(t *testing.T) {
|
|||
|
||||
func TestStatefulSetStatusUpdaterUpdatesObservedGeneration(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := appsv1alpha1.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2}
|
||||
status := appsv1beta1.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2}
|
||||
fakeClient := &fake.Clientset{}
|
||||
updater := NewRealStatefulSetStatusUpdater(fakeClient, nil)
|
||||
fakeClient.AddReactor("update", "statefulsets", func(action core.Action) (bool, runtime.Object, error) {
|
||||
update := action.(core.UpdateAction)
|
||||
sts := update.GetObject().(*appsv1alpha1.StatefulSet)
|
||||
sts := update.GetObject().(*appsv1beta1.StatefulSet)
|
||||
if sts.Status.ObservedGeneration != 3 {
|
||||
t.Errorf("expected observedGeneration to be synced with generation for statefulset %q", sts.Name)
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ func TestStatefulSetStatusUpdaterUpdatesObservedGeneration(t *testing.T) {
|
|||
|
||||
func TestStatefulSetStatusUpdaterUpdateReplicasFailure(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := appsv1alpha1.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2}
|
||||
status := appsv1beta1.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2}
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
indexer.Add(set)
|
||||
|
|
@ -83,7 +83,7 @@ func TestStatefulSetStatusUpdaterUpdateReplicasFailure(t *testing.T) {
|
|||
|
||||
func TestStatefulSetStatusUpdaterUpdateReplicasConflict(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := appsv1alpha1.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2}
|
||||
status := appsv1beta1.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2}
|
||||
conflict := false
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
|
|
@ -108,7 +108,7 @@ func TestStatefulSetStatusUpdaterUpdateReplicasConflict(t *testing.T) {
|
|||
|
||||
func TestStatefulSetStatusUpdaterUpdateReplicasConflictFailure(t *testing.T) {
|
||||
set := newStatefulSet(3)
|
||||
status := appsv1alpha1.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2}
|
||||
status := appsv1beta1.StatefulSetStatus{ObservedGeneration: 3, Replicas: 2}
|
||||
fakeClient := &fake.Clientset{}
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
indexer.Add(set)
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ import (
|
|||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/history"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
)
|
||||
|
||||
var patchCodec = scheme.Codecs.LegacyCodec(appsv1alpha1.SchemeGroupVersion)
|
||||
var patchCodec = scheme.Codecs.LegacyCodec(appsv1beta1.SchemeGroupVersion)
|
||||
|
||||
// statefulPodRegex is a regular expression that extracts the parent StatefulSet and ordinal from the Name of a Pod
|
||||
var statefulPodRegex = regexp.MustCompile("(.*)-([0-9]+)$")
|
||||
|
|
@ -73,24 +73,24 @@ func getOrdinal(pod *v1.Pod) int {
|
|||
}
|
||||
|
||||
// getPodName gets the name of set's child Pod with an ordinal index of ordinal
|
||||
func getPodName(set *appsv1alpha1.StatefulSet, ordinal int) string {
|
||||
func getPodName(set *appsv1beta1.StatefulSet, ordinal int) string {
|
||||
return fmt.Sprintf("%s-%d", set.Name, ordinal)
|
||||
}
|
||||
|
||||
// getPersistentVolumeClaimName gets the name of PersistentVolumeClaim for a Pod with an ordinal index of ordinal. claim
|
||||
// must be a PersistentVolumeClaim from set's VolumeClaims template.
|
||||
func getPersistentVolumeClaimName(set *appsv1alpha1.StatefulSet, claim *v1.PersistentVolumeClaim, ordinal int) string {
|
||||
func getPersistentVolumeClaimName(set *appsv1beta1.StatefulSet, claim *v1.PersistentVolumeClaim, ordinal int) string {
|
||||
// NOTE: This name format is used by the heuristics for zone spreading in ChooseZoneForVolume
|
||||
return fmt.Sprintf("%s-%s-%d", claim.Name, set.Name, ordinal)
|
||||
}
|
||||
|
||||
// isMemberOf tests if pod is a member of set.
|
||||
func isMemberOf(set *appsv1alpha1.StatefulSet, pod *v1.Pod) bool {
|
||||
func isMemberOf(set *appsv1beta1.StatefulSet, pod *v1.Pod) bool {
|
||||
return getParentName(pod) == set.Name
|
||||
}
|
||||
|
||||
// identityMatches returns true if pod has a valid identity and network identity for a member of set.
|
||||
func identityMatches(set *appsv1alpha1.StatefulSet, pod *v1.Pod) bool {
|
||||
func identityMatches(set *appsv1beta1.StatefulSet, pod *v1.Pod) bool {
|
||||
parent, ordinal := getParentNameAndOrdinal(pod)
|
||||
return ordinal >= 0 &&
|
||||
set.Name == parent &&
|
||||
|
|
@ -100,7 +100,7 @@ func identityMatches(set *appsv1alpha1.StatefulSet, pod *v1.Pod) bool {
|
|||
}
|
||||
|
||||
// storageMatches returns true if pod's Volumes cover the set of PersistentVolumeClaims
|
||||
func storageMatches(set *appsv1alpha1.StatefulSet, pod *v1.Pod) bool {
|
||||
func storageMatches(set *appsv1beta1.StatefulSet, pod *v1.Pod) bool {
|
||||
ordinal := getOrdinal(pod)
|
||||
if ordinal < 0 {
|
||||
return false
|
||||
|
|
@ -124,7 +124,7 @@ func storageMatches(set *appsv1alpha1.StatefulSet, pod *v1.Pod) bool {
|
|||
// getPersistentVolumeClaims gets a map of PersistentVolumeClaims to their template names, as defined in set. The
|
||||
// returned PersistentVolumeClaims are each constructed with a the name specific to the Pod. This name is determined
|
||||
// by getPersistentVolumeClaimName.
|
||||
func getPersistentVolumeClaims(set *appsv1alpha1.StatefulSet, pod *v1.Pod) map[string]v1.PersistentVolumeClaim {
|
||||
func getPersistentVolumeClaims(set *appsv1beta1.StatefulSet, pod *v1.Pod) map[string]v1.PersistentVolumeClaim {
|
||||
ordinal := getOrdinal(pod)
|
||||
templates := set.Spec.VolumeClaimTemplates
|
||||
claims := make(map[string]v1.PersistentVolumeClaim, len(templates))
|
||||
|
|
@ -140,7 +140,7 @@ func getPersistentVolumeClaims(set *appsv1alpha1.StatefulSet, pod *v1.Pod) map[s
|
|||
|
||||
// updateStorage updates pod's Volumes to conform with the PersistentVolumeClaim of set's templates. If pod has
|
||||
// conflicting local Volumes these are replaced with Volumes that conform to the set's templates.
|
||||
func updateStorage(set *appsv1alpha1.StatefulSet, pod *v1.Pod) {
|
||||
func updateStorage(set *appsv1beta1.StatefulSet, pod *v1.Pod) {
|
||||
currentVolumes := pod.Spec.Volumes
|
||||
claims := getPersistentVolumeClaims(set, pod)
|
||||
newVolumes := make([]v1.Volume, 0, len(claims))
|
||||
|
|
@ -164,7 +164,7 @@ func updateStorage(set *appsv1alpha1.StatefulSet, pod *v1.Pod) {
|
|||
pod.Spec.Volumes = newVolumes
|
||||
}
|
||||
|
||||
func initIdentity(set *appsv1alpha1.StatefulSet, pod *v1.Pod) {
|
||||
func initIdentity(set *appsv1beta1.StatefulSet, pod *v1.Pod) {
|
||||
updateIdentity(set, pod)
|
||||
// Set these immutable fields only on initial Pod creation, not updates.
|
||||
pod.Spec.Hostname = pod.Name
|
||||
|
|
@ -173,7 +173,7 @@ func initIdentity(set *appsv1alpha1.StatefulSet, pod *v1.Pod) {
|
|||
|
||||
// updateIdentity updates pod's name, hostname, and subdomain, and StatefulSetPodNameLabel to conform to set's name
|
||||
// and headless service.
|
||||
func updateIdentity(set *appsv1alpha1.StatefulSet, pod *v1.Pod) {
|
||||
func updateIdentity(set *appsv1beta1.StatefulSet, pod *v1.Pod) {
|
||||
pod.Name = getPodName(set, getOrdinal(pod))
|
||||
pod.Namespace = set.Namespace
|
||||
if pod.Labels == nil {
|
||||
|
|
@ -232,12 +232,12 @@ func isHealthy(pod *v1.Pod) bool {
|
|||
}
|
||||
|
||||
// allowsBurst is true if the alpha burst annotation is set.
|
||||
func allowsBurst(set *appsv1alpha1.StatefulSet) bool {
|
||||
func allowsBurst(set *appsv1beta1.StatefulSet) bool {
|
||||
return set.Spec.PodManagementPolicy == apps.ParallelPodManagement
|
||||
}
|
||||
|
||||
// getMinReadySeconds returns the minReadySeconds set in the rollingUpdate, default is 0
|
||||
func getMinReadySeconds(set *appsv1alpha1.StatefulSet) int32 {
|
||||
func getMinReadySeconds(set *appsv1beta1.StatefulSet) int32 {
|
||||
if set.Spec.UpdateStrategy.RollingUpdate == nil ||
|
||||
set.Spec.UpdateStrategy.RollingUpdate.MinReadySeconds == nil {
|
||||
return 0
|
||||
|
|
@ -263,7 +263,7 @@ func getPodRevision(pod *v1.Pod) string {
|
|||
}
|
||||
|
||||
// newStatefulSetPod returns a new Pod conforming to the set's Spec with an identity generated from ordinal.
|
||||
func newStatefulSetPod(set *appsv1alpha1.StatefulSet, ordinal int) *v1.Pod {
|
||||
func newStatefulSetPod(set *appsv1beta1.StatefulSet, ordinal int) *v1.Pod {
|
||||
pod, _ := controller.GetPodFromTemplate(&set.Spec.Template, set, metav1.NewControllerRef(set, controllerKind))
|
||||
pod.Name = getPodName(set, ordinal)
|
||||
initIdentity(set, pod)
|
||||
|
|
@ -275,7 +275,7 @@ func newStatefulSetPod(set *appsv1alpha1.StatefulSet, ordinal int) *v1.Pod {
|
|||
// current revision. updateSet is the representation of the set at the updateRevision. currentRevision is the name of
|
||||
// the current revision. updateRevision is the name of the update revision. ordinal is the ordinal of the Pod. If the
|
||||
// returned error is nil, the returned Pod is valid.
|
||||
func newVersionedStatefulSetPod(currentSet, updateSet *appsv1alpha1.StatefulSet, currentRevision, updateRevision string,
|
||||
func newVersionedStatefulSetPod(currentSet, updateSet *appsv1beta1.StatefulSet, currentRevision, updateRevision string,
|
||||
ordinal int, replicas []*v1.Pod,
|
||||
) *v1.Pod {
|
||||
if isCurrentRevisionNeeded(currentSet, updateRevision, ordinal, replicas) {
|
||||
|
|
@ -289,7 +289,7 @@ func newVersionedStatefulSetPod(currentSet, updateSet *appsv1alpha1.StatefulSet,
|
|||
}
|
||||
|
||||
// isCurrentRevisionNeeded calculate if the 'ordinal' Pod should be current revision.
|
||||
func isCurrentRevisionNeeded(set *appsv1alpha1.StatefulSet, updateRevision string, ordinal int, replicas []*v1.Pod) bool {
|
||||
func isCurrentRevisionNeeded(set *appsv1beta1.StatefulSet, updateRevision string, ordinal int, replicas []*v1.Pod) bool {
|
||||
if set.Spec.UpdateStrategy.Type != apps.RollingUpdateStatefulSetStrategyType {
|
||||
return false
|
||||
}
|
||||
|
|
@ -313,7 +313,7 @@ func isCurrentRevisionNeeded(set *appsv1alpha1.StatefulSet, updateRevision strin
|
|||
}
|
||||
|
||||
// Match check if the given StatefulSet's template matches the template stored in the given history.
|
||||
func Match(ss *appsv1alpha1.StatefulSet, history *apps.ControllerRevision) (bool, error) {
|
||||
func Match(ss *appsv1beta1.StatefulSet, history *apps.ControllerRevision) (bool, error) {
|
||||
patch, err := getPatch(ss)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
|
@ -325,7 +325,7 @@ func Match(ss *appsv1alpha1.StatefulSet, history *apps.ControllerRevision) (bool
|
|||
// previous version. If the returned error is nil the patch is valid. The current state that we save is just the
|
||||
// PodSpecTemplate. We can modify this later to encompass more state (or less) and remain compatible with previously
|
||||
// recorded patches.
|
||||
func getPatch(set *appsv1alpha1.StatefulSet) ([]byte, error) {
|
||||
func getPatch(set *appsv1beta1.StatefulSet) ([]byte, error) {
|
||||
str, err := runtime.Encode(patchCodec, set)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -350,7 +350,7 @@ func getPatch(set *appsv1alpha1.StatefulSet) ([]byte, error) {
|
|||
// The Revision of the returned ControllerRevision is set to revision. If the returned error is nil, the returned
|
||||
// ControllerRevision is valid. StatefulSet revisions are stored as patches that re-apply the current state of set
|
||||
// to a new StatefulSet using a strategic merge patch to replace the saved state of the new StatefulSet.
|
||||
func newRevision(set *appsv1alpha1.StatefulSet, revision int64, collisionCount *int32) (*apps.ControllerRevision, error) {
|
||||
func newRevision(set *appsv1beta1.StatefulSet, revision int64, collisionCount *int32) (*apps.ControllerRevision, error) {
|
||||
patch, err := getPatch(set)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -375,13 +375,13 @@ func newRevision(set *appsv1alpha1.StatefulSet, revision int64, collisionCount *
|
|||
|
||||
// ApplyRevision returns a new StatefulSet constructed by restoring the state in revision to set. If the returned error
|
||||
// is nil, the returned StatefulSet is valid.
|
||||
func ApplyRevision(set *appsv1alpha1.StatefulSet, revision *apps.ControllerRevision) (*appsv1alpha1.StatefulSet, error) {
|
||||
func ApplyRevision(set *appsv1beta1.StatefulSet, revision *apps.ControllerRevision) (*appsv1beta1.StatefulSet, error) {
|
||||
clone := set.DeepCopy()
|
||||
patched, err := strategicpatch.StrategicMergePatch([]byte(runtime.EncodeOrDie(patchCodec, clone)), revision.Data.Raw, clone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
restoredSet := &appsv1alpha1.StatefulSet{}
|
||||
restoredSet := &appsv1beta1.StatefulSet{}
|
||||
err = json.Unmarshal(patched, restoredSet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -402,7 +402,7 @@ func nextRevision(revisions []*apps.ControllerRevision) int64 {
|
|||
|
||||
// inconsistentStatus returns true if the ObservedGeneration of status is greater than set's
|
||||
// Generation or if any of the status's fields do not match those of set's status.
|
||||
func inconsistentStatus(set *appsv1alpha1.StatefulSet, status *appsv1alpha1.StatefulSetStatus) bool {
|
||||
func inconsistentStatus(set *appsv1beta1.StatefulSet, status *appsv1beta1.StatefulSetStatus) bool {
|
||||
return status.ObservedGeneration > set.Status.ObservedGeneration ||
|
||||
status.Replicas != set.Status.Replicas ||
|
||||
status.CurrentReplicas != set.Status.CurrentReplicas ||
|
||||
|
|
@ -418,7 +418,7 @@ func inconsistentStatus(set *appsv1alpha1.StatefulSet, status *appsv1alpha1.Stat
|
|||
// to the updateRevision. status's currentRevision is set to updateRevision and its' updateRevision
|
||||
// is set to the empty string. status's currentReplicas is set to updateReplicas and its updateReplicas
|
||||
// are set to 0.
|
||||
func completeRollingUpdate(set *appsv1alpha1.StatefulSet, status *appsv1alpha1.StatefulSetStatus) {
|
||||
func completeRollingUpdate(set *appsv1beta1.StatefulSet, status *appsv1beta1.StatefulSetStatus) {
|
||||
if set.Spec.UpdateStrategy.Type == apps.RollingUpdateStatefulSetStrategyType &&
|
||||
status.UpdatedReplicas == status.Replicas &&
|
||||
status.ReadyReplicas == status.Replicas {
|
||||
|
|
@ -456,7 +456,7 @@ func NewStatefulsetCondition(conditionType apps.StatefulSetConditionType, condit
|
|||
}
|
||||
|
||||
// GetStatefulsetConditition returns the condition with the provided type.
|
||||
func GetStatefulsetConditition(status appsv1alpha1.StatefulSetStatus, condType apps.StatefulSetConditionType) *apps.StatefulSetCondition {
|
||||
func GetStatefulsetConditition(status appsv1beta1.StatefulSetStatus, condType apps.StatefulSetConditionType) *apps.StatefulSetCondition {
|
||||
for i := range status.Conditions {
|
||||
c := status.Conditions[i]
|
||||
if c.Type == condType {
|
||||
|
|
@ -467,7 +467,7 @@ func GetStatefulsetConditition(status appsv1alpha1.StatefulSetStatus, condType a
|
|||
}
|
||||
|
||||
// SetStatefulsetCondition updates the statefulset to include the provided condition. If the condition that
|
||||
func SetStatefulsetCondition(status *appsv1alpha1.StatefulSetStatus, condition apps.StatefulSetCondition) {
|
||||
func SetStatefulsetCondition(status *appsv1beta1.StatefulSetStatus, condition apps.StatefulSetCondition) {
|
||||
currentCond := GetStatefulsetConditition(*status, condition.Type)
|
||||
if currentCond != nil && currentCond.Status == condition.Status && currentCond.Reason == condition.Reason {
|
||||
return
|
||||
|
|
@ -495,7 +495,7 @@ func getStatefulSetKey(o metav1.Object) string {
|
|||
return o.GetNamespace() + "/" + o.GetName()
|
||||
}
|
||||
|
||||
func isInPlaceOnly(set *appsv1alpha1.StatefulSet) bool {
|
||||
func isInPlaceOnly(set *appsv1beta1.StatefulSet) bool {
|
||||
return set.Spec.UpdateStrategy.RollingUpdate != nil &&
|
||||
set.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy == appsv1alpha1.InPlaceOnlyPodUpdateStrategyType
|
||||
set.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy == appsv1beta1.InPlaceOnlyPodUpdateStrategyType
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ import (
|
|||
"k8s.io/kubernetes/pkg/controller/history"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
)
|
||||
|
||||
// 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.
|
||||
type overlappingStatefulSets []*appsv1alpha1.StatefulSet
|
||||
type overlappingStatefulSets []*appsv1beta1.StatefulSet
|
||||
|
||||
func (o overlappingStatefulSets) Len() int { return len(o) }
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ func TestGetMinReadySeconds(t *testing.T) {
|
|||
if getMinReadySeconds(set) != 0 {
|
||||
t.Error("getMinReadySeconds should be zero")
|
||||
}
|
||||
set.Spec.UpdateStrategy.RollingUpdate = &appsv1alpha1.RollingUpdateStatefulSetStrategy{}
|
||||
set.Spec.UpdateStrategy.RollingUpdate = &appsv1beta1.RollingUpdateStatefulSetStrategy{}
|
||||
if getMinReadySeconds(set) != 0 {
|
||||
t.Error("getMinReadySeconds should be zero")
|
||||
}
|
||||
|
|
@ -286,7 +286,7 @@ func TestAscendingOrdinal(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestOverlappingStatefulSets(t *testing.T) {
|
||||
sets := make([]*appsv1alpha1.StatefulSet, 10)
|
||||
sets := make([]*appsv1beta1.StatefulSet, 10)
|
||||
perm := rand.Perm(10)
|
||||
for i, v := range perm {
|
||||
sets[i] = newStatefulSet(10)
|
||||
|
|
@ -313,7 +313,7 @@ func TestNewPodControllerRef(t *testing.T) {
|
|||
if controllerRef == nil {
|
||||
t.Fatalf("No ControllerRef found on new pod")
|
||||
}
|
||||
if got, want := controllerRef.APIVersion, appsv1alpha1.SchemeGroupVersion.String(); got != want {
|
||||
if got, want := controllerRef.APIVersion, appsv1beta1.SchemeGroupVersion.String(); got != want {
|
||||
t.Errorf("controllerRef.APIVersion = %q, want %q", got, want)
|
||||
}
|
||||
if got, want := controllerRef.Kind, "StatefulSet"; got != want {
|
||||
|
|
@ -412,7 +412,7 @@ func newPVC(name string) v1.PersistentVolumeClaim {
|
|||
}
|
||||
}
|
||||
|
||||
func newStatefulSetWithVolumes(replicas int, name string, petMounts []v1.VolumeMount, podMounts []v1.VolumeMount) *appsv1alpha1.StatefulSet {
|
||||
func newStatefulSetWithVolumes(replicas int, name string, petMounts []v1.VolumeMount, podMounts []v1.VolumeMount) *appsv1beta1.StatefulSet {
|
||||
mounts := append(petMounts, podMounts...)
|
||||
claims := []v1.PersistentVolumeClaim{}
|
||||
for _, m := range petMounts {
|
||||
|
|
@ -446,7 +446,7 @@ func newStatefulSetWithVolumes(replicas int, name string, petMounts []v1.VolumeM
|
|||
|
||||
template.Labels = map[string]string{"foo": "bar"}
|
||||
|
||||
return &appsv1alpha1.StatefulSet{
|
||||
return &appsv1beta1.StatefulSet{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "StatefulSet",
|
||||
APIVersion: "apps/v1",
|
||||
|
|
@ -456,7 +456,7 @@ func newStatefulSetWithVolumes(replicas int, name string, petMounts []v1.VolumeM
|
|||
Namespace: v1.NamespaceDefault,
|
||||
UID: types.UID("test"),
|
||||
},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"foo": "bar"},
|
||||
},
|
||||
|
|
@ -464,7 +464,7 @@ func newStatefulSetWithVolumes(replicas int, name string, petMounts []v1.VolumeM
|
|||
Template: template,
|
||||
VolumeClaimTemplates: claims,
|
||||
ServiceName: "governingsvc",
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
RevisionHistoryLimit: func() *int32 {
|
||||
limit := int32(2)
|
||||
return &limit
|
||||
|
|
@ -473,7 +473,7 @@ func newStatefulSetWithVolumes(replicas int, name string, petMounts []v1.VolumeM
|
|||
}
|
||||
}
|
||||
|
||||
func newStatefulSet(replicas int) *appsv1alpha1.StatefulSet {
|
||||
func newStatefulSet(replicas int) *appsv1beta1.StatefulSet {
|
||||
petMounts := []v1.VolumeMount{
|
||||
{Name: "datadir", MountPath: "/tmp/zookeeper"},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||
package statefulset
|
||||
|
||||
import (
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/util/updatesort"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func sortPodsToUpdate(rollingUpdateStrategy *appsv1alpha1.RollingUpdateStatefulSetStrategy, updateRevision string, replicas []*v1.Pod) []int {
|
||||
func sortPodsToUpdate(rollingUpdateStrategy *appsv1beta1.RollingUpdateStatefulSetStrategy, updateRevision string, replicas []*v1.Pod) []int {
|
||||
var updateMin int
|
||||
if rollingUpdateStrategy != nil && rollingUpdateStrategy.Partition != nil {
|
||||
updateMin = int(*rollingUpdateStrategy.Partition)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -28,7 +29,7 @@ import (
|
|||
|
||||
func TestSortPodsToUpdate(t *testing.T) {
|
||||
cases := []struct {
|
||||
strategy *appsv1alpha1.RollingUpdateStatefulSetStrategy
|
||||
strategy *appsv1beta1.RollingUpdateStatefulSetStrategy
|
||||
updateRevision string
|
||||
replicas []*v1.Pod
|
||||
expected []int
|
||||
|
|
@ -44,9 +45,9 @@ func TestSortPodsToUpdate(t *testing.T) {
|
|||
expected: []int{2, 1, 0},
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.RollingUpdateStatefulSetStrategy{
|
||||
UnorderedUpdate: &appsv1alpha1.UnorderedUpdateStrategy{PriorityStrategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
strategy: &appsv1beta1.RollingUpdateStatefulSetStrategy{
|
||||
UnorderedUpdate: &appsv1beta1.UnorderedUpdateStrategy{PriorityStrategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"k": "v1"}}},
|
||||
{Weight: 10, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"k": "v2"}}},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/client"
|
||||
kruiseclientset "github.com/openkruise/kruise/pkg/client/clientset/versioned"
|
||||
kruiseappslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1alpha1"
|
||||
kruiseappslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/util/expectations"
|
||||
"github.com/openkruise/kruise/pkg/util/gate"
|
||||
"github.com/openkruise/kruise/pkg/util/inplaceupdate"
|
||||
|
|
@ -61,7 +61,7 @@ func init() {
|
|||
|
||||
var (
|
||||
// controllerKind contains the schema.GroupVersionKind for this controller type.
|
||||
controllerKind = appsv1alpha1.SchemeGroupVersion.WithKind("StatefulSet")
|
||||
controllerKind = appsv1beta1.SchemeGroupVersion.WithKind("StatefulSet")
|
||||
concurrentReconciles = 3
|
||||
|
||||
updateExpectations = expectations.NewUpdateExpectations(func(o metav1.Object) string {
|
||||
|
|
@ -75,7 +75,7 @@ var (
|
|||
// Add creates a new StatefulSet Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
|
||||
// and Start it when the Manager is Started.
|
||||
func Add(mgr manager.Manager) error {
|
||||
if !gate.ResourceEnabled(&appsv1alpha1.StatefulSet{}) {
|
||||
if !gate.ResourceEnabled(&appsv1beta1.StatefulSet{}) {
|
||||
return nil
|
||||
}
|
||||
r, err := newReconciler(mgr)
|
||||
|
|
@ -162,10 +162,10 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
|
|||
}
|
||||
|
||||
// Watch for changes to StatefulSet
|
||||
err = c.Watch(&source.Kind{Type: &appsv1alpha1.StatefulSet{}}, &handler.EnqueueRequestForObject{}, predicate.Funcs{
|
||||
err = c.Watch(&source.Kind{Type: &appsv1beta1.StatefulSet{}}, &handler.EnqueueRequestForObject{}, predicate.Funcs{
|
||||
UpdateFunc: func(e event.UpdateEvent) bool {
|
||||
oldSS := e.ObjectOld.(*appsv1alpha1.StatefulSet)
|
||||
newSS := e.ObjectNew.(*appsv1alpha1.StatefulSet)
|
||||
oldSS := e.ObjectOld.(*appsv1beta1.StatefulSet)
|
||||
newSS := e.ObjectNew.(*appsv1beta1.StatefulSet)
|
||||
if oldSS.Status.Replicas != newSS.Status.Replicas {
|
||||
klog.V(4).Infof("Observed updated replica count for StatefulSet: %v, %d->%d", newSS.Name, oldSS.Status.Replicas, newSS.Status.Replicas)
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
|
|||
// Watch for changes to Pod created by StatefulSet
|
||||
err = c.Watch(&source.Kind{Type: &v1.Pod{}}, &handler.EnqueueRequestForOwner{
|
||||
IsController: true,
|
||||
OwnerType: &appsv1alpha1.StatefulSet{},
|
||||
OwnerType: &appsv1beta1.StatefulSet{},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -251,7 +251,7 @@ func (ssc *ReconcileStatefulSet) Reconcile(request reconcile.Request) (res recon
|
|||
}
|
||||
|
||||
// adoptOrphanRevisions adopts any orphaned ControllerRevisions matched by set's Selector.
|
||||
func (ssc *ReconcileStatefulSet) adoptOrphanRevisions(set *appsv1alpha1.StatefulSet) error {
|
||||
func (ssc *ReconcileStatefulSet) adoptOrphanRevisions(set *appsv1beta1.StatefulSet) error {
|
||||
revisions, err := ssc.control.ListRevisions(set)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -263,7 +263,7 @@ func (ssc *ReconcileStatefulSet) adoptOrphanRevisions(set *appsv1alpha1.Stateful
|
|||
}
|
||||
}
|
||||
if len(orphanRevisions) > 0 {
|
||||
fresh, err := ssc.kruiseClient.AppsV1alpha1().StatefulSets(set.Namespace).Get(set.Name, metav1.GetOptions{})
|
||||
fresh, err := ssc.kruiseClient.AppsV1beta1().StatefulSets(set.Namespace).Get(set.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -280,7 +280,7 @@ func (ssc *ReconcileStatefulSet) adoptOrphanRevisions(set *appsv1alpha1.Stateful
|
|||
//
|
||||
// NOTE: Returned Pods are pointers to objects from the cache.
|
||||
// If you need to modify one, you need to copy it first.
|
||||
func (ssc *ReconcileStatefulSet) getPodsForStatefulSet(set *appsv1alpha1.StatefulSet, selector labels.Selector) ([]*v1.Pod, error) {
|
||||
func (ssc *ReconcileStatefulSet) getPodsForStatefulSet(set *appsv1beta1.StatefulSet, selector labels.Selector) ([]*v1.Pod, error) {
|
||||
// List all pods to include the pods that don't match the selector anymore but
|
||||
// has a ControllerRef pointing to this StatefulSet.
|
||||
pods, err := ssc.podLister.Pods(set.Namespace).List(labels.Everything())
|
||||
|
|
@ -296,7 +296,7 @@ func (ssc *ReconcileStatefulSet) getPodsForStatefulSet(set *appsv1alpha1.Statefu
|
|||
// If any adoptions are attempted, we should first recheck for deletion with
|
||||
// an uncached quorum read sometime after listing Pods (see #42639).
|
||||
canAdoptFunc := kubecontroller.RecheckDeletionTimestamp(func() (metav1.Object, error) {
|
||||
fresh, err := ssc.kruiseClient.AppsV1alpha1().StatefulSets(set.Namespace).Get(set.Name, metav1.GetOptions{})
|
||||
fresh, err := ssc.kruiseClient.AppsV1beta1().StatefulSets(set.Namespace).Get(set.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -311,7 +311,7 @@ func (ssc *ReconcileStatefulSet) getPodsForStatefulSet(set *appsv1alpha1.Statefu
|
|||
}
|
||||
|
||||
// syncStatefulSet syncs a tuple of (statefulset, []*v1.Pod).
|
||||
func (ssc *ReconcileStatefulSet) syncStatefulSet(set *appsv1alpha1.StatefulSet, pods []*v1.Pod) error {
|
||||
func (ssc *ReconcileStatefulSet) syncStatefulSet(set *appsv1beta1.StatefulSet, pods []*v1.Pod) error {
|
||||
klog.V(4).Infof("Syncing StatefulSet %v/%v with %d pods", set.Namespace, set.Name, len(pods))
|
||||
// TODO: investigate where we mutate the set during the update as it is not obvious.
|
||||
if err := ssc.control.UpdateStatefulSet(set.DeepCopy(), pods); err != nil {
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
kruiseclientset "github.com/openkruise/kruise/pkg/client/clientset/versioned"
|
||||
kruisefake "github.com/openkruise/kruise/pkg/client/clientset/versioned/fake"
|
||||
kruiseinformers "github.com/openkruise/kruise/pkg/client/informers/externalversions"
|
||||
kruiseappsinformers "github.com/openkruise/kruise/pkg/client/informers/externalversions/apps/v1alpha1"
|
||||
kruiseappslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1alpha1"
|
||||
kruiseappsinformers "github.com/openkruise/kruise/pkg/client/informers/externalversions/apps/v1beta1"
|
||||
kruiseappslisters "github.com/openkruise/kruise/pkg/client/listers/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/util/inplaceupdate"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
|
@ -72,7 +72,7 @@ func TestStatefulSetControllerCreates(t *testing.T) {
|
|||
if obj, _, err := spc.setsIndexer.Get(set); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
set = obj.(*appsv1alpha1.StatefulSet)
|
||||
set = obj.(*appsv1beta1.StatefulSet)
|
||||
}
|
||||
if set.Status.Replicas != 3 {
|
||||
t.Errorf("set.Status.Replicas = %v; want 3", set.Status.Replicas)
|
||||
|
|
@ -88,7 +88,7 @@ func TestStatefulSetControllerDeletes(t *testing.T) {
|
|||
if obj, _, err := spc.setsIndexer.Get(set); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
set = obj.(*appsv1alpha1.StatefulSet)
|
||||
set = obj.(*appsv1beta1.StatefulSet)
|
||||
}
|
||||
if set.Status.Replicas != 3 {
|
||||
t.Errorf("set.Status.Replicas = %v; want 3", set.Status.Replicas)
|
||||
|
|
@ -100,7 +100,7 @@ func TestStatefulSetControllerDeletes(t *testing.T) {
|
|||
if obj, _, err := spc.setsIndexer.Get(set); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
set = obj.(*appsv1alpha1.StatefulSet)
|
||||
set = obj.(*appsv1beta1.StatefulSet)
|
||||
}
|
||||
if set.Status.Replicas != 0 {
|
||||
t.Errorf("set.Status.Replicas = %v; want 0", set.Status.Replicas)
|
||||
|
|
@ -116,7 +116,7 @@ func TestStatefulSetControllerRespectsTermination(t *testing.T) {
|
|||
if obj, _, err := spc.setsIndexer.Get(set); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
set = obj.(*appsv1alpha1.StatefulSet)
|
||||
set = obj.(*appsv1beta1.StatefulSet)
|
||||
}
|
||||
if set.Status.Replicas != 3 {
|
||||
t.Errorf("set.Status.Replicas = %v; want 3", set.Status.Replicas)
|
||||
|
|
@ -151,7 +151,7 @@ func TestStatefulSetControllerRespectsTermination(t *testing.T) {
|
|||
if obj, _, err := spc.setsIndexer.Get(set); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
set = obj.(*appsv1alpha1.StatefulSet)
|
||||
set = obj.(*appsv1beta1.StatefulSet)
|
||||
}
|
||||
if set.Status.Replicas != 0 {
|
||||
t.Errorf("set.Status.Replicas = %v; want 0", set.Status.Replicas)
|
||||
|
|
@ -167,7 +167,7 @@ func TestStatefulSetControllerBlocksScaling(t *testing.T) {
|
|||
if obj, _, err := spc.setsIndexer.Get(set); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
set = obj.(*appsv1alpha1.StatefulSet)
|
||||
set = obj.(*appsv1beta1.StatefulSet)
|
||||
}
|
||||
if set.Status.Replicas != 3 {
|
||||
t.Errorf("set.Status.Replicas = %v; want 3", set.Status.Replicas)
|
||||
|
|
@ -604,7 +604,7 @@ func splitObjects(initialObjects []runtime.Object) ([]runtime.Object, []runtime.
|
|||
var kubeObjects []runtime.Object
|
||||
var kruiseObjects []runtime.Object
|
||||
for _, o := range initialObjects {
|
||||
if _, ok := o.(*appsv1alpha1.StatefulSet); ok {
|
||||
if _, ok := o.(*appsv1beta1.StatefulSet); ok {
|
||||
kruiseObjects = append(kruiseObjects, o)
|
||||
} else {
|
||||
kubeObjects = append(kubeObjects, o)
|
||||
|
|
@ -619,11 +619,11 @@ func newFakeStatefulSetController(initialObjects ...runtime.Object) (*StatefulSe
|
|||
kruiseClient := kruisefake.NewSimpleClientset(kruiseObjects...)
|
||||
informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
|
||||
kruiseInformerFactory := kruiseinformers.NewSharedInformerFactory(kruiseClient, controller.NoResyncPeriodFunc())
|
||||
fpc := newFakeStatefulPodControl(informerFactory.Core().V1().Pods(), kruiseInformerFactory.Apps().V1alpha1().StatefulSets())
|
||||
ssu := newFakeStatefulSetStatusUpdater(kruiseInformerFactory.Apps().V1alpha1().StatefulSets())
|
||||
fpc := newFakeStatefulPodControl(informerFactory.Core().V1().Pods(), kruiseInformerFactory.Apps().V1beta1().StatefulSets())
|
||||
ssu := newFakeStatefulSetStatusUpdater(kruiseInformerFactory.Apps().V1beta1().StatefulSets())
|
||||
ssc := NewStatefulSetController(
|
||||
informerFactory.Core().V1().Pods(),
|
||||
kruiseInformerFactory.Apps().V1alpha1().StatefulSets(),
|
||||
kruiseInformerFactory.Apps().V1beta1().StatefulSets(),
|
||||
informerFactory.Core().V1().PersistentVolumeClaims(),
|
||||
informerFactory.Apps().V1().ControllerRevisions(),
|
||||
client,
|
||||
|
|
@ -654,7 +654,7 @@ func getPodAtOrdinal(pods []*v1.Pod, ordinal int) *v1.Pod {
|
|||
return pods[ordinal]
|
||||
}
|
||||
|
||||
func scaleUpStatefulSetController(set *appsv1alpha1.StatefulSet, ssc *StatefulSetController, spc *fakeStatefulPodControl) error {
|
||||
func scaleUpStatefulSetController(set *appsv1beta1.StatefulSet, ssc *StatefulSetController, spc *fakeStatefulPodControl) error {
|
||||
spc.setsIndexer.Add(set)
|
||||
ssc.enqueueStatefulSet(set)
|
||||
fakeWorker(ssc)
|
||||
|
|
@ -697,12 +697,12 @@ func scaleUpStatefulSetController(set *appsv1alpha1.StatefulSet, ssc *StatefulSe
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
set = obj.(*appsv1alpha1.StatefulSet)
|
||||
set = obj.(*appsv1beta1.StatefulSet)
|
||||
}
|
||||
return assertMonotonicInvariants(set, spc)
|
||||
}
|
||||
|
||||
func scaleDownStatefulSetController(set *appsv1alpha1.StatefulSet, ssc *StatefulSetController, spc *fakeStatefulPodControl) error {
|
||||
func scaleDownStatefulSetController(set *appsv1beta1.StatefulSet, ssc *StatefulSetController, spc *fakeStatefulPodControl) error {
|
||||
selector, err := metav1.LabelSelectorAsSelector(set.Spec.Selector)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -749,7 +749,7 @@ func scaleDownStatefulSetController(set *appsv1alpha1.StatefulSet, ssc *Stateful
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
set = obj.(*appsv1alpha1.StatefulSet)
|
||||
set = obj.(*appsv1beta1.StatefulSet)
|
||||
}
|
||||
return assertMonotonicInvariants(set, spc)
|
||||
}
|
||||
|
|
@ -821,8 +821,8 @@ func NewStatefulSetController(
|
|||
cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: ssc.enqueueStatefulSet,
|
||||
UpdateFunc: func(old, cur interface{}) {
|
||||
oldPS := old.(*appsv1alpha1.StatefulSet)
|
||||
curPS := cur.(*appsv1alpha1.StatefulSet)
|
||||
oldPS := old.(*appsv1beta1.StatefulSet)
|
||||
curPS := cur.(*appsv1beta1.StatefulSet)
|
||||
if oldPS.Status.Replicas != curPS.Status.Replicas {
|
||||
klog.V(4).Infof("Observed updated replica count for StatefulSet: %v, %d->%d", curPS.Name, oldPS.Status.Replicas, curPS.Status.Replicas)
|
||||
}
|
||||
|
|
@ -1018,7 +1018,7 @@ func (ssc *StatefulSetController) deletePod(obj interface{}) {
|
|||
// resolveControllerRef returns the controller referenced by a ControllerRef,
|
||||
// or nil if the ControllerRef could not be resolved to a matching controller
|
||||
// of the correct Kind.
|
||||
func (ssc *StatefulSetController) resolveControllerRef(namespace string, controllerRef *metav1.OwnerReference) *appsv1alpha1.StatefulSet {
|
||||
func (ssc *StatefulSetController) resolveControllerRef(namespace string, controllerRef *metav1.OwnerReference) *appsv1beta1.StatefulSet {
|
||||
// We can't look up by UID, so look up by Name and then verify UID.
|
||||
// Don't even try to look up by Name if it's the wrong Kind.
|
||||
if controllerRef.Kind != controllerKind.Kind {
|
||||
|
|
@ -1038,7 +1038,7 @@ func (ssc *StatefulSetController) resolveControllerRef(namespace string, control
|
|||
|
||||
// getStatefulSetsForPod returns a list of StatefulSets that potentially match
|
||||
// a given pod.
|
||||
func (ssc *StatefulSetController) getStatefulSetsForPod(pod *v1.Pod) []*appsv1alpha1.StatefulSet {
|
||||
func (ssc *StatefulSetController) getStatefulSetsForPod(pod *v1.Pod) []*appsv1beta1.StatefulSet {
|
||||
sets, err := getPodStatefulSets(ssc.setLister, pod)
|
||||
if err != nil {
|
||||
return nil
|
||||
|
|
@ -1055,9 +1055,9 @@ func (ssc *StatefulSetController) getStatefulSetsForPod(pod *v1.Pod) []*appsv1al
|
|||
return sets
|
||||
}
|
||||
|
||||
func getPodStatefulSets(s kruiseappslisters.StatefulSetLister, pod *v1.Pod) ([]*appsv1alpha1.StatefulSet, error) {
|
||||
func getPodStatefulSets(s kruiseappslisters.StatefulSetLister, pod *v1.Pod) ([]*appsv1beta1.StatefulSet, error) {
|
||||
var selector labels.Selector
|
||||
var ps *appsv1alpha1.StatefulSet
|
||||
var ps *appsv1beta1.StatefulSet
|
||||
|
||||
if len(pod.Labels) == 0 {
|
||||
return nil, fmt.Errorf("no StatefulSets found for pod %v because it has no labels", pod.Name)
|
||||
|
|
@ -1068,7 +1068,7 @@ func getPodStatefulSets(s kruiseappslisters.StatefulSetLister, pod *v1.Pod) ([]*
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var psList []*appsv1alpha1.StatefulSet
|
||||
var psList []*appsv1beta1.StatefulSet
|
||||
for i := range list {
|
||||
ps = list[i]
|
||||
if ps.Namespace != pod.Namespace {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/appscode/jsonpatch"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -118,7 +118,7 @@ func (c *realControl) Refresh(pod *v1.Pod, opts *UpdateOptions) RefreshResult {
|
|||
|
||||
var delayDuration time.Duration
|
||||
var err error
|
||||
if pod.Annotations[appsv1alpha1.InPlaceUpdateGraceKey] != "" {
|
||||
if pod.Annotations[appspub.InPlaceUpdateGraceKey] != "" {
|
||||
if delayDuration, err = c.finishGracePeriod(pod, opts); err != nil {
|
||||
return RefreshResult{RefreshErr: err}
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ func (c *realControl) refreshCondition(pod *v1.Pod, opts *UpdateOptions) error {
|
|||
}
|
||||
|
||||
newCondition := v1.PodCondition{
|
||||
Type: appsv1alpha1.InPlaceUpdateReady,
|
||||
Type: appspub.InPlaceUpdateReady,
|
||||
Status: v1.ConditionTrue,
|
||||
LastTransitionTime: c.now(),
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ func (c *realControl) finishGracePeriod(pod *v1.Pod, opts *UpdateOptions) (time.
|
|||
}
|
||||
|
||||
spec := UpdateSpec{}
|
||||
updateSpecJSON, ok := clone.Annotations[appsv1alpha1.InPlaceUpdateGraceKey]
|
||||
updateSpecJSON, ok := clone.Annotations[appspub.InPlaceUpdateGraceKey]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -187,10 +187,10 @@ func (c *realControl) finishGracePeriod(pod *v1.Pod, opts *UpdateOptions) (time.
|
|||
}
|
||||
graceDuration := time.Second * time.Duration(spec.GraceSeconds)
|
||||
|
||||
updateState := appsv1alpha1.InPlaceUpdateState{}
|
||||
updateStateJSON, ok := clone.Annotations[appsv1alpha1.InPlaceUpdateStateKey]
|
||||
updateState := appspub.InPlaceUpdateState{}
|
||||
updateStateJSON, ok := clone.Annotations[appspub.InPlaceUpdateStateKey]
|
||||
if !ok {
|
||||
return fmt.Errorf("pod has %s but %s not found", appsv1alpha1.InPlaceUpdateGraceKey, appsv1alpha1.InPlaceUpdateStateKey)
|
||||
return fmt.Errorf("pod has %s but %s not found", appspub.InPlaceUpdateGraceKey, appspub.InPlaceUpdateStateKey)
|
||||
}
|
||||
if err := json.Unmarshal([]byte(updateStateJSON), &updateState); err != nil {
|
||||
return nil
|
||||
|
|
@ -198,7 +198,7 @@ func (c *realControl) finishGracePeriod(pod *v1.Pod, opts *UpdateOptions) (time.
|
|||
|
||||
if clone.Labels[c.revisionKey] != spec.Revision {
|
||||
// If revision-hash has changed, just drop this GracePeriodSpec and go through the normal update process again.
|
||||
delete(clone.Annotations, appsv1alpha1.InPlaceUpdateGraceKey)
|
||||
delete(clone.Annotations, appspub.InPlaceUpdateGraceKey)
|
||||
} else {
|
||||
if span := time.Since(updateState.UpdateTimestamp.Time); span < graceDuration {
|
||||
delayDuration = roundupSeconds(graceDuration - span)
|
||||
|
|
@ -208,7 +208,7 @@ func (c *realControl) finishGracePeriod(pod *v1.Pod, opts *UpdateOptions) (time.
|
|||
if clone, err = patchUpdateSpecToPod(clone, &spec, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
delete(clone.Annotations, appsv1alpha1.InPlaceUpdateGraceKey)
|
||||
delete(clone.Annotations, appspub.InPlaceUpdateGraceKey)
|
||||
}
|
||||
|
||||
return c.adp.updatePod(clone)
|
||||
|
|
@ -236,7 +236,7 @@ func (c *realControl) Update(pod *v1.Pod, oldRevision, newRevision *apps.Control
|
|||
// 2. update condition for pod with readiness-gate
|
||||
if containsReadinessGate(pod) {
|
||||
newCondition := v1.PodCondition{
|
||||
Type: appsv1alpha1.InPlaceUpdateReady,
|
||||
Type: appspub.InPlaceUpdateReady,
|
||||
LastTransitionTime: c.now(),
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "StartInPlaceUpdate",
|
||||
|
|
@ -279,29 +279,29 @@ func (c *realControl) updatePodInPlace(pod *v1.Pod, spec *UpdateSpec, opts *Upda
|
|||
}
|
||||
|
||||
// record old containerStatuses
|
||||
inPlaceUpdateState := appsv1alpha1.InPlaceUpdateState{
|
||||
inPlaceUpdateState := appspub.InPlaceUpdateState{
|
||||
Revision: spec.Revision,
|
||||
UpdateTimestamp: c.now(),
|
||||
LastContainerStatuses: make(map[string]appsv1alpha1.InPlaceUpdateContainerStatus, len(spec.ContainerImages)),
|
||||
LastContainerStatuses: make(map[string]appspub.InPlaceUpdateContainerStatus, len(spec.ContainerImages)),
|
||||
}
|
||||
for _, c := range clone.Status.ContainerStatuses {
|
||||
if _, ok := spec.ContainerImages[c.Name]; ok {
|
||||
inPlaceUpdateState.LastContainerStatuses[c.Name] = appsv1alpha1.InPlaceUpdateContainerStatus{
|
||||
inPlaceUpdateState.LastContainerStatuses[c.Name] = appspub.InPlaceUpdateContainerStatus{
|
||||
ImageID: c.ImageID,
|
||||
}
|
||||
}
|
||||
}
|
||||
inPlaceUpdateStateJSON, _ := json.Marshal(inPlaceUpdateState)
|
||||
clone.Annotations[appsv1alpha1.InPlaceUpdateStateKey] = string(inPlaceUpdateStateJSON)
|
||||
clone.Annotations[appspub.InPlaceUpdateStateKey] = string(inPlaceUpdateStateJSON)
|
||||
|
||||
if spec.GraceSeconds <= 0 {
|
||||
if clone, err = patchUpdateSpecToPod(clone, spec, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
delete(clone.Annotations, appsv1alpha1.InPlaceUpdateGraceKey)
|
||||
delete(clone.Annotations, appspub.InPlaceUpdateGraceKey)
|
||||
} else {
|
||||
inPlaceUpdateSpecJSON, _ := json.Marshal(spec)
|
||||
clone.Annotations[appsv1alpha1.InPlaceUpdateGraceKey] = string(inPlaceUpdateSpecJSON)
|
||||
clone.Annotations[appspub.InPlaceUpdateGraceKey] = string(inPlaceUpdateSpecJSON)
|
||||
}
|
||||
|
||||
return c.adp.updatePod(clone)
|
||||
|
|
@ -416,8 +416,8 @@ func GetTemplateFromRevision(revision *apps.ControllerRevision) (*v1.PodTemplate
|
|||
// If the imageID in containerStatuses has not been changed, we assume that kubelet has not updated
|
||||
// containers in Pod.
|
||||
func CheckInPlaceUpdateCompleted(pod *v1.Pod) error {
|
||||
inPlaceUpdateState := appsv1alpha1.InPlaceUpdateState{}
|
||||
if stateStr, ok := pod.Annotations[appsv1alpha1.InPlaceUpdateStateKey]; !ok {
|
||||
inPlaceUpdateState := appspub.InPlaceUpdateState{}
|
||||
if stateStr, ok := pod.Annotations[appspub.InPlaceUpdateStateKey]; !ok {
|
||||
return nil
|
||||
} else if err := json.Unmarshal([]byte(stateStr), &inPlaceUpdateState); err != nil {
|
||||
return err
|
||||
|
|
@ -438,7 +438,7 @@ func CheckInPlaceUpdateCompleted(pod *v1.Pod) error {
|
|||
}
|
||||
}
|
||||
|
||||
_, isInGraceState := pod.Annotations[appsv1alpha1.InPlaceUpdateGraceKey]
|
||||
_, isInGraceState := pod.Annotations[appspub.InPlaceUpdateGraceKey]
|
||||
for _, cs := range pod.Status.ContainerStatuses {
|
||||
if oldStatus, ok := inPlaceUpdateState.LastContainerStatuses[cs.Name]; ok {
|
||||
// TODO: we assume that users should not update workload template with new image which actually has the same imageID as the old image
|
||||
|
|
@ -461,16 +461,16 @@ func CheckInPlaceUpdateCompleted(pod *v1.Pod) error {
|
|||
// InjectReadinessGate injects InPlaceUpdateReady into pod.spec.readinessGates
|
||||
func InjectReadinessGate(pod *v1.Pod) {
|
||||
for _, r := range pod.Spec.ReadinessGates {
|
||||
if r.ConditionType == appsv1alpha1.InPlaceUpdateReady {
|
||||
if r.ConditionType == appspub.InPlaceUpdateReady {
|
||||
return
|
||||
}
|
||||
}
|
||||
pod.Spec.ReadinessGates = append(pod.Spec.ReadinessGates, v1.PodReadinessGate{ConditionType: appsv1alpha1.InPlaceUpdateReady})
|
||||
pod.Spec.ReadinessGates = append(pod.Spec.ReadinessGates, v1.PodReadinessGate{ConditionType: appspub.InPlaceUpdateReady})
|
||||
}
|
||||
|
||||
func containsReadinessGate(pod *v1.Pod) bool {
|
||||
for _, r := range pod.Spec.ReadinessGates {
|
||||
if r.ConditionType == appsv1alpha1.InPlaceUpdateReady {
|
||||
if r.ConditionType == appspub.InPlaceUpdateReady {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -479,7 +479,7 @@ func containsReadinessGate(pod *v1.Pod) bool {
|
|||
|
||||
// GetCondition returns the InPlaceUpdateReady condition in Pod.
|
||||
func GetCondition(pod *v1.Pod) *v1.PodCondition {
|
||||
return getCondition(pod, appsv1alpha1.InPlaceUpdateReady)
|
||||
return getCondition(pod, appspub.InPlaceUpdateReady)
|
||||
}
|
||||
|
||||
func getCondition(pod *v1.Pod, cType v1.PodConditionType) *v1.PodCondition {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
"github.com/openkruise/kruise/pkg/util"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
|
@ -143,7 +143,7 @@ func TestCheckInPlaceUpdateCompleted(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
appspub.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
|
|
@ -164,7 +164,7 @@ func TestCheckInPlaceUpdateCompleted(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: `{"revision":"old-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
appspub.InPlaceUpdateStateKey: `{"revision":"old-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
|
|
@ -183,7 +183,7 @@ func TestCheckInPlaceUpdateCompleted(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
appspub.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
|
|
@ -203,7 +203,7 @@ func TestCheckInPlaceUpdateCompleted(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
appspub.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{},
|
||||
|
|
@ -244,11 +244,11 @@ func TestRefresh(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
appspub.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
},
|
||||
expectedPod: &v1.Pod{
|
||||
|
|
@ -257,11 +257,11 @@ func TestRefresh(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
appspub.InPlaceUpdateStateKey: `{"revision":"new-revision","lastContainerStatuses":{"c1":{"imageID":"img01"}}}`,
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -269,16 +269,16 @@ func TestRefresh(t *testing.T) {
|
|||
name: "no existing condition",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
},
|
||||
expectedPod: &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Conditions: []v1.PodCondition{{Type: appsv1alpha1.InPlaceUpdateReady, Status: v1.ConditionTrue, LastTransitionTime: aHourAgo}},
|
||||
Conditions: []v1.PodCondition{{Type: appspub.InPlaceUpdateReady, Status: v1.ConditionTrue, LastTransitionTime: aHourAgo}},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -286,7 +286,7 @@ func TestRefresh(t *testing.T) {
|
|||
name: "existing condition status is False",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Conditions: []v1.PodCondition{
|
||||
|
|
@ -295,7 +295,7 @@ func TestRefresh(t *testing.T) {
|
|||
Status: v1.ConditionTrue,
|
||||
},
|
||||
{
|
||||
Type: appsv1alpha1.InPlaceUpdateReady,
|
||||
Type: appspub.InPlaceUpdateReady,
|
||||
Status: v1.ConditionFalse,
|
||||
},
|
||||
},
|
||||
|
|
@ -304,7 +304,7 @@ func TestRefresh(t *testing.T) {
|
|||
expectedPod: &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"},
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Conditions: []v1.PodCondition{
|
||||
|
|
@ -313,7 +313,7 @@ func TestRefresh(t *testing.T) {
|
|||
Status: v1.ConditionTrue,
|
||||
},
|
||||
{
|
||||
Type: appsv1alpha1.InPlaceUpdateReady,
|
||||
Type: appspub.InPlaceUpdateReady,
|
||||
Status: v1.ConditionTrue,
|
||||
LastTransitionTime: aHourAgo,
|
||||
},
|
||||
|
|
@ -325,7 +325,7 @@ func TestRefresh(t *testing.T) {
|
|||
name: "existing condition status is True",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Conditions: []v1.PodCondition{
|
||||
|
|
@ -334,7 +334,7 @@ func TestRefresh(t *testing.T) {
|
|||
Status: v1.ConditionFalse,
|
||||
},
|
||||
{
|
||||
Type: appsv1alpha1.InPlaceUpdateReady,
|
||||
Type: appspub.InPlaceUpdateReady,
|
||||
Status: v1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
|
|
@ -342,7 +342,7 @@ func TestRefresh(t *testing.T) {
|
|||
},
|
||||
expectedPod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Conditions: []v1.PodCondition{
|
||||
|
|
@ -351,7 +351,7 @@ func TestRefresh(t *testing.T) {
|
|||
Status: v1.ConditionFalse,
|
||||
},
|
||||
{
|
||||
Type: appsv1alpha1.InPlaceUpdateReady,
|
||||
Type: appspub.InPlaceUpdateReady,
|
||||
Status: v1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
|
|
@ -366,13 +366,13 @@ func TestRefresh(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{Revision: "new-revision", UpdateTimestamp: tenSecondsAgo, LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "img01"}}}),
|
||||
appsv1alpha1.InPlaceUpdateGraceKey: `{"revision":"new-revision","containerImages":{"main":"img-name02"},"graceSeconds":30}`,
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{Revision: "new-revision", UpdateTimestamp: tenSecondsAgo, LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "img01"}}}),
|
||||
appspub.InPlaceUpdateGraceKey: `{"revision":"new-revision","containerImages":{"main":"img-name02"},"graceSeconds":30}`,
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{{Name: "main", Image: "img-name01"}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
},
|
||||
expectedPod: &v1.Pod{
|
||||
|
|
@ -381,13 +381,13 @@ func TestRefresh(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{Revision: "new-revision", UpdateTimestamp: tenSecondsAgo, LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "img01"}}}),
|
||||
appsv1alpha1.InPlaceUpdateGraceKey: `{"revision":"new-revision","containerImages":{"main":"img-name02"},"graceSeconds":30}`,
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{Revision: "new-revision", UpdateTimestamp: tenSecondsAgo, LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "img01"}}}),
|
||||
appspub.InPlaceUpdateGraceKey: `{"revision":"new-revision","containerImages":{"main":"img-name02"},"graceSeconds":30}`,
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{{Name: "main", Image: "img-name01"}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -399,13 +399,13 @@ func TestRefresh(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{Revision: "new-revision", UpdateTimestamp: tenSecondsAgo, LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "img01"}}}),
|
||||
appsv1alpha1.InPlaceUpdateGraceKey: `{"revision":"new-revision","containerImages":{"main":"img-name02"},"graceSeconds":5}`,
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{Revision: "new-revision", UpdateTimestamp: tenSecondsAgo, LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "img01"}}}),
|
||||
appspub.InPlaceUpdateGraceKey: `{"revision":"new-revision","containerImages":{"main":"img-name02"},"graceSeconds":5}`,
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{{Name: "main", Image: "img-name01"}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
},
|
||||
expectedPod: &v1.Pod{
|
||||
|
|
@ -414,13 +414,13 @@ func TestRefresh(t *testing.T) {
|
|||
apps.StatefulSetRevisionLabel: "new-revision",
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
appsv1alpha1.InPlaceUpdateStateKey: util.DumpJSON(appsv1alpha1.InPlaceUpdateState{Revision: "new-revision", UpdateTimestamp: tenSecondsAgo, LastContainerStatuses: map[string]appsv1alpha1.InPlaceUpdateContainerStatus{"c1": {ImageID: "img01"}}}),
|
||||
appspub.InPlaceUpdateStateKey: util.DumpJSON(appspub.InPlaceUpdateState{Revision: "new-revision", UpdateTimestamp: tenSecondsAgo, LastContainerStatuses: map[string]appspub.InPlaceUpdateContainerStatus{"c1": {ImageID: "img01"}}}),
|
||||
},
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{{Name: "main", Image: "img-name02"}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appsv1alpha1.InPlaceUpdateReady}},
|
||||
ReadinessGates: []v1.PodReadinessGate{{ConditionType: appspub.InPlaceUpdateReady}},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,18 +20,18 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
func GetPodLifecycleState(pod *v1.Pod) appsv1alpha1.LifecycleStateType {
|
||||
return appsv1alpha1.LifecycleStateType(pod.Labels[appsv1alpha1.LifecycleStateKey])
|
||||
func GetPodLifecycleState(pod *v1.Pod) appspub.LifecycleStateType {
|
||||
return appspub.LifecycleStateType(pod.Labels[appspub.LifecycleStateKey])
|
||||
}
|
||||
|
||||
func SetPodLifecycle(state appsv1alpha1.LifecycleStateType) func(*v1.Pod) {
|
||||
func SetPodLifecycle(state appspub.LifecycleStateType) func(*v1.Pod) {
|
||||
return func(pod *v1.Pod) {
|
||||
if pod.Labels == nil {
|
||||
pod.Labels = make(map[string]string)
|
||||
|
|
@ -39,27 +39,27 @@ func SetPodLifecycle(state appsv1alpha1.LifecycleStateType) func(*v1.Pod) {
|
|||
if pod.Annotations == nil {
|
||||
pod.Annotations = make(map[string]string)
|
||||
}
|
||||
pod.Labels[appsv1alpha1.LifecycleStateKey] = string(state)
|
||||
pod.Annotations[appsv1alpha1.LifecycleTimestampKey] = time.Now().Format(time.RFC3339)
|
||||
pod.Labels[appspub.LifecycleStateKey] = string(state)
|
||||
pod.Annotations[appspub.LifecycleTimestampKey] = time.Now().Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
|
||||
func PatchPodLifecycle(c client.Client, pod *v1.Pod, state appsv1alpha1.LifecycleStateType) (bool, error) {
|
||||
func PatchPodLifecycle(c client.Client, pod *v1.Pod, state appspub.LifecycleStateType) (bool, error) {
|
||||
if GetPodLifecycleState(pod) == state {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
body := fmt.Sprintf(
|
||||
`{"metadata":{"labels":{"%s":"%s"},"annotations":{"%s":"%s"}}}`,
|
||||
appsv1alpha1.LifecycleStateKey,
|
||||
appspub.LifecycleStateKey,
|
||||
string(state),
|
||||
appsv1alpha1.LifecycleTimestampKey,
|
||||
appspub.LifecycleTimestampKey,
|
||||
time.Now().Format(time.RFC3339),
|
||||
)
|
||||
return true, c.Patch(nil, pod, client.RawPatch(types.StrategicMergePatchType, []byte(body)))
|
||||
}
|
||||
|
||||
func IsPodHooked(hook *appsv1alpha1.LifecycleHook, pod *v1.Pod) bool {
|
||||
func IsPodHooked(hook *appspub.LifecycleHook, pod *v1.Pod) bool {
|
||||
if hook == nil || pod == nil {
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,17 +20,17 @@ import (
|
|||
"sort"
|
||||
"strconv"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
type prioritySort struct {
|
||||
strategy *appsv1alpha1.UpdatePriorityStrategy
|
||||
strategy *appspub.UpdatePriorityStrategy
|
||||
}
|
||||
|
||||
func NewPrioritySorter(s *appsv1alpha1.UpdatePriorityStrategy) Sorter {
|
||||
func NewPrioritySorter(s *appspub.UpdatePriorityStrategy) Sorter {
|
||||
return &prioritySort{strategy: s}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,20 +19,20 @@ package updatesort
|
|||
import (
|
||||
"testing"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestCompare(t *testing.T) {
|
||||
cases := []struct {
|
||||
strategy *appsv1alpha1.UpdatePriorityStrategy
|
||||
strategy *appspub.UpdatePriorityStrategy
|
||||
podI map[string]string
|
||||
podJ map[string]string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "foo"}}},
|
||||
{Weight: 10, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "bar"}}},
|
||||
},
|
||||
|
|
@ -42,8 +42,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: true,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "foo"}}},
|
||||
{Weight: 10, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "bar"}}},
|
||||
},
|
||||
|
|
@ -53,8 +53,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: true,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "foo"}}},
|
||||
{Weight: 10, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "bar"}}},
|
||||
},
|
||||
|
|
@ -64,8 +64,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: false,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "foo"}}},
|
||||
{Weight: 10, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "bar"}}},
|
||||
},
|
||||
|
|
@ -75,8 +75,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: false,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "foo"}}},
|
||||
{Weight: 10, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "bar"}}},
|
||||
},
|
||||
|
|
@ -86,8 +86,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: false,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key1": "foo"}}},
|
||||
{Weight: 10, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key2": "bar"}}},
|
||||
{Weight: 15, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key3": "baz"}}},
|
||||
|
|
@ -98,8 +98,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: false,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key1": "foo"}}},
|
||||
{Weight: 10, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key2": "bar"}}},
|
||||
{Weight: 5, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key3": "baz"}}},
|
||||
|
|
@ -110,8 +110,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: false,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
OrderPriority: []appsv1alpha1.UpdatePriorityOrderTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
OrderPriority: []appspub.UpdatePriorityOrderTerm{
|
||||
{OrderedKey: "key1"},
|
||||
{OrderedKey: "key2"},
|
||||
},
|
||||
|
|
@ -121,8 +121,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: true,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
OrderPriority: []appsv1alpha1.UpdatePriorityOrderTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
OrderPriority: []appspub.UpdatePriorityOrderTerm{
|
||||
{OrderedKey: "key1"},
|
||||
{OrderedKey: "key2"},
|
||||
},
|
||||
|
|
@ -132,8 +132,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: true,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
OrderPriority: []appsv1alpha1.UpdatePriorityOrderTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
OrderPriority: []appspub.UpdatePriorityOrderTerm{
|
||||
{OrderedKey: "key1"},
|
||||
{OrderedKey: "key2"},
|
||||
},
|
||||
|
|
@ -143,8 +143,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: true,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
OrderPriority: []appsv1alpha1.UpdatePriorityOrderTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
OrderPriority: []appspub.UpdatePriorityOrderTerm{
|
||||
{OrderedKey: "key1"},
|
||||
{OrderedKey: "key2"},
|
||||
},
|
||||
|
|
@ -154,8 +154,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: false,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
OrderPriority: []appsv1alpha1.UpdatePriorityOrderTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
OrderPriority: []appspub.UpdatePriorityOrderTerm{
|
||||
{OrderedKey: "key1"},
|
||||
{OrderedKey: "key2"},
|
||||
},
|
||||
|
|
@ -165,8 +165,8 @@ func TestCompare(t *testing.T) {
|
|||
expected: false,
|
||||
},
|
||||
{
|
||||
strategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
OrderPriority: []appsv1alpha1.UpdatePriorityOrderTerm{
|
||||
strategy: &appspub.UpdatePriorityStrategy{
|
||||
OrderPriority: []appspub.UpdatePriorityOrderTerm{
|
||||
{OrderedKey: "key1"},
|
||||
{OrderedKey: "key2"},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
)
|
||||
|
||||
|
|
@ -151,8 +151,8 @@ func TestValidate(t *testing.T) {
|
|||
Type: appsv1alpha1.InPlaceIfPossibleCloneSetUpdateStrategyType,
|
||||
Partition: &val2,
|
||||
MaxUnavailable: &maxUnavailable120Percent,
|
||||
PriorityStrategy: &appsv1alpha1.UpdatePriorityStrategy{
|
||||
WeightPriority: []appsv1alpha1.UpdatePriorityWeightTerm{
|
||||
PriorityStrategy: &appspub.UpdatePriorityStrategy{
|
||||
WeightPriority: []appspub.UpdatePriorityWeightTerm{
|
||||
{Weight: 20, MatchSelector: metav1.LabelSelector{MatchLabels: map[string]string{"key": "foo"}}},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/conversion"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -66,6 +67,9 @@ func SetupWithManager(mgr manager.Manager) error {
|
|||
klog.V(3).Infof("Registered webhook handler %s", path)
|
||||
}
|
||||
|
||||
// register conversion webhook
|
||||
server.Register("/convert", &conversion.Webhook{})
|
||||
|
||||
// register health handler
|
||||
server.Register("/healthz", &health.Handler{})
|
||||
|
||||
|
|
@ -75,6 +79,7 @@ func SetupWithManager(mgr manager.Manager) error {
|
|||
// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=validatingwebhookconfigurations,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch;update;patch
|
||||
|
||||
func Initialize(mgr manager.Manager, stopCh <-chan struct{}) error {
|
||||
cli := &client.DelegatingClient{
|
||||
|
|
@ -83,7 +88,7 @@ func Initialize(mgr manager.Manager, stopCh <-chan struct{}) error {
|
|||
StatusClient: mgr.GetClient(),
|
||||
}
|
||||
|
||||
c, err := webhookcontroller.New(cli, HandlerMap)
|
||||
c, err := webhookcontroller.New(mgr.GetConfig(), cli, HandlerMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -91,7 +96,7 @@ func Initialize(mgr manager.Manager, stopCh <-chan struct{}) error {
|
|||
c.Start(stopCh)
|
||||
}()
|
||||
|
||||
timer := time.NewTimer(time.Second * 5)
|
||||
timer := time.NewTimer(time.Second * 20)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case <-webhookcontroller.Inited():
|
||||
|
|
|
|||
|
|
@ -19,9 +19,11 @@ package mutating
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
"github.com/openkruise/kruise/pkg/util"
|
||||
"k8s.io/klog"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
|
@ -43,20 +45,44 @@ var _ admission.Handler = &StatefulSetCreateUpdateHandler{}
|
|||
|
||||
// Handle handles admission requests.
|
||||
func (h *StatefulSetCreateUpdateHandler) Handle(ctx context.Context, req admission.Request) admission.Response {
|
||||
obj := &appsv1alpha1.StatefulSet{}
|
||||
obj := &appsv1beta1.StatefulSet{}
|
||||
var objv1alpha1 *appsv1alpha1.StatefulSet
|
||||
|
||||
err := h.Decoder.Decode(req, obj)
|
||||
if err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
switch req.AdmissionRequest.Resource.Version {
|
||||
case appsv1beta1.GroupVersion.Version:
|
||||
if err := h.Decoder.Decode(req, obj); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
}
|
||||
case appsv1alpha1.GroupVersion.Version:
|
||||
objv1alpha1 = &appsv1alpha1.StatefulSet{}
|
||||
if err := h.Decoder.Decode(req, objv1alpha1); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
}
|
||||
if err := objv1alpha1.ConvertTo(obj); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, fmt.Errorf("failed to convert v1alpha1->v1beta1: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
appsv1alpha1.SetDefaultsStatefulSet(obj)
|
||||
obj.Status = appsv1alpha1.StatefulSetStatus{}
|
||||
appsv1beta1.SetDefaultsStatefulSet(obj)
|
||||
obj.Status = appsv1beta1.StatefulSetStatus{}
|
||||
|
||||
marshalled, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return admission.Errored(http.StatusInternalServerError, err)
|
||||
var err error
|
||||
var marshalled []byte
|
||||
if objv1alpha1 != nil {
|
||||
if err := objv1alpha1.ConvertFrom(obj); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, fmt.Errorf("failed to convert v1beta1->v1alpha1: %v", err))
|
||||
}
|
||||
marshalled, err = json.Marshal(objv1alpha1)
|
||||
if err != nil {
|
||||
return admission.Errored(http.StatusInternalServerError, err)
|
||||
}
|
||||
} else {
|
||||
marshalled, err = json.Marshal(obj)
|
||||
if err != nil {
|
||||
return admission.Errored(http.StatusInternalServerError, err)
|
||||
}
|
||||
}
|
||||
|
||||
resp := admission.PatchResponseFromRaw(req.AdmissionRequest.Object.Raw, marshalled)
|
||||
if len(resp.Patches) > 0 {
|
||||
klog.V(5).Infof("Admit StatefulSet %s/%s patches: %v", obj.Namespace, obj.Name, util.DumpJSON(resp.Patches))
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ import (
|
|||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
)
|
||||
|
||||
// +kubebuilder:webhook:path=/mutate-apps-kruise-io-v1alpha1-statefulset,mutating=true,failurePolicy=fail,groups=apps.kruise.io,resources=statefulsets,verbs=create;update,versions=v1alpha1,name=mstatefulset.kb.io
|
||||
// +kubebuilder:webhook:path=/mutate-apps-kruise-io-statefulset,mutating=true,failurePolicy=fail,groups=apps.kruise.io,resources=statefulsets,verbs=create;update,versions=v1alpha1;v1beta1,name=mstatefulset.kb.io
|
||||
|
||||
var (
|
||||
// HandlerMap contains admission webhook handlers
|
||||
HandlerMap = map[string]admission.Handler{
|
||||
"mutate-apps-kruise-io-v1alpha1-statefulset": &StatefulSetCreateUpdateHandler{},
|
||||
"mutate-apps-kruise-io-statefulset": &StatefulSetCreateUpdateHandler{},
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import (
|
|||
"net/http"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
)
|
||||
|
|
@ -42,11 +44,21 @@ var _ admission.Handler = &StatefulSetCreateUpdateHandler{}
|
|||
|
||||
// Handle handles admission requests.
|
||||
func (h *StatefulSetCreateUpdateHandler) Handle(ctx context.Context, req admission.Request) admission.Response {
|
||||
obj := &appsv1alpha1.StatefulSet{}
|
||||
obj := &appsv1beta1.StatefulSet{}
|
||||
|
||||
err := h.Decoder.Decode(req, obj)
|
||||
if err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
switch req.AdmissionRequest.Resource.Version {
|
||||
case appsv1beta1.GroupVersion.Version:
|
||||
if err := h.Decoder.Decode(req, obj); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
}
|
||||
case appsv1alpha1.GroupVersion.Version:
|
||||
objv1alpha1 := &appsv1alpha1.StatefulSet{}
|
||||
if err := h.Decoder.Decode(req, objv1alpha1); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
}
|
||||
if err := objv1alpha1.ConvertTo(obj); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, fmt.Errorf("failed to convert v1alpha1->v1beta1: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
switch req.AdmissionRequest.Operation {
|
||||
|
|
@ -55,9 +67,21 @@ func (h *StatefulSetCreateUpdateHandler) Handle(ctx context.Context, req admissi
|
|||
return admission.Errored(http.StatusUnprocessableEntity, allErrs.ToAggregate())
|
||||
}
|
||||
case admissionv1beta1.Update:
|
||||
oldObj := &appsv1alpha1.StatefulSet{}
|
||||
if err := h.Decoder.DecodeRaw(req.AdmissionRequest.OldObject, oldObj); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
oldObj := &appsv1beta1.StatefulSet{}
|
||||
|
||||
switch req.AdmissionRequest.Resource.Version {
|
||||
case appsv1beta1.GroupVersion.Version:
|
||||
if err := h.Decoder.DecodeRaw(req.AdmissionRequest.OldObject, oldObj); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
}
|
||||
case appsv1alpha1.GroupVersion.Version:
|
||||
objv1alpha1 := &appsv1alpha1.StatefulSet{}
|
||||
if err := h.Decoder.DecodeRaw(req.AdmissionRequest.OldObject, objv1alpha1); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
}
|
||||
if err := objv1alpha1.ConvertTo(oldObj); err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, fmt.Errorf("failed to convert v1alpha1->v1beta1: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
validationErrorList := validateStatefulSet(obj)
|
||||
|
|
@ -67,7 +91,7 @@ func (h *StatefulSetCreateUpdateHandler) Handle(ctx context.Context, req admissi
|
|||
}
|
||||
|
||||
if obj.Spec.UpdateStrategy.RollingUpdate != nil &&
|
||||
obj.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy == appsv1alpha1.InPlaceOnlyPodUpdateStrategyType {
|
||||
obj.Spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy == appsv1beta1.InPlaceOnlyPodUpdateStrategyType {
|
||||
if err := validateTemplateInPlaceOnly(&oldObj.Spec.Template, &obj.Spec.Template); err != nil {
|
||||
return admission.Errored(http.StatusUnprocessableEntity,
|
||||
fmt.Errorf("invalid template modified with InPlaceOnly strategy: %v, currently only image update is allowed for InPlaceOnly", err))
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import (
|
|||
"regexp"
|
||||
|
||||
"github.com/appscode/jsonpatch"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
|
|
@ -18,15 +20,13 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/core"
|
||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
)
|
||||
|
||||
var inPlaceUpdateTemplateSpecPatchRexp = regexp.MustCompile("/containers/([0-9]+)/image")
|
||||
|
||||
// TODO (rz): break this giant function down further and use unit testing
|
||||
// ValidateStatefulSetSpec tests if required fields in the StatefulSet spec are set.
|
||||
func validateStatefulSetSpec(spec *appsv1alpha1.StatefulSetSpec, fldPath *field.Path) field.ErrorList {
|
||||
func validateStatefulSetSpec(spec *appsv1beta1.StatefulSetSpec, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
switch spec.PodManagementPolicy {
|
||||
|
|
@ -60,7 +60,7 @@ func validateStatefulSetSpec(spec *appsv1alpha1.StatefulSetSpec, fldPath *field.
|
|||
apivalidation.ValidateNonnegativeField(
|
||||
int64(*spec.UpdateStrategy.RollingUpdate.MinReadySeconds),
|
||||
fldPath.Child("updateStrategy").Child("rollingUpdate").Child("minReadySeconds"))...)
|
||||
if *spec.UpdateStrategy.RollingUpdate.MinReadySeconds > appsv1alpha1.MaxMinReadySeconds {
|
||||
if *spec.UpdateStrategy.RollingUpdate.MinReadySeconds > appsv1beta1.MaxMinReadySeconds {
|
||||
allErrs = append(allErrs,
|
||||
field.Invalid(fldPath.Child("updateStrategy").Child("rollingUpdate").Child("minReadySeconds"),
|
||||
*spec.UpdateStrategy.RollingUpdate.MinReadySeconds,
|
||||
|
|
@ -126,16 +126,16 @@ func validateStatefulSetSpec(spec *appsv1alpha1.StatefulSetSpec, fldPath *field.
|
|||
return allErrs
|
||||
}
|
||||
|
||||
func validatePodUpdatePolicy(spec *appsv1alpha1.StatefulSetSpec, fldPath *field.Path) field.ErrorList {
|
||||
func validatePodUpdatePolicy(spec *appsv1beta1.StatefulSetSpec, fldPath *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
switch spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy {
|
||||
case "":
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("updateStrategy").Child("rollingUpdate").Child("podUpdatePolicy"), ""))
|
||||
case appsv1alpha1.RecreatePodUpdateStrategyType:
|
||||
case appsv1alpha1.InPlaceIfPossiblePodUpdateStrategyType, appsv1alpha1.InPlaceOnlyPodUpdateStrategyType:
|
||||
case appsv1beta1.RecreatePodUpdateStrategyType:
|
||||
case appsv1beta1.InPlaceIfPossiblePodUpdateStrategyType, appsv1beta1.InPlaceOnlyPodUpdateStrategyType:
|
||||
var containsReadinessGate bool
|
||||
for _, r := range spec.Template.Spec.ReadinessGates {
|
||||
if r.ConditionType == appsv1alpha1.InPlaceUpdateReady {
|
||||
if r.ConditionType == appspub.InPlaceUpdateReady {
|
||||
containsReadinessGate = true
|
||||
break
|
||||
}
|
||||
|
|
@ -145,7 +145,7 @@ func validatePodUpdatePolicy(spec *appsv1alpha1.StatefulSetSpec, fldPath *field.
|
|||
field.Invalid(fldPath.Child("template").Child("spec").Child("readinessGates"),
|
||||
spec.Template.Spec.ReadinessGates,
|
||||
fmt.Sprintf("must contains %v when podUpdatePolicy is %v",
|
||||
appsv1alpha1.InPlaceUpdateReady,
|
||||
appspub.InPlaceUpdateReady,
|
||||
spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy)))
|
||||
}
|
||||
default:
|
||||
|
|
@ -153,14 +153,14 @@ func validatePodUpdatePolicy(spec *appsv1alpha1.StatefulSetSpec, fldPath *field.
|
|||
field.Invalid(fldPath.Child("updateStrategy").Child("rollingUpdate").Child("podUpdatePolicy"),
|
||||
spec.UpdateStrategy.RollingUpdate.PodUpdatePolicy,
|
||||
fmt.Sprintf("must be '%s', %s or '%s'",
|
||||
appsv1alpha1.RecreatePodUpdateStrategyType,
|
||||
appsv1alpha1.InPlaceIfPossiblePodUpdateStrategyType,
|
||||
appsv1alpha1.InPlaceOnlyPodUpdateStrategyType)))
|
||||
appsv1beta1.RecreatePodUpdateStrategyType,
|
||||
appsv1beta1.InPlaceIfPossiblePodUpdateStrategyType,
|
||||
appsv1beta1.InPlaceOnlyPodUpdateStrategyType)))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateMaxUnavailableField(spec *appsv1alpha1.StatefulSetSpec, fldPath *field.Path) field.ErrorList {
|
||||
func validateMaxUnavailableField(spec *appsv1beta1.StatefulSetSpec, fldPath *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
if spec.UpdateStrategy.RollingUpdate.MaxUnavailable == nil {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("updateStrategy").
|
||||
|
|
@ -201,14 +201,14 @@ func validateMaxUnavailableField(spec *appsv1alpha1.StatefulSetSpec, fldPath *fi
|
|||
}
|
||||
|
||||
// ValidateStatefulSet validates a StatefulSet.
|
||||
func validateStatefulSet(statefulSet *appsv1alpha1.StatefulSet) field.ErrorList {
|
||||
func validateStatefulSet(statefulSet *appsv1beta1.StatefulSet) field.ErrorList {
|
||||
allErrs := apivalidation.ValidateObjectMeta(&statefulSet.ObjectMeta, true, appsvalidation.ValidateStatefulSetName, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, validateStatefulSetSpec(&statefulSet.Spec, field.NewPath("spec"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateStatefulSetUpdate tests if required fields in the StatefulSet are set.
|
||||
func ValidateStatefulSetUpdate(statefulSet, oldStatefulSet *appsv1alpha1.StatefulSet) field.ErrorList {
|
||||
func ValidateStatefulSetUpdate(statefulSet, oldStatefulSet *appsv1beta1.StatefulSet) field.ErrorList {
|
||||
allErrs := apivalidation.ValidateObjectMetaUpdate(&statefulSet.ObjectMeta, &oldStatefulSet.ObjectMeta, field.NewPath("metadata"))
|
||||
|
||||
restoreReplicas := statefulSet.Spec.Replicas
|
||||
|
|
|
|||
|
|
@ -21,13 +21,12 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
)
|
||||
|
||||
func TestValidateStatefulSet(t *testing.T) {
|
||||
|
|
@ -78,56 +77,56 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
var minus1 int32 = -1
|
||||
maxUnavailable1 := intstr.FromInt(1)
|
||||
maxUnavailable120Percent := intstr.FromString("120%")
|
||||
successCases := []appsv1alpha1.StatefulSet{
|
||||
successCases := []appsv1beta1.StatefulSet{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.ParallelPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{
|
||||
Type: apps.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1alpha1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1alpha1.RollingUpdateStatefulSetStrategy{
|
||||
RollingUpdate: func() *appsv1beta1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1beta1.RollingUpdateStatefulSetStrategy{
|
||||
Partition: &val2,
|
||||
PodUpdatePolicy: appsv1alpha1.RecreatePodUpdateStrategyType,
|
||||
PodUpdatePolicy: appsv1beta1.RecreatePodUpdateStrategyType,
|
||||
MaxUnavailable: &maxUnavailable1,
|
||||
MinReadySeconds: utilpointer.Int32Ptr(10),
|
||||
}
|
||||
|
|
@ -146,57 +145,57 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
}
|
||||
|
||||
// TODO: break the failed cases out with expected error instead of just pass with any error
|
||||
errorCases := map[string]appsv1alpha1.StatefulSet{
|
||||
errorCases := map[string]appsv1beta1.StatefulSet{
|
||||
"zero-length ID": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"missing-namespace": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123"},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"empty selector": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"selector_doesnt_match": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid manifest": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"negative_replicas": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Replicas: &minus1,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid_label": {
|
||||
|
|
@ -207,11 +206,11 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid_label 2": {
|
||||
|
|
@ -222,10 +221,10 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Template: invalidPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid_annotation": {
|
||||
|
|
@ -236,11 +235,11 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid restart policy 1": {
|
||||
|
|
@ -248,7 +247,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Name: "abc-123",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: v1.PodTemplateSpec{
|
||||
|
|
@ -261,7 +260,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Labels: validLabels,
|
||||
},
|
||||
},
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid restart policy 2": {
|
||||
|
|
@ -269,7 +268,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Name: "abc-123",
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: v1.PodTemplateSpec{
|
||||
|
|
@ -282,93 +281,93 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
Labels: validLabels,
|
||||
},
|
||||
},
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid update strategy": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: "foo"},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: "foo"},
|
||||
},
|
||||
},
|
||||
"empty update strategy": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: ""},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: ""},
|
||||
},
|
||||
},
|
||||
"invalid rolling update": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1alpha1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1alpha1.RollingUpdateStatefulSetStrategy{Partition: &val1}
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1beta1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1beta1.RollingUpdateStatefulSetStrategy{Partition: &val1}
|
||||
}()},
|
||||
},
|
||||
},
|
||||
"invalid rolling update 1": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1alpha1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1alpha1.RollingUpdateStatefulSetStrategy{MaxUnavailable: &maxUnavailable120Percent}
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1beta1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1beta1.RollingUpdateStatefulSetStrategy{MaxUnavailable: &maxUnavailable120Percent}
|
||||
}()},
|
||||
},
|
||||
},
|
||||
"invalid rolling update 2": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1alpha1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1alpha1.RollingUpdateStatefulSetStrategy{PodUpdatePolicy: "Unknown"}
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1beta1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1beta1.RollingUpdateStatefulSetStrategy{PodUpdatePolicy: "Unknown"}
|
||||
}()},
|
||||
},
|
||||
},
|
||||
"invalid rolling update 3": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1alpha1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1alpha1.RollingUpdateStatefulSetStrategy{PodUpdatePolicy: appsv1alpha1.InPlaceIfPossiblePodUpdateStrategyType}
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.OnDeleteStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1beta1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1beta1.RollingUpdateStatefulSetStrategy{PodUpdatePolicy: appsv1beta1.InPlaceIfPossiblePodUpdateStrategyType}
|
||||
}()},
|
||||
},
|
||||
},
|
||||
"negative partition": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1alpha1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1alpha1.RollingUpdateStatefulSetStrategy{
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: func() *appsv1beta1.RollingUpdateStatefulSetStrategy {
|
||||
return &appsv1beta1.RollingUpdateStatefulSetStrategy{
|
||||
Partition: &minus1,
|
||||
PodUpdatePolicy: appsv1alpha1.RecreatePodUpdateStrategyType,
|
||||
PodUpdatePolicy: appsv1beta1.RecreatePodUpdateStrategyType,
|
||||
MaxUnavailable: &maxUnavailable1,
|
||||
MinReadySeconds: utilpointer.Int32Ptr(1),
|
||||
}
|
||||
|
|
@ -377,15 +376,15 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
},
|
||||
"negative minReadySeconds": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: &appsv1alpha1.RollingUpdateStatefulSetStrategy{
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: &appsv1beta1.RollingUpdateStatefulSetStrategy{
|
||||
Partition: &minus1,
|
||||
PodUpdatePolicy: appsv1alpha1.RecreatePodUpdateStrategyType,
|
||||
PodUpdatePolicy: appsv1beta1.RecreatePodUpdateStrategyType,
|
||||
MaxUnavailable: &maxUnavailable1,
|
||||
MinReadySeconds: utilpointer.Int32Ptr(-1),
|
||||
},
|
||||
|
|
@ -394,49 +393,49 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
},
|
||||
"too large minReadySeconds": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: &appsv1alpha1.RollingUpdateStatefulSetStrategy{
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType,
|
||||
RollingUpdate: &appsv1beta1.RollingUpdateStatefulSetStrategy{
|
||||
Partition: &minus1,
|
||||
PodUpdatePolicy: appsv1alpha1.RecreatePodUpdateStrategyType,
|
||||
PodUpdatePolicy: appsv1beta1.RecreatePodUpdateStrategyType,
|
||||
MaxUnavailable: &maxUnavailable1,
|
||||
MinReadySeconds: utilpointer.Int32Ptr(appsv1alpha1.MaxMinReadySeconds + 1),
|
||||
MinReadySeconds: utilpointer.Int32Ptr(appsv1beta1.MaxMinReadySeconds + 1),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"empty pod management policy": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: "",
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"invalid pod management policy": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: "foo",
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: validPodTemplate.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
"set active deadline seconds": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
|
||||
Spec: appsv1alpha1.StatefulSetSpec{
|
||||
Spec: appsv1beta1.StatefulSetSpec{
|
||||
PodManagementPolicy: "foo",
|
||||
Selector: &metav1.LabelSelector{MatchLabels: validLabels},
|
||||
Template: invalidPodTemplate2.Template,
|
||||
Replicas: &val3,
|
||||
UpdateStrategy: appsv1alpha1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
UpdateStrategy: appsv1beta1.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -478,7 +477,7 @@ func TestValidateStatefulSet(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func setTestDefault(obj *appsv1alpha1.StatefulSet) {
|
||||
func setTestDefault(obj *appsv1beta1.StatefulSet) {
|
||||
if obj.Spec.Replicas == nil {
|
||||
obj.Spec.Replicas = new(int32)
|
||||
*obj.Spec.Replicas = 0
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ import (
|
|||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
)
|
||||
|
||||
// +kubebuilder:webhook:path=/validate-apps-kruise-io-v1alpha1-statefulset,mutating=false,failurePolicy=fail,groups=apps.kruise.io,resources=statefulsets,verbs=create;update,versions=v1alpha1,name=vstatefulset.kb.io
|
||||
// +kubebuilder:webhook:path=/validate-apps-kruise-io-statefulset,mutating=false,failurePolicy=fail,groups=apps.kruise.io,resources=statefulsets,verbs=create;update,versions=v1alpha1;v1beta1,name=vstatefulset.kb.io
|
||||
|
||||
var (
|
||||
// HandlerMap contains admission webhook handlers
|
||||
HandlerMap = map[string]admission.Handler{
|
||||
"validate-apps-kruise-io-v1alpha1-statefulset": &StatefulSetCreateUpdateHandler{},
|
||||
"validate-apps-kruise-io-statefulset": &StatefulSetCreateUpdateHandler{},
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24,10 +24,15 @@ import (
|
|||
extclient "github.com/openkruise/kruise/pkg/client"
|
||||
webhookutil "github.com/openkruise/kruise/pkg/webhook/util"
|
||||
"github.com/openkruise/kruise/pkg/webhook/util/configuration"
|
||||
"github.com/openkruise/kruise/pkg/webhook/util/crd"
|
||||
"github.com/openkruise/kruise/pkg/webhook/util/generator"
|
||||
"github.com/openkruise/kruise/pkg/webhook/util/writer"
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
apiextensionsinformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1beta1"
|
||||
apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
|
@ -35,8 +40,7 @@ import (
|
|||
admissionregistrationinformers "k8s.io/client-go/informers/admissionregistration/v1beta1"
|
||||
coreinformers "k8s.io/client-go/informers/core/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
admissionregistrationlisters "k8s.io/client-go/listers/admissionregistration/v1beta1"
|
||||
corelisters "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog"
|
||||
|
|
@ -64,16 +68,19 @@ type Controller struct {
|
|||
runtimeClient client.Client
|
||||
handlers map[string]admission.Handler
|
||||
|
||||
informerFactory informers.SharedInformerFactory
|
||||
secretLister corelisters.SecretNamespaceLister
|
||||
mutatingWCLister admissionregistrationlisters.MutatingWebhookConfigurationLister
|
||||
validatingWCLister admissionregistrationlisters.ValidatingWebhookConfigurationLister
|
||||
synced []cache.InformerSynced
|
||||
informerFactory informers.SharedInformerFactory
|
||||
//secretLister corelisters.SecretNamespaceLister
|
||||
//mutatingWCLister admissionregistrationlisters.MutatingWebhookConfigurationLister
|
||||
//validatingWCLister admissionregistrationlisters.ValidatingWebhookConfigurationLister
|
||||
crdClient apiextensionsclientset.Interface
|
||||
crdInformer cache.SharedIndexInformer
|
||||
crdLister apiextensionslisters.CustomResourceDefinitionLister
|
||||
synced []cache.InformerSynced
|
||||
|
||||
queue workqueue.RateLimitingInterface
|
||||
}
|
||||
|
||||
func New(cli client.Client, handlers map[string]admission.Handler) (*Controller, error) {
|
||||
func New(cfg *rest.Config, cli client.Client, handlers map[string]admission.Handler) (*Controller, error) {
|
||||
c := &Controller{
|
||||
kubeClient: extclient.GetGenericClient().KubeClient,
|
||||
runtimeClient: cli,
|
||||
|
|
@ -85,17 +92,10 @@ func New(cli client.Client, handlers map[string]admission.Handler) (*Controller,
|
|||
c.informerFactory = informers.NewSharedInformerFactory(c.kubeClient, 0)
|
||||
|
||||
secretInformer := coreinformers.New(c.informerFactory, namespace, nil).Secrets()
|
||||
c.secretLister = secretInformer.Lister().Secrets(namespace)
|
||||
|
||||
admissionRegistrationInformer := admissionregistrationinformers.New(c.informerFactory, v1.NamespaceAll, nil)
|
||||
c.mutatingWCLister = admissionRegistrationInformer.MutatingWebhookConfigurations().Lister()
|
||||
c.validatingWCLister = admissionRegistrationInformer.ValidatingWebhookConfigurations().Lister()
|
||||
|
||||
c.synced = []cache.InformerSynced{
|
||||
secretInformer.Informer().HasSynced,
|
||||
admissionRegistrationInformer.MutatingWebhookConfigurations().Informer().HasSynced,
|
||||
admissionRegistrationInformer.ValidatingWebhookConfigurations().Informer().HasSynced,
|
||||
}
|
||||
//c.secretLister = secretInformer.Lister().Secrets(namespace)
|
||||
//c.mutatingWCLister = admissionRegistrationInformer.MutatingWebhookConfigurations().Lister()
|
||||
//c.validatingWCLister = admissionRegistrationInformer.ValidatingWebhookConfigurations().Lister()
|
||||
|
||||
secretInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
|
|
@ -148,6 +148,33 @@ func New(cli client.Client, handlers map[string]admission.Handler) (*Controller,
|
|||
},
|
||||
})
|
||||
|
||||
c.crdClient = apiextensionsclientset.NewForConfigOrDie(cfg)
|
||||
c.crdInformer = apiextensionsinformers.NewCustomResourceDefinitionInformer(c.crdClient, 0, cache.Indexers{})
|
||||
c.crdInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
crd := obj.(*apiextensionsv1beta1.CustomResourceDefinition)
|
||||
if crd.Spec.Group == "apps.kruise.io" {
|
||||
klog.Infof("CustomResourceDefinition %s added", crd.Name)
|
||||
c.queue.Add("")
|
||||
}
|
||||
},
|
||||
UpdateFunc: func(old, cur interface{}) {
|
||||
crd := cur.(*apiextensionsv1beta1.CustomResourceDefinition)
|
||||
if crd.Spec.Group == "apps.kruise.io" {
|
||||
klog.Infof("CustomResourceDefinition %s updated", crd.Name)
|
||||
c.queue.Add("")
|
||||
}
|
||||
},
|
||||
})
|
||||
c.crdLister = apiextensionslisters.NewCustomResourceDefinitionLister(c.crdInformer.GetIndexer())
|
||||
|
||||
c.synced = []cache.InformerSynced{
|
||||
secretInformer.Informer().HasSynced,
|
||||
admissionRegistrationInformer.MutatingWebhookConfigurations().Informer().HasSynced,
|
||||
admissionRegistrationInformer.ValidatingWebhookConfigurations().Informer().HasSynced,
|
||||
c.crdInformer.HasSynced,
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
|
|
@ -159,6 +186,9 @@ func (c *Controller) Start(stopCh <-chan struct{}) {
|
|||
defer klog.Infof("Shutting down webhook-controller")
|
||||
|
||||
c.informerFactory.Start(stopCh)
|
||||
go func() {
|
||||
c.crdInformer.Run(stopCh)
|
||||
}()
|
||||
if !cache.WaitForNamedCacheSync("webhook-controller", stopCh, c.synced...) {
|
||||
return
|
||||
}
|
||||
|
|
@ -228,6 +258,10 @@ func (c *Controller) sync() error {
|
|||
return fmt.Errorf("failed to ensure configuration: %v", err)
|
||||
}
|
||||
|
||||
if err := crd.Ensure(c.crdClient, c.crdLister, certs.CACert); err != nil {
|
||||
return fmt.Errorf("failed to ensure crd: %v", err)
|
||||
}
|
||||
|
||||
onceInit.Do(func() {
|
||||
close(uninit)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright 2020 The Kruise 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 crd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
webhookutil "github.com/openkruise/kruise/pkg/webhook/util"
|
||||
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
func Ensure(client apiextensionsclientset.Interface, lister apiextensionslisters.CustomResourceDefinitionLister, caBundle []byte) error {
|
||||
crdList, err := lister.List(labels.Everything())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list crds: %v", err)
|
||||
}
|
||||
|
||||
webhookConfig := apiextensionsv1beta1.WebhookClientConfig{
|
||||
CABundle: caBundle,
|
||||
}
|
||||
path := "/convert"
|
||||
if host := webhookutil.GetHost(); len(host) > 0 {
|
||||
url := fmt.Sprintf("https://%s:%d%s", host, webhookutil.GetPort(), path)
|
||||
webhookConfig.URL = &url
|
||||
} else {
|
||||
var port int32 = 443
|
||||
webhookConfig.Service = &apiextensionsv1beta1.ServiceReference{
|
||||
Namespace: webhookutil.GetNamespace(),
|
||||
Name: webhookutil.GetServiceName(),
|
||||
Port: &port,
|
||||
Path: &path,
|
||||
}
|
||||
}
|
||||
|
||||
for _, crd := range crdList {
|
||||
if crd.Spec.Group != "apps.kruise.io" {
|
||||
continue
|
||||
}
|
||||
if crd.Spec.Conversion == nil || crd.Spec.Conversion.Strategy != apiextensionsv1beta1.WebhookConverter {
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(crd.Spec.Conversion.WebhookClientConfig, webhookConfig) {
|
||||
newCRD := crd.DeepCopy()
|
||||
newCRD.Spec.Conversion.WebhookClientConfig = webhookConfig.DeepCopy()
|
||||
if _, err := client.ApiextensionsV1beta1().CustomResourceDefinitions().Update(newCRD); err != nil {
|
||||
return fmt.Errorf("failed to update CRD %s: %v", newCRD.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ func (s *secretCertWriter) read() (*generator.Artifacts, error) {
|
|||
return nil, notFoundError{err}
|
||||
}
|
||||
certs := secretToCerts(secret)
|
||||
if certs != nil {
|
||||
if certs != nil && certs.CACert != nil && certs.CAKey != nil {
|
||||
// Store the CA for next usage.
|
||||
s.CertGenerator.SetCA(certs.CAKey, certs.CACert)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ cp -r ./{apis,hack,vendor} "${TMP_DIR}"/src/github.com/openkruise/kruise/
|
|||
|
||||
(cd "${TMP_DIR}"/src/github.com/openkruise/kruise; \
|
||||
GOPATH=${TMP_DIR} GO111MODULE=off /bin/bash vendor/k8s.io/code-generator/generate-groups.sh all \
|
||||
github.com/openkruise/kruise/pkg/client github.com/openkruise/kruise/apis apps:v1alpha1 -h ./hack/boilerplate.go.txt)
|
||||
github.com/openkruise/kruise/pkg/client github.com/openkruise/kruise/apis "apps:v1alpha1 apps:v1beta1" -h ./hack/boilerplate.go.txt)
|
||||
|
||||
rm -rf ./pkg/client/{clientset,informers,listers}
|
||||
mv "${TMP_DIR}"/src/github.com/openkruise/kruise/pkg/client/* ./pkg/client
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/gomega"
|
||||
appspub "github.com/openkruise/kruise/apis/apps/pub"
|
||||
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
|
||||
kruiseclientset "github.com/openkruise/kruise/pkg/client/clientset/versioned"
|
||||
"github.com/openkruise/kruise/test/e2e/framework"
|
||||
|
|
@ -586,7 +587,7 @@ var _ = SIGDescribe("StatefulSet", func() {
|
|||
PodUpdatePolicy: appsv1alpha1.InPlaceIfPossiblePodUpdateStrategyType,
|
||||
},
|
||||
}
|
||||
ss.Spec.Template.Spec.ReadinessGates = append(ss.Spec.Template.Spec.ReadinessGates, v1.PodReadinessGate{ConditionType: appsv1alpha1.InPlaceUpdateReady})
|
||||
ss.Spec.Template.Spec.ReadinessGates = append(ss.Spec.Template.Spec.ReadinessGates, v1.PodReadinessGate{ConditionType: appspub.InPlaceUpdateReady})
|
||||
ss, err := kc.AppsV1alpha1().StatefulSets(ns).Create(ss)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
sst.WaitForRunningAndReady(*ss.Spec.Replicas, ss)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue