github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/controllers/apps/operations/vertical_scaling.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package operations 21 22 import ( 23 "time" 24 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "sigs.k8s.io/controller-runtime/pkg/client" 27 28 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 29 intctrlutil "github.com/1aal/kubeblocks/pkg/controllerutil" 30 ) 31 32 type verticalScalingHandler struct{} 33 34 var _ OpsHandler = verticalScalingHandler{} 35 36 func init() { 37 vsHandler := verticalScalingHandler{} 38 verticalScalingBehaviour := OpsBehaviour{ 39 // if cluster is Abnormal or Failed, new opsRequest may can repair it. 40 // TODO: we should add "force" flag for these opsRequest. 41 FromClusterPhases: appsv1alpha1.GetClusterUpRunningPhases(), 42 ToClusterPhase: appsv1alpha1.UpdatingClusterPhase, 43 OpsHandler: vsHandler, 44 ProcessingReasonInClusterCondition: ProcessingReasonVerticalScaling, 45 CancelFunc: vsHandler.Cancel, 46 } 47 48 opsMgr := GetOpsManager() 49 opsMgr.RegisterOps(appsv1alpha1.VerticalScalingType, verticalScalingBehaviour) 50 } 51 52 // ActionStartedCondition the started condition when handle the vertical scaling request. 53 func (vs verticalScalingHandler) ActionStartedCondition(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) (*metav1.Condition, error) { 54 return appsv1alpha1.NewVerticalScalingCondition(opsRes.OpsRequest), nil 55 } 56 57 // Action modifies cluster component resources according to 58 // the definition of opsRequest with spec.componentNames and spec.componentOps.verticalScaling 59 func (vs verticalScalingHandler) Action(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { 60 verticalScalingMap := opsRes.OpsRequest.Spec.ToVerticalScalingListToMap() 61 for index, component := range opsRes.Cluster.Spec.ComponentSpecs { 62 verticalScaling, ok := verticalScalingMap[component.Name] 63 if !ok { 64 continue 65 } 66 // TODO: support specify class object name in the Class field 67 if verticalScaling.ClassDefRef != nil { 68 component.ClassDefRef = verticalScaling.ClassDefRef 69 } else { 70 // clear old class ref 71 component.ClassDefRef = &appsv1alpha1.ClassDefRef{} 72 component.Resources = verticalScaling.ResourceRequirements 73 } 74 opsRes.Cluster.Spec.ComponentSpecs[index] = component 75 } 76 return cli.Update(reqCtx.Ctx, opsRes.Cluster) 77 } 78 79 // ReconcileAction will be performed when action is done and loops till OpsRequest.status.phase is Succeed/Failed. 80 // the Reconcile function for vertical scaling opsRequest. 81 func (vs verticalScalingHandler) ReconcileAction(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) (appsv1alpha1.OpsPhase, time.Duration, error) { 82 return reconcileActionWithComponentOps(reqCtx, cli, opsRes, "vertical scale", handleComponentStatusProgress) 83 } 84 85 // SaveLastConfiguration records last configuration to the OpsRequest.status.lastConfiguration 86 func (vs verticalScalingHandler) SaveLastConfiguration(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { 87 componentNameSet := opsRes.OpsRequest.GetComponentNameSet() 88 lastComponentInfo := map[string]appsv1alpha1.LastComponentConfiguration{} 89 for _, v := range opsRes.Cluster.Spec.ComponentSpecs { 90 if _, ok := componentNameSet[v.Name]; !ok { 91 continue 92 } 93 lastConfiguration := appsv1alpha1.LastComponentConfiguration{ 94 ResourceRequirements: v.Resources, 95 } 96 if v.ClassDefRef != nil { 97 lastConfiguration.ClassDefRef = v.ClassDefRef 98 } 99 lastComponentInfo[v.Name] = lastConfiguration 100 } 101 opsRes.OpsRequest.Status.LastConfiguration.Components = lastComponentInfo 102 return nil 103 } 104 105 // Cancel this function defines the cancel verticalScaling action. 106 func (vs verticalScalingHandler) Cancel(reqCxt intctrlutil.RequestCtx, cli client.Client, opsRes *OpsResource) error { 107 return cancelComponentOps(reqCxt.Ctx, cli, opsRes, func(lastConfig *appsv1alpha1.LastComponentConfiguration, comp *appsv1alpha1.ClusterComponentSpec) error { 108 comp.Resources = lastConfig.ResourceRequirements 109 if lastConfig.ClassDefRef != nil { 110 comp.ClassDefRef = lastConfig.ClassDefRef 111 } 112 return nil 113 }) 114 }