From ab818e53db9b836c9bd69c1fac939b9ec0d89c31 Mon Sep 17 00:00:00 2001
From: wanglong <46259301+gnolong@users.noreply.github.com>
Date: Tue, 6 Aug 2024 11:16:15 +0800
Subject: [PATCH] feat: support filtering backup target pods by the alternative
label selector (#7831)
---
.../v1alpha1/backuppolicytemplate_types.go | 6 +
.../v1alpha1/backuppolicy_types.go | 6 +
.../v1alpha1/zz_generated.deepcopy.go | 5 +
...s.kubeblocks.io_backuppolicytemplates.yaml | 104 ++++++++++
...otection.kubeblocks.io_backuppolicies.yaml | 185 ++++++++++++++++++
.../dataprotection.kubeblocks.io_backups.yaml | 184 +++++++++++++++++
...dataprotection.kubeblocks.io_restores.yaml | 47 +++++
.../apps/transformer_cluster_backup_policy.go | 28 ++-
.../dataprotection/backup_controller_test.go | 73 +++++++
controllers/dataprotection/utils.go | 89 +++++----
...s.kubeblocks.io_backuppolicytemplates.yaml | 104 ++++++++++
...otection.kubeblocks.io_backuppolicies.yaml | 185 ++++++++++++++++++
.../dataprotection.kubeblocks.io_backups.yaml | 184 +++++++++++++++++
...dataprotection.kubeblocks.io_restores.yaml | 47 +++++
docs/developer_docs/api-reference/backup.md | 15 ++
docs/developer_docs/api-reference/cluster.md | 13 ++
pkg/dataprotection/restore/manager.go | 2 +-
pkg/dataprotection/utils/utils.go | 16 +-
18 files changed, 1240 insertions(+), 53 deletions(-)
diff --git a/apis/apps/v1alpha1/backuppolicytemplate_types.go b/apis/apps/v1alpha1/backuppolicytemplate_types.go
index acd19f3f105..200e9fb5428 100644
--- a/apis/apps/v1alpha1/backuppolicytemplate_types.go
+++ b/apis/apps/v1alpha1/backuppolicytemplate_types.go
@@ -210,6 +210,12 @@ type TargetInstance struct {
// the `strategy` field below.
Role string `json:"role"`
+ // Specifies the fallback role to select one replica for backup, this only takes effect when the
+ // `strategy` field below is set to `Any`.
+ //
+ // +optional
+ FallbackRole string `json:"fallbackRole,omitempty"`
+
// If `backupPolicy.componentDefs` is set, this field is required to specify the system account name.
// This account must match one listed in `componentDefinition.spec.systemAccounts[*].name`.
// The corresponding secret created by this account is used to connect to the database.
diff --git a/apis/dataprotection/v1alpha1/backuppolicy_types.go b/apis/dataprotection/v1alpha1/backuppolicy_types.go
index 92527c5c17e..31fe87f49e7 100644
--- a/apis/dataprotection/v1alpha1/backuppolicy_types.go
+++ b/apis/dataprotection/v1alpha1/backuppolicy_types.go
@@ -111,6 +111,12 @@ type PodSelector struct {
// labelsSelector is the label selector to filter the target pods.
*metav1.LabelSelector `json:",inline"`
+ // fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ // This only takes effect when the `strategy` field below is set to `Any`.
+ //
+ // +optional
+ FallbackLabelSelector *metav1.LabelSelector `json:"fallbackLabelSelector,omitempty"`
+
// Specifies the strategy to select the target pod when multiple pods are selected.
// Valid values are:
//
diff --git a/apis/dataprotection/v1alpha1/zz_generated.deepcopy.go b/apis/dataprotection/v1alpha1/zz_generated.deepcopy.go
index 0279a22601b..0fb63af2b21 100644
--- a/apis/dataprotection/v1alpha1/zz_generated.deepcopy.go
+++ b/apis/dataprotection/v1alpha1/zz_generated.deepcopy.go
@@ -1162,6 +1162,11 @@ func (in *PodSelector) DeepCopyInto(out *PodSelector) {
*out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out)
}
+ if in.FallbackLabelSelector != nil {
+ in, out := &in.FallbackLabelSelector, &out.FallbackLabelSelector
+ *out = new(metav1.LabelSelector)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSelector.
diff --git a/config/crd/bases/apps.kubeblocks.io_backuppolicytemplates.yaml b/config/crd/bases/apps.kubeblocks.io_backuppolicytemplates.yaml
index 4f0ae6e1b58..d9fee4b254a 100644
--- a/config/crd/bases/apps.kubeblocks.io_backuppolicytemplates.yaml
+++ b/config/crd/bases/apps.kubeblocks.io_backuppolicytemplates.yaml
@@ -416,6 +416,11 @@ spec:
If not specified, the default key "username" is used.
type: string
type: object
+ fallbackRole:
+ description: |-
+ Specifies the fallback role to select one replica for backup, this only takes effect when the
+ `strategy` field below is set to `Any`.
+ type: string
name:
description: |-
Specifies a mandatory and unique identifier for each target when using the "targets" field.
@@ -425,6 +430,53 @@ spec:
description: Used to find the target pod. The volumes
of the target pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of
+ label selector requirements. The requirements
+ are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that
+ the selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label
selector requirements. The requirements are
@@ -687,6 +739,53 @@ spec:
description: Used to find the target pod. The volumes
of the target pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list
+ of label selector requirements. The requirements
+ are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key
+ that the selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label
selector requirements. The requirements are
@@ -916,6 +1015,11 @@ spec:
If not specified, the default key "username" is used.
type: string
type: object
+ fallbackRole:
+ description: |-
+ Specifies the fallback role to select one replica for backup, this only takes effect when the
+ `strategy` field below is set to `Any`.
+ type: string
role:
description: |-
Specifies the role to select one or more replicas for backup.
diff --git a/config/crd/bases/dataprotection.kubeblocks.io_backuppolicies.yaml b/config/crd/bases/dataprotection.kubeblocks.io_backuppolicies.yaml
index ee2934a16f3..d7fa06edd4c 100644
--- a/config/crd/bases/dataprotection.kubeblocks.io_backuppolicies.yaml
+++ b/config/crd/bases/dataprotection.kubeblocks.io_backuppolicies.yaml
@@ -307,6 +307,52 @@ spec:
description: Used to find the target pod. The volumes of
the target pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
@@ -538,6 +584,53 @@ spec:
description: Used to find the target pod. The volumes
of the target pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
@@ -774,6 +867,52 @@ spec:
description: Used to find the target pod. The volumes of the target
pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
@@ -948,6 +1087,52 @@ spec:
description: Used to find the target pod. The volumes of the
target pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
diff --git a/config/crd/bases/dataprotection.kubeblocks.io_backups.yaml b/config/crd/bases/dataprotection.kubeblocks.io_backups.yaml
index 2e140a05cc8..76b17beecad 100644
--- a/config/crd/bases/dataprotection.kubeblocks.io_backups.yaml
+++ b/config/crd/bases/dataprotection.kubeblocks.io_backups.yaml
@@ -501,6 +501,52 @@ spec:
description: Used to find the target pod. The volumes of the
target pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
@@ -731,6 +777,52 @@ spec:
description: Used to find the target pod. The volumes of
the target pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
@@ -1013,6 +1105,52 @@ spec:
description: Used to find the target pod. The volumes of the target
pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
@@ -1189,6 +1327,52 @@ spec:
description: Used to find the target pod. The volumes of the
target pod will be backed up.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector
+ requirements. The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector
+ applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
diff --git a/config/crd/bases/dataprotection.kubeblocks.io_restores.yaml b/config/crd/bases/dataprotection.kubeblocks.io_restores.yaml
index defd85fe5bd..bcd3ca3b0af 100644
--- a/config/crd/bases/dataprotection.kubeblocks.io_restores.yaml
+++ b/config/crd/bases/dataprotection.kubeblocks.io_restores.yaml
@@ -2042,6 +2042,53 @@ spec:
Selects one of the pods, identified by labels, to build the job spec.
This includes mounting required volumes and injecting built-in environment variables of the selected pod.
properties:
+ fallbackLabelSelector:
+ description: |-
+ fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+ This only takes effect when the `strategy` field below is set to `Any`.
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label
+ selector requirements. The requirements are
+ ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the
+ selector applies to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
diff --git a/controllers/apps/transformer_cluster_backup_policy.go b/controllers/apps/transformer_cluster_backup_policy.go
index fff26d0d612..49ad32b562a 100644
--- a/controllers/apps/transformer_cluster_backup_policy.go
+++ b/controllers/apps/transformer_cluster_backup_policy.go
@@ -362,7 +362,7 @@ func (r *clusterBackupPolicyTransformer) syncBackupPolicy(comp componentItem, ba
r.syncBackupPolicyTargetSpec(backupPolicy, comp)
}
-func (r *clusterBackupPolicyTransformer) syncRoleLabelSelector(comp componentItem, target *dpv1alpha1.BackupTarget, role string) {
+func (r *clusterBackupPolicyTransformer) syncRoleLabelSelector(comp componentItem, target *dpv1alpha1.BackupTarget, role, alternateRole string) {
if len(role) == 0 || target == nil {
return
}
@@ -372,8 +372,17 @@ func (r *clusterBackupPolicyTransformer) syncRoleLabelSelector(comp componentIte
}
if r.getCompReplicas(comp) == 1 {
delete(podSelector.LabelSelector.MatchLabels, constant.RoleLabelKey)
- } else if podSelector.LabelSelector.MatchLabels[constant.RoleLabelKey] == "" {
+ if podSelector.FallbackLabelSelector != nil && podSelector.FallbackLabelSelector.MatchLabels != nil {
+ delete(podSelector.FallbackLabelSelector.MatchLabels, constant.RoleLabelKey)
+ }
+ } else {
podSelector.LabelSelector.MatchLabels[constant.RoleLabelKey] = role
+ if len(alternateRole) > 0 {
+ if podSelector.FallbackLabelSelector == nil || podSelector.FallbackLabelSelector.MatchLabels == nil {
+ podSelector.FallbackLabelSelector = &metav1.LabelSelector{MatchLabels: map[string]string{}}
+ }
+ podSelector.FallbackLabelSelector.MatchLabels[constant.RoleLabelKey] = alternateRole
+ }
}
}
@@ -489,7 +498,7 @@ func (r *clusterBackupPolicyTransformer) buildBackupTarget(
) *dpv1alpha1.BackupTarget {
if oldTarget != nil {
// if the target already exists, only sync the role by component replicas automatically.
- r.syncRoleLabelSelector(comp, oldTarget, targetTpl.Role)
+ r.syncRoleLabelSelector(comp, oldTarget, targetTpl.Role, targetTpl.FallbackRole)
return oldTarget
}
clusterName := r.OrigCluster.Name
@@ -500,12 +509,17 @@ func (r *clusterBackupPolicyTransformer) buildBackupTarget(
PodSelector: &dpv1alpha1.PodSelector{
Strategy: targetTpl.Strategy,
LabelSelector: &metav1.LabelSelector{
- MatchLabels: r.buildTargetPodLabels(targetTpl, comp),
+ MatchLabels: r.buildTargetPodLabels(targetTpl.Role, comp),
},
},
// dataprotection will use its dedicated service account if this field is empty.
ServiceAccountName: "",
}
+ if len(targetTpl.Role) != 0 && len(targetTpl.FallbackRole) != 0 {
+ target.PodSelector.FallbackLabelSelector = &metav1.LabelSelector{
+ MatchLabels: r.buildTargetPodLabels(targetTpl.FallbackRole, comp),
+ }
+ }
if comp.isSharding {
target.Name = comp.fullComponentName
}
@@ -724,16 +738,16 @@ func (r *clusterBackupPolicyTransformer) compDefNameFromPolicy(policy *dpv1alpha
// buildTargetPodLabels builds the target labels for the backup policy that will be
// used to select the target pod.
-func (r *clusterBackupPolicyTransformer) buildTargetPodLabels(targetTpl appsv1alpha1.TargetInstance, comp componentItem) map[string]string {
+func (r *clusterBackupPolicyTransformer) buildTargetPodLabels(role string, comp componentItem) map[string]string {
labels := map[string]string{
constant.AppInstanceLabelKey: r.OrigCluster.Name,
constant.AppManagedByLabelKey: constant.AppName,
constant.KBAppComponentLabelKey: comp.fullComponentName,
}
// append label to filter specific role of the component.
- if len(targetTpl.Role) > 0 && r.getCompReplicas(comp) > 1 {
+ if len(role) > 0 && r.getCompReplicas(comp) > 1 {
// the role only works when the component has multiple replicas.
- labels[constant.RoleLabelKey] = targetTpl.Role
+ labels[constant.RoleLabelKey] = role
}
if comp.isSharding {
labels[constant.KBAppShardingNameLabelKey] = comp.componentName
diff --git a/controllers/dataprotection/backup_controller_test.go b/controllers/dataprotection/backup_controller_test.go
index 3ff97117a17..9084cc590d5 100644
--- a/controllers/dataprotection/backup_controller_test.go
+++ b/controllers/dataprotection/backup_controller_test.go
@@ -20,6 +20,7 @@ along with this program. If not, see
fallbackLabelSelector
fallbackLabelSelector is used to filter available pods when the labelSelector fails.
+This only takes effect when the strategy
field below is set to Any
.
strategy
strategy
field below.
fallbackRole
Specifies the fallback role to select one replica for backup, this only takes effect when the
+strategy
field below is set to Any
.
account