Skip to content

Commit

Permalink
chore: support to delete failed backups when deleting cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyelei committed Nov 11, 2024
1 parent 0d4a0b5 commit 307c463
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 37 deletions.
24 changes: 10 additions & 14 deletions controllers/apps/cluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ var _ = Describe("Cluster Controller", func() {
}
}

deleteClusterWithBackup := func(terminationPolicy appsv1.TerminationPolicyType, backupRetainPolicy string) {
deleteClusterWithBackup := func(terminationPolicy appsv1.TerminationPolicyType) {
By("mocking a retained backup")
backupPolicyName := "test-backup-policy"
backupName := "test-backup"
Expand All @@ -779,9 +779,8 @@ var _ = Describe("Cluster Controller", func() {
SetBackupPolicyName(backupPolicyName).
SetBackupMethod(backupMethod).
SetLabels(map[string]string{
constant.AppManagedByLabelKey: constant.AppName,
constant.AppInstanceLabelKey: clusterObj.Name,
constant.BackupProtectionLabelKey: backupRetainPolicy,
constant.AppManagedByLabelKey: constant.AppName,
constant.AppInstanceLabelKey: clusterObj.Name,
}).
WithRandomName().
Create(&testCtx).GetObject()
Expand All @@ -795,7 +794,7 @@ var _ = Describe("Cluster Controller", func() {
Eventually(testapps.CheckObjExists(&testCtx, clusterKey, &appsv1.Cluster{}, false)).Should(Succeed())

By(fmt.Sprintf("checking the backup with TerminationPolicyType=%s", terminationPolicy))
if terminationPolicy == appsv1.WipeOut && backupRetainPolicy == constant.BackupDelete {
if terminationPolicy == appsv1.WipeOut {
Eventually(testapps.CheckObjExists(&testCtx, backupKey, &dpv1alpha1.Backup{}, false)).Should(Succeed())
} else {
Consistently(testapps.CheckObjExists(&testCtx, backupKey, &dpv1alpha1.Backup{}, true)).Should(Succeed())
Expand All @@ -807,7 +806,7 @@ var _ = Describe("Cluster Controller", func() {
Client: testCtx.Cli,
}
var namespacedKinds, clusteredKinds []client.ObjectList
if terminationPolicy == appsv1.WipeOut && backupRetainPolicy == constant.BackupDelete {
if terminationPolicy == appsv1.WipeOut {
namespacedKinds, clusteredKinds = kindsForWipeOut()
} else {
namespacedKinds, clusteredKinds = kindsForDelete()
Expand All @@ -820,12 +819,12 @@ var _ = Describe("Cluster Controller", func() {

testDeleteClusterWithDelete := func(createObj func(appsv1.TerminationPolicyType)) {
createObj(appsv1.Delete)
deleteClusterWithBackup(appsv1.Delete, constant.BackupRetain)
deleteClusterWithBackup(appsv1.Delete)
}

testDeleteClusterWithWipeOut := func(createObj func(appsv1.TerminationPolicyType), backupRetainPolicy string) {
testDeleteClusterWithWipeOut := func(createObj func(appsv1.TerminationPolicyType)) {
createObj(appsv1.WipeOut)
deleteClusterWithBackup(appsv1.WipeOut, backupRetainPolicy)
deleteClusterWithBackup(appsv1.WipeOut)
}

Context("cluster provisioning", func() {
Expand Down Expand Up @@ -912,13 +911,10 @@ var _ = Describe("Cluster Controller", func() {
testDeleteClusterWithDelete(createObj)
})

It("delete cluster with terminationPolicy=WipeOut and backupRetainPolicy=Delete", func() {
testDeleteClusterWithWipeOut(createObj, constant.BackupDelete)
It("delete cluster with terminationPolicy=WipeOut", func() {
testDeleteClusterWithWipeOut(createObj)
})

It("delete cluster with terminationPolicy=WipeOut and backupRetainPolicy=Retain", func() {
testDeleteClusterWithWipeOut(createObj, constant.BackupRetain)
})
})

Context("cluster status", func() {
Expand Down
28 changes: 28 additions & 0 deletions controllers/apps/transform_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"

appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
dpv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1"
workloads "github.com/apecloud/kubeblocks/apis/workloads/v1"
"github.com/apecloud/kubeblocks/pkg/constant"
intctrlutil "github.com/apecloud/kubeblocks/pkg/controllerutil"
dptypes "github.com/apecloud/kubeblocks/pkg/dataprotection/types"
)

func newRequeueError(after time.Duration, reason string) error {
Expand All @@ -60,6 +62,32 @@ func getAppInstanceML(cluster appsv1.Cluster) client.MatchingLabels {
}
}

func getFailedBackups(ctx context.Context,
cli client.Reader,
namespace string,
labels client.MatchingLabels,
owningNamespacedObjects owningObjects) error {
backupList := &dpv1alpha1.BackupList{}
if err := cli.List(ctx, backupList, client.InNamespace(namespace), labels); err != nil {
return err
}

for i := range backupList.Items {
backup := &backupList.Items[i]
if backup.Status.Phase != dpv1alpha1.BackupPhaseFailed {
continue
}
if backup.Labels[dptypes.BackupTypeLabelKey] != string(dpv1alpha1.BackupTypeContinuous) {
gvr, err := getGVKName(backup, rscheme)
if err != nil {
return err
}
owningNamespacedObjects[*gvr] = backup
}
}
return nil
}

func getOwningNamespacedObjects(ctx context.Context,
cli client.Reader,
namespace string,
Expand Down
15 changes: 12 additions & 3 deletions controllers/apps/transformer_cluster_deletion.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"github.com/apecloud/kubeblocks/pkg/constant"
"github.com/apecloud/kubeblocks/pkg/controller/graph"
"github.com/apecloud/kubeblocks/pkg/controller/model"
dptypes "github.com/apecloud/kubeblocks/pkg/dataprotection/types"
)

// clusterDeletionTransformer handles cluster deletion
Expand Down Expand Up @@ -87,9 +88,12 @@ func (t *clusterDeletionTransformer) Transform(ctx graph.TransformContext, dag *
toDeleteObjs := func(objs owningObjects) []client.Object {
var delObjs []client.Object
for _, obj := range objs {
// retain backup for data protection even if the cluster is wiped out.
if strings.EqualFold(obj.GetLabels()[constant.BackupProtectionLabelKey], constant.BackupRetain) {
continue
if obj.GetObjectKind().GroupVersionKind().Kind == dptypes.BackupKind {
backupObj := obj.(*dpv1alpha1.Backup)
// retain backup for data protection even if the cluster is wiped out.
if backupObj.Spec.DeletionPolicy == dpv1alpha1.BackupDeletionPolicyRetain {
continue
}
}
delObjs = append(delObjs, obj)
}
Expand All @@ -104,6 +108,11 @@ func (t *clusterDeletionTransformer) Transform(ctx graph.TransformContext, dag *
return err
}
}
if cluster.Spec.TerminationPolicy != kbappsv1.WipeOut {
if err = getFailedBackups(transCtx.Context, transCtx.Client, cluster.Namespace, ml, namespacedObjs); err != nil {
return err
}
}
delObjs := toDeleteObjs(namespacedObjs)

// add non-namespaced objects deletion vertex
Expand Down
11 changes: 0 additions & 11 deletions pkg/constant/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

package constant

const (
// BackupRetain always retained, unless manually deleted by the user
BackupRetain = "Retain"

// BackupRetainUntilExpired retains backup till it expires
BackupRetainUntilExpired = "RetainUntilExpired"

// BackupDelete (default) deletes backup immediately when cluster's terminationPolicy is WipeOut
BackupDelete = "Delete"
)

const (
BackupNameKeyForRestore = "name"
BackupNamespaceKeyForRestore = "namespace"
Expand Down
9 changes: 4 additions & 5 deletions pkg/constant/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ const (
VolumeClaimTemplateNameLabelKey = "apps.kubeblocks.io/vct-name"
KBAppPodNameLabelKey = "apps.kubeblocks.io/pod-name"

RoleLabelKey = "kubeblocks.io/role" // RoleLabelKey consensusSet and replicationSet role label key
KBAppServiceVersionKey = "apps.kubeblocks.io/service-version"
BackupProtectionLabelKey = "kubeblocks.io/backup-protection" // BackupProtectionLabelKey Backup delete protection policy label
AccessModeLabelKey = "workloads.kubeblocks.io/access-mode"
ReadyWithoutPrimaryKey = "kubeblocks.io/ready-without-primary"
RoleLabelKey = "kubeblocks.io/role" // RoleLabelKey consensusSet and replicationSet role label key
KBAppServiceVersionKey = "apps.kubeblocks.io/service-version"
AccessModeLabelKey = "workloads.kubeblocks.io/access-mode"
ReadyWithoutPrimaryKey = "kubeblocks.io/ready-without-primary"
)

func GetClusterLabels(clusterName string, labels ...map[string]string) map[string]string {
Expand Down
7 changes: 3 additions & 4 deletions pkg/operations/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,8 @@ func getDefaultBackupPolicy(reqCtx intctrlutil.RequestCtx, cli client.Client, cl

func getBackupLabels(cluster, request string) map[string]string {
return map[string]string{
constant.AppInstanceLabelKey: cluster,
constant.BackupProtectionLabelKey: constant.BackupRetain,
constant.OpsRequestNameLabelKey: request,
constant.OpsRequestTypeLabelKey: string(opsv1alpha1.BackupType),
constant.AppInstanceLabelKey: cluster,
constant.OpsRequestNameLabelKey: request,
constant.OpsRequestTypeLabelKey: string(opsv1alpha1.BackupType),
}
}

0 comments on commit 307c463

Please sign in to comment.