Skip to content

Commit

Permalink
chore: remove the Halt termination policy (#8202)
Browse files Browse the repository at this point in the history
  • Loading branch information
leon-inf committed Sep 26, 2024
1 parent 78fb0b1 commit beedc37
Show file tree
Hide file tree
Showing 16 changed files with 37 additions and 431 deletions.
12 changes: 3 additions & 9 deletions apis/apps/v1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,7 @@ type ClusterSpec struct {
// Choose a policy based on the desired level of resource cleanup and data preservation:
//
// - `DoNotTerminate`: Prevents deletion of the Cluster. This policy ensures that all resources remain intact.
// - `Halt`: Deletes Cluster resources like Pods and Services but retains Persistent Volume Claims (PVCs),
// allowing for data preservation while stopping other operations.
// - `Delete`: Extends the `Halt` policy by also removing PVCs, leading to a thorough cleanup while
// removing all persistent data.
// - `Delete`: Deletes all runtime resources belong to the Cluster.
// - `WipeOut`: An aggressive policy that deletes all Cluster resources, including volume snapshots and
// backups in external storage.
// This results in complete data removal and should be used cautiously, primarily in non-production environments
Expand Down Expand Up @@ -244,17 +241,14 @@ type ClusterStatus struct {
// TerminationPolicyType defines termination policy types.
//
// +enum
// +kubebuilder:validation:Enum={DoNotTerminate,Halt,Delete,WipeOut}
// +kubebuilder:validation:Enum={DoNotTerminate,Delete,WipeOut}
type TerminationPolicyType string

const (
// DoNotTerminate will block delete operation.
DoNotTerminate TerminationPolicyType = "DoNotTerminate"

// Halt will delete workload resources such as statefulset, deployment workloads but keep PVCs.
Halt TerminationPolicyType = "Halt"

// Delete is based on Halt and deletes PVCs.
// Delete will delete all runtime resources belong to the cluster.
Delete TerminationPolicyType = "Delete"

// WipeOut is based on Delete and wipe out all volume snapshots and snapshot data from backup storage location.
Expand Down
1 change: 0 additions & 1 deletion apis/apps/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ const (
)

const (
ConditionTypeHaltRecovery = "HaltRecovery" // ConditionTypeHaltRecovery describe Halt recovery processing stage
ConditionTypeProvisioningStarted = "ProvisioningStarted" // ConditionTypeProvisioningStarted the operator starts resource provisioning to create or change the cluster
ConditionTypeApplyResources = "ApplyResources" // ConditionTypeApplyResources the operator start to apply resources to create or change the cluster
ConditionTypeReplicasReady = "ReplicasReady" // ConditionTypeReplicasReady all pods of components are ready
Expand Down
9 changes: 9 additions & 0 deletions apis/apps/v1alpha1/cluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ func (r *Cluster) changesToCluster(cluster *appsv1.Cluster) {
if len(r.Spec.ClusterDefRef) > 0 {
cluster.Spec.ClusterDef = r.Spec.ClusterDefRef
}
if r.Spec.TerminationPolicy == Halt {
cluster.Spec.TerminationPolicy = appsv1.DoNotTerminate
} else {
cluster.Spec.TerminationPolicy = appsv1.TerminationPolicyType(r.Spec.TerminationPolicy)
}
}

func (r *Cluster) changesFromCluster(cluster *appsv1.Cluster) {
Expand All @@ -140,6 +145,7 @@ func (r *Cluster) changesFromCluster(cluster *appsv1.Cluster) {
if len(cluster.Spec.ClusterDef) > 0 {
r.Spec.ClusterDefRef = cluster.Spec.ClusterDef
}
// appsv1.TerminationPolicyType is a subset of appsv1alpha1.TerminationPolicyType, it can be converted directly.
}

type clusterConverter struct {
Expand All @@ -149,6 +155,7 @@ type clusterConverter struct {

type clusterSpecConverter struct {
ClusterVersionRef string `json:"clusterVersionRef,omitempty"`
TerminationPolicy TerminationPolicyType `json:"terminationPolicy"`
Affinity *Affinity `json:"affinity,omitempty"`
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
Tenancy TenancyType `json:"tenancy,omitempty"`
Expand Down Expand Up @@ -186,6 +193,7 @@ type clusterCompStatusConverter struct {

func (c *clusterConverter) fromCluster(cluster *Cluster) {
c.Spec.ClusterVersionRef = cluster.Spec.ClusterVersionRef
c.Spec.TerminationPolicy = cluster.Spec.TerminationPolicy
c.Spec.Affinity = cluster.Spec.Affinity
c.Spec.Tolerations = cluster.Spec.Tolerations
c.Spec.Tenancy = cluster.Spec.Tenancy
Expand Down Expand Up @@ -227,6 +235,7 @@ func (c *clusterConverter) fromCluster(cluster *Cluster) {

func (c *clusterConverter) toCluster(cluster *Cluster) {
cluster.Spec.ClusterVersionRef = c.Spec.ClusterVersionRef
cluster.Spec.TerminationPolicy = c.Spec.TerminationPolicy
cluster.Spec.Affinity = c.Spec.Affinity
cluster.Spec.Tolerations = c.Spec.Tolerations
cluster.Spec.Tenancy = c.Spec.Tenancy
Expand Down
6 changes: 1 addition & 5 deletions config/crd/bases/apps.kubeblocks.io_clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15884,10 +15884,7 @@ spec:


- `DoNotTerminate`: Prevents deletion of the Cluster. This policy ensures that all resources remain intact.
- `Halt`: Deletes Cluster resources like Pods and Services but retains Persistent Volume Claims (PVCs),
allowing for data preservation while stopping other operations.
- `Delete`: Extends the `Halt` policy by also removing PVCs, leading to a thorough cleanup while
removing all persistent data.
- `Delete`: Deletes all runtime resources belong to the Cluster.
- `WipeOut`: An aggressive policy that deletes all Cluster resources, including volume snapshots and
backups in external storage.
This results in complete data removal and should be used cautiously, primarily in non-production environments
Expand All @@ -15898,7 +15895,6 @@ spec:
The `WipeOut` policy is particularly risky in production environments due to its irreversible nature.
enum:
- DoNotTerminate
- Halt
- Delete
- WipeOut
type: string
Expand Down
4 changes: 0 additions & 4 deletions controllers/apps/cluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,8 @@ func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
// TODO: transformers are vertices, theirs' dependencies are edges, make plan Build stage a DAG.
plan, errBuild := planBuilder.
AddTransformer(
// handle cluster halt first
&clusterHaltTransformer{},
// handle cluster deletion
&clusterDeletionTransformer{},
// check is recovering from halted cluster
&clusterHaltRecoveryTransformer{},
// update finalizer and cd&cv labels
&clusterAssureMetaTransformer{},
// validate cd & cv's existence and availability
Expand Down
38 changes: 0 additions & 38 deletions controllers/apps/cluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -784,36 +784,6 @@ var _ = Describe("Cluster Controller", func() {
}
}

testDeleteClusterWithHalt := func(createObj func(appsv1.TerminationPolicyType)) {
createObj(appsv1.Halt)

transCtx := &clusterTransformContext{
Context: testCtx.Ctx,
Client: testCtx.Cli,
}
namespacedKinds, clusteredKinds := kindsForWipeOut()
allKinds := append(namespacedKinds, clusteredKinds...)
createdObjs, err := getOwningNamespacedObjects(transCtx.Context, transCtx.Client, clusterObj.Namespace, getAppInstanceML(*clusterObj), allKinds)
Expect(err).Should(Succeed())

By("delete the cluster")
testapps.DeleteObject(&testCtx, clusterKey, &appsv1.Cluster{})
Consistently(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, true)).Should(Succeed())

By("check all cluster resources again")
objs, err := getOwningNamespacedObjects(transCtx.Context, transCtx.Client, clusterObj.Namespace, getAppInstanceML(*clusterObj), allKinds)
Expect(err).Should(Succeed())
// check all objects existed before cluster deletion still be there
for key, obj := range createdObjs {
Expect(objs).Should(HaveKey(key))
Expect(obj.GetUID()).Should(BeEquivalentTo(objs[key].GetUID()))
}
}

testClusterHaltNRecovery := func(createObj func(appsv1.TerminationPolicyType)) {
// TODO(component)
}

deleteClusterWithBackup := func(terminationPolicy appsv1.TerminationPolicyType, backupRetainPolicy string) {
By("mocking a retained backup")
backupPolicyName := "test-backup-policy"
Expand Down Expand Up @@ -952,14 +922,6 @@ var _ = Describe("Cluster Controller", func() {
testDeleteClusterWithDoNotTerminate(createObj)
})

It("delete cluster with terminationPolicy=Halt", func() {
testDeleteClusterWithHalt(createObj)
})

It("cluster Halt and Recovery", func() {
testClusterHaltNRecovery(createObj)
})

It("delete cluster with terminationPolicy=Delete", func() {
testDeleteClusterWithDelete(createObj)
})
Expand Down
4 changes: 1 addition & 3 deletions controllers/apps/component_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package apps

import (
"encoding/json"
"fmt"
"strconv"
"strings"
Expand Down Expand Up @@ -362,14 +361,13 @@ var _ = Describe("Component Controller", func() {
if storageSize == "" {
storageSize = "1Gi"
}
clusterBytes, _ := json.Marshal(clusterObj)
testapps.NewPersistentVolumeClaimFactory(testCtx.DefaultNamespace, pvcName, clusterName,
compName, testapps.DataVolumeName).
AddLabelsInMap(map[string]string{
constant.AppInstanceLabelKey: clusterName,
constant.KBAppComponentLabelKey: compName,
constant.AppManagedByLabelKey: constant.AppName,
}).AddAnnotations(constant.LastAppliedClusterAnnotationKey, string(clusterBytes)).
}).
SetStorage(storageSize).
SetStorageClass(storageClassName).
CheckedCreate(&testCtx)
Expand Down
57 changes: 0 additions & 57 deletions controllers/apps/transform_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,18 @@ package apps

import (
"context"
"encoding/json"
"reflect"
"time"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
workloads "github.com/apecloud/kubeblocks/apis/workloads/v1"
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/controller/graph"
"github.com/apecloud/kubeblocks/pkg/controller/model"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
)

Expand Down Expand Up @@ -167,58 +162,6 @@ func isVolumeClaimTemplatesEqual(a, b []appsv1.ClusterComponentVolumeClaimTempla
return true
}

func preserveObjects[T client.Object](ctx context.Context, cli client.Reader, graphCli model.GraphClient, dag *graph.DAG,
obj T, ml client.MatchingLabels, toPreserveKinds []client.ObjectList, finalizerName string, lastApplyAnnotationKey string) error {
if len(toPreserveKinds) == 0 {
return nil
}

objs, err := getOwningNamespacedObjects(ctx, cli, obj.GetNamespace(), ml, toPreserveKinds)
if err != nil {
return err
}

objSpec := obj.DeepCopyObject().(client.Object)
objSpec.SetNamespace("")
objSpec.SetName(obj.GetName())
objSpec.SetUID(obj.GetUID())
objSpec.SetResourceVersion("")
objSpec.SetGeneration(0)
objSpec.SetManagedFields(nil)

b, err := json.Marshal(objSpec)
if err != nil {
return err
}
objJSON := string(b)

for _, o := range objs {
origObj := o.DeepCopyObject().(client.Object)
controllerutil.RemoveFinalizer(o, finalizerName)
removeOwnerRefOfType(o, obj.GetObjectKind().GroupVersionKind())

annot := o.GetAnnotations()
if annot == nil {
annot = make(map[string]string)
}
annot[lastApplyAnnotationKey] = objJSON
o.SetAnnotations(annot)
graphCli.Update(dag, origObj, o)
}
return nil
}

func removeOwnerRefOfType(obj client.Object, gvk schema.GroupVersionKind) {
ownerRefs := obj.GetOwnerReferences()
for i, ref := range ownerRefs {
if ref.Kind == gvk.Kind && ref.APIVersion == gvk.GroupVersion().String() {
ownerRefs = append(ownerRefs[:i], ownerRefs[i+1:]...)
break
}
}
obj.SetOwnerReferences(ownerRefs)
}

// isOwnedByComp is used to judge if the obj is owned by Component.
func isOwnedByComp(obj client.Object) bool {
for _, ref := range obj.GetOwnerReferences() {
Expand Down
11 changes: 1 addition & 10 deletions controllers/apps/transformer_cluster_deletion.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ func (t *clusterDeletionTransformer) Transform(ctx graph.TransformContext, dag *
transCtx.EventRecorder.Eventf(cluster, corev1.EventTypeWarning, "DoNotTerminate",
"spec.terminationPolicy %s is preventing deletion.", cluster.Spec.TerminationPolicy)
return graph.ErrPrematureStop
case kbappsv1.Halt:
transCtx.EventRecorder.Eventf(cluster, corev1.EventTypeWarning, "Halt",
"spec.terminationPolicy %s is preventing deletion. Halt policy is deprecated is 0.9.1 and will have same meaning as DoNotTerminate.", cluster.Spec.TerminationPolicy)
return graph.ErrPrematureStop
case kbappsv1.Delete:
toDeleteNamespacedKinds, toDeleteNonNamespacedKinds = kindsForDelete()
case kbappsv1.WipeOut:
Expand Down Expand Up @@ -149,7 +145,7 @@ func kindsForDoNotTerminate() ([]client.ObjectList, []client.ObjectList) {
return []client.ObjectList{}, []client.ObjectList{}
}

func kindsForHalt() ([]client.ObjectList, []client.ObjectList) {
func kindsForDelete() ([]client.ObjectList, []client.ObjectList) {
namespacedKinds, nonNamespacedKinds := kindsForDoNotTerminate()
namespacedKindsPlus := []client.ObjectList{
&kbappsv1.ComponentList{},
Expand All @@ -161,11 +157,6 @@ func kindsForHalt() ([]client.ObjectList, []client.ObjectList) {
return append(namespacedKinds, namespacedKindsPlus...), nonNamespacedKinds
}

func kindsForDelete() ([]client.ObjectList, []client.ObjectList) {
namespacedKinds, nonNamespacedKinds := kindsForHalt()
return append(namespacedKinds, haltPreserveKinds()...), nonNamespacedKinds
}

func kindsForWipeOut() ([]client.ObjectList, []client.ObjectList) {
namespacedKinds, nonNamespacedKinds := kindsForDelete()
namespacedKindsPlus := []client.ObjectList{
Expand Down
65 changes: 0 additions & 65 deletions controllers/apps/transformer_cluster_halt.go

This file was deleted.

Loading

0 comments on commit beedc37

Please sign in to comment.