Skip to content

Commit

Permalink
chore: support switch to disable ha duing doring opsRequest (#7195)
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyelei authored Apr 28, 2024
1 parent a3ac2e8 commit eee3914
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 10 deletions.
31 changes: 23 additions & 8 deletions controllers/apps/operations/ops_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"sync"
"time"

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

Expand Down Expand Up @@ -104,6 +105,9 @@ func (opsMgr *OpsManager) Do(reqCtx intctrlutil.RequestCtx, cli client.Client, o
return &ctrl.Result{}, patchOpsRequestToCreating(reqCtx, cli, opsRes, opsDeepCopy, opsBehaviour.OpsHandler)
}

if err = updateHAConfigIfNecessary(reqCtx, cli, opsRes.OpsRequest, "false"); err != nil {
return nil, err
}
if err = opsBehaviour.OpsHandler.Action(reqCtx, cli, opsRes); err != nil {
// patch the status.phase to Failed when the error is Fatal, which means the operation is failed and there is no need to retry
if intctrlutil.IsTargetError(err, intctrlutil.ErrorTypeFatal) {
Expand Down Expand Up @@ -146,20 +150,31 @@ func (opsMgr *OpsManager) Reconcile(reqCtx intctrlutil.RequestCtx, cli client.Cl
}
switch opsRequestPhase {
case appsv1alpha1.OpsSucceedPhase:
if opsRequest.Status.Phase == appsv1alpha1.OpsCancellingPhase {
return 0, PatchOpsStatus(reqCtx.Ctx, cli, opsRes, appsv1alpha1.OpsCancelledPhase, appsv1alpha1.NewCancelSucceedCondition(opsRequest.Name))
}
return 0, PatchOpsStatus(reqCtx.Ctx, cli, opsRes, opsRequestPhase, appsv1alpha1.NewSucceedCondition(opsRequest))
return 0, opsMgr.handleOpsCompleted(reqCtx, cli, opsRes, opsRequestPhase,
appsv1alpha1.NewCancelSucceedCondition(opsRequest.Name), appsv1alpha1.NewSucceedCondition(opsRequest))
case appsv1alpha1.OpsFailedPhase:
if opsRequest.Status.Phase == appsv1alpha1.OpsCancellingPhase {
return 0, PatchOpsStatus(reqCtx.Ctx, cli, opsRes, appsv1alpha1.OpsCancelledPhase, appsv1alpha1.NewCancelFailedCondition(opsRequest, err))
}
return 0, PatchOpsStatus(reqCtx.Ctx, cli, opsRes, opsRequestPhase, appsv1alpha1.NewFailedCondition(opsRequest, err))
return 0, opsMgr.handleOpsCompleted(reqCtx, cli, opsRes, opsRequestPhase,
appsv1alpha1.NewCancelFailedCondition(opsRequest, err), appsv1alpha1.NewFailedCondition(opsRequest, err))
default:
return requeueAfter, nil
}
}

func (opsMgr *OpsManager) handleOpsCompleted(reqCtx intctrlutil.RequestCtx,
cli client.Client,
opsRes *OpsResource,
opsRequestPhase appsv1alpha1.OpsPhase,
cancelledCondition,
completedCondition *metav1.Condition) error {
if err := updateHAConfigIfNecessary(reqCtx, cli, opsRes.OpsRequest, "true"); err != nil {
return err
}
if opsRes.OpsRequest.Status.Phase == appsv1alpha1.OpsCancellingPhase {
return PatchOpsStatus(reqCtx.Ctx, cli, opsRes, appsv1alpha1.OpsCancelledPhase, cancelledCondition)
}
return PatchOpsStatus(reqCtx.Ctx, cli, opsRes, opsRequestPhase, completedCondition)
}

func GetOpsManager() *OpsManager {
opsManagerOnce.Do(func() {
opsManager = &OpsManager{OpsMap: make(map[appsv1alpha1.OpsType]OpsBehaviour)}
Expand Down
18 changes: 18 additions & 0 deletions controllers/apps/operations/ops_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1"
opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util"
"github.com/apecloud/kubeblocks/pkg/configuration/core"
"github.com/apecloud/kubeblocks/pkg/constant"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
)

Expand Down Expand Up @@ -291,3 +292,20 @@ func abortEarlierOpsRequestWithSameKind(reqCtx intctrlutil.RequestCtx,
}
return opsutil.UpdateClusterOpsAnnotations(reqCtx.Ctx, cli, opsRes.Cluster, opsRequestSlice)
}

func updateHAConfigIfNecessary(reqCtx intctrlutil.RequestCtx, cli client.Client, opsRequest *appsv1alpha1.OpsRequest, switchBoolStr string) error {
haConfigName, ok := opsRequest.Annotations[constant.DisableHAAnnotationKey]
if !ok {
return nil
}
haConfig := &corev1.ConfigMap{}
if err := cli.Get(reqCtx.Ctx, client.ObjectKey{Name: haConfigName, Namespace: opsRequest.Namespace}, haConfig); err != nil {
return err
}
val, ok := haConfig.Annotations["enable"]
if !ok || val == switchBoolStr {
return nil
}
haConfig.Annotations["enable"] = switchBoolStr
return cli.Update(reqCtx.Ctx, haConfig)
}
56 changes: 55 additions & 1 deletion controllers/apps/operations/ops_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import (

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

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

appsv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1"
opsutil "github.com/apecloud/kubeblocks/controllers/apps/operations/util"
"github.com/apecloud/kubeblocks/pkg/constant"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
"github.com/apecloud/kubeblocks/pkg/generics"
testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps"
Expand Down Expand Up @@ -59,6 +60,7 @@ var _ = Describe("OpsUtil functions", func() {
ml := client.HasLabels{testCtx.TestObjLabelKey}
// namespaced
testapps.ClearResources(&testCtx, generics.OpsRequestSignature, inNS, ml)
testapps.ClearResources(&testCtx, generics.ConfigMapSignature, inNS, ml)
}

BeforeEach(cleanEnv)
Expand Down Expand Up @@ -118,6 +120,58 @@ var _ = Describe("OpsUtil functions", func() {
Expect(opsPhase).Should(Equal(appsv1alpha1.OpsFailedPhase))
})

It("Test opsRequest with disable ha", func() {
By("init operations resources ")
opsRes, _, _ := initOperationsResources(clusterDefinitionName, clusterVersionName, clusterName)

By("Test the functions in ops_util.go")
ops := testapps.NewOpsRequestObj("restart-ops-"+randomStr, testCtx.DefaultNamespace,
clusterName, appsv1alpha1.RestartType)
ops.Spec.RestartList = []appsv1alpha1.ComponentOps{{ComponentName: consensusComp}}
opsRes.OpsRequest = testapps.CreateOpsRequest(ctx, testCtx, ops)
Expect(testapps.ChangeObjStatus(&testCtx, opsRes.OpsRequest, func() {
opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsCreatingPhase
opsRes.OpsRequest.Status.StartTimestamp = metav1.Time{Time: time.Now()}
})).Should(Succeed())

By("create ha configmap and do horizontalScaling with disable ha")
haConfigName := "ha-config"
haConfig := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: haConfigName,
Namespace: testCtx.DefaultNamespace,
Annotations: map[string]string{
"enable": "true",
},
},
}
Expect(k8sClient.Create(ctx, haConfig)).Should(Succeed())
opsRes.OpsRequest.Annotations = map[string]string{
constant.DisableHAAnnotationKey: haConfigName,
}

By("mock instance set")
_ = testapps.MockInstanceSetComponent(&testCtx, clusterName, consensusComp)

By("expect to disable ha")
reqCtx := intctrlutil.RequestCtx{Ctx: testCtx.Ctx}
_, err := GetOpsManager().Do(reqCtx, k8sClient, opsRes)
Expect(err).ShouldNot(HaveOccurred())
Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(haConfig), func(g Gomega, cm *corev1.ConfigMap) {
cm.Annotations["enable"] = "false"
})).Should(Succeed())

By("mock restart ops to succeed and expect to enable ha")
opsRes.OpsRequest.Status.Phase = appsv1alpha1.OpsRunningPhase
_ = initInstanceSetPods(ctx, k8sClient, opsRes, clusterName)
_, err = GetOpsManager().Reconcile(reqCtx, k8sClient, opsRes)
Expect(err).ShouldNot(HaveOccurred())
Eventually(testapps.GetOpsRequestPhase(&testCtx, client.ObjectKeyFromObject(opsRes.OpsRequest))).Should(Equal(appsv1alpha1.OpsSucceedPhase))
Eventually(testapps.CheckObj(&testCtx, client.ObjectKeyFromObject(haConfig), func(g Gomega, cm *corev1.ConfigMap) {
cm.Annotations["enable"] = "true"
})).Should(Succeed())
})

It("Test opsRequest Queue functions", func() {
By("init operations resources ")
reqCtx := intctrlutil.RequestCtx{Ctx: testCtx.Ctx}
Expand Down
2 changes: 1 addition & 1 deletion pkg/constant/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ const (
ExtraEnvAnnotationKey = "kubeblocks.io/extra-env"
LastRoleSnapshotVersionAnnotationKey = "apps.kubeblocks.io/last-role-snapshot-version"
ComponentScaleInAnnotationKey = "apps.kubeblocks.io/component-scale-in" // ComponentScaleInAnnotationKey specifies whether the component is scaled in

DisableHAAnnotationKey = "kubeblocks.io/disable-ha"
// kubeblocks.io well-known finalizers
DBClusterFinalizerName = "cluster.kubeblocks.io/finalizer"
DBComponentFinalizerName = "component.kubeblocks.io/finalizer"
Expand Down

0 comments on commit eee3914

Please sign in to comment.