Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions xset/api/resourcecontext_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const (
EnumJustCreateContextDataKey
EnumRecreateUpdateContextDataKey
EnumScaleInContextDataKey
EnumReplaceNewTargetIDContextDataKey
EnumReplaceOriginTargetIDContextDataKey
)

// ResourceContextSpec defines the desired state of ResourceContext
Expand Down
9 changes: 8 additions & 1 deletion xset/api/xset_controller_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package api

import (
"context"

appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -35,18 +37,23 @@ type XSetController interface {

GetXSetSpec(object XSetObject) *XSetSpec
GetXSetPatch(object metav1.Object) ([]byte, error)
UpdateScaleStrategy(object XSetObject, scaleStrategy *ScaleStrategy) (err error)
GetXSetTemplatePatcher(object metav1.Object) func(client.Object) error
GetXSetStatus(object XSetObject) *XSetStatus
SetXSetStatus(object XSetObject, status *XSetStatus)
GetReadyTime(object client.Object) *metav1.Time

GetLifeCycleLabelManager() LifeCycleLabelManager
GetXSetControllerLabelManager() XSetLabelManager
GetScaleInOpsLifecycleAdapter() LifecycleAdapter
GetUpdateOpsLifecycleAdapter() LifecycleAdapter
GetResourceContextAdapter() ResourceContextAdapter

CheckScheduled(object client.Object) bool
CheckReady(object client.Object) bool
CheckAvailable(object client.Object) bool

UpdateScaleStrategy(ctx context.Context, c client.Client, object XSetObject, scaleStrategy *ScaleStrategy) error
GetXOpsPriority(ctx context.Context, c client.Client, object client.Object) (*OpsPriority, error)
}

type XSetObject client.Object
47 changes: 46 additions & 1 deletion xset/api/xset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,56 @@ type XSetStatus struct {
AvailableReplicas int32 `json:"availableReplicas,omitempty"`

// UpdatedAvailableReplicas indicates the number of available updated revision replicas for this replicas set.
// A model is updated available means the model is ready for updated revision and accessible
// A target is updated available means the target is ready for updated revision and accessible
// +optional
UpdatedAvailableReplicas int32 `json:"updatedAvailableReplicas,omitempty"`

// Represents the latest available observations of a XSet's current state.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// OpsPriority is used to store the ops priority of a target
type OpsPriority struct {
// PriorityClass is the priority class of the target
PriorityClass int32
// DeletionCost is the deletion cost of the target
DeletionCost int32
}

type XSetControllerLabelEnum int

const (
EnumXSetControlledLabel XSetControllerLabelEnum = iota

EnumXSetInstanceIdLabel

EnumXSetUpdateIndicationLabel

EnumXSetDeletionIndicationLabel

EnumXSetReplaceIndicationLabel

EnumXSetReplacePairNewIdLabel

EnumXSetReplacePairOriginNameLabel

EnumXSetReplaceByReplaceUpdateLabel

EnumXSetOrphanedLabel

EnumXSetTargetCreatingLabel

EnumXSetTargetCompletingLabel

EnumXSetTargetExcludeIndicationLabel

EnumXSetLastTargetStatusAnnotationKey
)

type XSetLabelManager interface {
Get(labels map[string]string, labelType XSetControllerLabelEnum) (string, bool)
Set(labels map[string]string, labelType XSetControllerLabelEnum, value string)
Delete(labels map[string]string, labelType XSetControllerLabelEnum)
Label(labelType XSetControllerLabelEnum) string
}
18 changes: 11 additions & 7 deletions xset/opslifecycle/default_adapters.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
package opslifecycle

import (
"strings"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"kusionstack.io/kube-utils/xset/api"
Expand All @@ -26,10 +29,11 @@ var _ api.LifecycleAdapter = &DefaultUpdateLifecycleAdapter{}

type DefaultUpdateLifecycleAdapter struct {
LabelManager api.LifeCycleLabelManager
XSetType metav1.TypeMeta
}

func (d *DefaultUpdateLifecycleAdapter) GetID() string {
return "xset"
return strings.ToLower(d.XSetType.Kind)
}

func (d *DefaultUpdateLifecycleAdapter) GetType() api.OperationType {
Expand All @@ -40,23 +44,24 @@ func (d *DefaultUpdateLifecycleAdapter) AllowMultiType() bool {
return true
}

func (d *DefaultUpdateLifecycleAdapter) WhenBegin(target client.Object) (bool, error) {
setOperate(d.LabelManager, d, target)
func (d *DefaultUpdateLifecycleAdapter) WhenBegin(_ client.Object) (bool, error) {
return true, nil
}

func (d *DefaultUpdateLifecycleAdapter) WhenFinish(target client.Object) (bool, error) {
// TODO inplace update post actions
return false, nil
}

var _ api.LifecycleAdapter = &DefaultScaleInLifecycleAdapter{}

type DefaultScaleInLifecycleAdapter struct {
LabelManager api.LifeCycleLabelManager
XSetType metav1.TypeMeta
}

func (d *DefaultScaleInLifecycleAdapter) GetID() string {
return "xset"
return strings.ToLower(d.XSetType.Kind)
}

func (d *DefaultScaleInLifecycleAdapter) GetType() api.OperationType {
Expand All @@ -68,10 +73,9 @@ func (d *DefaultScaleInLifecycleAdapter) AllowMultiType() bool {
}

func (d *DefaultScaleInLifecycleAdapter) WhenBegin(target client.Object) (bool, error) {
setOperate(d.LabelManager, d, target)
return true, nil
return WhenBeginDelete(d.LabelManager, target)
}

func (d *DefaultScaleInLifecycleAdapter) WhenFinish(target client.Object) (bool, error) {
func (d *DefaultScaleInLifecycleAdapter) WhenFinish(_ client.Object) (bool, error) {
return false, nil
}
20 changes: 15 additions & 5 deletions xset/opslifecycle/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@ import (

type UpdateFunc func(object client.Object) (bool, error)

func IsServiceAvailable(m api.LifeCycleLabelManager, target client.Object) bool {
_, exists := target.GetLabels()[m.Get(api.ServiceAvailableLabel)]
return exists
}

// IDToLabelsMap returns a map of pod id to labels map and a map of operation type to number of pods.
func IDToLabelsMap(m *LabelManagerImpl, target client.Object) (map[string]map[string]string, map[string]int, error) {
idToLabelsMap := map[string]map[string]string{}
Expand Down Expand Up @@ -310,6 +305,21 @@ func IsLifecycleOnTarget(m api.LifeCycleLabelManager, operatingID string, target
return false, nil
}

func CancelOpsLifecycle(m api.LifeCycleLabelManager, client client.Client, adapter api.LifecycleAdapter, target client.Object) error {
if target == nil {
return nil
}

// only cancel when lifecycle exist on pod
if exist, err := IsLifecycleOnTarget(m, adapter.GetID(), target); err != nil {
return fmt.Errorf("fail to check %s PodOpsLifecycle on Pod %s/%s: %w", adapter.GetID(), target.GetNamespace(), target.GetName(), err)
} else if !exist {
return nil
}

return Undo(m, client, adapter, target)
}

func DefaultUpdateAll(target client.Object, updateFuncs ...UpdateFunc) (updated bool, err error) {
for _, updateFunc := range updateFuncs {
ok, updateErr := updateFunc(target)
Expand Down
14 changes: 8 additions & 6 deletions xset/resourcecontexts/default_adapters.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ import (
var _ api.ResourceContextAdapter = &DefaultResourceContextAdapter{}

var defaultResourceContextKeys = map[api.ResourceContextKeyEnum]string{
api.EnumOwnerContextKey: "Owner",
api.EnumRevisionContextDataKey: "Revision",
api.EnumTargetDecorationRevisionKey: "TargetDecorationRevisions",
api.EnumJustCreateContextDataKey: "TargetJustCreate",
api.EnumRecreateUpdateContextDataKey: "TargetRecreateUpdate",
api.EnumScaleInContextDataKey: "ScaleIn",
api.EnumOwnerContextKey: "Owner",
api.EnumRevisionContextDataKey: "Revision",
api.EnumTargetDecorationRevisionKey: "TargetDecorationRevisions",
api.EnumJustCreateContextDataKey: "TargetJustCreate",
api.EnumRecreateUpdateContextDataKey: "TargetRecreateUpdate",
api.EnumScaleInContextDataKey: "ScaleIn",
api.EnumReplaceNewTargetIDContextDataKey: "ReplaceNewTargetID",
api.EnumReplaceOriginTargetIDContextDataKey: "ReplaceOriginTargetID",
}

// DefaultResourceContextAdapter is the adapter to api apps.kusionstack.io.resourcecontexts
Expand Down
48 changes: 0 additions & 48 deletions xset/synccontrols/const.go

This file was deleted.

11 changes: 6 additions & 5 deletions xset/synccontrols/inexclude.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ import (
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
appsv1alpha1 "kusionstack.io/kube-api/apps/v1alpha1"

"kusionstack.io/kube-utils/xset/api"
)

// AllowResourceExclude checks if pod or pvc is allowed to exclude
func AllowResourceExclude(obj metav1.Object, ownerName, ownerKind string) (bool, string) {
func AllowResourceExclude(obj metav1.Object, ownerName, ownerKind string, manager api.XSetLabelManager) (bool, string) {
labels := obj.GetLabels()
// not controlled by ks manager
if labels == nil {
return false, "object's label is empty"
} else if val, exist := labels[appsv1alpha1.ControlledByKusionStackLabelKey]; !exist || val != "true" {
} else if val, exist := manager.Get(labels, api.EnumXSetControlledLabel); !exist || val != "true" {
return false, "object is not controlled by kusionstack system"
}

Expand All @@ -41,14 +42,14 @@ func AllowResourceExclude(obj metav1.Object, ownerName, ownerKind string) (bool,
}

// AllowResourceInclude checks if pod or pvc is allowed to include
func AllowResourceInclude(obj metav1.Object, ownerName, ownerKind string) (bool, string) {
func AllowResourceInclude(obj metav1.Object, ownerName, ownerKind string, manager api.XSetLabelManager) (bool, string) {
labels := obj.GetLabels()
ownerRefs := obj.GetOwnerReferences()

// not controlled by ks manager
if labels == nil {
return false, "object's label is empty"
} else if val, exist := labels[appsv1alpha1.ControlledByKusionStackLabelKey]; !exist || val != "true" {
} else if val, exist := manager.Get(labels, api.EnumXSetControlledLabel); !exist || val != "true" {
return false, "object is not controlled by kusionstack system"
}

Expand Down
4 changes: 2 additions & 2 deletions xset/synccontrols/inexclude_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func TestAllowResourceExclude(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := AllowResourceExclude(tt.obj, ownerName, ownerKind)
got, got1 := AllowResourceExclude(tt.obj, ownerName, ownerKind, NewXSetControllerLabelManager())
if got != tt.allow {
t.Errorf("AllowResourceExclude() got = %v, want %v", got, tt.allow)
}
Expand Down Expand Up @@ -288,7 +288,7 @@ func TestAllowResourceInclude(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := AllowResourceInclude(tt.obj, ownerName, ownerKind)
got, got1 := AllowResourceInclude(tt.obj, ownerName, ownerKind, NewXSetControllerLabelManager())
if got != tt.allow {
t.Errorf("AllowResourceExclude() got = %v, want %v", got, tt.allow)
}
Expand Down
Loading
Loading