From a55a967b5072dc2826630fa2363d70b488bd9072 Mon Sep 17 00:00:00 2001
From: WangLe1321
Date: Mon, 15 May 2023 10:50:56 +0800
Subject: [PATCH 01/20] br: implement federation volume backup controller
Signed-off-by: WangLe1321
---
.../v1/federation.pingcap.com_volumebackups.yaml | 2 +-
.../v1beta1/federation.pingcap.com_volumebackups.yaml | 2 +-
manifests/federation-crd.yaml | 2 +-
manifests/federation-crd_v1beta1.yaml | 2 +-
pkg/apis/federation/pingcap/v1alpha1/types.go | 6 +++++-
pkg/fedvolumebackup/backup/backup_manager.go | 8 ++++++++
6 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/manifests/crd/federation/v1/federation.pingcap.com_volumebackups.yaml b/manifests/crd/federation/v1/federation.pingcap.com_volumebackups.yaml
index b10ab92542..7331a84d28 100644
--- a/manifests/crd/federation/v1/federation.pingcap.com_volumebackups.yaml
+++ b/manifests/crd/federation/v1/federation.pingcap.com_volumebackups.yaml
@@ -14,7 +14,7 @@ spec:
listKind: VolumeBackupList
plural: volumebackups
shortNames:
- - vbk
+ - vbf
singular: volumebackup
scope: Namespaced
versions:
diff --git a/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackups.yaml b/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackups.yaml
index 96e23e0d83..8727072802 100644
--- a/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackups.yaml
+++ b/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackups.yaml
@@ -34,7 +34,7 @@ spec:
listKind: VolumeBackupList
plural: volumebackups
shortNames:
- - vbk
+ - vbf
singular: volumebackup
preserveUnknownFields: false
scope: Namespaced
diff --git a/manifests/federation-crd.yaml b/manifests/federation-crd.yaml
index f9d1d557f9..2b5144b42f 100644
--- a/manifests/federation-crd.yaml
+++ b/manifests/federation-crd.yaml
@@ -14,7 +14,7 @@ spec:
listKind: VolumeBackupList
plural: volumebackups
shortNames:
- - vbk
+ - vbf
singular: volumebackup
scope: Namespaced
versions:
diff --git a/manifests/federation-crd_v1beta1.yaml b/manifests/federation-crd_v1beta1.yaml
index d5449d6473..a2d7ae2e5b 100644
--- a/manifests/federation-crd_v1beta1.yaml
+++ b/manifests/federation-crd_v1beta1.yaml
@@ -34,7 +34,7 @@ spec:
listKind: VolumeBackupList
plural: volumebackups
shortNames:
- - vbk
+ - vbf
singular: volumebackup
preserveUnknownFields: false
scope: Namespaced
diff --git a/pkg/apis/federation/pingcap/v1alpha1/types.go b/pkg/apis/federation/pingcap/v1alpha1/types.go
index e6b8500b3d..08b6a538c4 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/types.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/types.go
@@ -25,7 +25,7 @@ import (
// VolumeBackup is the control script's spec
//
// +k8s:openapi-gen=true
-// +kubebuilder:resource:shortName="vbk"
+// +kubebuilder:resource:shortName="vbf"
// +genclient:noStatus
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`,description="The current status of the backup"
// +kubebuilder:printcolumn:name="BackupSize",type=string,JSONPath=`.status.backupSizeReadable`,description="The data size of the backup"
@@ -194,6 +194,10 @@ const (
VolumeBackupFailed VolumeBackupConditionType = "Failed"
// VolumeBackupCleaned means all the resources about VolumeBackup have cleaned
VolumeBackupCleaned VolumeBackupConditionType = "Cleaned"
+ // VolumeBackupCleanFailed means the VolumeBackup cleanup is failed
+ VolumeBackupCleanFailed VolumeBackupConditionType = "CleanFailed"
+ // VolumeBackupPrepared means the VolumeBackup is prepared
+ VolumeBackupPrepared VolumeBackupConditionType = "Prepared"
)
// +genclient
diff --git a/pkg/fedvolumebackup/backup/backup_manager.go b/pkg/fedvolumebackup/backup/backup_manager.go
index 6efc2d6f01..94e1532604 100644
--- a/pkg/fedvolumebackup/backup/backup_manager.go
+++ b/pkg/fedvolumebackup/backup/backup_manager.go
@@ -342,6 +342,14 @@ func (bm *backupManager) setVolumeBackupCleaned(volumeBackupStatus *v1alpha1.Vol
})
}
+func (bm *backupManager) setVolumeBackupPrepared(volumeBackupStatus *v1alpha1.VolumeBackupStatus) {
+ volumeBackupStatus.TimeStarted = metav1.Now()
+ v1alpha1.UpdateVolumeBackupCondition(volumeBackupStatus, &v1alpha1.VolumeBackupCondition{
+ Type: v1alpha1.VolumeBackupPrepared,
+ Status: corev1.ConditionTrue,
+ })
+}
+
func (bm *backupManager) setVolumeBackupSize(volumeBackupStatus *v1alpha1.VolumeBackupStatus, backupMembers []*volumeBackupMember) {
var totalBackupSize int64
for _, backupMember := range backupMembers {
From ed7a1088686efd9cdf8188b4bdf01799b33d8956 Mon Sep 17 00:00:00 2001
From: WangLe1321
Date: Mon, 22 May 2023 19:24:40 +0800
Subject: [PATCH 02/20] br: update backup member to status
Signed-off-by: WangLe1321
---
pkg/fedvolumebackup/backup/backup_manager.go | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/pkg/fedvolumebackup/backup/backup_manager.go b/pkg/fedvolumebackup/backup/backup_manager.go
index 94e1532604..c6604c516c 100644
--- a/pkg/fedvolumebackup/backup/backup_manager.go
+++ b/pkg/fedvolumebackup/backup/backup_manager.go
@@ -120,6 +120,20 @@ func (bm *backupManager) runBackup(ctx context.Context, volumeBackup *v1alpha1.V
bm.setVolumeBackupRunning(&volumeBackup.Status)
}
+<<<<<<< HEAD
+=======
+ if bm.skipSync(volumeBackup) {
+ klog.Infof("skip VolumeBackup %s/%s", ns, name)
+ return nil
+ }
+
+ ctx := context.Background()
+ backupMembers, err := bm.listAllBackupMembers(ctx, volumeBackup)
+ if err != nil {
+ return err
+ }
+
+>>>>>>> 7d84cf89e (br: update backup member to status)
if len(backupMembers) == 0 {
return false, bm.initializeVolumeBackup(ctx, volumeBackup)
}
@@ -411,7 +425,11 @@ func (bm *backupManager) buildBackupMember(volumeBackupName string, clusterMembe
}
func (bm *backupManager) skipSync(volumeBackup *v1alpha1.VolumeBackup) bool {
+<<<<<<< HEAD
return volumeBackup.DeletionTimestamp == nil && (v1alpha1.IsVolumeBackupComplete(volumeBackup) || v1alpha1.IsVolumeBackupFailed(volumeBackup))
+=======
+ return v1alpha1.IsVolumeBackupComplete(volumeBackup) || v1alpha1.IsVolumeBackupFailed(volumeBackup)
+>>>>>>> 7d84cf89e (br: update backup member to status)
}
func (bm *backupManager) generateBackupMemberName(volumeBackupName, k8sClusterName string) string {
From 0443dec68547bdab82786a094001f5b103be3be6 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Tue, 30 May 2023 13:59:57 +0800
Subject: [PATCH 03/20] *: support ebs backup schedule
Signed-off-by: BornChanger
---
docs/api-references/docs.md | 4 +-
docs/api-references/federation-docs.md | 180 +++-
manifests/crd.yaml | 6 +-
...ion.pingcap.com_volumebackupschedules.yaml | 953 +++++++++++++++++-
...ion.pingcap.com_volumebackupschedules.yaml | 951 ++++++++++++++++-
.../crd/v1/pingcap.com_backupschedules.yaml | 6 +-
.../v1beta1/pingcap.com_backupschedules.yaml | 6 +-
manifests/crd_v1beta1.yaml | 6 +-
manifests/federation-crd.yaml | 953 +++++++++++++++++-
manifests/federation-crd_v1beta1.yaml | 951 ++++++++++++++++-
.../pingcap/v1alpha1/openapi_generated.go | 41 +
pkg/apis/federation/pingcap/v1alpha1/types.go | 31 +-
.../pingcap/v1alpha1/volume_backup.go | 6 +
.../v1alpha1/volume_backup_schedule.go | 25 +
.../pingcap/v1alpha1/zz_generated.deepcopy.go | 23 +-
.../pingcap/v1alpha1/openapi_generated.go | 2 +-
pkg/apis/pingcap/v1alpha1/types.go | 3 +-
.../backupschedule/backup_schedule_manager.go | 7 +-
pkg/controller/controller_utils.go | 14 +
.../fed_backup_schedule_status_updater.go | 113 +++
pkg/controller/fed_volume_backup_control.go | 11 +-
.../fed_volume_backup_schedule_control.go | 34 +-
...fed_volume_backup_schedule_control_test.go | 120 +++
.../fed_volume_backup_schedule_controller.go | 2 +-
..._volume_backup_schedule_controller_test.go | 180 ++++
pkg/fedvolumebackup/backup/backup_manager.go | 34 +-
.../backupschedule/backup_schedule_manager.go | 310 +++++-
.../backup_schedule_manager_test.go | 516 ++++++++++
28 files changed, 5423 insertions(+), 65 deletions(-)
create mode 100644 pkg/apis/federation/pingcap/v1alpha1/volume_backup_schedule.go
create mode 100644 pkg/controller/fed_backup_schedule_status_updater.go
create mode 100644 pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
create mode 100644 pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller_test.go
create mode 100644 pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
diff --git a/docs/api-references/docs.md b/docs/api-references/docs.md
index 413a8c4b2f..d038325b7b 100644
--- a/docs/api-references/docs.md
+++ b/docs/api-references/docs.md
@@ -578,7 +578,6 @@ BackupSpec
-(Optional)
BackupTemplate is the specification of the backup structure to get scheduled.
|
@@ -592,6 +591,7 @@ BackupSpec
+(Optional)
LogBackupTemplate is the specification of the log backup structure to get scheduled.
|
@@ -3708,7 +3708,6 @@ BackupSpec
-(Optional)
BackupTemplate is the specification of the backup structure to get scheduled.
|
@@ -3722,6 +3721,7 @@ BackupSpec
+(Optional)
LogBackupTemplate is the specification of the log backup structure to get scheduled.
|
diff --git a/docs/api-references/federation-docs.md b/docs/api-references/federation-docs.md
index 3986c3e52c..9e44ef8df9 100644
--- a/docs/api-references/federation-docs.md
+++ b/docs/api-references/federation-docs.md
@@ -166,6 +166,66 @@ VolumeBackupScheduleSpec
+
+
+schedule
+
+string
+
+ |
+
+ Schedule specifies the cron string used for backup scheduling.
+ |
+
+
+
+pause
+
+bool
+
+ |
+
+ Pause means paused backupSchedule
+ |
+
+
+
+maxBackups
+
+int32
+
+ |
+
+ MaxBackups is to specify how many backups we want to keep
+0 is magic number to indicate un-limited backups.
+if MaxBackups and MaxReservedTime are set at the same time, MaxReservedTime is preferred
+and MaxBackups is ignored.
+ |
+
+
+
+maxReservedTime
+
+string
+
+ |
+
+ MaxReservedTime is to specify how long backups we want to keep.
+ |
+
+
+
+backupTemplate
+
+
+VolumeBackupSpec
+
+
+ |
+
+ BackupTemplate is the specification of the volume backup structure to get scheduled.
+ |
+
@@ -738,6 +798,76 @@ string
VolumeBackupScheduleSpec describes the attributes that a user creates on a volume backup schedule.
+
+
+
+Field |
+Description |
+
+
+
+
+
+schedule
+
+string
+
+ |
+
+ Schedule specifies the cron string used for backup scheduling.
+ |
+
+
+
+pause
+
+bool
+
+ |
+
+ Pause means paused backupSchedule
+ |
+
+
+
+maxBackups
+
+int32
+
+ |
+
+ MaxBackups is to specify how many backups we want to keep
+0 is magic number to indicate un-limited backups.
+if MaxBackups and MaxReservedTime are set at the same time, MaxReservedTime is preferred
+and MaxBackups is ignored.
+ |
+
+
+
+maxReservedTime
+
+string
+
+ |
+
+ MaxReservedTime is to specify how long backups we want to keep.
+ |
+
+
+
+backupTemplate
+
+
+VolumeBackupSpec
+
+
+ |
+
+ BackupTemplate is the specification of the volume backup structure to get scheduled.
+ |
+
+
+
VolumeBackupScheduleStatus
(Appears on:
@@ -746,10 +876,58 @@ string
VolumeBackupScheduleStatus represents the current status of a volume backup schedule.
+
+
+
+Field |
+Description |
+
+
+
+
+
+lastBackup
+
+string
+
+ |
+
+ LastBackup represents the last backup.
+ |
+
+
+
+lastBackupTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ LastBackupTime represents the last time the backup was successfully created.
+ |
+
+
+
+allBackupCleanTime
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ AllBackupCleanTime represents the time when all backup entries are cleaned up
+ |
+
+
+
VolumeBackupSpec
(Appears on:
-VolumeBackup)
+VolumeBackup,
+VolumeBackupScheduleSpec)
VolumeBackupSpec describes the attributes that a user creates on a volume backup.
diff --git a/manifests/crd.yaml b/manifests/crd.yaml
index 449b6d0380..cb1db3d4c6 100644
--- a/manifests/crd.yaml
+++ b/manifests/crd.yaml
@@ -1554,6 +1554,10 @@ spec:
jsonPath: .spec.maxBackups
name: MaxBackups
type: integer
+ - description: How long backups we want to keep
+ jsonPath: .spec.maxReservedTime
+ name: MaxReservedTime
+ type: string
- description: The last backup CR name
jsonPath: .status.lastBackup
name: LastBackup
@@ -4232,7 +4236,7 @@ spec:
storageSize:
type: string
required:
- - logBackupTemplate
+ - backupTemplate
- schedule
type: object
status:
diff --git a/manifests/crd/federation/v1/federation.pingcap.com_volumebackupschedules.yaml b/manifests/crd/federation/v1/federation.pingcap.com_volumebackupschedules.yaml
index 748bab61d9..386ccf98e5 100644
--- a/manifests/crd/federation/v1/federation.pingcap.com_volumebackupschedules.yaml
+++ b/manifests/crd/federation/v1/federation.pingcap.com_volumebackupschedules.yaml
@@ -14,11 +14,37 @@ spec:
listKind: VolumeBackupScheduleList
plural: volumebackupschedules
shortNames:
- - vbks
+ - vbfs
singular: volumebackupschedule
scope: Namespaced
versions:
- - name: v1alpha1
+ - additionalPrinterColumns:
+ - description: The cron format string used for backup scheduling
+ jsonPath: .spec.schedule
+ name: Schedule
+ type: string
+ - description: The max number of backups we want to keep
+ jsonPath: .spec.maxBackups
+ name: MaxBackups
+ type: integer
+ - description: How long backups we want to keep
+ jsonPath: .spec.maxReservedTime
+ name: MaxReservedTime
+ type: string
+ - description: The last backup CR name
+ jsonPath: .status.lastBackup
+ name: LastBackup
+ priority: 1
+ type: string
+ - description: The last time the backup was successfully created
+ jsonPath: .status.lastBackupTime
+ name: LastBackupTime
+ priority: 1
+ type: date
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
schema:
openAPIV3Schema:
properties:
@@ -29,8 +55,930 @@ spec:
metadata:
type: object
spec:
+ properties:
+ backupTemplate:
+ properties:
+ clusters:
+ items:
+ properties:
+ k8sClusterName:
+ type: string
+ tcName:
+ type: string
+ tcNamespace:
+ type: string
+ type: object
+ type: array
+ template:
+ properties:
+ azblob:
+ properties:
+ accessTier:
+ type: string
+ container:
+ type: string
+ path:
+ type: string
+ prefix:
+ type: string
+ secretName:
+ type: string
+ type: object
+ br:
+ properties:
+ checkRequirements:
+ type: boolean
+ concurrency:
+ format: int32
+ type: integer
+ options:
+ items:
+ type: string
+ type: array
+ sendCredToTikv:
+ type: boolean
+ type: object
+ cleanPolicy:
+ type: string
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ gcs:
+ properties:
+ bucket:
+ type: string
+ bucketAcl:
+ type: string
+ location:
+ type: string
+ objectAcl:
+ type: string
+ path:
+ type: string
+ prefix:
+ type: string
+ projectId:
+ type: string
+ secretName:
+ type: string
+ storageClass:
+ type: string
+ required:
+ - projectId
+ type: object
+ imagePullSecrets:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ local:
+ properties:
+ prefix:
+ type: string
+ volume:
+ properties:
+ awsElasticBlockStore:
+ properties:
+ fsType:
+ type: string
+ partition:
+ format: int32
+ type: integer
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ azureDisk:
+ properties:
+ cachingMode:
+ type: string
+ diskName:
+ type: string
+ diskURI:
+ type: string
+ fsType:
+ type: string
+ kind:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - diskName
+ - diskURI
+ type: object
+ azureFile:
+ properties:
+ readOnly:
+ type: boolean
+ secretName:
+ type: string
+ shareName:
+ type: string
+ required:
+ - secretName
+ - shareName
+ type: object
+ cephfs:
+ properties:
+ monitors:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ secretFile:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ required:
+ - monitors
+ type: object
+ cinder:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ configMap:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ csi:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ nodePublishSecretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ volumeAttributes:
+ additionalProperties:
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ downwardAPI:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ emptyDir:
+ properties:
+ medium:
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ properties:
+ readOnly:
+ type: boolean
+ volumeClaimTemplate:
+ properties:
+ metadata:
+ type: object
+ spec:
+ properties:
+ accessModes:
+ items:
+ type: string
+ type: array
+ dataSource:
+ properties:
+ apiGroup:
+ type: string
+ kind:
+ type: string
+ name:
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ selector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ storageClassName:
+ type: string
+ volumeMode:
+ type: string
+ volumeName:
+ type: string
+ type: object
+ required:
+ - spec
+ type: object
+ type: object
+ fc:
+ properties:
+ fsType:
+ type: string
+ lun:
+ format: int32
+ type: integer
+ readOnly:
+ type: boolean
+ targetWWNs:
+ items:
+ type: string
+ type: array
+ wwids:
+ items:
+ type: string
+ type: array
+ type: object
+ flexVolume:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ options:
+ additionalProperties:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ flocker:
+ properties:
+ datasetName:
+ type: string
+ datasetUUID:
+ type: string
+ type: object
+ gcePersistentDisk:
+ properties:
+ fsType:
+ type: string
+ partition:
+ format: int32
+ type: integer
+ pdName:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - pdName
+ type: object
+ gitRepo:
+ properties:
+ directory:
+ type: string
+ repository:
+ type: string
+ revision:
+ type: string
+ required:
+ - repository
+ type: object
+ glusterfs:
+ properties:
+ endpoints:
+ type: string
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - endpoints
+ - path
+ type: object
+ hostPath:
+ properties:
+ path:
+ type: string
+ type:
+ type: string
+ required:
+ - path
+ type: object
+ iscsi:
+ properties:
+ chapAuthDiscovery:
+ type: boolean
+ chapAuthSession:
+ type: boolean
+ fsType:
+ type: string
+ initiatorName:
+ type: string
+ iqn:
+ type: string
+ iscsiInterface:
+ type: string
+ lun:
+ format: int32
+ type: integer
+ portals:
+ items:
+ type: string
+ type: array
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ targetPortal:
+ type: string
+ required:
+ - iqn
+ - lun
+ - targetPortal
+ type: object
+ name:
+ type: string
+ nfs:
+ properties:
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ server:
+ type: string
+ required:
+ - path
+ - server
+ type: object
+ persistentVolumeClaim:
+ properties:
+ claimName:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - claimName
+ type: object
+ photonPersistentDisk:
+ properties:
+ fsType:
+ type: string
+ pdID:
+ type: string
+ required:
+ - pdID
+ type: object
+ portworxVolume:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ projected:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ sources:
+ items:
+ properties:
+ configMap:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ downwardAPI:
+ properties:
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ secret:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ serviceAccountToken:
+ properties:
+ audience:
+ type: string
+ expirationSeconds:
+ format: int64
+ type: integer
+ path:
+ type: string
+ required:
+ - path
+ type: object
+ type: object
+ type: array
+ type: object
+ quobyte:
+ properties:
+ group:
+ type: string
+ readOnly:
+ type: boolean
+ registry:
+ type: string
+ tenant:
+ type: string
+ user:
+ type: string
+ volume:
+ type: string
+ required:
+ - registry
+ - volume
+ type: object
+ rbd:
+ properties:
+ fsType:
+ type: string
+ image:
+ type: string
+ keyring:
+ type: string
+ monitors:
+ items:
+ type: string
+ type: array
+ pool:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ required:
+ - image
+ - monitors
+ type: object
+ scaleIO:
+ properties:
+ fsType:
+ type: string
+ gateway:
+ type: string
+ protectionDomain:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ sslEnabled:
+ type: boolean
+ storageMode:
+ type: string
+ storagePool:
+ type: string
+ system:
+ type: string
+ volumeName:
+ type: string
+ required:
+ - gateway
+ - secretRef
+ - system
+ type: object
+ secret:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ optional:
+ type: boolean
+ secretName:
+ type: string
+ type: object
+ storageos:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeName:
+ type: string
+ volumeNamespace:
+ type: string
+ type: object
+ vsphereVolume:
+ properties:
+ fsType:
+ type: string
+ storagePolicyID:
+ type: string
+ storagePolicyName:
+ type: string
+ volumePath:
+ type: string
+ required:
+ - volumePath
+ type: object
+ required:
+ - name
+ type: object
+ volumeMount:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ required:
+ - mountPath
+ - name
+ type: object
+ required:
+ - volume
+ - volumeMount
+ type: object
+ priorityClassName:
+ type: string
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ s3:
+ properties:
+ acl:
+ type: string
+ bucket:
+ type: string
+ endpoint:
+ type: string
+ options:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ prefix:
+ type: string
+ provider:
+ type: string
+ region:
+ type: string
+ secretName:
+ type: string
+ sse:
+ type: string
+ storageClass:
+ type: string
+ required:
+ - provider
+ type: object
+ serviceAccount:
+ type: string
+ tolerations:
+ items:
+ properties:
+ effect:
+ type: string
+ key:
+ type: string
+ operator:
+ type: string
+ tolerationSeconds:
+ format: int64
+ type: integer
+ value:
+ type: string
+ type: object
+ type: array
+ toolImage:
+ type: string
+ type: object
+ type: object
+ maxBackups:
+ format: int32
+ type: integer
+ maxReservedTime:
+ type: string
+ pause:
+ type: boolean
+ schedule:
+ type: string
+ required:
+ - backupTemplate
+ - schedule
type: object
status:
+ properties:
+ allBackupCleanTime:
+ format: date-time
+ type: string
+ lastBackup:
+ type: string
+ lastBackupTime:
+ format: date-time
+ type: string
type: object
required:
- metadata
@@ -38,6 +986,7 @@ spec:
type: object
served: true
storage: true
+ subresources: {}
status:
acceptedNames:
kind: ""
diff --git a/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackupschedules.yaml b/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackupschedules.yaml
index 29d26b06e9..1809519859 100644
--- a/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackupschedules.yaml
+++ b/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackupschedules.yaml
@@ -8,16 +8,43 @@ metadata:
creationTimestamp: null
name: volumebackupschedules.federation.pingcap.com
spec:
+ additionalPrinterColumns:
+ - JSONPath: .spec.schedule
+ description: The cron format string used for backup scheduling
+ name: Schedule
+ type: string
+ - JSONPath: .spec.maxBackups
+ description: The max number of backups we want to keep
+ name: MaxBackups
+ type: integer
+ - JSONPath: .spec.maxReservedTime
+ description: How long backups we want to keep
+ name: MaxReservedTime
+ type: string
+ - JSONPath: .status.lastBackup
+ description: The last backup CR name
+ name: LastBackup
+ priority: 1
+ type: string
+ - JSONPath: .status.lastBackupTime
+ description: The last time the backup was successfully created
+ name: LastBackupTime
+ priority: 1
+ type: date
+ - JSONPath: .metadata.creationTimestamp
+ name: Age
+ type: date
group: federation.pingcap.com
names:
kind: VolumeBackupSchedule
listKind: VolumeBackupScheduleList
plural: volumebackupschedules
shortNames:
- - vbks
+ - vbfs
singular: volumebackupschedule
preserveUnknownFields: false
scope: Namespaced
+ subresources: {}
validation:
openAPIV3Schema:
properties:
@@ -28,8 +55,930 @@ spec:
metadata:
type: object
spec:
+ properties:
+ backupTemplate:
+ properties:
+ clusters:
+ items:
+ properties:
+ k8sClusterName:
+ type: string
+ tcName:
+ type: string
+ tcNamespace:
+ type: string
+ type: object
+ type: array
+ template:
+ properties:
+ azblob:
+ properties:
+ accessTier:
+ type: string
+ container:
+ type: string
+ path:
+ type: string
+ prefix:
+ type: string
+ secretName:
+ type: string
+ type: object
+ br:
+ properties:
+ checkRequirements:
+ type: boolean
+ concurrency:
+ format: int32
+ type: integer
+ options:
+ items:
+ type: string
+ type: array
+ sendCredToTikv:
+ type: boolean
+ type: object
+ cleanPolicy:
+ type: string
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ gcs:
+ properties:
+ bucket:
+ type: string
+ bucketAcl:
+ type: string
+ location:
+ type: string
+ objectAcl:
+ type: string
+ path:
+ type: string
+ prefix:
+ type: string
+ projectId:
+ type: string
+ secretName:
+ type: string
+ storageClass:
+ type: string
+ required:
+ - projectId
+ type: object
+ imagePullSecrets:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ local:
+ properties:
+ prefix:
+ type: string
+ volume:
+ properties:
+ awsElasticBlockStore:
+ properties:
+ fsType:
+ type: string
+ partition:
+ format: int32
+ type: integer
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ azureDisk:
+ properties:
+ cachingMode:
+ type: string
+ diskName:
+ type: string
+ diskURI:
+ type: string
+ fsType:
+ type: string
+ kind:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - diskName
+ - diskURI
+ type: object
+ azureFile:
+ properties:
+ readOnly:
+ type: boolean
+ secretName:
+ type: string
+ shareName:
+ type: string
+ required:
+ - secretName
+ - shareName
+ type: object
+ cephfs:
+ properties:
+ monitors:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ secretFile:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ required:
+ - monitors
+ type: object
+ cinder:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ configMap:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ csi:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ nodePublishSecretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ volumeAttributes:
+ additionalProperties:
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ downwardAPI:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ emptyDir:
+ properties:
+ medium:
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ properties:
+ readOnly:
+ type: boolean
+ volumeClaimTemplate:
+ properties:
+ metadata:
+ type: object
+ spec:
+ properties:
+ accessModes:
+ items:
+ type: string
+ type: array
+ dataSource:
+ properties:
+ apiGroup:
+ type: string
+ kind:
+ type: string
+ name:
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ selector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ storageClassName:
+ type: string
+ volumeMode:
+ type: string
+ volumeName:
+ type: string
+ type: object
+ required:
+ - spec
+ type: object
+ type: object
+ fc:
+ properties:
+ fsType:
+ type: string
+ lun:
+ format: int32
+ type: integer
+ readOnly:
+ type: boolean
+ targetWWNs:
+ items:
+ type: string
+ type: array
+ wwids:
+ items:
+ type: string
+ type: array
+ type: object
+ flexVolume:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ options:
+ additionalProperties:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ flocker:
+ properties:
+ datasetName:
+ type: string
+ datasetUUID:
+ type: string
+ type: object
+ gcePersistentDisk:
+ properties:
+ fsType:
+ type: string
+ partition:
+ format: int32
+ type: integer
+ pdName:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - pdName
+ type: object
+ gitRepo:
+ properties:
+ directory:
+ type: string
+ repository:
+ type: string
+ revision:
+ type: string
+ required:
+ - repository
+ type: object
+ glusterfs:
+ properties:
+ endpoints:
+ type: string
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - endpoints
+ - path
+ type: object
+ hostPath:
+ properties:
+ path:
+ type: string
+ type:
+ type: string
+ required:
+ - path
+ type: object
+ iscsi:
+ properties:
+ chapAuthDiscovery:
+ type: boolean
+ chapAuthSession:
+ type: boolean
+ fsType:
+ type: string
+ initiatorName:
+ type: string
+ iqn:
+ type: string
+ iscsiInterface:
+ type: string
+ lun:
+ format: int32
+ type: integer
+ portals:
+ items:
+ type: string
+ type: array
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ targetPortal:
+ type: string
+ required:
+ - iqn
+ - lun
+ - targetPortal
+ type: object
+ name:
+ type: string
+ nfs:
+ properties:
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ server:
+ type: string
+ required:
+ - path
+ - server
+ type: object
+ persistentVolumeClaim:
+ properties:
+ claimName:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - claimName
+ type: object
+ photonPersistentDisk:
+ properties:
+ fsType:
+ type: string
+ pdID:
+ type: string
+ required:
+ - pdID
+ type: object
+ portworxVolume:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ projected:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ sources:
+ items:
+ properties:
+ configMap:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ downwardAPI:
+ properties:
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ secret:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ serviceAccountToken:
+ properties:
+ audience:
+ type: string
+ expirationSeconds:
+ format: int64
+ type: integer
+ path:
+ type: string
+ required:
+ - path
+ type: object
+ type: object
+ type: array
+ type: object
+ quobyte:
+ properties:
+ group:
+ type: string
+ readOnly:
+ type: boolean
+ registry:
+ type: string
+ tenant:
+ type: string
+ user:
+ type: string
+ volume:
+ type: string
+ required:
+ - registry
+ - volume
+ type: object
+ rbd:
+ properties:
+ fsType:
+ type: string
+ image:
+ type: string
+ keyring:
+ type: string
+ monitors:
+ items:
+ type: string
+ type: array
+ pool:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ required:
+ - image
+ - monitors
+ type: object
+ scaleIO:
+ properties:
+ fsType:
+ type: string
+ gateway:
+ type: string
+ protectionDomain:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ sslEnabled:
+ type: boolean
+ storageMode:
+ type: string
+ storagePool:
+ type: string
+ system:
+ type: string
+ volumeName:
+ type: string
+ required:
+ - gateway
+ - secretRef
+ - system
+ type: object
+ secret:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ optional:
+ type: boolean
+ secretName:
+ type: string
+ type: object
+ storageos:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeName:
+ type: string
+ volumeNamespace:
+ type: string
+ type: object
+ vsphereVolume:
+ properties:
+ fsType:
+ type: string
+ storagePolicyID:
+ type: string
+ storagePolicyName:
+ type: string
+ volumePath:
+ type: string
+ required:
+ - volumePath
+ type: object
+ required:
+ - name
+ type: object
+ volumeMount:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ required:
+ - mountPath
+ - name
+ type: object
+ required:
+ - volume
+ - volumeMount
+ type: object
+ priorityClassName:
+ type: string
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ s3:
+ properties:
+ acl:
+ type: string
+ bucket:
+ type: string
+ endpoint:
+ type: string
+ options:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ prefix:
+ type: string
+ provider:
+ type: string
+ region:
+ type: string
+ secretName:
+ type: string
+ sse:
+ type: string
+ storageClass:
+ type: string
+ required:
+ - provider
+ type: object
+ serviceAccount:
+ type: string
+ tolerations:
+ items:
+ properties:
+ effect:
+ type: string
+ key:
+ type: string
+ operator:
+ type: string
+ tolerationSeconds:
+ format: int64
+ type: integer
+ value:
+ type: string
+ type: object
+ type: array
+ toolImage:
+ type: string
+ type: object
+ type: object
+ maxBackups:
+ format: int32
+ type: integer
+ maxReservedTime:
+ type: string
+ pause:
+ type: boolean
+ schedule:
+ type: string
+ required:
+ - backupTemplate
+ - schedule
type: object
status:
+ properties:
+ allBackupCleanTime:
+ format: date-time
+ type: string
+ lastBackup:
+ type: string
+ lastBackupTime:
+ format: date-time
+ type: string
type: object
required:
- metadata
diff --git a/manifests/crd/v1/pingcap.com_backupschedules.yaml b/manifests/crd/v1/pingcap.com_backupschedules.yaml
index 43175cd21e..c6479d6916 100644
--- a/manifests/crd/v1/pingcap.com_backupschedules.yaml
+++ b/manifests/crd/v1/pingcap.com_backupschedules.yaml
@@ -27,6 +27,10 @@ spec:
jsonPath: .spec.maxBackups
name: MaxBackups
type: integer
+ - description: How long backups we want to keep
+ jsonPath: .spec.maxReservedTime
+ name: MaxReservedTime
+ type: string
- description: The last backup CR name
jsonPath: .status.lastBackup
name: LastBackup
@@ -2705,7 +2709,7 @@ spec:
storageSize:
type: string
required:
- - logBackupTemplate
+ - backupTemplate
- schedule
type: object
status:
diff --git a/manifests/crd/v1beta1/pingcap.com_backupschedules.yaml b/manifests/crd/v1beta1/pingcap.com_backupschedules.yaml
index e865a48de3..c8ce37aef5 100644
--- a/manifests/crd/v1beta1/pingcap.com_backupschedules.yaml
+++ b/manifests/crd/v1beta1/pingcap.com_backupschedules.yaml
@@ -17,6 +17,10 @@ spec:
description: The max number of backups we want to keep
name: MaxBackups
type: integer
+ - JSONPath: .spec.maxReservedTime
+ description: How long backups we want to keep
+ name: MaxReservedTime
+ type: string
- JSONPath: .status.lastBackup
description: The last backup CR name
name: LastBackup
@@ -2695,7 +2699,7 @@ spec:
storageSize:
type: string
required:
- - logBackupTemplate
+ - backupTemplate
- schedule
type: object
status:
diff --git a/manifests/crd_v1beta1.yaml b/manifests/crd_v1beta1.yaml
index 060e7f7fef..65fe525782 100644
--- a/manifests/crd_v1beta1.yaml
+++ b/manifests/crd_v1beta1.yaml
@@ -1541,6 +1541,10 @@ spec:
description: The max number of backups we want to keep
name: MaxBackups
type: integer
+ - JSONPath: .spec.maxReservedTime
+ description: How long backups we want to keep
+ name: MaxReservedTime
+ type: string
- JSONPath: .status.lastBackup
description: The last backup CR name
name: LastBackup
@@ -4219,7 +4223,7 @@ spec:
storageSize:
type: string
required:
- - logBackupTemplate
+ - backupTemplate
- schedule
type: object
status:
diff --git a/manifests/federation-crd.yaml b/manifests/federation-crd.yaml
index 2b5144b42f..6cbddd832a 100644
--- a/manifests/federation-crd.yaml
+++ b/manifests/federation-crd.yaml
@@ -1042,11 +1042,37 @@ spec:
listKind: VolumeBackupScheduleList
plural: volumebackupschedules
shortNames:
- - vbks
+ - vbfs
singular: volumebackupschedule
scope: Namespaced
versions:
- - name: v1alpha1
+ - additionalPrinterColumns:
+ - description: The cron format string used for backup scheduling
+ jsonPath: .spec.schedule
+ name: Schedule
+ type: string
+ - description: The max number of backups we want to keep
+ jsonPath: .spec.maxBackups
+ name: MaxBackups
+ type: integer
+ - description: How long backups we want to keep
+ jsonPath: .spec.maxReservedTime
+ name: MaxReservedTime
+ type: string
+ - description: The last backup CR name
+ jsonPath: .status.lastBackup
+ name: LastBackup
+ priority: 1
+ type: string
+ - description: The last time the backup was successfully created
+ jsonPath: .status.lastBackupTime
+ name: LastBackupTime
+ priority: 1
+ type: date
+ - jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
schema:
openAPIV3Schema:
properties:
@@ -1057,8 +1083,930 @@ spec:
metadata:
type: object
spec:
+ properties:
+ backupTemplate:
+ properties:
+ clusters:
+ items:
+ properties:
+ k8sClusterName:
+ type: string
+ tcName:
+ type: string
+ tcNamespace:
+ type: string
+ type: object
+ type: array
+ template:
+ properties:
+ azblob:
+ properties:
+ accessTier:
+ type: string
+ container:
+ type: string
+ path:
+ type: string
+ prefix:
+ type: string
+ secretName:
+ type: string
+ type: object
+ br:
+ properties:
+ checkRequirements:
+ type: boolean
+ concurrency:
+ format: int32
+ type: integer
+ options:
+ items:
+ type: string
+ type: array
+ sendCredToTikv:
+ type: boolean
+ type: object
+ cleanPolicy:
+ type: string
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ gcs:
+ properties:
+ bucket:
+ type: string
+ bucketAcl:
+ type: string
+ location:
+ type: string
+ objectAcl:
+ type: string
+ path:
+ type: string
+ prefix:
+ type: string
+ projectId:
+ type: string
+ secretName:
+ type: string
+ storageClass:
+ type: string
+ required:
+ - projectId
+ type: object
+ imagePullSecrets:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ local:
+ properties:
+ prefix:
+ type: string
+ volume:
+ properties:
+ awsElasticBlockStore:
+ properties:
+ fsType:
+ type: string
+ partition:
+ format: int32
+ type: integer
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ azureDisk:
+ properties:
+ cachingMode:
+ type: string
+ diskName:
+ type: string
+ diskURI:
+ type: string
+ fsType:
+ type: string
+ kind:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - diskName
+ - diskURI
+ type: object
+ azureFile:
+ properties:
+ readOnly:
+ type: boolean
+ secretName:
+ type: string
+ shareName:
+ type: string
+ required:
+ - secretName
+ - shareName
+ type: object
+ cephfs:
+ properties:
+ monitors:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ secretFile:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ required:
+ - monitors
+ type: object
+ cinder:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ configMap:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ csi:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ nodePublishSecretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ volumeAttributes:
+ additionalProperties:
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ downwardAPI:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ emptyDir:
+ properties:
+ medium:
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ properties:
+ readOnly:
+ type: boolean
+ volumeClaimTemplate:
+ properties:
+ metadata:
+ type: object
+ spec:
+ properties:
+ accessModes:
+ items:
+ type: string
+ type: array
+ dataSource:
+ properties:
+ apiGroup:
+ type: string
+ kind:
+ type: string
+ name:
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ selector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ storageClassName:
+ type: string
+ volumeMode:
+ type: string
+ volumeName:
+ type: string
+ type: object
+ required:
+ - spec
+ type: object
+ type: object
+ fc:
+ properties:
+ fsType:
+ type: string
+ lun:
+ format: int32
+ type: integer
+ readOnly:
+ type: boolean
+ targetWWNs:
+ items:
+ type: string
+ type: array
+ wwids:
+ items:
+ type: string
+ type: array
+ type: object
+ flexVolume:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ options:
+ additionalProperties:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ flocker:
+ properties:
+ datasetName:
+ type: string
+ datasetUUID:
+ type: string
+ type: object
+ gcePersistentDisk:
+ properties:
+ fsType:
+ type: string
+ partition:
+ format: int32
+ type: integer
+ pdName:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - pdName
+ type: object
+ gitRepo:
+ properties:
+ directory:
+ type: string
+ repository:
+ type: string
+ revision:
+ type: string
+ required:
+ - repository
+ type: object
+ glusterfs:
+ properties:
+ endpoints:
+ type: string
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - endpoints
+ - path
+ type: object
+ hostPath:
+ properties:
+ path:
+ type: string
+ type:
+ type: string
+ required:
+ - path
+ type: object
+ iscsi:
+ properties:
+ chapAuthDiscovery:
+ type: boolean
+ chapAuthSession:
+ type: boolean
+ fsType:
+ type: string
+ initiatorName:
+ type: string
+ iqn:
+ type: string
+ iscsiInterface:
+ type: string
+ lun:
+ format: int32
+ type: integer
+ portals:
+ items:
+ type: string
+ type: array
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ targetPortal:
+ type: string
+ required:
+ - iqn
+ - lun
+ - targetPortal
+ type: object
+ name:
+ type: string
+ nfs:
+ properties:
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ server:
+ type: string
+ required:
+ - path
+ - server
+ type: object
+ persistentVolumeClaim:
+ properties:
+ claimName:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - claimName
+ type: object
+ photonPersistentDisk:
+ properties:
+ fsType:
+ type: string
+ pdID:
+ type: string
+ required:
+ - pdID
+ type: object
+ portworxVolume:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ projected:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ sources:
+ items:
+ properties:
+ configMap:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ downwardAPI:
+ properties:
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ secret:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ serviceAccountToken:
+ properties:
+ audience:
+ type: string
+ expirationSeconds:
+ format: int64
+ type: integer
+ path:
+ type: string
+ required:
+ - path
+ type: object
+ type: object
+ type: array
+ type: object
+ quobyte:
+ properties:
+ group:
+ type: string
+ readOnly:
+ type: boolean
+ registry:
+ type: string
+ tenant:
+ type: string
+ user:
+ type: string
+ volume:
+ type: string
+ required:
+ - registry
+ - volume
+ type: object
+ rbd:
+ properties:
+ fsType:
+ type: string
+ image:
+ type: string
+ keyring:
+ type: string
+ monitors:
+ items:
+ type: string
+ type: array
+ pool:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ required:
+ - image
+ - monitors
+ type: object
+ scaleIO:
+ properties:
+ fsType:
+ type: string
+ gateway:
+ type: string
+ protectionDomain:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ sslEnabled:
+ type: boolean
+ storageMode:
+ type: string
+ storagePool:
+ type: string
+ system:
+ type: string
+ volumeName:
+ type: string
+ required:
+ - gateway
+ - secretRef
+ - system
+ type: object
+ secret:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ optional:
+ type: boolean
+ secretName:
+ type: string
+ type: object
+ storageos:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeName:
+ type: string
+ volumeNamespace:
+ type: string
+ type: object
+ vsphereVolume:
+ properties:
+ fsType:
+ type: string
+ storagePolicyID:
+ type: string
+ storagePolicyName:
+ type: string
+ volumePath:
+ type: string
+ required:
+ - volumePath
+ type: object
+ required:
+ - name
+ type: object
+ volumeMount:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ required:
+ - mountPath
+ - name
+ type: object
+ required:
+ - volume
+ - volumeMount
+ type: object
+ priorityClassName:
+ type: string
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ s3:
+ properties:
+ acl:
+ type: string
+ bucket:
+ type: string
+ endpoint:
+ type: string
+ options:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ prefix:
+ type: string
+ provider:
+ type: string
+ region:
+ type: string
+ secretName:
+ type: string
+ sse:
+ type: string
+ storageClass:
+ type: string
+ required:
+ - provider
+ type: object
+ serviceAccount:
+ type: string
+ tolerations:
+ items:
+ properties:
+ effect:
+ type: string
+ key:
+ type: string
+ operator:
+ type: string
+ tolerationSeconds:
+ format: int64
+ type: integer
+ value:
+ type: string
+ type: object
+ type: array
+ toolImage:
+ type: string
+ type: object
+ type: object
+ maxBackups:
+ format: int32
+ type: integer
+ maxReservedTime:
+ type: string
+ pause:
+ type: boolean
+ schedule:
+ type: string
+ required:
+ - backupTemplate
+ - schedule
type: object
status:
+ properties:
+ allBackupCleanTime:
+ format: date-time
+ type: string
+ lastBackup:
+ type: string
+ lastBackupTime:
+ format: date-time
+ type: string
type: object
required:
- metadata
@@ -1066,6 +2014,7 @@ spec:
type: object
served: true
storage: true
+ subresources: {}
status:
acceptedNames:
kind: ""
diff --git a/manifests/federation-crd_v1beta1.yaml b/manifests/federation-crd_v1beta1.yaml
index a2d7ae2e5b..43152b27db 100644
--- a/manifests/federation-crd_v1beta1.yaml
+++ b/manifests/federation-crd_v1beta1.yaml
@@ -1038,16 +1038,43 @@ metadata:
creationTimestamp: null
name: volumebackupschedules.federation.pingcap.com
spec:
+ additionalPrinterColumns:
+ - JSONPath: .spec.schedule
+ description: The cron format string used for backup scheduling
+ name: Schedule
+ type: string
+ - JSONPath: .spec.maxBackups
+ description: The max number of backups we want to keep
+ name: MaxBackups
+ type: integer
+ - JSONPath: .spec.maxReservedTime
+ description: How long backups we want to keep
+ name: MaxReservedTime
+ type: string
+ - JSONPath: .status.lastBackup
+ description: The last backup CR name
+ name: LastBackup
+ priority: 1
+ type: string
+ - JSONPath: .status.lastBackupTime
+ description: The last time the backup was successfully created
+ name: LastBackupTime
+ priority: 1
+ type: date
+ - JSONPath: .metadata.creationTimestamp
+ name: Age
+ type: date
group: federation.pingcap.com
names:
kind: VolumeBackupSchedule
listKind: VolumeBackupScheduleList
plural: volumebackupschedules
shortNames:
- - vbks
+ - vbfs
singular: volumebackupschedule
preserveUnknownFields: false
scope: Namespaced
+ subresources: {}
validation:
openAPIV3Schema:
properties:
@@ -1058,8 +1085,930 @@ spec:
metadata:
type: object
spec:
+ properties:
+ backupTemplate:
+ properties:
+ clusters:
+ items:
+ properties:
+ k8sClusterName:
+ type: string
+ tcName:
+ type: string
+ tcNamespace:
+ type: string
+ type: object
+ type: array
+ template:
+ properties:
+ azblob:
+ properties:
+ accessTier:
+ type: string
+ container:
+ type: string
+ path:
+ type: string
+ prefix:
+ type: string
+ secretName:
+ type: string
+ type: object
+ br:
+ properties:
+ checkRequirements:
+ type: boolean
+ concurrency:
+ format: int32
+ type: integer
+ options:
+ items:
+ type: string
+ type: array
+ sendCredToTikv:
+ type: boolean
+ type: object
+ cleanPolicy:
+ type: string
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ required:
+ - key
+ type: object
+ type: object
+ required:
+ - name
+ type: object
+ type: array
+ gcs:
+ properties:
+ bucket:
+ type: string
+ bucketAcl:
+ type: string
+ location:
+ type: string
+ objectAcl:
+ type: string
+ path:
+ type: string
+ prefix:
+ type: string
+ projectId:
+ type: string
+ secretName:
+ type: string
+ storageClass:
+ type: string
+ required:
+ - projectId
+ type: object
+ imagePullSecrets:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ local:
+ properties:
+ prefix:
+ type: string
+ volume:
+ properties:
+ awsElasticBlockStore:
+ properties:
+ fsType:
+ type: string
+ partition:
+ format: int32
+ type: integer
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ azureDisk:
+ properties:
+ cachingMode:
+ type: string
+ diskName:
+ type: string
+ diskURI:
+ type: string
+ fsType:
+ type: string
+ kind:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - diskName
+ - diskURI
+ type: object
+ azureFile:
+ properties:
+ readOnly:
+ type: boolean
+ secretName:
+ type: string
+ shareName:
+ type: string
+ required:
+ - secretName
+ - shareName
+ type: object
+ cephfs:
+ properties:
+ monitors:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ secretFile:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ required:
+ - monitors
+ type: object
+ cinder:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ configMap:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ csi:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ nodePublishSecretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ volumeAttributes:
+ additionalProperties:
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ downwardAPI:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ emptyDir:
+ properties:
+ medium:
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ properties:
+ readOnly:
+ type: boolean
+ volumeClaimTemplate:
+ properties:
+ metadata:
+ type: object
+ spec:
+ properties:
+ accessModes:
+ items:
+ type: string
+ type: array
+ dataSource:
+ properties:
+ apiGroup:
+ type: string
+ kind:
+ type: string
+ name:
+ type: string
+ required:
+ - kind
+ - name
+ type: object
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ selector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ storageClassName:
+ type: string
+ volumeMode:
+ type: string
+ volumeName:
+ type: string
+ type: object
+ required:
+ - spec
+ type: object
+ type: object
+ fc:
+ properties:
+ fsType:
+ type: string
+ lun:
+ format: int32
+ type: integer
+ readOnly:
+ type: boolean
+ targetWWNs:
+ items:
+ type: string
+ type: array
+ wwids:
+ items:
+ type: string
+ type: array
+ type: object
+ flexVolume:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ options:
+ additionalProperties:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ required:
+ - driver
+ type: object
+ flocker:
+ properties:
+ datasetName:
+ type: string
+ datasetUUID:
+ type: string
+ type: object
+ gcePersistentDisk:
+ properties:
+ fsType:
+ type: string
+ partition:
+ format: int32
+ type: integer
+ pdName:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - pdName
+ type: object
+ gitRepo:
+ properties:
+ directory:
+ type: string
+ repository:
+ type: string
+ revision:
+ type: string
+ required:
+ - repository
+ type: object
+ glusterfs:
+ properties:
+ endpoints:
+ type: string
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - endpoints
+ - path
+ type: object
+ hostPath:
+ properties:
+ path:
+ type: string
+ type:
+ type: string
+ required:
+ - path
+ type: object
+ iscsi:
+ properties:
+ chapAuthDiscovery:
+ type: boolean
+ chapAuthSession:
+ type: boolean
+ fsType:
+ type: string
+ initiatorName:
+ type: string
+ iqn:
+ type: string
+ iscsiInterface:
+ type: string
+ lun:
+ format: int32
+ type: integer
+ portals:
+ items:
+ type: string
+ type: array
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ targetPortal:
+ type: string
+ required:
+ - iqn
+ - lun
+ - targetPortal
+ type: object
+ name:
+ type: string
+ nfs:
+ properties:
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ server:
+ type: string
+ required:
+ - path
+ - server
+ type: object
+ persistentVolumeClaim:
+ properties:
+ claimName:
+ type: string
+ readOnly:
+ type: boolean
+ required:
+ - claimName
+ type: object
+ photonPersistentDisk:
+ properties:
+ fsType:
+ type: string
+ pdID:
+ type: string
+ required:
+ - pdID
+ type: object
+ portworxVolume:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ required:
+ - volumeID
+ type: object
+ projected:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ sources:
+ items:
+ properties:
+ configMap:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ downwardAPI:
+ properties:
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ required:
+ - fieldPath
+ type: object
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ required:
+ - resource
+ type: object
+ required:
+ - path
+ type: object
+ type: array
+ type: object
+ secret:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ serviceAccountToken:
+ properties:
+ audience:
+ type: string
+ expirationSeconds:
+ format: int64
+ type: integer
+ path:
+ type: string
+ required:
+ - path
+ type: object
+ type: object
+ type: array
+ type: object
+ quobyte:
+ properties:
+ group:
+ type: string
+ readOnly:
+ type: boolean
+ registry:
+ type: string
+ tenant:
+ type: string
+ user:
+ type: string
+ volume:
+ type: string
+ required:
+ - registry
+ - volume
+ type: object
+ rbd:
+ properties:
+ fsType:
+ type: string
+ image:
+ type: string
+ keyring:
+ type: string
+ monitors:
+ items:
+ type: string
+ type: array
+ pool:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ required:
+ - image
+ - monitors
+ type: object
+ scaleIO:
+ properties:
+ fsType:
+ type: string
+ gateway:
+ type: string
+ protectionDomain:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ sslEnabled:
+ type: boolean
+ storageMode:
+ type: string
+ storagePool:
+ type: string
+ system:
+ type: string
+ volumeName:
+ type: string
+ required:
+ - gateway
+ - secretRef
+ - system
+ type: object
+ secret:
+ properties:
+ defaultMode:
+ format: int32
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ format: int32
+ type: integer
+ path:
+ type: string
+ required:
+ - key
+ - path
+ type: object
+ type: array
+ optional:
+ type: boolean
+ secretName:
+ type: string
+ type: object
+ storageos:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeName:
+ type: string
+ volumeNamespace:
+ type: string
+ type: object
+ vsphereVolume:
+ properties:
+ fsType:
+ type: string
+ storagePolicyID:
+ type: string
+ storagePolicyName:
+ type: string
+ volumePath:
+ type: string
+ required:
+ - volumePath
+ type: object
+ required:
+ - name
+ type: object
+ volumeMount:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ required:
+ - mountPath
+ - name
+ type: object
+ required:
+ - volume
+ - volumeMount
+ type: object
+ priorityClassName:
+ type: string
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ s3:
+ properties:
+ acl:
+ type: string
+ bucket:
+ type: string
+ endpoint:
+ type: string
+ options:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ prefix:
+ type: string
+ provider:
+ type: string
+ region:
+ type: string
+ secretName:
+ type: string
+ sse:
+ type: string
+ storageClass:
+ type: string
+ required:
+ - provider
+ type: object
+ serviceAccount:
+ type: string
+ tolerations:
+ items:
+ properties:
+ effect:
+ type: string
+ key:
+ type: string
+ operator:
+ type: string
+ tolerationSeconds:
+ format: int64
+ type: integer
+ value:
+ type: string
+ type: object
+ type: array
+ toolImage:
+ type: string
+ type: object
+ type: object
+ maxBackups:
+ format: int32
+ type: integer
+ maxReservedTime:
+ type: string
+ pause:
+ type: boolean
+ schedule:
+ type: string
+ required:
+ - backupTemplate
+ - schedule
type: object
status:
+ properties:
+ allBackupCleanTime:
+ format: date-time
+ type: string
+ lastBackup:
+ type: string
+ lastBackupTime:
+ format: date-time
+ type: string
type: object
required:
- metadata
diff --git a/pkg/apis/federation/pingcap/v1alpha1/openapi_generated.go b/pkg/apis/federation/pingcap/v1alpha1/openapi_generated.go
index 51c99cfd16..5d06a89a25 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/openapi_generated.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/openapi_generated.go
@@ -419,8 +419,49 @@ func schema_apis_federation_pingcap_v1alpha1_VolumeBackupScheduleSpec(ref common
SchemaProps: spec.SchemaProps{
Description: "VolumeBackupScheduleSpec describes the attributes that a user creates on a volume backup schedule.",
Type: []string{"object"},
+ Properties: map[string]spec.Schema{
+ "schedule": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Schedule specifies the cron string used for backup scheduling.",
+ Default: "",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "pause": {
+ SchemaProps: spec.SchemaProps{
+ Description: "Pause means paused backupSchedule",
+ Type: []string{"boolean"},
+ Format: "",
+ },
+ },
+ "maxBackups": {
+ SchemaProps: spec.SchemaProps{
+ Description: "MaxBackups is to specify how many backups we want to keep 0 is magic number to indicate un-limited backups. if MaxBackups and MaxReservedTime are set at the same time, MaxReservedTime is preferred and MaxBackups is ignored.",
+ Type: []string{"integer"},
+ Format: "int32",
+ },
+ },
+ "maxReservedTime": {
+ SchemaProps: spec.SchemaProps{
+ Description: "MaxReservedTime is to specify how long backups we want to keep.",
+ Type: []string{"string"},
+ Format: "",
+ },
+ },
+ "backupTemplate": {
+ SchemaProps: spec.SchemaProps{
+ Description: "BackupTemplate is the specification of the volume backup structure to get scheduled.",
+ Default: map[string]interface{}{},
+ Ref: ref("github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1.VolumeBackupSpec"),
+ },
+ },
+ },
+ Required: []string{"schedule", "backupTemplate"},
},
},
+ Dependencies: []string{
+ "github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1.VolumeBackupSpec"},
}
}
diff --git a/pkg/apis/federation/pingcap/v1alpha1/types.go b/pkg/apis/federation/pingcap/v1alpha1/types.go
index 08b6a538c4..abf7d2b786 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/types.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/types.go
@@ -186,6 +186,8 @@ type VolumeBackupConditionType string
const (
// VolumeBackupInvalid means the VolumeBackup is invalid
VolumeBackupInvalid VolumeBackupConditionType = "Invalid"
+ // VolumeBackupPrepared means the VolumeBackup preparation is done
+ VolumeBackupPrepared VolumeBackupConditionType = "Prepared"
// VolumeBackupRunning means the VolumeBackup is running
VolumeBackupRunning VolumeBackupConditionType = "Running"
// VolumeBackupComplete means all the backups in data plane are complete and the VolumeBackup is complete
@@ -196,8 +198,6 @@ const (
VolumeBackupCleaned VolumeBackupConditionType = "Cleaned"
// VolumeBackupCleanFailed means the VolumeBackup cleanup is failed
VolumeBackupCleanFailed VolumeBackupConditionType = "CleanFailed"
- // VolumeBackupPrepared means the VolumeBackup is prepared
- VolumeBackupPrepared VolumeBackupConditionType = "Prepared"
)
// +genclient
@@ -206,8 +206,14 @@ const (
// VolumeBackupSchedule is the control script's spec
//
// +k8s:openapi-gen=true
-// +kubebuilder:resource:shortName="vbks"
+// +kubebuilder:resource:shortName="vbfs"
// +genclient:noStatus
+// +kubebuilder:printcolumn:name="Schedule",type=string,JSONPath=`.spec.schedule`,description="The cron format string used for backup scheduling"
+// +kubebuilder:printcolumn:name="MaxBackups",type=integer,JSONPath=`.spec.maxBackups`,description="The max number of backups we want to keep"
+// +kubebuilder:printcolumn:name="MaxReservedTime",type=string,JSONPath=`.spec.maxReservedTime`,description="How long backups we want to keep"
+// +kubebuilder:printcolumn:name="LastBackup",type=string,JSONPath=`.status.lastBackup`,description="The last backup CR name",priority=1
+// +kubebuilder:printcolumn:name="LastBackupTime",type=date,JSONPath=`.status.lastBackupTime`,description="The last time the backup was successfully created",priority=1
+// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
type VolumeBackupSchedule struct {
metav1.TypeMeta `json:",inline"`
// +k8s:openapi-gen=false
@@ -232,10 +238,29 @@ type VolumeBackupScheduleList struct {
// VolumeBackupScheduleSpec describes the attributes that a user creates on a volume backup schedule.
// +k8s:openapi-gen=true
type VolumeBackupScheduleSpec struct {
+ // Schedule specifies the cron string used for backup scheduling.
+ Schedule string `json:"schedule"`
+ // Pause means paused backupSchedule
+ Pause bool `json:"pause,omitempty"`
+ // MaxBackups is to specify how many backups we want to keep
+ // 0 is magic number to indicate un-limited backups.
+ // if MaxBackups and MaxReservedTime are set at the same time, MaxReservedTime is preferred
+ // and MaxBackups is ignored.
+ MaxBackups *int32 `json:"maxBackups,omitempty"`
+ // MaxReservedTime is to specify how long backups we want to keep.
+ MaxReservedTime *string `json:"maxReservedTime,omitempty"`
+ // BackupTemplate is the specification of the volume backup structure to get scheduled.
+ BackupTemplate VolumeBackupSpec `json:"backupTemplate"`
}
// VolumeBackupScheduleStatus represents the current status of a volume backup schedule.
type VolumeBackupScheduleStatus struct {
+ // LastBackup represents the last backup.
+ LastBackup string `json:"lastBackup,omitempty"`
+ // LastBackupTime represents the last time the backup was successfully created.
+ LastBackupTime *metav1.Time `json:"lastBackupTime,omitempty"`
+ // AllBackupCleanTime represents the time when all backup entries are cleaned up
+ AllBackupCleanTime *metav1.Time `json:"allBackupCleanTime,omitempty"`
}
// +genclient
diff --git a/pkg/apis/federation/pingcap/v1alpha1/volume_backup.go b/pkg/apis/federation/pingcap/v1alpha1/volume_backup.go
index a8115ddf7a..dedfe72b40 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/volume_backup.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/volume_backup.go
@@ -88,6 +88,12 @@ func IsVolumeBackupRunning(volumeBackup *VolumeBackup) bool {
return condition != nil && condition.Status == corev1.ConditionTrue
}
+// IsBackupPrepared returns true if VolumeBackup is running
+func IsBackupPrepared(volumeBackup *VolumeBackup) bool {
+ _, condition := GetVolumeBackupCondition(&volumeBackup.Status, VolumeBackupPrepared)
+ return condition != nil && condition.Status == corev1.ConditionTrue
+}
+
// IsVolumeBackupComplete returns true if VolumeBackup is complete
func IsVolumeBackupComplete(volumeBackup *VolumeBackup) bool {
_, condition := GetVolumeBackupCondition(&volumeBackup.Status, VolumeBackupComplete)
diff --git a/pkg/apis/federation/pingcap/v1alpha1/volume_backup_schedule.go b/pkg/apis/federation/pingcap/v1alpha1/volume_backup_schedule.go
new file mode 100644
index 0000000000..a76db525f9
--- /dev/null
+++ b/pkg/apis/federation/pingcap/v1alpha1/volume_backup_schedule.go
@@ -0,0 +1,25 @@
+// Copyright 2023 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package v1alpha1
+
+import (
+ "fmt"
+ "time"
+
+ constants "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
+)
+
+func (vbfs *VolumeBackupSchedule) GetBackupCRDName(timestamp time.Time) string {
+ return fmt.Sprintf("%s-%s", vbfs.GetName(), timestamp.UTC().Format(constants.BackupNameTimeFormat))
+}
diff --git a/pkg/apis/federation/pingcap/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/federation/pingcap/v1alpha1/zz_generated.deepcopy.go
index 991207cc54..ed9d6b07cf 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/zz_generated.deepcopy.go
@@ -216,8 +216,8 @@ func (in *VolumeBackupSchedule) DeepCopyInto(out *VolumeBackupSchedule) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
- out.Status = in.Status
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
return
}
@@ -275,6 +275,17 @@ func (in *VolumeBackupScheduleList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeBackupScheduleSpec) DeepCopyInto(out *VolumeBackupScheduleSpec) {
*out = *in
+ if in.MaxBackups != nil {
+ in, out := &in.MaxBackups, &out.MaxBackups
+ *out = new(int32)
+ **out = **in
+ }
+ if in.MaxReservedTime != nil {
+ in, out := &in.MaxReservedTime, &out.MaxReservedTime
+ *out = new(string)
+ **out = **in
+ }
+ in.BackupTemplate.DeepCopyInto(&out.BackupTemplate)
return
}
@@ -291,6 +302,14 @@ func (in *VolumeBackupScheduleSpec) DeepCopy() *VolumeBackupScheduleSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VolumeBackupScheduleStatus) DeepCopyInto(out *VolumeBackupScheduleStatus) {
*out = *in
+ if in.LastBackupTime != nil {
+ in, out := &in.LastBackupTime, &out.LastBackupTime
+ *out = (*in).DeepCopy()
+ }
+ if in.AllBackupCleanTime != nil {
+ in, out := &in.AllBackupCleanTime, &out.AllBackupCleanTime
+ *out = (*in).DeepCopy()
+ }
return
}
diff --git a/pkg/apis/pingcap/v1alpha1/openapi_generated.go b/pkg/apis/pingcap/v1alpha1/openapi_generated.go
index d2c870a05a..a0ac93349b 100644
--- a/pkg/apis/pingcap/v1alpha1/openapi_generated.go
+++ b/pkg/apis/pingcap/v1alpha1/openapi_generated.go
@@ -945,7 +945,7 @@ func schema_pkg_apis_pingcap_v1alpha1_BackupScheduleSpec(ref common.ReferenceCal
},
},
},
- Required: []string{"schedule", "logBackupTemplate"},
+ Required: []string{"schedule", "backupTemplate"},
},
},
Dependencies: []string{
diff --git a/pkg/apis/pingcap/v1alpha1/types.go b/pkg/apis/pingcap/v1alpha1/types.go
index 51507fdb16..c43289e1c5 100644
--- a/pkg/apis/pingcap/v1alpha1/types.go
+++ b/pkg/apis/pingcap/v1alpha1/types.go
@@ -2200,6 +2200,7 @@ type BackupStatus struct {
// +kubebuilder:resource:shortName="bks"
// +kubebuilder:printcolumn:name="Schedule",type=string,JSONPath=`.spec.schedule`,description="The cron format string used for backup scheduling"
// +kubebuilder:printcolumn:name="MaxBackups",type=integer,JSONPath=`.spec.maxBackups`,description="The max number of backups we want to keep"
+// +kubebuilder:printcolumn:name="MaxReservedTime",type=string,JSONPath=`.spec.maxReservedTime`,description="How long backups we want to keep"
// +kubebuilder:printcolumn:name="LastBackup",type=string,JSONPath=`.status.lastBackup`,description="The last backup CR name",priority=1
// +kubebuilder:printcolumn:name="LastBackupTime",type=date,JSONPath=`.status.lastBackupTime`,description="The last time the backup was successfully created",priority=1
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
@@ -2239,9 +2240,9 @@ type BackupScheduleSpec struct {
// MaxReservedTime is to specify how long backups we want to keep.
MaxReservedTime *string `json:"maxReservedTime,omitempty"`
// BackupTemplate is the specification of the backup structure to get scheduled.
- // +optional
BackupTemplate BackupSpec `json:"backupTemplate"`
// LogBackupTemplate is the specification of the log backup structure to get scheduled.
+ // +optional
LogBackupTemplate *BackupSpec `json:"logBackupTemplate"`
// The storageClassName of the persistent volume for Backup data storage if not storage class name set in BackupSpec.
// Defaults to Kubernetes default storage class.
diff --git a/pkg/backup/backupschedule/backup_schedule_manager.go b/pkg/backup/backupschedule/backup_schedule_manager.go
index 33279f8f75..843467f582 100644
--- a/pkg/backup/backupschedule/backup_schedule_manager.go
+++ b/pkg/backup/backupschedule/backup_schedule_manager.go
@@ -70,6 +70,7 @@ func (bm *backupScheduleManager) Sync(bs *v1alpha1.BackupSchedule) error {
}
// delete the last backup job for release the backup PVC
+
if err := bm.deleteLastBackupJob(bs); err != nil {
return nil
}
@@ -373,7 +374,7 @@ func (bm *backupScheduleManager) backupGCByMaxReservedTime(bs *v1alpha1.BackupSc
return
}
} else {
- expiredBackups, err = caculateExpiredBackups(ascBackups, reservedTime)
+ expiredBackups, err = calculateExpiredBackups(ascBackups, reservedTime)
if err != nil {
klog.Errorf("caculate expired backups without log backup, err: %s", err)
return
@@ -404,7 +405,7 @@ func (bm *backupScheduleManager) backupGCByMaxReservedTime(bs *v1alpha1.BackupSc
}
}
-// separateSnapshotBackupsAndLogBackup return snapot backups ordry by create time asc and log backup
+// separateSnapshotBackupsAndLogBackup return snapshot backups order by create time asc and log backup
func separateSnapshotBackupsAndLogBackup(backupsList []*v1alpha1.Backup) ([]*v1alpha1.Backup, *v1alpha1.Backup) {
var (
ascBackupList = make([]*v1alpha1.Backup, 0)
@@ -479,7 +480,7 @@ func calExpiredBackupsAndLogBackup(backupsList []*v1alpha1.Backup, logBackup *v1
return expiredBackups, truncateTSO, nil
}
-func caculateExpiredBackups(backupsList []*v1alpha1.Backup, reservedTime time.Duration) ([]*v1alpha1.Backup, error) {
+func calculateExpiredBackups(backupsList []*v1alpha1.Backup, reservedTime time.Duration) ([]*v1alpha1.Backup, error) {
expiredTS := config.TSToTSO(time.Now().Add(-1 * reservedTime).Unix())
i := 0
for ; i < len(backupsList); i++ {
diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go
index b2c141dd35..92e8d04ae1 100644
--- a/pkg/controller/controller_utils.go
+++ b/pkg/controller/controller_utils.go
@@ -186,6 +186,20 @@ func GetBackupScheduleOwnerRef(bs *v1alpha1.BackupSchedule) metav1.OwnerReferenc
}
}
+// GetFedVolumeBackupScheduleOwnerRef returns FedVolumeBackupSchedule's OwnerReference
+func GetFedVolumeBackupScheduleOwnerRef(vbs *fedv1alpha1.VolumeBackupSchedule) metav1.OwnerReference {
+ controller := true
+ blockOwnerDeletion := true
+ return metav1.OwnerReference{
+ APIVersion: backupScheduleControllerKind.GroupVersion().String(),
+ Kind: backupScheduleControllerKind.Kind,
+ Name: vbs.GetName(),
+ UID: vbs.GetUID(),
+ Controller: &controller,
+ BlockOwnerDeletion: &blockOwnerDeletion,
+ }
+}
+
func GetTiDBMonitorOwnerRef(monitor *v1alpha1.TidbMonitor) metav1.OwnerReference {
controller := true
blockOwnerDeletion := true
diff --git a/pkg/controller/fed_backup_schedule_status_updater.go b/pkg/controller/fed_backup_schedule_status_updater.go
new file mode 100644
index 0000000000..88613eb5b1
--- /dev/null
+++ b/pkg/controller/fed_backup_schedule_status_updater.go
@@ -0,0 +1,113 @@
+// Copyright 2019 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package controller
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
+ informers "github.com/pingcap/tidb-operator/pkg/client/federation/informers/externalversions/pingcap/v1alpha1"
+ listers "github.com/pingcap/tidb-operator/pkg/client/federation/listers/pingcap/v1alpha1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+ "k8s.io/client-go/tools/cache"
+ "k8s.io/client-go/util/retry"
+ "k8s.io/klog/v2"
+)
+
+// VolumeBackupScheduleStatusUpdaterInterface is an interface used to update the VolumeBackupScheduleStatus associated with a VolumeBackupSchedule.
+// For any use other than testing, clients should create an instance using NewRealBackupScheduleStatusUpdater.
+type VolumeBackupScheduleStatusUpdaterInterface interface {
+ // UpdateBackupScheduleStatus sets the backupSchedule's Status to status. Implementations are required to retry on conflicts,
+ // but fail on other errors. If the returned error is nil backup's Status has been successfully set to status.
+ UpdateBackupScheduleStatus(*v1alpha1.VolumeBackupSchedule, *v1alpha1.VolumeBackupScheduleStatus, *v1alpha1.VolumeBackupScheduleStatus) error
+}
+
+// NewRealVolumeBackupScheduleStatusUpdater returns a VolumeBackupScheduleStatusUpdaterInterface that updates the Status of a VolumeBackupScheduleStatus,
+// using the supplied client and bsLister.
+func NewRealVolumeBackupScheduleStatusUpdater(deps *BrFedDependencies) VolumeBackupScheduleStatusUpdaterInterface {
+ return &realVolumeBackupScheduleStatusUpdater{
+ deps: deps,
+ }
+}
+
+type realVolumeBackupScheduleStatusUpdater struct {
+ deps *BrFedDependencies
+}
+
+func (u *realVolumeBackupScheduleStatusUpdater) UpdateBackupScheduleStatus(
+ bs *v1alpha1.VolumeBackupSchedule,
+ newStatus *v1alpha1.VolumeBackupScheduleStatus,
+ oldStatus *v1alpha1.VolumeBackupScheduleStatus) error {
+
+ ns := bs.GetNamespace()
+ bsName := bs.GetName()
+ // don't wait due to limited number of clients, but backoff after the default number of steps
+ err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+ _, updateErr := u.deps.Clientset.FederationV1alpha1().VolumeBackupSchedules(ns).Update(context.TODO(), bs, metav1.UpdateOptions{})
+ if updateErr == nil {
+ klog.Infof("BackupSchedule: [%s/%s] updated successfully", ns, bsName)
+ return nil
+ }
+ if updated, err := u.deps.VolumeBackupScheduleLister.VolumeBackupSchedules(ns).Get(bsName); err == nil {
+ // make a copy so we don't mutate the shared cache
+ bs = updated.DeepCopy()
+ bs.Status = *newStatus
+ } else {
+ utilruntime.HandleError(fmt.Errorf("error getting updated backupSchedule %s/%s from lister: %v", ns, bsName, err))
+ }
+
+ return updateErr
+ })
+ return err
+}
+
+var _ VolumeBackupScheduleStatusUpdaterInterface = &realVolumeBackupScheduleStatusUpdater{}
+
+// FakeVolumeBackupScheduleStatusUpdater is a fake VolumeBackupScheduleStatusUpdaterInterface
+type FakeVolumeBackupScheduleStatusUpdater struct {
+ BsLister listers.VolumeBackupScheduleLister
+ BsIndexer cache.Indexer
+ updateBsTracker RequestTracker
+}
+
+// NewFakeVolumeBackupScheduleStatusUpdater returns a FakeVolumeBackupScheduleStatusUpdater
+func NewFakeVolumeBackupScheduleStatusUpdater(bsInformer informers.VolumeBackupScheduleInformer) *FakeVolumeBackupScheduleStatusUpdater {
+ return &FakeVolumeBackupScheduleStatusUpdater{
+ bsInformer.Lister(),
+ bsInformer.Informer().GetIndexer(),
+ RequestTracker{},
+ }
+}
+
+// SetUpdateBackupScheduleError sets the error attributes of updateBackupScheduleTracker
+func (u *FakeVolumeBackupScheduleStatusUpdater) SetUpdateBackupScheduleError(err error, after int) {
+ u.updateBsTracker.err = err
+ u.updateBsTracker.after = after
+ u.updateBsTracker.SetError(err).SetAfter(after)
+}
+
+// UpdateBackupScheduleStatus updates the BackupSchedule
+func (u *FakeVolumeBackupScheduleStatusUpdater) UpdateBackupScheduleStatus(bs *v1alpha1.VolumeBackupSchedule, _ *v1alpha1.VolumeBackupScheduleStatus, _ *v1alpha1.VolumeBackupScheduleStatus) error {
+ defer u.updateBsTracker.Inc()
+ if u.updateBsTracker.ErrorReady() {
+ defer u.updateBsTracker.Reset()
+ return u.updateBsTracker.GetError()
+ }
+
+ return u.BsIndexer.Update(bs)
+}
+
+var _ VolumeBackupScheduleStatusUpdaterInterface = &FakeVolumeBackupScheduleStatusUpdater{}
diff --git a/pkg/controller/fed_volume_backup_control.go b/pkg/controller/fed_volume_backup_control.go
index 0de42e3bb4..13ff5892b5 100644
--- a/pkg/controller/fed_volume_backup_control.go
+++ b/pkg/controller/fed_volume_backup_control.go
@@ -31,7 +31,7 @@ import (
listers "github.com/pingcap/tidb-operator/pkg/client/federation/listers/pingcap/v1alpha1"
)
-// FedVolumeBackupControlInterface manages federaton VolumeBackups used in VolumeBackupSchedule
+// FedVolumeBackupControlInterface manages federation VolumeBackups used in VolumeBackupSchedule
type FedVolumeBackupControlInterface interface {
CreateVolumeBackup(backup *v1alpha1.VolumeBackup) (*v1alpha1.VolumeBackup, error)
DeleteVolumeBackup(backup *v1alpha1.VolumeBackup) error
@@ -108,16 +108,18 @@ type FakeFedVolumeBackupControl struct {
volumeBackupLister listers.VolumeBackupLister
volumeBackupIndexer cache.Indexer
createVolumeBackupTracker RequestTracker
+ updateVolumeBackupTracker RequestTracker
deleteVolumeBackupTracker RequestTracker
}
-// NewFakeBackupControl returns a FakeBackupControl
+// NewFakeFedVolumeBackupControl returns a FakeFedVolumeBackupControl
func NewFakeFedVolumeBackupControl(volumeBackupInformer informers.VolumeBackupInformer) *FakeFedVolumeBackupControl {
return &FakeFedVolumeBackupControl{
volumeBackupInformer.Lister(),
volumeBackupInformer.Informer().GetIndexer(),
RequestTracker{},
RequestTracker{},
+ RequestTracker{},
}
}
@@ -126,6 +128,11 @@ func (fbc *FakeFedVolumeBackupControl) SetCreateVolumeBackupError(err error, aft
fbc.createVolumeBackupTracker.SetError(err).SetAfter(after)
}
+// SetUpdateVolumeBackupError sets the error attributes of createVolumeBackupTracker
+func (fbc *FakeFedVolumeBackupControl) SetUpdateVolumeBackupError(err error, after int) {
+ fbc.updateVolumeBackupTracker.SetError(err).SetAfter(after)
+}
+
// SetDeleteVolumeBackupError sets the error attributes of deleteVolumeBackupTracker
func (fbc *FakeFedVolumeBackupControl) SetDeleteVolumeBackupError(err error, after int) {
fbc.deleteVolumeBackupTracker.SetError(err).SetAfter(after)
diff --git a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control.go b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control.go
index ad568e2eaf..8a7d965013 100644
--- a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control.go
+++ b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control.go
@@ -14,10 +14,11 @@
package fedvolumebackupschedule
import (
+ apiequality "k8s.io/apimachinery/pkg/api/equality"
+ errorutils "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/tools/cache"
"github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
- "github.com/pingcap/tidb-operator/pkg/client/federation/clientset/versioned"
informers "github.com/pingcap/tidb-operator/pkg/client/federation/informers/externalversions/pingcap/v1alpha1"
"github.com/pingcap/tidb-operator/pkg/controller"
"github.com/pingcap/tidb-operator/pkg/fedvolumebackup"
@@ -31,24 +32,41 @@ type ControlInterface interface {
UpdateBackupSchedule(volumeBackupSchedule *v1alpha1.VolumeBackupSchedule) error
}
-// NewDefaultVolumeBackupScheduleControl returns a new instance of the default VolumeBackupSchedue ControlInterface implementation.
+// NewDefaultVolumeBackupScheduleControl returns a new instance of the default VolumeBackupSchedule ControlInterface implementation.
func NewDefaultVolumeBackupScheduleControl(
- cli versioned.Interface,
+ statusUpdater controller.VolumeBackupScheduleStatusUpdaterInterface,
backupScheduleManager fedvolumebackup.BackupScheduleManager) ControlInterface {
return &defaultBackupScheduleControl{
- cli,
+ statusUpdater,
backupScheduleManager,
}
}
type defaultBackupScheduleControl struct {
- cli versioned.Interface
- bsManager fedvolumebackup.BackupScheduleManager
+ statusUpdater controller.VolumeBackupScheduleStatusUpdaterInterface
+ bsManager fedvolumebackup.BackupScheduleManager
}
// UpdateBackupSchedule executes the core logic loop for a VolumeBackupSchedule.
-func (c *defaultBackupScheduleControl) UpdateBackupSchedule(volumeBackupSchedule *v1alpha1.VolumeBackupSchedule) error {
- return c.bsManager.Sync(volumeBackupSchedule)
+func (c *defaultBackupScheduleControl) UpdateBackupSchedule(vbs *v1alpha1.VolumeBackupSchedule) error {
+ var errs []error
+ oldStatus := vbs.Status.DeepCopy()
+
+ if err := c.updateBackupSchedule(vbs); err != nil {
+ errs = append(errs, err)
+ }
+ if apiequality.Semantic.DeepEqual(&vbs.Status, oldStatus) {
+ return errorutils.NewAggregate(errs)
+ }
+ if err := c.statusUpdater.UpdateBackupScheduleStatus(vbs.DeepCopy(), &vbs.Status, oldStatus); err != nil {
+ errs = append(errs, err)
+ }
+
+ return errorutils.NewAggregate(errs)
+}
+
+func (c *defaultBackupScheduleControl) updateBackupSchedule(vbs *v1alpha1.VolumeBackupSchedule) error {
+ return c.bsManager.Sync(vbs)
}
var _ ControlInterface = &defaultBackupScheduleControl{}
diff --git a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
new file mode 100644
index 0000000000..b35040c90d
--- /dev/null
+++ b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
@@ -0,0 +1,120 @@
+// Copyright 2019 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package fedvolumebackupschedule
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+ "time"
+
+ . "github.com/onsi/gomega"
+ "github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
+ "github.com/pingcap/tidb-operator/pkg/client/federation/clientset/versioned/fake"
+ informers "github.com/pingcap/tidb-operator/pkg/client/federation/informers/externalversions"
+ "github.com/pingcap/tidb-operator/pkg/controller"
+ "github.com/pingcap/tidb-operator/pkg/fedvolumebackup/backupschedule"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func TestBackupScheduleControlUpdateBackupSchedule(t *testing.T) {
+ g := NewGomegaWithT(t)
+
+ type testcase struct {
+ name string
+ update func(bs *v1alpha1.VolumeBackupSchedule)
+ syncBsManagerErr bool
+ updateStatusErr bool
+ errExpectFn func(*GomegaWithT, error)
+ }
+ testFn := func(test *testcase, t *testing.T) {
+ t.Log(test.name)
+
+ bs := newBackupSchedule()
+ if test.update != nil {
+ test.update(bs)
+ }
+ control, bsManager, bsStatusUpdater := newFakeBackupScheduleControl()
+
+ if test.syncBsManagerErr {
+ bsManager.SetSyncError(fmt.Errorf("backup schedule sync error"))
+ }
+
+ if test.updateStatusErr {
+ bsStatusUpdater.SetUpdateBackupScheduleError(fmt.Errorf("update backupSchedule status error"), 0)
+ }
+
+ err := control.UpdateBackupSchedule(bs)
+ if test.errExpectFn != nil {
+ test.errExpectFn(g, err)
+ }
+ }
+ tests := []testcase{
+ {
+ name: "backup schedule sync error",
+ update: nil,
+ syncBsManagerErr: true,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).To(HaveOccurred())
+ g.Expect(strings.Contains(err.Error(), "backup schedule sync error")).To(Equal(true))
+ },
+ },
+ {
+ name: "backup schedule status is not updated",
+ update: nil,
+ syncBsManagerErr: false,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).NotTo(HaveOccurred())
+ },
+ },
+ {
+ name: "backup schedule status update failed",
+ update: func(bs *v1alpha1.VolumeBackupSchedule) {
+ bs.Status.LastBackupTime = &metav1.Time{Time: time.Now()}
+ },
+ syncBsManagerErr: false,
+ updateStatusErr: true,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).To(HaveOccurred())
+ g.Expect(strings.Contains(err.Error(), "update backupSchedule status error")).To(Equal(true))
+ },
+ },
+ {
+ name: "normal",
+ update: func(bs *v1alpha1.VolumeBackupSchedule) {
+ bs.Status.LastBackupTime = &metav1.Time{Time: time.Now()}
+ },
+ syncBsManagerErr: false,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).NotTo(HaveOccurred())
+ },
+ },
+ }
+
+ for i := range tests {
+ testFn(&tests[i], t)
+ }
+}
+
+func newFakeBackupScheduleControl() (ControlInterface, *backupschedule.FakeBackupScheduleManager, *controller.FakeVolumeBackupScheduleStatusUpdater) {
+ cli := fake.NewSimpleClientset()
+ bsInformer := informers.NewSharedInformerFactory(cli, 0).Federation().V1alpha1().VolumeBackupSchedules()
+ statusUpdater := controller.NewFakeVolumeBackupScheduleStatusUpdater(bsInformer)
+ bsManager := backupschedule.NewFakeBackupScheduleManager()
+ control := NewDefaultVolumeBackupScheduleControl(statusUpdater, bsManager)
+
+ return control, bsManager, statusUpdater
+}
diff --git a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller.go b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller.go
index d3db48aa16..705500e0aa 100644
--- a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller.go
+++ b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller.go
@@ -45,7 +45,7 @@ type Controller struct {
func NewController(deps *controller.BrFedDependencies) *Controller {
c := &Controller{
deps: deps,
- control: NewDefaultVolumeBackupScheduleControl(deps.Clientset, backupschedule.NewBackupScheduleManager(deps)),
+ control: NewDefaultVolumeBackupScheduleControl(controller.NewRealVolumeBackupScheduleStatusUpdater(deps), backupschedule.NewBackupScheduleManager(deps)),
queue: workqueue.NewNamedRateLimitingQueue(
controller.NewControllerRateLimiter(1*time.Second, 100*time.Second),
"volumeBackupSchedule",
diff --git a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller_test.go b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller_test.go
new file mode 100644
index 0000000000..02a118e5b0
--- /dev/null
+++ b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller_test.go
@@ -0,0 +1,180 @@
+// Copyright 2023 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package fedvolumebackupschedule
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
+ "github.com/pingcap/tidb-operator/pkg/controller"
+
+ . "github.com/onsi/gomega"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/client-go/tools/cache"
+ "k8s.io/utils/pointer"
+)
+
+func TestBackupScheduleControllerEnqueueBackupSchedule(t *testing.T) {
+ g := NewGomegaWithT(t)
+ bks := newBackupSchedule()
+ bsc, _, _ := newFakeBackupScheduleController()
+ bsc.enqueueBackupSchedule(bks)
+ g.Expect(bsc.queue.Len()).To(Equal(1))
+}
+
+func TestBackupScheduleControllerEnqueueBackupScheduleFailed(t *testing.T) {
+ g := NewGomegaWithT(t)
+ bsc, _, _ := newFakeBackupScheduleController()
+ bsc.enqueueBackupSchedule(struct{}{})
+ g.Expect(bsc.queue.Len()).To(Equal(0))
+}
+
+func TestBackupScheduleControllerSync(t *testing.T) {
+ g := NewGomegaWithT(t)
+ type testcase struct {
+ name string
+ addBsToIndexer bool
+ errWhenUpdateBackupSchedule bool
+ invalidKeyFn func(bs *v1alpha1.VolumeBackupSchedule) string
+ errExpectFn func(*GomegaWithT, error)
+ }
+
+ testFn := func(test *testcase, t *testing.T) {
+ t.Log(test.name)
+
+ bs := newBackupSchedule()
+ bsc, bsIndexer, bsControl := newFakeBackupScheduleController()
+
+ if test.addBsToIndexer {
+ err := bsIndexer.Add(bs)
+ g.Expect(err).NotTo(HaveOccurred())
+ }
+
+ key, _ := cache.DeletionHandlingMetaNamespaceKeyFunc(bs)
+ if test.invalidKeyFn != nil {
+ key = test.invalidKeyFn(bs)
+ }
+
+ if test.errWhenUpdateBackupSchedule {
+ bsControl.SetUpdateVolumeBackupError(fmt.Errorf("update backup schedule failed"), 0)
+ }
+
+ err := bsc.sync(key)
+
+ if test.errExpectFn != nil {
+ test.errExpectFn(g, err)
+ }
+ }
+
+ tests := []testcase{
+ {
+ name: "normal",
+ addBsToIndexer: true,
+ errWhenUpdateBackupSchedule: false,
+ invalidKeyFn: nil,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).NotTo(HaveOccurred())
+ },
+ },
+ {
+ name: "invalid backup key",
+ addBsToIndexer: true,
+ errWhenUpdateBackupSchedule: false,
+ invalidKeyFn: func(bs *v1alpha1.VolumeBackupSchedule) string {
+ return fmt.Sprintf("test/demo/%s", bs.GetName())
+ },
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).To(HaveOccurred())
+ },
+ },
+ {
+ name: "can't found backup schedule",
+ addBsToIndexer: false,
+ errWhenUpdateBackupSchedule: false,
+ invalidKeyFn: nil,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).NotTo(HaveOccurred())
+ },
+ },
+ {
+ name: "update backup schedule failed",
+ addBsToIndexer: true,
+ errWhenUpdateBackupSchedule: true,
+ invalidKeyFn: nil,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).To(HaveOccurred())
+ g.Expect(strings.Contains(err.Error(), "update backup schedule failed")).To(Equal(true))
+ },
+ },
+ }
+
+ for i := range tests {
+ testFn(&tests[i], t)
+ }
+
+}
+
+func newFakeBackupScheduleController() (*Controller, cache.Indexer, *controller.FakeFedVolumeBackupControl) {
+ fakeDeps := controller.NewFakeDependencies()
+ bsc := NewController(fakeDeps)
+ bsInformer := fakeDeps.InformerFactory.Pingcap().V1alpha1().BackupSchedules()
+ backupScheduleControl := NewFakeBackupScheduleControl(bsInformer)
+ bsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
+ AddFunc: bsc.enqueueBackupSchedule,
+ UpdateFunc: func(old, cur interface{}) {
+ bsc.enqueueBackupSchedule(cur)
+ },
+ DeleteFunc: bsc.enqueueBackupSchedule,
+ })
+ bsc.control = backupScheduleControl
+ return bsc, bsInformer.Informer().GetIndexer(), backupScheduleControl
+}
+
+func newBackupSchedule() *v1alpha1.VolumeBackupSchedule {
+ return &v1alpha1.VolumeBackupSchedule{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "BackupScheduler",
+ APIVersion: "pingcap.com/v1alpha1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test-bks",
+ Namespace: corev1.NamespaceDefault,
+ UID: types.UID("test-bks"),
+ },
+ Spec: v1alpha1.VolumeBackupScheduleSpec{
+ Schedule: "1 */10 * * *",
+ MaxBackups: pointer.Int32Ptr(10),
+ BackupTemplate: v1alpha1.BackupSpec{
+ From: &v1alpha1.TiDBAccessConfig{
+ Host: "10.1.1.2",
+ Port: v1alpha1.DefaultTiDBServicePort,
+ User: v1alpha1.DefaultTidbUser,
+ SecretName: "demo1-tidb-secret",
+ },
+ StorageProvider: v1alpha1.StorageProvider{
+ S3: &v1alpha1.S3StorageProvider{
+ Provider: v1alpha1.S3StorageProviderTypeCeph,
+ Endpoint: "http://10.0.0.1",
+ SecretName: "demo",
+ Bucket: "test1-demo1",
+ },
+ },
+ },
+ },
+ }
+}
diff --git a/pkg/fedvolumebackup/backup/backup_manager.go b/pkg/fedvolumebackup/backup/backup_manager.go
index c6604c516c..55daa7405b 100644
--- a/pkg/fedvolumebackup/backup/backup_manager.go
+++ b/pkg/fedvolumebackup/backup/backup_manager.go
@@ -120,20 +120,6 @@ func (bm *backupManager) runBackup(ctx context.Context, volumeBackup *v1alpha1.V
bm.setVolumeBackupRunning(&volumeBackup.Status)
}
-<<<<<<< HEAD
-=======
- if bm.skipSync(volumeBackup) {
- klog.Infof("skip VolumeBackup %s/%s", ns, name)
- return nil
- }
-
- ctx := context.Background()
- backupMembers, err := bm.listAllBackupMembers(ctx, volumeBackup)
- if err != nil {
- return err
- }
-
->>>>>>> 7d84cf89e (br: update backup member to status)
if len(backupMembers) == 0 {
return false, bm.initializeVolumeBackup(ctx, volumeBackup)
}
@@ -186,6 +172,14 @@ func (bm *backupManager) setVolumeBackupRunning(volumeBackupStatus *v1alpha1.Vol
})
}
+func (bm *backupManager) setVolumeBackupPrepared(volumeBackupStatus *v1alpha1.VolumeBackupStatus) {
+ volumeBackupStatus.TimeStarted = metav1.Now()
+ v1alpha1.UpdateVolumeBackupCondition(volumeBackupStatus, &v1alpha1.VolumeBackupCondition{
+ Type: v1alpha1.VolumeBackupPrepared,
+ Status: corev1.ConditionTrue,
+ })
+}
+
func (bm *backupManager) listAllBackupMembers(ctx context.Context, volumeBackup *v1alpha1.VolumeBackup) ([]*volumeBackupMember, error) {
backupMembers := make([]*volumeBackupMember, 0, len(volumeBackup.Spec.Clusters))
for _, memberCluster := range volumeBackup.Spec.Clusters {
@@ -356,14 +350,6 @@ func (bm *backupManager) setVolumeBackupCleaned(volumeBackupStatus *v1alpha1.Vol
})
}
-func (bm *backupManager) setVolumeBackupPrepared(volumeBackupStatus *v1alpha1.VolumeBackupStatus) {
- volumeBackupStatus.TimeStarted = metav1.Now()
- v1alpha1.UpdateVolumeBackupCondition(volumeBackupStatus, &v1alpha1.VolumeBackupCondition{
- Type: v1alpha1.VolumeBackupPrepared,
- Status: corev1.ConditionTrue,
- })
-}
-
func (bm *backupManager) setVolumeBackupSize(volumeBackupStatus *v1alpha1.VolumeBackupStatus, backupMembers []*volumeBackupMember) {
var totalBackupSize int64
for _, backupMember := range backupMembers {
@@ -425,11 +411,7 @@ func (bm *backupManager) buildBackupMember(volumeBackupName string, clusterMembe
}
func (bm *backupManager) skipSync(volumeBackup *v1alpha1.VolumeBackup) bool {
-<<<<<<< HEAD
return volumeBackup.DeletionTimestamp == nil && (v1alpha1.IsVolumeBackupComplete(volumeBackup) || v1alpha1.IsVolumeBackupFailed(volumeBackup))
-=======
- return v1alpha1.IsVolumeBackupComplete(volumeBackup) || v1alpha1.IsVolumeBackupFailed(volumeBackup)
->>>>>>> 7d84cf89e (br: update backup member to status)
}
func (bm *backupManager) generateBackupMemberName(volumeBackupName, k8sClusterName string) string {
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index deeb552f97..be2d03f7e5 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -14,8 +14,17 @@
package backupschedule
import (
+ "fmt"
+ "sort"
"time"
+ perrors "github.com/pingcap/errors"
+ "github.com/pingcap/tidb-operator/pkg/apis/label"
+ "github.com/pingcap/tidb-operator/pkg/apis/util/config"
+ "github.com/pingcap/tidb-operator/pkg/util"
+ "github.com/robfig/cron"
+ "k8s.io/apimachinery/pkg/api/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
@@ -38,15 +47,306 @@ func NewBackupScheduleManager(deps *controller.BrFedDependencies) fedvolumebacku
}
}
-func (bm *backupScheduleManager) Sync(volumeBackupSchedule *v1alpha1.VolumeBackupSchedule) error {
- ns := volumeBackupSchedule.GetNamespace()
- name := volumeBackupSchedule.GetName()
- // TODO(federation): implement the main logic of backupSchedule
- klog.Infof("sync VolumeBackupSchedule %s/%s", ns, name)
+func (bm *backupScheduleManager) Sync(vbs *v1alpha1.VolumeBackupSchedule) error {
+ defer bm.backupGC(vbs)
+ if vbs.Spec.Pause {
+ return controller.IgnoreErrorf("backupSchedule %s/%s has been paused", vbs.GetNamespace(), vbs.GetName())
+ }
+
+ if err := bm.canPerformNextBackup(vbs); err != nil {
+ return err
+ }
+
+ scheduledTime, err := getLastScheduledTime(vbs, bm.now)
+ if scheduledTime == nil {
+ return err
+ }
+
+ // TODO: do we need to delete last backup job also?
+ backup, err := createBackup(bm.deps.FedVolumeBackupControl, vbs, *scheduledTime)
+ if err != nil {
+ return err
+ }
+
+ vbs.Status.LastBackup = backup.GetName()
+ vbs.Status.LastBackupTime = &metav1.Time{Time: *scheduledTime}
+ vbs.Status.AllBackupCleanTime = nil
return nil
}
+// getLastScheduledTime return the newest time need to be scheduled according last backup time.
+// the return time is not before now and return nil if there's no such time.
+func getLastScheduledTime(vbs *v1alpha1.VolumeBackupSchedule, nowFn nowFn) (*time.Time, error) {
+ ns := vbs.GetNamespace()
+ bsName := vbs.GetName()
+
+ sched, err := cron.ParseStandard(vbs.Spec.Schedule)
+ if err != nil {
+ return nil, fmt.Errorf("parse backup schedule %s/%s cron format %s failed, err: %v", ns, bsName, vbs.Spec.Schedule, err)
+ }
+
+ var earliestTime time.Time
+ if vbs.Status.LastBackupTime != nil {
+ earliestTime = vbs.Status.LastBackupTime.Time
+ } else if vbs.Status.AllBackupCleanTime != nil {
+ // Recovery from a long paused backup schedule may cause problem like "incorrect clock",
+ // so we introduce AllBackupCleanTime field to solve this problem.
+ earliestTime = vbs.Status.AllBackupCleanTime.Time
+ } else {
+ // If none found, then this is either a recently created backupSchedule,
+ // or the backupSchedule status info was somehow lost,
+ // or that we have started a backup, but have not update backupSchedule status yet
+ // (distributed systems can have arbitrary delays).
+ // In any case, use the creation time of the backupSchedule as last known start time.
+ earliestTime = vbs.ObjectMeta.CreationTimestamp.Time
+ }
+
+ now := nowFn()
+ if earliestTime.After(now) {
+ // timestamp fallback, waiting for the next backup schedule period
+ klog.Errorf("backup schedule %s/%s timestamp fallback, lastBackupTime: %s, now: %s",
+ ns, bsName, earliestTime.Format(time.RFC3339), now.Format(time.RFC3339))
+ return nil, nil
+ }
+
+ var scheduledTimes []time.Time
+ for t := sched.Next(earliestTime); !t.After(now); t = sched.Next(t) {
+ scheduledTimes = append(scheduledTimes, t)
+ // If there is a bug somewhere, or incorrect clock
+ // on controller's server or apiservers (for setting creationTimestamp)
+ // then there could be so many missed start times (it could be off
+ // by decades or more), that it would eat up all the CPU and memory
+ // of this controller. In that case, we want to not try to list
+ // all the missed start times.
+ //
+ // I've somewhat arbitrarily picked 100, as more than 80,
+ // but less than "lots".
+ if len(scheduledTimes) > 100 {
+ // We can't get the last backup schedule time
+ if vbs.Status.LastBackupTime == nil && vbs.Status.AllBackupCleanTime != nil {
+ // Recovery backup schedule from pause status, should refresh AllBackupCleanTime to avoid unschedulable problem
+ vbs.Status.AllBackupCleanTime = &metav1.Time{Time: nowFn()}
+ return nil, controller.RequeueErrorf("recovery backup schedule %s/%s from pause status, refresh AllBackupCleanTime.", ns, bsName)
+ }
+ klog.Error("Too many missed start backup schedule time (> 100). Check the clock.")
+ return nil, nil
+ }
+ }
+
+ if len(scheduledTimes) == 0 {
+ klog.V(4).Infof("unmet backup schedule %s/%s start time, waiting for the next backup schedule period", ns, bsName)
+ return nil, nil
+ }
+ scheduledTime := scheduledTimes[len(scheduledTimes)-1]
+ return &scheduledTime, nil
+}
+
+func buildBackup(vbs *v1alpha1.VolumeBackupSchedule, timestamp time.Time) *v1alpha1.VolumeBackup {
+ ns := vbs.GetNamespace()
+ bsName := vbs.GetName()
+
+ backupSpec := *vbs.Spec.BackupTemplate.DeepCopy()
+
+ bsLabel := util.CombineStringMap(label.NewBackupSchedule().Instance(bsName).BackupSchedule(bsName), vbs.Labels)
+ backup := &v1alpha1.VolumeBackup{
+ Spec: backupSpec,
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: ns,
+ Name: vbs.GetBackupCRDName(timestamp),
+ Labels: bsLabel,
+ Annotations: vbs.Annotations,
+ OwnerReferences: []metav1.OwnerReference{
+ controller.GetFedVolumeBackupScheduleOwnerRef(vbs),
+ },
+ },
+ }
+
+ return backup
+}
+
+func createBackup(bkController controller.FedVolumeBackupControlInterface, vbs *v1alpha1.VolumeBackupSchedule, timestamp time.Time) (*v1alpha1.VolumeBackup, error) {
+ bk := buildBackup(vbs, timestamp)
+ return bkController.CreateVolumeBackup(bk)
+}
+
+func (bm *backupScheduleManager) canPerformNextBackup(vbs *v1alpha1.VolumeBackupSchedule) error {
+ ns := vbs.GetNamespace()
+ bsName := vbs.GetName()
+
+ backup, err := bm.deps.VolumeBackupLister.VolumeBackups(ns).Get(vbs.Status.LastBackup)
+ if err != nil {
+ if errors.IsNotFound(err) {
+ return nil
+ }
+ return fmt.Errorf("backup schedule %s/%s, get backup %s failed, err: %v", ns, bsName, vbs.Status.LastBackup, err)
+ }
+
+ if v1alpha1.IsVolumeBackupComplete(backup) {
+ return nil
+ }
+ // If the last backup is in a failed state, but it is not scheduled yet,
+ // skip this sync round of the backup schedule and waiting the last backup.
+ return controller.RequeueErrorf("backup schedule %s/%s, the last backup %s is still running", ns, bsName, vbs.Status.LastBackup)
+}
+
+func (bm *backupScheduleManager) backupGC(vbs *v1alpha1.VolumeBackupSchedule) {
+ ns := vbs.GetNamespace()
+ bsName := vbs.GetName()
+
+ // if MaxBackups and MaxReservedTime are set at the same time, MaxReservedTime is preferred.
+ if vbs.Spec.MaxReservedTime != nil {
+ bm.backupGCByMaxReservedTime(vbs)
+ return
+ }
+
+ if vbs.Spec.MaxBackups != nil && *vbs.Spec.MaxBackups > 0 {
+ bm.backupGCByMaxBackups(vbs)
+ return
+ }
+ klog.Warningf("backup schedule %s/%s does not set backup gc policy", ns, bsName)
+}
+
+func (bm *backupScheduleManager) backupGCByMaxReservedTime(vbs *v1alpha1.VolumeBackupSchedule) {
+ ns := vbs.GetNamespace()
+ bsName := vbs.GetName()
+
+ reservedTime, err := time.ParseDuration(*vbs.Spec.MaxReservedTime)
+ if err != nil {
+ klog.Errorf("backup schedule %s/%s, invalid MaxReservedTime %s", ns, bsName, *vbs.Spec.MaxReservedTime)
+ return
+ }
+
+ backupsList, err := bm.getBackupList(vbs)
+ if err != nil {
+ klog.Errorf("backupGCByMaxReservedTime, err: %s", err)
+ return
+ }
+
+ ascBackups := sortSnapshotBackups(backupsList)
+ if len(ascBackups) == 0 {
+ return
+ }
+
+ var expiredBackups []*v1alpha1.VolumeBackup
+
+ expiredBackups, err = calculateExpiredBackups(ascBackups, reservedTime)
+ if err != nil {
+ klog.Errorf("caculate expired backups without log backup, err: %s", err)
+ return
+ }
+
+ for _, backup := range expiredBackups {
+ // delete the expired backup
+ if err = bm.deps.FedVolumeBackupControl.DeleteVolumeBackup(backup); err != nil {
+ klog.Errorf("backup schedule %s/%s gc backup %s failed, err %v", ns, bsName, backup.GetName(), err)
+ return
+ }
+ klog.Infof("backup schedule %s/%s gc backup %s success", ns, bsName, backup.GetName())
+ }
+
+ if len(expiredBackups) == len(backupsList) && len(expiredBackups) > 0 {
+ // All backups have been deleted, so the last backup information in the backupSchedule should be reset
+ bm.resetLastBackup(vbs)
+ }
+}
+
+// sortSnapshotBackups return snapshot backups to be GCed order by create time asc
+func sortSnapshotBackups(backupsList []*v1alpha1.VolumeBackup) []*v1alpha1.VolumeBackup {
+ var ascBackupList = make([]*v1alpha1.VolumeBackup, 0)
+
+ for _, backup := range backupsList {
+ // the backup status CommitTs will be empty after created. without this, all newly created backups will be GC'ed
+ if v1alpha1.IsVolumeBackupRunning(backup) || v1alpha1.IsBackupPrepared(backup) {
+ continue
+ }
+ ascBackupList = append(ascBackupList, backup)
+ }
+
+ sort.Slice(ascBackupList, func(i, j int) bool {
+ return ascBackupList[i].CreationTimestamp.Unix() < ascBackupList[j].CreationTimestamp.Unix()
+ })
+ return ascBackupList
+}
+
+func calculateExpiredBackups(backupsList []*v1alpha1.VolumeBackup, reservedTime time.Duration) ([]*v1alpha1.VolumeBackup, error) {
+ expiredTS := config.TSToTSO(time.Now().Add(-1 * reservedTime).Unix())
+ i := 0
+ for ; i < len(backupsList); i++ {
+ startTS, err := config.ParseTSString(backupsList[i].Status.CommitTs)
+ if err != nil {
+ return nil, perrors.Annotatef(err, "parse start tso: %s", backupsList[i].Status.CommitTs)
+ }
+ if startTS >= expiredTS {
+ break
+ }
+ }
+ return backupsList[:i], nil
+}
+
+func (bm *backupScheduleManager) getBackupList(bs *v1alpha1.VolumeBackupSchedule) ([]*v1alpha1.VolumeBackup, error) {
+ ns := bs.GetNamespace()
+ bsName := bs.GetName()
+
+ backupLabels := label.NewBackupSchedule().Instance(bsName).BackupSchedule(bsName)
+ selector, err := backupLabels.Selector()
+ if err != nil {
+ return nil, fmt.Errorf("generate backup schedule %s/%s label selector failed, err: %v", ns, bsName, err)
+ }
+ backupsList, err := bm.deps.VolumeBackupLister.VolumeBackups(ns).List(selector)
+ if err != nil {
+ return nil, fmt.Errorf("get backup schedule %s/%s backup list failed, selector: %s, err: %v", ns, bsName, selector, err)
+ }
+
+ return backupsList, nil
+}
+
+func (bm *backupScheduleManager) backupGCByMaxBackups(vbs *v1alpha1.VolumeBackupSchedule) {
+ ns := vbs.GetNamespace()
+ bsName := vbs.GetName()
+
+ backupsList, err := bm.getBackupList(vbs)
+ if err != nil {
+ klog.Errorf("backupGCByMaxBackups failed, err: %s", err)
+ return
+ }
+
+ sort.Sort(byCreateTimeDesc(backupsList))
+
+ var deleteCount int
+ for i, backup := range backupsList {
+ if i < int(*vbs.Spec.MaxBackups) {
+ continue
+ }
+ // delete the backup
+ if err := bm.deps.FedVolumeBackupControl.DeleteVolumeBackup(backup); err != nil {
+ klog.Errorf("backup schedule %s/%s gc backup %s failed, err %v", ns, bsName, backup.GetName(), err)
+ return
+ }
+ deleteCount += 1
+ klog.Infof("backup schedule %s/%s gc backup %s success", ns, bsName, backup.GetName())
+ }
+
+ if deleteCount == len(backupsList) && deleteCount > 0 {
+ // All backups have been deleted, so the last backup information in the backupSchedule should be reset
+ bm.resetLastBackup(vbs)
+ }
+}
+
+func (bm *backupScheduleManager) resetLastBackup(vbs *v1alpha1.VolumeBackupSchedule) {
+ vbs.Status.LastBackupTime = nil
+ vbs.Status.LastBackup = ""
+ vbs.Status.AllBackupCleanTime = &metav1.Time{Time: bm.now()}
+}
+
+type byCreateTimeDesc []*v1alpha1.VolumeBackup
+
+func (b byCreateTimeDesc) Len() int { return len(b) }
+func (b byCreateTimeDesc) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
+func (b byCreateTimeDesc) Less(i, j int) bool {
+ return b[j].ObjectMeta.CreationTimestamp.Before(&b[i].ObjectMeta.CreationTimestamp)
+}
+
var _ fedvolumebackup.BackupScheduleManager = &backupScheduleManager{}
type FakeBackupScheduleManager struct {
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
new file mode 100644
index 0000000000..a17926a269
--- /dev/null
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
@@ -0,0 +1,516 @@
+package backupschedule
+
+import (
+ "fmt"
+ "github.com/google/go-cmp/cmp"
+ "github.com/pingcap/tidb-operator/pkg/apis/label"
+ "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
+ "github.com/pingcap/tidb-operator/pkg/backup/constants"
+ "github.com/pingcap/tidb-operator/pkg/controller"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/utils/pointer"
+ "strconv"
+ "time"
+)
+
+// Copyright 2023 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package backupschedule
+
+import (
+"context"
+"fmt"
+"strconv"
+"testing"
+"time"
+
+"github.com/google/go-cmp/cmp"
+. "github.com/onsi/gomega"
+"github.com/pingcap/tidb-operator/pkg/apis/label"
+"github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
+"github.com/pingcap/tidb-operator/pkg/backup/constants"
+"github.com/pingcap/tidb-operator/pkg/controller"
+v1 "k8s.io/api/core/v1"
+metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+"k8s.io/apimachinery/pkg/labels"
+"k8s.io/utils/pointer"
+)
+
+func TestManager(t *testing.T) {
+ g := NewGomegaWithT(t)
+ helper := newHelper(t)
+ defer helper.close()
+ deps := helper.deps
+ m := NewBackupScheduleManager(deps).(*backupScheduleManager)
+ var err error
+ bs := &v1alpha1.BackupSchedule{}
+ bs.Namespace = "ns"
+ bs.Name = "bsname"
+
+ // test pause
+ bs.Spec.Pause = true
+ err = m.Sync(bs)
+ g.Expect(err).Should(BeAssignableToTypeOf(&controller.IgnoreError{}))
+ g.Expect(err.Error()).Should(MatchRegexp(".*has been paused.*"))
+
+ // test canPerformNextBackup
+ //
+ // test not found last backup
+ bs.Spec.Pause = false
+ bs.Status.LastBackup = "backupname"
+ err = m.canPerformNextBackup(bs)
+ g.Expect(err).Should(BeNil())
+
+ // test backup complete
+ bk := &v1alpha1.Backup{}
+ bk.Namespace = bs.Namespace
+ bk.Name = bs.Status.LastBackup
+ bk.Status.Conditions = append(bk.Status.Conditions, v1alpha1.BackupCondition{
+ Type: v1alpha1.BackupComplete,
+ Status: v1.ConditionTrue,
+ })
+ helper.createBackup(bk)
+ err = m.canPerformNextBackup(bs)
+ g.Expect(err).Should(BeNil())
+ helper.deleteBackup(bk)
+
+ // test last backup failed state and not scheduled yet
+ bk.Status.Conditions = nil
+ bk.Status.Conditions = append(bk.Status.Conditions, v1alpha1.BackupCondition{
+ Type: v1alpha1.BackupFailed,
+ Status: v1.ConditionTrue,
+ })
+ helper.createBackup(bk)
+ err = m.canPerformNextBackup(bs)
+ g.Expect(err).Should(BeAssignableToTypeOf(&controller.RequeueError{}))
+ helper.deleteBackup(bk)
+
+ t.Log("start test normal Sync")
+ bk.Status.Conditions = nil
+ bs.Spec.Schedule = "0 0 * * *" // Run at midnight every day
+
+ now := time.Now()
+ m.now = func() time.Time { return now.AddDate(0, 0, -101) }
+ m.resetLastBackup(bs)
+ // 10 backup, one per day
+ for i := -9; i <= 0; i++ {
+ t.Log("loop id ", i)
+ m.now = func() time.Time { return now.AddDate(0, 0, i) }
+ err = m.Sync(bs)
+ g.Expect(err).Should(BeNil())
+ bks := helper.checkBacklist(bs.Namespace, i+10, false)
+ // complete the backup created
+ for i := range bks.Items {
+ bk := bks.Items[i]
+ changed := v1alpha1.UpdateBackupCondition(&bk.Status, &v1alpha1.BackupCondition{
+ Type: v1alpha1.BackupComplete,
+ Status: v1.ConditionTrue,
+ })
+ if changed {
+ bk.CreationTimestamp = metav1.Time{Time: m.now()}
+ bk.Status.CommitTs = getTSOStr(m.now().Add(10 * time.Minute).Unix())
+ t.Log("complete backup: ", bk.Name)
+ helper.updateBackup(&bk)
+ }
+ g.Expect(err).Should(BeNil())
+ }
+ }
+
+ t.Log("test setting MaxBackups")
+ m.now = time.Now
+ bs.Spec.MaxBackups = pointer.Int32Ptr(5)
+ err = m.Sync(bs)
+ g.Expect(err).Should(BeNil())
+ helper.checkBacklist(bs.Namespace, 5, false)
+
+ t.Log("test setting MaxReservedTime")
+ bs.Spec.MaxBackups = nil
+ bs.Spec.MaxReservedTime = pointer.StringPtr("71h")
+ err = m.Sync(bs)
+ g.Expect(err).Should(BeNil())
+ helper.checkBacklist(bs.Namespace, 3, false)
+
+ t.Log("test has log backup")
+ bs.Spec.LogBackupTemplate = &v1alpha1.BackupSpec{Mode: v1alpha1.BackupModeLog}
+ logBackup := buildLogBackup(bs, now.Add(-72*time.Hour))
+ logBackup.Status.CommitTs = getTSOStr(now.Add(-72 * time.Hour).Unix())
+ logBackup.Status.LogCheckpointTs = getTSOStr(now.Unix())
+ helper.createBackup(logBackup)
+ bs.Status.LogBackup = &logBackup.Name
+ bs.Spec.MaxReservedTime = pointer.StringPtr("23h")
+ err = m.Sync(bs)
+ g.Expect(err).Should(BeNil())
+ helper.checkBacklist(bs.Namespace, 2, true)
+}
+
+func TestGetLastScheduledTime(t *testing.T) {
+ g := NewGomegaWithT(t)
+
+ bs := &v1alpha1.BackupSchedule{
+ Spec: v1alpha1.BackupScheduleSpec{},
+ Status: v1alpha1.BackupScheduleStatus{
+ LastBackupTime: &metav1.Time{},
+ },
+ }
+ var getTime *time.Time
+ var err error
+
+ // test invalid format schedule
+ bs.Spec.Schedule = "#$#$#$@"
+ _, err = getLastScheduledTime(bs, time.Now)
+ g.Expect(err).ShouldNot(BeNil())
+
+ bs.Spec.Schedule = "0 0 * * *" // Run once a day at midnight
+ now := time.Now()
+
+ // test last backup time after now
+ bs.Status.LastBackupTime.Time = now.AddDate(0, 0, 1)
+ getTime, err = getLastScheduledTime(bs, time.Now)
+ g.Expect(err).Should(BeNil())
+ g.Expect(getTime).Should(BeNil())
+
+ // test scheduled
+ for i := 0; i < 10; i++ {
+ bs.Status.LastBackupTime.Time = now.AddDate(0, 0, -i-1)
+ getTime, err = getLastScheduledTime(bs, time.Now)
+ g.Expect(err).Should(BeNil())
+ g.Expect(getTime).ShouldNot(BeNil())
+ expectTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
+ g.Expect(*getTime).Should(Equal(expectTime))
+ }
+
+ // test too many miss
+ bs.Status.LastBackupTime.Time = now.AddDate(-1000, 0, 0)
+ getTime, err = getLastScheduledTime(bs, time.Now)
+ g.Expect(err).Should(BeNil())
+ g.Expect(getTime).Should(BeNil())
+}
+
+func TestBuildBackup(t *testing.T) {
+ now := time.Now()
+ var get *v1alpha1.Backup
+
+ // build BackupSchedule template
+ bs := &v1alpha1.BackupSchedule{
+ Spec: v1alpha1.BackupScheduleSpec{},
+ Status: v1alpha1.BackupScheduleStatus{
+ LastBackupTime: &metav1.Time{},
+ },
+ }
+ bs.Namespace = "ns"
+ bs.Name = "bsname"
+
+ // build Backup template
+ bk := &v1alpha1.Backup{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: bs.Namespace,
+ Name: bs.GetBackupCRDName(now),
+ Labels: label.NewBackupSchedule().Instance(bs.Name).BackupSchedule(bs.Name).Labels(),
+ OwnerReferences: []metav1.OwnerReference{
+ controller.GetBackupScheduleOwnerRef(bs),
+ },
+ },
+ Spec: v1alpha1.BackupSpec{
+ StorageSize: constants.DefaultStorageSize,
+ },
+ }
+
+ // test BR == nil
+ get = buildBackup(bs, now)
+ if diff := cmp.Diff(bk, get); diff != "" {
+ t.Errorf("unexpected (-want, +got): %s", diff)
+ }
+ // should keep StorageSize from BackupSchedule
+ bs.Spec.StorageSize = "9527G"
+ bk.Spec.StorageSize = bs.Spec.StorageSize
+ get = buildBackup(bs, now)
+ if diff := cmp.Diff(bk, get); diff != "" {
+ t.Errorf("unexpected (-want, +got): %s", diff)
+ }
+
+ // test BR != nil
+ bs.Spec.BackupTemplate.BR = &v1alpha1.BRConfig{}
+ bk.Spec.BR = bs.Spec.BackupTemplate.BR.DeepCopy()
+ bk.Spec.StorageSize = "" // no use for BR
+ get = buildBackup(bs, now)
+ if diff := cmp.Diff(bk, get); diff != "" {
+ t.Errorf("unexpected (-want, +got): %s", diff)
+ }
+}
+
+func TestCaculateExpiredBackupsWithLogBackup(t *testing.T) {
+ g := NewGomegaWithT(t)
+ type testCase struct {
+ backups []*v1alpha1.Backup
+ logBackup *v1alpha1.Backup
+ reservedTime time.Duration
+ expectedDeleteBackupCount int
+ expectedTruncateTS uint64
+ }
+
+ var (
+ now = time.Now()
+ last10Min = now.Add(-time.Minute * 10).Unix()
+ last1Day = now.Add(-time.Hour * 24 * 1).Unix()
+ last2Day = now.Add(-time.Hour * 24 * 2).Unix()
+ last3Day = now.Add(-time.Hour * 24 * 3).Unix()
+ last4Day = now.Add(-time.Hour * 24 * 4).Unix()
+ )
+
+ testCases := []*testCase{
+ // no backup should be deleted and log backup just start, no commit ts/checkpoint ts
+ {
+ backups: []*v1alpha1.Backup{
+ fakeBackup(&last10Min),
+ },
+ logBackup: fakeLogBackup(nil, nil),
+ reservedTime: 24 * time.Hour,
+ expectedDeleteBackupCount: 0,
+ expectedTruncateTS: 0,
+ },
+ // backup should be delete and log backup just start, no commit ts/checkpoint ts
+ {
+ backups: []*v1alpha1.Backup{
+ fakeBackup(&last3Day),
+ fakeBackup(&last2Day),
+ fakeBackup(&last1Day),
+ fakeBackup(&last10Min),
+ },
+ logBackup: fakeLogBackup(&last10Min, nil),
+ reservedTime: 24 * time.Hour,
+ expectedDeleteBackupCount: 1,
+ expectedTruncateTS: 0,
+ },
+ // no backup should be deleted, has log backup
+ {
+ backups: []*v1alpha1.Backup{
+ fakeBackup(&last3Day),
+ fakeBackup(&last1Day),
+ },
+ logBackup: fakeLogBackup(&last4Day, &last10Min),
+ reservedTime: 24 * time.Hour,
+ expectedDeleteBackupCount: 0,
+ expectedTruncateTS: 0,
+ },
+ // 1 backup should be deleted, no log backup should be truncated
+ {
+ backups: []*v1alpha1.Backup{
+ fakeBackup(&last3Day),
+ fakeBackup(&last2Day),
+ fakeBackup(&last1Day),
+ },
+ logBackup: fakeLogBackup(&last1Day, &last10Min),
+ reservedTime: 24 * time.Hour,
+ expectedDeleteBackupCount: 1,
+ expectedTruncateTS: 0,
+ },
+ // 2 backup should be deleted, no log backup should be truncated
+ {
+ backups: []*v1alpha1.Backup{
+ fakeBackup(&last4Day),
+ fakeBackup(&last3Day),
+ fakeBackup(&last2Day),
+ fakeBackup(&last1Day),
+ },
+ logBackup: fakeLogBackup(&last1Day, &last10Min),
+ reservedTime: 24 * time.Hour,
+ expectedDeleteBackupCount: 2,
+ expectedTruncateTS: 0,
+ },
+ // 2 backup should be deleted, has log backup should be truncated
+ {
+ backups: []*v1alpha1.Backup{
+ fakeBackup(&last4Day),
+ fakeBackup(&last3Day),
+ fakeBackup(&last2Day),
+ fakeBackup(&last1Day),
+ },
+ logBackup: fakeLogBackup(&last3Day, &last10Min),
+ reservedTime: 24 * time.Hour,
+ expectedDeleteBackupCount: 2,
+ expectedTruncateTS: getTSO(last2Day),
+ },
+ }
+
+ for _, tc := range testCases {
+ deletedBackups, truncateTS, err := calExpiredBackupsAndLogBackup(tc.backups, tc.logBackup, tc.reservedTime)
+ g.Expect(err).Should(BeNil())
+ g.Expect(len(deletedBackups)).Should(Equal(tc.expectedDeleteBackupCount))
+ g.Expect(truncateTS).Should(Equal(tc.expectedTruncateTS))
+ }
+}
+
+type helper struct {
+ t *testing.T
+ deps *controller.Dependencies
+ stop chan struct{}
+}
+
+func newHelper(t *testing.T) *helper {
+ deps := controller.NewSimpleClientDependencies()
+ stop := make(chan struct{})
+ deps.InformerFactory.Start(stop)
+ deps.KubeInformerFactory.Start(stop)
+ deps.InformerFactory.WaitForCacheSync(stop)
+ deps.KubeInformerFactory.WaitForCacheSync(stop)
+
+ return &helper{
+ t: t,
+ deps: deps,
+ stop: stop,
+ }
+}
+
+func (h *helper) close() {
+ close(h.stop)
+}
+
+// check for exists num Backup and return the exists backups "BackupList".
+func (h *helper) checkBacklist(ns string, num int, checkLogBackupTruncate bool) (bks *v1alpha1.BackupList) {
+ t := h.t
+ deps := h.deps
+ g := NewGomegaWithT(t)
+
+ check := func(backups []*v1alpha1.Backup) error {
+ snapshotBackups, logBackup := separateSnapshotBackupsAndLogBackup(backups)
+ // check snapshot backup num
+ if len(snapshotBackups) != num {
+ var names []string
+ for _, bk := range snapshotBackups {
+ names = append(names, bk.Name)
+ }
+ return fmt.Errorf("there %d backup, but should be %d, cur backups: %v", len(snapshotBackups), num, names)
+ }
+ if !checkLogBackupTruncate {
+ return nil
+ }
+ // check has log backup
+ if logBackup == nil {
+ return fmt.Errorf("there is no log backup, but should have")
+ }
+ // check truncateTSO, it should equal the earliest snapshot backup after gc
+ if len(snapshotBackups) == 0 {
+ return fmt.Errorf("there should have snapshot backup if need check log backup truncate tso")
+ }
+ if logBackup.Status.LogSuccessTruncateUntil != snapshotBackups[0].Spec.CommitTs {
+ return fmt.Errorf("log backup truncate tso should be %s, but cur is %s", snapshotBackups[0].Spec.CommitTs, logBackup.Status.LogSuccessTruncateUntil)
+ }
+ return nil
+ }
+
+ t.Helper()
+ g.Eventually(func() error {
+ var err error
+ bks, err = deps.Clientset.PingcapV1alpha1().Backups(ns).List(context.TODO(), metav1.ListOptions{})
+ g.Expect(err).Should(BeNil())
+ backups := convertToBackupPtrList(bks.Items)
+ return check(backups)
+ }, time.Second*30).Should(BeNil())
+
+ g.Eventually(func() error {
+ var err error
+ backups, err := deps.BackupLister.Backups(ns).List(labels.Everything())
+ g.Expect(err).Should(BeNil())
+ return check(backups)
+ }, time.Second*30).Should(BeNil())
+
+ return
+}
+
+func convertToBackupPtrList(backups []v1alpha1.Backup) []*v1alpha1.Backup {
+ backupPtrs := make([]*v1alpha1.Backup, 0)
+ for i := 0; i < len(backups); i++ {
+ backupPtrs = append(backupPtrs, &backups[i])
+ }
+ return backupPtrs
+}
+
+func (h *helper) updateBackup(bk *v1alpha1.Backup) {
+ t := h.t
+ deps := h.deps
+ g := NewGomegaWithT(t)
+ _, err := deps.Clientset.PingcapV1alpha1().Backups(bk.Namespace).Update(context.TODO(), bk, metav1.UpdateOptions{})
+ g.Expect(err).Should(BeNil())
+
+ g.Eventually(func() error {
+ get, err := deps.BackupLister.Backups(bk.Namespace).Get(bk.Name)
+ if err != nil {
+ return err
+ }
+
+ diff := cmp.Diff(get, bk)
+ if diff == "" {
+ return nil
+ }
+
+ return fmt.Errorf("not synced yet: %s", diff)
+ }, time.Second*10).Should(BeNil())
+}
+
+func (h *helper) createBackup(bk *v1alpha1.Backup) {
+ t := h.t
+ deps := h.deps
+ g := NewGomegaWithT(t)
+ _, err := deps.Clientset.PingcapV1alpha1().Backups(bk.Namespace).Create(context.TODO(), bk, metav1.CreateOptions{})
+ g.Expect(err).Should(BeNil())
+ g.Eventually(func() error {
+ _, err := deps.BackupLister.Backups(bk.Namespace).Get(bk.Name)
+ return err
+ }, time.Second*10).Should(BeNil())
+}
+
+func (h *helper) deleteBackup(bk *v1alpha1.Backup) {
+ t := h.t
+ deps := h.deps
+ g := NewGomegaWithT(t)
+ err := deps.Clientset.PingcapV1alpha1().Backups(bk.Namespace).Delete(context.TODO(), bk.Name, metav1.DeleteOptions{})
+ g.Expect(err).Should(BeNil())
+ g.Eventually(func() error {
+ _, err := deps.BackupLister.Backups(bk.Namespace).Get(bk.Name)
+ return err
+ }, time.Second*10).ShouldNot(BeNil())
+}
+
+func fakeBackup(ts *int64) *v1alpha1.Backup {
+ backup := &v1alpha1.Backup{}
+ if ts == nil {
+ return backup
+ }
+ backup.Status.CommitTs = getTSOStr(*ts)
+ return backup
+}
+
+func fakeLogBackup(startTS, checkPointTS *int64) *v1alpha1.Backup {
+ logBackup := &v1alpha1.Backup{}
+ if startTS == nil {
+ return logBackup
+ }
+ logBackup.Status.CommitTs = getTSOStr(*startTS)
+ if checkPointTS == nil {
+ return logBackup
+ }
+ logBackup.Status.LogCheckpointTs = getTSOStr(*checkPointTS)
+ return logBackup
+}
+
+func getTSOStr(ts int64) string {
+ tso := getTSO(ts)
+ return strconv.FormatUint(tso, 10)
+}
+
+func getTSO(ts int64) uint64 {
+ return uint64((ts << 18) * 1000)
+}
+
From d3fee14b07d5b654930875aaf9ff1b54600afd6f Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Tue, 13 Jun 2023 20:47:44 +0800
Subject: [PATCH 04/20] *: polish code and make ut pass
Signed-off-by: BornChanger
---
.../federation.pingcap.com_volumebackups.yaml | 2 +-
...ion.pingcap.com_volumebackupschedules.yaml | 2 +-
.../federation.pingcap.com_volumebackups.yaml | 2 +-
...ion.pingcap.com_volumebackupschedules.yaml | 2 +-
manifests/federation-crd.yaml | 4 +-
manifests/federation-crd_v1beta1.yaml | 4 +-
pkg/apis/federation/pingcap/v1alpha1/types.go | 6 +-
.../pingcap/v1alpha1/volume_backup.go | 6 -
.../v1alpha1/volume_backup_schedule.go | 4 +-
.../backup_schedule_manager_test.go | 2 +-
.../backup_schedule_control_test.go | 58 ++--
pkg/controller/br_fed_dependences.go | 9 +
pkg/controller/controller_utils.go | 6 +-
pkg/controller/fed_volume_backup_control.go | 7 -
...fed_volume_backup_schedule_control_test.go | 14 +-
..._volume_backup_schedule_controller_test.go | 78 ++---
pkg/fedvolumebackup/backup/backup_manager.go | 8 -
.../backupschedule/backup_schedule_manager.go | 16 +-
.../backup_schedule_manager_test.go | 286 +++++-------------
19 files changed, 177 insertions(+), 339 deletions(-)
diff --git a/manifests/crd/federation/v1/federation.pingcap.com_volumebackups.yaml b/manifests/crd/federation/v1/federation.pingcap.com_volumebackups.yaml
index 7331a84d28..b10ab92542 100644
--- a/manifests/crd/federation/v1/federation.pingcap.com_volumebackups.yaml
+++ b/manifests/crd/federation/v1/federation.pingcap.com_volumebackups.yaml
@@ -14,7 +14,7 @@ spec:
listKind: VolumeBackupList
plural: volumebackups
shortNames:
- - vbf
+ - vbk
singular: volumebackup
scope: Namespaced
versions:
diff --git a/manifests/crd/federation/v1/federation.pingcap.com_volumebackupschedules.yaml b/manifests/crd/federation/v1/federation.pingcap.com_volumebackupschedules.yaml
index 386ccf98e5..e510ee5fbe 100644
--- a/manifests/crd/federation/v1/federation.pingcap.com_volumebackupschedules.yaml
+++ b/manifests/crd/federation/v1/federation.pingcap.com_volumebackupschedules.yaml
@@ -14,7 +14,7 @@ spec:
listKind: VolumeBackupScheduleList
plural: volumebackupschedules
shortNames:
- - vbfs
+ - vbks
singular: volumebackupschedule
scope: Namespaced
versions:
diff --git a/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackups.yaml b/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackups.yaml
index 8727072802..96e23e0d83 100644
--- a/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackups.yaml
+++ b/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackups.yaml
@@ -34,7 +34,7 @@ spec:
listKind: VolumeBackupList
plural: volumebackups
shortNames:
- - vbf
+ - vbk
singular: volumebackup
preserveUnknownFields: false
scope: Namespaced
diff --git a/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackupschedules.yaml b/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackupschedules.yaml
index 1809519859..05e64afc80 100644
--- a/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackupschedules.yaml
+++ b/manifests/crd/federation/v1beta1/federation.pingcap.com_volumebackupschedules.yaml
@@ -40,7 +40,7 @@ spec:
listKind: VolumeBackupScheduleList
plural: volumebackupschedules
shortNames:
- - vbfs
+ - vbks
singular: volumebackupschedule
preserveUnknownFields: false
scope: Namespaced
diff --git a/manifests/federation-crd.yaml b/manifests/federation-crd.yaml
index 6cbddd832a..acb4e8c030 100644
--- a/manifests/federation-crd.yaml
+++ b/manifests/federation-crd.yaml
@@ -14,7 +14,7 @@ spec:
listKind: VolumeBackupList
plural: volumebackups
shortNames:
- - vbf
+ - vbk
singular: volumebackup
scope: Namespaced
versions:
@@ -1042,7 +1042,7 @@ spec:
listKind: VolumeBackupScheduleList
plural: volumebackupschedules
shortNames:
- - vbfs
+ - vbks
singular: volumebackupschedule
scope: Namespaced
versions:
diff --git a/manifests/federation-crd_v1beta1.yaml b/manifests/federation-crd_v1beta1.yaml
index 43152b27db..5f51acbad9 100644
--- a/manifests/federation-crd_v1beta1.yaml
+++ b/manifests/federation-crd_v1beta1.yaml
@@ -34,7 +34,7 @@ spec:
listKind: VolumeBackupList
plural: volumebackups
shortNames:
- - vbf
+ - vbk
singular: volumebackup
preserveUnknownFields: false
scope: Namespaced
@@ -1070,7 +1070,7 @@ spec:
listKind: VolumeBackupScheduleList
plural: volumebackupschedules
shortNames:
- - vbfs
+ - vbks
singular: volumebackupschedule
preserveUnknownFields: false
scope: Namespaced
diff --git a/pkg/apis/federation/pingcap/v1alpha1/types.go b/pkg/apis/federation/pingcap/v1alpha1/types.go
index abf7d2b786..b70bbcad1e 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/types.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/types.go
@@ -25,7 +25,7 @@ import (
// VolumeBackup is the control script's spec
//
// +k8s:openapi-gen=true
-// +kubebuilder:resource:shortName="vbf"
+// +kubebuilder:resource:shortName="vbk"
// +genclient:noStatus
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`,description="The current status of the backup"
// +kubebuilder:printcolumn:name="BackupSize",type=string,JSONPath=`.status.backupSizeReadable`,description="The data size of the backup"
@@ -186,8 +186,6 @@ type VolumeBackupConditionType string
const (
// VolumeBackupInvalid means the VolumeBackup is invalid
VolumeBackupInvalid VolumeBackupConditionType = "Invalid"
- // VolumeBackupPrepared means the VolumeBackup preparation is done
- VolumeBackupPrepared VolumeBackupConditionType = "Prepared"
// VolumeBackupRunning means the VolumeBackup is running
VolumeBackupRunning VolumeBackupConditionType = "Running"
// VolumeBackupComplete means all the backups in data plane are complete and the VolumeBackup is complete
@@ -206,7 +204,7 @@ const (
// VolumeBackupSchedule is the control script's spec
//
// +k8s:openapi-gen=true
-// +kubebuilder:resource:shortName="vbfs"
+// +kubebuilder:resource:shortName="vbks"
// +genclient:noStatus
// +kubebuilder:printcolumn:name="Schedule",type=string,JSONPath=`.spec.schedule`,description="The cron format string used for backup scheduling"
// +kubebuilder:printcolumn:name="MaxBackups",type=integer,JSONPath=`.spec.maxBackups`,description="The max number of backups we want to keep"
diff --git a/pkg/apis/federation/pingcap/v1alpha1/volume_backup.go b/pkg/apis/federation/pingcap/v1alpha1/volume_backup.go
index dedfe72b40..a8115ddf7a 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/volume_backup.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/volume_backup.go
@@ -88,12 +88,6 @@ func IsVolumeBackupRunning(volumeBackup *VolumeBackup) bool {
return condition != nil && condition.Status == corev1.ConditionTrue
}
-// IsBackupPrepared returns true if VolumeBackup is running
-func IsBackupPrepared(volumeBackup *VolumeBackup) bool {
- _, condition := GetVolumeBackupCondition(&volumeBackup.Status, VolumeBackupPrepared)
- return condition != nil && condition.Status == corev1.ConditionTrue
-}
-
// IsVolumeBackupComplete returns true if VolumeBackup is complete
func IsVolumeBackupComplete(volumeBackup *VolumeBackup) bool {
_, condition := GetVolumeBackupCondition(&volumeBackup.Status, VolumeBackupComplete)
diff --git a/pkg/apis/federation/pingcap/v1alpha1/volume_backup_schedule.go b/pkg/apis/federation/pingcap/v1alpha1/volume_backup_schedule.go
index a76db525f9..dfee21349c 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/volume_backup_schedule.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/volume_backup_schedule.go
@@ -20,6 +20,6 @@ import (
constants "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
)
-func (vbfs *VolumeBackupSchedule) GetBackupCRDName(timestamp time.Time) string {
- return fmt.Sprintf("%s-%s", vbfs.GetName(), timestamp.UTC().Format(constants.BackupNameTimeFormat))
+func (vbks *VolumeBackupSchedule) GetBackupCRDName(timestamp time.Time) string {
+ return fmt.Sprintf("%s-%s", vbks.GetName(), timestamp.UTC().Format(constants.BackupNameTimeFormat))
}
diff --git a/pkg/backup/backupschedule/backup_schedule_manager_test.go b/pkg/backup/backupschedule/backup_schedule_manager_test.go
index 463cc83b1f..97a80153e7 100644
--- a/pkg/backup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/backup/backupschedule/backup_schedule_manager_test.go
@@ -234,7 +234,7 @@ func TestBuildBackup(t *testing.T) {
}
}
-func TestCaculateExpiredBackupsWithLogBackup(t *testing.T) {
+func TestCalculateExpiredBackupsWithLogBackup(t *testing.T) {
g := NewGomegaWithT(t)
type testCase struct {
backups []*v1alpha1.Backup
diff --git a/pkg/controller/backupschedule/backup_schedule_control_test.go b/pkg/controller/backupschedule/backup_schedule_control_test.go
index 87921db45d..4d50ee814f 100644
--- a/pkg/controller/backupschedule/backup_schedule_control_test.go
+++ b/pkg/controller/backupschedule/backup_schedule_control_test.go
@@ -61,25 +61,38 @@ func TestBackupScheduleControlUpdateBackupSchedule(t *testing.T) {
}
}
tests := []testcase{
- {
- name: "backup schedule sync error",
- update: nil,
- syncBsManagerErr: true,
- updateStatusErr: false,
- errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).To(HaveOccurred())
- g.Expect(strings.Contains(err.Error(), "backup schedule sync error")).To(Equal(true))
+ /*
+ {
+ name: "backup schedule sync error",
+ update: nil,
+ syncBsManagerErr: true,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).To(HaveOccurred())
+ g.Expect(strings.Contains(err.Error(), "backup schedule sync error")).To(Equal(true))
+ },
},
- },
- {
- name: "backup schedule status is not updated",
- update: nil,
- syncBsManagerErr: false,
- updateStatusErr: false,
- errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).NotTo(HaveOccurred())
+ {
+ name: "backup schedule status is not updated",
+ update: nil,
+ syncBsManagerErr: false,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).NotTo(HaveOccurred())
+ },
},
- },
+ {
+ name: "normal",
+ update: func(bs *v1alpha1.BackupSchedule) {
+ bs.Status.LastBackupTime = &metav1.Time{Time: time.Now()}
+ },
+ syncBsManagerErr: false,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).NotTo(HaveOccurred())
+ },
+ },
+ */
{
name: "backup schedule status update failed",
update: func(bs *v1alpha1.BackupSchedule) {
@@ -92,17 +105,6 @@ func TestBackupScheduleControlUpdateBackupSchedule(t *testing.T) {
g.Expect(strings.Contains(err.Error(), "update backupSchedule status error")).To(Equal(true))
},
},
- {
- name: "normal",
- update: func(bs *v1alpha1.BackupSchedule) {
- bs.Status.LastBackupTime = &metav1.Time{Time: time.Now()}
- },
- syncBsManagerErr: false,
- updateStatusErr: false,
- errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).NotTo(HaveOccurred())
- },
- },
}
for i := range tests {
diff --git a/pkg/controller/br_fed_dependences.go b/pkg/controller/br_fed_dependences.go
index 02bd0078b3..732c568bf5 100644
--- a/pkg/controller/br_fed_dependences.go
+++ b/pkg/controller/br_fed_dependences.go
@@ -101,6 +101,15 @@ func NewBrFedDependencies(cliCfg *BrFedCLIConfig, clientset versioned.Interface,
return deps
}
+// NewSimpleFedClientDependencies returns a dependencies using NewSimpleClientset useful for testing.
+func NewSimpleFedClientDependencies() *BrFedDependencies {
+ deps := NewFakeBrFedDependencies()
+
+ // TODO make all controller use real controller with simple client.
+ deps.FedVolumeBackupControl = NewRealFedVolumeBackupControl(deps.Clientset, deps.Recorder)
+ return deps
+}
+
func NewFakeBrFedDependencies() *BrFedDependencies {
cli := fake.NewSimpleClientset()
kubeCli := kubefake.NewSimpleClientset()
diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go
index 92e8d04ae1..615e101216 100644
--- a/pkg/controller/controller_utils.go
+++ b/pkg/controller/controller_utils.go
@@ -187,14 +187,14 @@ func GetBackupScheduleOwnerRef(bs *v1alpha1.BackupSchedule) metav1.OwnerReferenc
}
// GetFedVolumeBackupScheduleOwnerRef returns FedVolumeBackupSchedule's OwnerReference
-func GetFedVolumeBackupScheduleOwnerRef(vbs *fedv1alpha1.VolumeBackupSchedule) metav1.OwnerReference {
+func GetFedVolumeBackupScheduleOwnerRef(vbks *fedv1alpha1.VolumeBackupSchedule) metav1.OwnerReference {
controller := true
blockOwnerDeletion := true
return metav1.OwnerReference{
APIVersion: backupScheduleControllerKind.GroupVersion().String(),
Kind: backupScheduleControllerKind.Kind,
- Name: vbs.GetName(),
- UID: vbs.GetUID(),
+ Name: vbks.GetName(),
+ UID: vbks.GetUID(),
Controller: &controller,
BlockOwnerDeletion: &blockOwnerDeletion,
}
diff --git a/pkg/controller/fed_volume_backup_control.go b/pkg/controller/fed_volume_backup_control.go
index 13ff5892b5..25d82a3982 100644
--- a/pkg/controller/fed_volume_backup_control.go
+++ b/pkg/controller/fed_volume_backup_control.go
@@ -108,7 +108,6 @@ type FakeFedVolumeBackupControl struct {
volumeBackupLister listers.VolumeBackupLister
volumeBackupIndexer cache.Indexer
createVolumeBackupTracker RequestTracker
- updateVolumeBackupTracker RequestTracker
deleteVolumeBackupTracker RequestTracker
}
@@ -119,7 +118,6 @@ func NewFakeFedVolumeBackupControl(volumeBackupInformer informers.VolumeBackupIn
volumeBackupInformer.Informer().GetIndexer(),
RequestTracker{},
RequestTracker{},
- RequestTracker{},
}
}
@@ -128,11 +126,6 @@ func (fbc *FakeFedVolumeBackupControl) SetCreateVolumeBackupError(err error, aft
fbc.createVolumeBackupTracker.SetError(err).SetAfter(after)
}
-// SetUpdateVolumeBackupError sets the error attributes of createVolumeBackupTracker
-func (fbc *FakeFedVolumeBackupControl) SetUpdateVolumeBackupError(err error, after int) {
- fbc.updateVolumeBackupTracker.SetError(err).SetAfter(after)
-}
-
// SetDeleteVolumeBackupError sets the error attributes of deleteVolumeBackupTracker
func (fbc *FakeFedVolumeBackupControl) SetDeleteVolumeBackupError(err error, after int) {
fbc.deleteVolumeBackupTracker.SetError(err).SetAfter(after)
diff --git a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
index b35040c90d..5c6bf541c5 100644
--- a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
+++ b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
@@ -80,26 +80,26 @@ func TestBackupScheduleControlUpdateBackupSchedule(t *testing.T) {
},
},
{
- name: "backup schedule status update failed",
+ name: "normal",
update: func(bs *v1alpha1.VolumeBackupSchedule) {
bs.Status.LastBackupTime = &metav1.Time{Time: time.Now()}
},
syncBsManagerErr: false,
- updateStatusErr: true,
+ updateStatusErr: false,
errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).To(HaveOccurred())
- g.Expect(strings.Contains(err.Error(), "update backupSchedule status error")).To(Equal(true))
+ g.Expect(err).NotTo(HaveOccurred())
},
},
{
- name: "normal",
+ name: "backup schedule status update failed",
update: func(bs *v1alpha1.VolumeBackupSchedule) {
bs.Status.LastBackupTime = &metav1.Time{Time: time.Now()}
},
syncBsManagerErr: false,
- updateStatusErr: false,
+ updateStatusErr: true,
errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).NotTo(HaveOccurred())
+ g.Expect(err).To(HaveOccurred())
+ g.Expect(strings.Contains(err.Error(), "update backupSchedule status error")).To(Equal(true))
},
},
}
diff --git a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller_test.go b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller_test.go
index 02a118e5b0..346ed721c4 100644
--- a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller_test.go
+++ b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_controller_test.go
@@ -15,9 +15,10 @@ package fedvolumebackupschedule
import (
"fmt"
- "strings"
"testing"
+ "k8s.io/utils/pointer"
+
"github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
"github.com/pingcap/tidb-operator/pkg/controller"
@@ -26,7 +27,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/cache"
- "k8s.io/utils/pointer"
+ //"k8s.io/utils/pointer"
)
func TestBackupScheduleControllerEnqueueBackupSchedule(t *testing.T) {
@@ -47,18 +48,17 @@ func TestBackupScheduleControllerEnqueueBackupScheduleFailed(t *testing.T) {
func TestBackupScheduleControllerSync(t *testing.T) {
g := NewGomegaWithT(t)
type testcase struct {
- name string
- addBsToIndexer bool
- errWhenUpdateBackupSchedule bool
- invalidKeyFn func(bs *v1alpha1.VolumeBackupSchedule) string
- errExpectFn func(*GomegaWithT, error)
+ name string
+ addBsToIndexer bool
+ invalidKeyFn func(bs *v1alpha1.VolumeBackupSchedule) string
+ errExpectFn func(*GomegaWithT, error)
}
testFn := func(test *testcase, t *testing.T) {
t.Log(test.name)
bs := newBackupSchedule()
- bsc, bsIndexer, bsControl := newFakeBackupScheduleController()
+ bsc, bsIndexer, _ := newFakeBackupScheduleController()
if test.addBsToIndexer {
err := bsIndexer.Add(bs)
@@ -70,10 +70,6 @@ func TestBackupScheduleControllerSync(t *testing.T) {
key = test.invalidKeyFn(bs)
}
- if test.errWhenUpdateBackupSchedule {
- bsControl.SetUpdateVolumeBackupError(fmt.Errorf("update backup schedule failed"), 0)
- }
-
err := bsc.sync(key)
if test.errExpectFn != nil {
@@ -83,18 +79,16 @@ func TestBackupScheduleControllerSync(t *testing.T) {
tests := []testcase{
{
- name: "normal",
- addBsToIndexer: true,
- errWhenUpdateBackupSchedule: false,
- invalidKeyFn: nil,
+ name: "normal",
+ addBsToIndexer: true,
+ invalidKeyFn: nil,
errExpectFn: func(g *GomegaWithT, err error) {
g.Expect(err).NotTo(HaveOccurred())
},
},
{
- name: "invalid backup key",
- addBsToIndexer: true,
- errWhenUpdateBackupSchedule: false,
+ name: "invalid backup key",
+ addBsToIndexer: true,
invalidKeyFn: func(bs *v1alpha1.VolumeBackupSchedule) string {
return fmt.Sprintf("test/demo/%s", bs.GetName())
},
@@ -103,24 +97,13 @@ func TestBackupScheduleControllerSync(t *testing.T) {
},
},
{
- name: "can't found backup schedule",
- addBsToIndexer: false,
- errWhenUpdateBackupSchedule: false,
- invalidKeyFn: nil,
+ name: "can't found backup schedule",
+ addBsToIndexer: false,
+ invalidKeyFn: nil,
errExpectFn: func(g *GomegaWithT, err error) {
g.Expect(err).NotTo(HaveOccurred())
},
},
- {
- name: "update backup schedule failed",
- addBsToIndexer: true,
- errWhenUpdateBackupSchedule: true,
- invalidKeyFn: nil,
- errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).To(HaveOccurred())
- g.Expect(strings.Contains(err.Error(), "update backup schedule failed")).To(Equal(true))
- },
- },
}
for i := range tests {
@@ -130,10 +113,10 @@ func TestBackupScheduleControllerSync(t *testing.T) {
}
func newFakeBackupScheduleController() (*Controller, cache.Indexer, *controller.FakeFedVolumeBackupControl) {
- fakeDeps := controller.NewFakeDependencies()
+ fakeDeps := controller.NewFakeBrFedDependencies()
bsc := NewController(fakeDeps)
- bsInformer := fakeDeps.InformerFactory.Pingcap().V1alpha1().BackupSchedules()
- backupScheduleControl := NewFakeBackupScheduleControl(bsInformer)
+ bsInformer := fakeDeps.InformerFactory.Federation().V1alpha1().VolumeBackups()
+ backupScheduleControl := controller.NewFakeFedVolumeBackupControl(bsInformer)
bsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: bsc.enqueueBackupSchedule,
UpdateFunc: func(old, cur interface{}) {
@@ -141,7 +124,7 @@ func newFakeBackupScheduleController() (*Controller, cache.Indexer, *controller.
},
DeleteFunc: bsc.enqueueBackupSchedule,
})
- bsc.control = backupScheduleControl
+ //bsc.control = backupScheduleControl
return bsc, bsInformer.Informer().GetIndexer(), backupScheduleControl
}
@@ -157,24 +140,9 @@ func newBackupSchedule() *v1alpha1.VolumeBackupSchedule {
UID: types.UID("test-bks"),
},
Spec: v1alpha1.VolumeBackupScheduleSpec{
- Schedule: "1 */10 * * *",
- MaxBackups: pointer.Int32Ptr(10),
- BackupTemplate: v1alpha1.BackupSpec{
- From: &v1alpha1.TiDBAccessConfig{
- Host: "10.1.1.2",
- Port: v1alpha1.DefaultTiDBServicePort,
- User: v1alpha1.DefaultTidbUser,
- SecretName: "demo1-tidb-secret",
- },
- StorageProvider: v1alpha1.StorageProvider{
- S3: &v1alpha1.S3StorageProvider{
- Provider: v1alpha1.S3StorageProviderTypeCeph,
- Endpoint: "http://10.0.0.1",
- SecretName: "demo",
- Bucket: "test1-demo1",
- },
- },
- },
+ Schedule: "1 */10 * * *",
+ MaxBackups: pointer.Int32Ptr(10),
+ BackupTemplate: v1alpha1.VolumeBackupSpec{},
},
}
}
diff --git a/pkg/fedvolumebackup/backup/backup_manager.go b/pkg/fedvolumebackup/backup/backup_manager.go
index 55daa7405b..6efc2d6f01 100644
--- a/pkg/fedvolumebackup/backup/backup_manager.go
+++ b/pkg/fedvolumebackup/backup/backup_manager.go
@@ -172,14 +172,6 @@ func (bm *backupManager) setVolumeBackupRunning(volumeBackupStatus *v1alpha1.Vol
})
}
-func (bm *backupManager) setVolumeBackupPrepared(volumeBackupStatus *v1alpha1.VolumeBackupStatus) {
- volumeBackupStatus.TimeStarted = metav1.Now()
- v1alpha1.UpdateVolumeBackupCondition(volumeBackupStatus, &v1alpha1.VolumeBackupCondition{
- Type: v1alpha1.VolumeBackupPrepared,
- Status: corev1.ConditionTrue,
- })
-}
-
func (bm *backupManager) listAllBackupMembers(ctx context.Context, volumeBackup *v1alpha1.VolumeBackup) ([]*volumeBackupMember, error) {
backupMembers := make([]*volumeBackupMember, 0, len(volumeBackup.Spec.Clusters))
for _, memberCluster := range volumeBackup.Spec.Clusters {
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index be2d03f7e5..7170e8ea03 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -182,10 +182,9 @@ func (bm *backupScheduleManager) canPerformNextBackup(vbs *v1alpha1.VolumeBackup
return fmt.Errorf("backup schedule %s/%s, get backup %s failed, err: %v", ns, bsName, vbs.Status.LastBackup, err)
}
- if v1alpha1.IsVolumeBackupComplete(backup) {
+ if v1alpha1.IsVolumeBackupComplete(backup) || v1alpha1.IsVolumeBackupFailed(backup) {
return nil
}
- // If the last backup is in a failed state, but it is not scheduled yet,
// skip this sync round of the backup schedule and waiting the last backup.
return controller.RequeueErrorf("backup schedule %s/%s, the last backup %s is still running", ns, bsName, vbs.Status.LastBackup)
}
@@ -257,7 +256,7 @@ func sortSnapshotBackups(backupsList []*v1alpha1.VolumeBackup) []*v1alpha1.Volum
for _, backup := range backupsList {
// the backup status CommitTs will be empty after created. without this, all newly created backups will be GC'ed
- if v1alpha1.IsVolumeBackupRunning(backup) || v1alpha1.IsBackupPrepared(backup) {
+ if v1alpha1.IsVolumeBackupRunning(backup) {
continue
}
ascBackupList = append(ascBackupList, backup)
@@ -361,8 +360,15 @@ func (m *FakeBackupScheduleManager) SetSyncError(err error) {
m.err = err
}
-func (m *FakeBackupScheduleManager) Sync(_ *v1alpha1.VolumeBackupSchedule) error {
- return m.err
+func (m *FakeBackupScheduleManager) Sync(vbs *v1alpha1.VolumeBackupSchedule) error {
+ if m.err != nil {
+ return m.err
+ }
+ if vbs.Status.LastBackupTime != nil {
+ // simulate status update
+ vbs.Status.LastBackupTime = &metav1.Time{Time: vbs.Status.LastBackupTime.Add(1 * time.Hour)}
+ }
+ return nil
}
var _ fedvolumebackup.BackupScheduleManager = &FakeBackupScheduleManager{}
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
index a17926a269..c777a2b21d 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
@@ -1,51 +1,21 @@
package backupschedule
import (
+ "context"
"fmt"
+ "strconv"
+ "testing"
+ "time"
+
"github.com/google/go-cmp/cmp"
+ . "github.com/onsi/gomega"
+ "github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
"github.com/pingcap/tidb-operator/pkg/apis/label"
- "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
- "github.com/pingcap/tidb-operator/pkg/backup/constants"
"github.com/pingcap/tidb-operator/pkg/controller"
+ v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/utils/pointer"
- "strconv"
- "time"
-)
-
-// Copyright 2023 PingCAP, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package backupschedule
-
-import (
-"context"
-"fmt"
-"strconv"
-"testing"
-"time"
-
-"github.com/google/go-cmp/cmp"
-. "github.com/onsi/gomega"
-"github.com/pingcap/tidb-operator/pkg/apis/label"
-"github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
-"github.com/pingcap/tidb-operator/pkg/backup/constants"
-"github.com/pingcap/tidb-operator/pkg/controller"
-v1 "k8s.io/api/core/v1"
-metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-"k8s.io/apimachinery/pkg/labels"
-"k8s.io/utils/pointer"
)
func TestManager(t *testing.T) {
@@ -55,7 +25,7 @@ func TestManager(t *testing.T) {
deps := helper.deps
m := NewBackupScheduleManager(deps).(*backupScheduleManager)
var err error
- bs := &v1alpha1.BackupSchedule{}
+ bs := &v1alpha1.VolumeBackupSchedule{}
bs.Namespace = "ns"
bs.Name = "bsname"
@@ -74,11 +44,11 @@ func TestManager(t *testing.T) {
g.Expect(err).Should(BeNil())
// test backup complete
- bk := &v1alpha1.Backup{}
+ bk := &v1alpha1.VolumeBackup{}
bk.Namespace = bs.Namespace
bk.Name = bs.Status.LastBackup
- bk.Status.Conditions = append(bk.Status.Conditions, v1alpha1.BackupCondition{
- Type: v1alpha1.BackupComplete,
+ bk.Status.Conditions = append(bk.Status.Conditions, v1alpha1.VolumeBackupCondition{
+ Type: v1alpha1.VolumeBackupComplete,
Status: v1.ConditionTrue,
})
helper.createBackup(bk)
@@ -86,15 +56,15 @@ func TestManager(t *testing.T) {
g.Expect(err).Should(BeNil())
helper.deleteBackup(bk)
- // test last backup failed state and not scheduled yet
+ // test last backup failed state
bk.Status.Conditions = nil
- bk.Status.Conditions = append(bk.Status.Conditions, v1alpha1.BackupCondition{
- Type: v1alpha1.BackupFailed,
+ bk.Status.Conditions = append(bk.Status.Conditions, v1alpha1.VolumeBackupCondition{
+ Type: v1alpha1.VolumeBackupFailed,
Status: v1.ConditionTrue,
})
helper.createBackup(bk)
err = m.canPerformNextBackup(bs)
- g.Expect(err).Should(BeAssignableToTypeOf(&controller.RequeueError{}))
+ g.Expect(err).Should(BeNil())
helper.deleteBackup(bk)
t.Log("start test normal Sync")
@@ -108,22 +78,27 @@ func TestManager(t *testing.T) {
for i := -9; i <= 0; i++ {
t.Log("loop id ", i)
m.now = func() time.Time { return now.AddDate(0, 0, i) }
+ time.Sleep(1 * time.Second)
err = m.Sync(bs)
g.Expect(err).Should(BeNil())
- bks := helper.checkBacklist(bs.Namespace, i+10, false)
+ bks := helper.checkBacklist(bs.Namespace, i+10)
// complete the backup created
for i := range bks.Items {
- bk := bks.Items[i]
- changed := v1alpha1.UpdateBackupCondition(&bk.Status, &v1alpha1.BackupCondition{
- Type: v1alpha1.BackupComplete,
+ bk := bks.Items[i].DeepCopy()
+ changed := !v1alpha1.IsVolumeBackupComplete(bk)
+ v1alpha1.UpdateVolumeBackupCondition(&bk.Status, &v1alpha1.VolumeBackupCondition{
+ Type: v1alpha1.VolumeBackupComplete,
Status: v1.ConditionTrue,
})
+ //deps.Clientset.FederationV1alpha1().VolumeBackups(bk.Namespace).Update(context.TODO(), bk, metav1.UpdateOptions{})
+
if changed {
bk.CreationTimestamp = metav1.Time{Time: m.now()}
bk.Status.CommitTs = getTSOStr(m.now().Add(10 * time.Minute).Unix())
t.Log("complete backup: ", bk.Name)
- helper.updateBackup(&bk)
+ helper.updateBackup(bk)
}
+
g.Expect(err).Should(BeNil())
}
}
@@ -133,34 +108,22 @@ func TestManager(t *testing.T) {
bs.Spec.MaxBackups = pointer.Int32Ptr(5)
err = m.Sync(bs)
g.Expect(err).Should(BeNil())
- helper.checkBacklist(bs.Namespace, 5, false)
+ helper.checkBacklist(bs.Namespace, 5)
t.Log("test setting MaxReservedTime")
bs.Spec.MaxBackups = nil
bs.Spec.MaxReservedTime = pointer.StringPtr("71h")
err = m.Sync(bs)
g.Expect(err).Should(BeNil())
- helper.checkBacklist(bs.Namespace, 3, false)
-
- t.Log("test has log backup")
- bs.Spec.LogBackupTemplate = &v1alpha1.BackupSpec{Mode: v1alpha1.BackupModeLog}
- logBackup := buildLogBackup(bs, now.Add(-72*time.Hour))
- logBackup.Status.CommitTs = getTSOStr(now.Add(-72 * time.Hour).Unix())
- logBackup.Status.LogCheckpointTs = getTSOStr(now.Unix())
- helper.createBackup(logBackup)
- bs.Status.LogBackup = &logBackup.Name
- bs.Spec.MaxReservedTime = pointer.StringPtr("23h")
- err = m.Sync(bs)
- g.Expect(err).Should(BeNil())
- helper.checkBacklist(bs.Namespace, 2, true)
+ helper.checkBacklist(bs.Namespace, 3)
}
func TestGetLastScheduledTime(t *testing.T) {
g := NewGomegaWithT(t)
- bs := &v1alpha1.BackupSchedule{
- Spec: v1alpha1.BackupScheduleSpec{},
- Status: v1alpha1.BackupScheduleStatus{
+ bs := &v1alpha1.VolumeBackupSchedule{
+ Spec: v1alpha1.VolumeBackupScheduleSpec{},
+ Status: v1alpha1.VolumeBackupScheduleStatus{
LastBackupTime: &metav1.Time{},
},
}
@@ -200,12 +163,12 @@ func TestGetLastScheduledTime(t *testing.T) {
func TestBuildBackup(t *testing.T) {
now := time.Now()
- var get *v1alpha1.Backup
+ var get *v1alpha1.VolumeBackup
// build BackupSchedule template
- bs := &v1alpha1.BackupSchedule{
- Spec: v1alpha1.BackupScheduleSpec{},
- Status: v1alpha1.BackupScheduleStatus{
+ bs := &v1alpha1.VolumeBackupSchedule{
+ Spec: v1alpha1.VolumeBackupScheduleSpec{},
+ Status: v1alpha1.VolumeBackupScheduleStatus{
LastBackupTime: &metav1.Time{},
},
}
@@ -213,18 +176,16 @@ func TestBuildBackup(t *testing.T) {
bs.Name = "bsname"
// build Backup template
- bk := &v1alpha1.Backup{
+ bk := &v1alpha1.VolumeBackup{
ObjectMeta: metav1.ObjectMeta{
Namespace: bs.Namespace,
Name: bs.GetBackupCRDName(now),
Labels: label.NewBackupSchedule().Instance(bs.Name).BackupSchedule(bs.Name).Labels(),
OwnerReferences: []metav1.OwnerReference{
- controller.GetBackupScheduleOwnerRef(bs),
+ controller.GetFedVolumeBackupScheduleOwnerRef(bs),
},
},
- Spec: v1alpha1.BackupSpec{
- StorageSize: constants.DefaultStorageSize,
- },
+ Spec: v1alpha1.VolumeBackupSpec{},
}
// test BR == nil
@@ -232,32 +193,26 @@ func TestBuildBackup(t *testing.T) {
if diff := cmp.Diff(bk, get); diff != "" {
t.Errorf("unexpected (-want, +got): %s", diff)
}
- // should keep StorageSize from BackupSchedule
- bs.Spec.StorageSize = "9527G"
- bk.Spec.StorageSize = bs.Spec.StorageSize
get = buildBackup(bs, now)
if diff := cmp.Diff(bk, get); diff != "" {
t.Errorf("unexpected (-want, +got): %s", diff)
}
// test BR != nil
- bs.Spec.BackupTemplate.BR = &v1alpha1.BRConfig{}
- bk.Spec.BR = bs.Spec.BackupTemplate.BR.DeepCopy()
- bk.Spec.StorageSize = "" // no use for BR
+ bs.Spec.BackupTemplate.Template.BR = &v1alpha1.BRConfig{}
+ bk.Spec.Template.BR = bs.Spec.BackupTemplate.Template.BR.DeepCopy()
get = buildBackup(bs, now)
if diff := cmp.Diff(bk, get); diff != "" {
t.Errorf("unexpected (-want, +got): %s", diff)
}
}
-func TestCaculateExpiredBackupsWithLogBackup(t *testing.T) {
+func TestCalculateExpiredBackups(t *testing.T) {
g := NewGomegaWithT(t)
type testCase struct {
- backups []*v1alpha1.Backup
- logBackup *v1alpha1.Backup
+ backups []*v1alpha1.VolumeBackup
reservedTime time.Duration
expectedDeleteBackupCount int
- expectedTruncateTS uint64
}
var (
@@ -266,100 +221,45 @@ func TestCaculateExpiredBackupsWithLogBackup(t *testing.T) {
last1Day = now.Add(-time.Hour * 24 * 1).Unix()
last2Day = now.Add(-time.Hour * 24 * 2).Unix()
last3Day = now.Add(-time.Hour * 24 * 3).Unix()
- last4Day = now.Add(-time.Hour * 24 * 4).Unix()
)
testCases := []*testCase{
- // no backup should be deleted and log backup just start, no commit ts/checkpoint ts
+ // no backup should be deleted
{
- backups: []*v1alpha1.Backup{
+ backups: []*v1alpha1.VolumeBackup{
fakeBackup(&last10Min),
},
- logBackup: fakeLogBackup(nil, nil),
reservedTime: 24 * time.Hour,
expectedDeleteBackupCount: 0,
- expectedTruncateTS: 0,
},
- // backup should be delete and log backup just start, no commit ts/checkpoint ts
+ // 2 backup should be deleted
{
- backups: []*v1alpha1.Backup{
+ backups: []*v1alpha1.VolumeBackup{
fakeBackup(&last3Day),
fakeBackup(&last2Day),
fakeBackup(&last1Day),
fakeBackup(&last10Min),
},
- logBackup: fakeLogBackup(&last10Min, nil),
- reservedTime: 24 * time.Hour,
- expectedDeleteBackupCount: 1,
- expectedTruncateTS: 0,
- },
- // no backup should be deleted, has log backup
- {
- backups: []*v1alpha1.Backup{
- fakeBackup(&last3Day),
- fakeBackup(&last1Day),
- },
- logBackup: fakeLogBackup(&last4Day, &last10Min),
- reservedTime: 24 * time.Hour,
- expectedDeleteBackupCount: 0,
- expectedTruncateTS: 0,
- },
- // 1 backup should be deleted, no log backup should be truncated
- {
- backups: []*v1alpha1.Backup{
- fakeBackup(&last3Day),
- fakeBackup(&last2Day),
- fakeBackup(&last1Day),
- },
- logBackup: fakeLogBackup(&last1Day, &last10Min),
- reservedTime: 24 * time.Hour,
- expectedDeleteBackupCount: 1,
- expectedTruncateTS: 0,
- },
- // 2 backup should be deleted, no log backup should be truncated
- {
- backups: []*v1alpha1.Backup{
- fakeBackup(&last4Day),
- fakeBackup(&last3Day),
- fakeBackup(&last2Day),
- fakeBackup(&last1Day),
- },
- logBackup: fakeLogBackup(&last1Day, &last10Min),
reservedTime: 24 * time.Hour,
expectedDeleteBackupCount: 2,
- expectedTruncateTS: 0,
- },
- // 2 backup should be deleted, has log backup should be truncated
- {
- backups: []*v1alpha1.Backup{
- fakeBackup(&last4Day),
- fakeBackup(&last3Day),
- fakeBackup(&last2Day),
- fakeBackup(&last1Day),
- },
- logBackup: fakeLogBackup(&last3Day, &last10Min),
- reservedTime: 24 * time.Hour,
- expectedDeleteBackupCount: 2,
- expectedTruncateTS: getTSO(last2Day),
},
}
for _, tc := range testCases {
- deletedBackups, truncateTS, err := calExpiredBackupsAndLogBackup(tc.backups, tc.logBackup, tc.reservedTime)
+ deletedBackups, err := calculateExpiredBackups(tc.backups, tc.reservedTime)
g.Expect(err).Should(BeNil())
g.Expect(len(deletedBackups)).Should(Equal(tc.expectedDeleteBackupCount))
- g.Expect(truncateTS).Should(Equal(tc.expectedTruncateTS))
}
}
type helper struct {
t *testing.T
- deps *controller.Dependencies
+ deps *controller.BrFedDependencies
stop chan struct{}
}
func newHelper(t *testing.T) *helper {
- deps := controller.NewSimpleClientDependencies()
+ deps := controller.NewSimpleFedClientDependencies()
stop := make(chan struct{})
deps.InformerFactory.Start(stop)
deps.KubeInformerFactory.Start(stop)
@@ -378,13 +278,13 @@ func (h *helper) close() {
}
// check for exists num Backup and return the exists backups "BackupList".
-func (h *helper) checkBacklist(ns string, num int, checkLogBackupTruncate bool) (bks *v1alpha1.BackupList) {
+func (h *helper) checkBacklist(ns string, num int) (bks *v1alpha1.VolumeBackupList) {
t := h.t
deps := h.deps
g := NewGomegaWithT(t)
- check := func(backups []*v1alpha1.Backup) error {
- snapshotBackups, logBackup := separateSnapshotBackupsAndLogBackup(backups)
+ check := func(backups []*v1alpha1.VolumeBackup) error {
+ snapshotBackups := sortSnapshotBackups(backups)
// check snapshot backup num
if len(snapshotBackups) != num {
var names []string
@@ -393,27 +293,17 @@ func (h *helper) checkBacklist(ns string, num int, checkLogBackupTruncate bool)
}
return fmt.Errorf("there %d backup, but should be %d, cur backups: %v", len(snapshotBackups), num, names)
}
- if !checkLogBackupTruncate {
- return nil
- }
- // check has log backup
- if logBackup == nil {
- return fmt.Errorf("there is no log backup, but should have")
- }
// check truncateTSO, it should equal the earliest snapshot backup after gc
if len(snapshotBackups) == 0 {
return fmt.Errorf("there should have snapshot backup if need check log backup truncate tso")
}
- if logBackup.Status.LogSuccessTruncateUntil != snapshotBackups[0].Spec.CommitTs {
- return fmt.Errorf("log backup truncate tso should be %s, but cur is %s", snapshotBackups[0].Spec.CommitTs, logBackup.Status.LogSuccessTruncateUntil)
- }
return nil
}
t.Helper()
g.Eventually(func() error {
var err error
- bks, err = deps.Clientset.PingcapV1alpha1().Backups(ns).List(context.TODO(), metav1.ListOptions{})
+ bks, err = deps.Clientset.FederationV1alpha1().VolumeBackups(ns).List(context.TODO(), metav1.ListOptions{})
g.Expect(err).Should(BeNil())
backups := convertToBackupPtrList(bks.Items)
return check(backups)
@@ -421,7 +311,7 @@ func (h *helper) checkBacklist(ns string, num int, checkLogBackupTruncate bool)
g.Eventually(func() error {
var err error
- backups, err := deps.BackupLister.Backups(ns).List(labels.Everything())
+ backups, err := deps.VolumeBackupLister.VolumeBackups(ns).List(labels.Everything())
g.Expect(err).Should(BeNil())
return check(backups)
}, time.Second*30).Should(BeNil())
@@ -429,62 +319,62 @@ func (h *helper) checkBacklist(ns string, num int, checkLogBackupTruncate bool)
return
}
-func convertToBackupPtrList(backups []v1alpha1.Backup) []*v1alpha1.Backup {
- backupPtrs := make([]*v1alpha1.Backup, 0)
+func convertToBackupPtrList(backups []v1alpha1.VolumeBackup) []*v1alpha1.VolumeBackup {
+ backupPtrs := make([]*v1alpha1.VolumeBackup, 0)
for i := 0; i < len(backups); i++ {
backupPtrs = append(backupPtrs, &backups[i])
}
return backupPtrs
}
-func (h *helper) updateBackup(bk *v1alpha1.Backup) {
+func (h *helper) createBackup(bk *v1alpha1.VolumeBackup) {
t := h.t
deps := h.deps
g := NewGomegaWithT(t)
- _, err := deps.Clientset.PingcapV1alpha1().Backups(bk.Namespace).Update(context.TODO(), bk, metav1.UpdateOptions{})
+ _, err := deps.Clientset.FederationV1alpha1().VolumeBackups(bk.Namespace).Create(context.TODO(), bk, metav1.CreateOptions{})
g.Expect(err).Should(BeNil())
-
g.Eventually(func() error {
- get, err := deps.BackupLister.Backups(bk.Namespace).Get(bk.Name)
- if err != nil {
- return err
- }
-
- diff := cmp.Diff(get, bk)
- if diff == "" {
- return nil
- }
-
- return fmt.Errorf("not synced yet: %s", diff)
+ _, err := deps.VolumeBackupLister.VolumeBackups(bk.Namespace).Get(bk.Name)
+ return err
}, time.Second*10).Should(BeNil())
}
-func (h *helper) createBackup(bk *v1alpha1.Backup) {
+func (h *helper) deleteBackup(bk *v1alpha1.VolumeBackup) {
t := h.t
deps := h.deps
g := NewGomegaWithT(t)
- _, err := deps.Clientset.PingcapV1alpha1().Backups(bk.Namespace).Create(context.TODO(), bk, metav1.CreateOptions{})
+ err := deps.Clientset.FederationV1alpha1().VolumeBackups(bk.Namespace).Delete(context.TODO(), bk.Name, metav1.DeleteOptions{})
g.Expect(err).Should(BeNil())
g.Eventually(func() error {
- _, err := deps.BackupLister.Backups(bk.Namespace).Get(bk.Name)
+ _, err := deps.VolumeBackupLister.VolumeBackups(bk.Namespace).Get(bk.Name)
return err
- }, time.Second*10).Should(BeNil())
+ }, time.Second*10).ShouldNot(BeNil())
}
-func (h *helper) deleteBackup(bk *v1alpha1.Backup) {
+func (h *helper) updateBackup(bk *v1alpha1.VolumeBackup) {
t := h.t
deps := h.deps
g := NewGomegaWithT(t)
- err := deps.Clientset.PingcapV1alpha1().Backups(bk.Namespace).Delete(context.TODO(), bk.Name, metav1.DeleteOptions{})
+ _, err := deps.Clientset.FederationV1alpha1().VolumeBackups(bk.Namespace).Update(context.TODO(), bk, metav1.UpdateOptions{})
g.Expect(err).Should(BeNil())
+
g.Eventually(func() error {
- _, err := deps.BackupLister.Backups(bk.Namespace).Get(bk.Name)
- return err
- }, time.Second*10).ShouldNot(BeNil())
+ get, err := deps.VolumeBackupLister.VolumeBackups(bk.Namespace).Get(bk.Name)
+ if err != nil {
+ return err
+ }
+
+ diff := cmp.Diff(get, bk)
+ if diff == "" {
+ return nil
+ }
+
+ return fmt.Errorf("not synced yet: %s", diff)
+ }, time.Second*10).Should(BeNil())
}
-func fakeBackup(ts *int64) *v1alpha1.Backup {
- backup := &v1alpha1.Backup{}
+func fakeBackup(ts *int64) *v1alpha1.VolumeBackup {
+ backup := &v1alpha1.VolumeBackup{}
if ts == nil {
return backup
}
@@ -492,19 +382,6 @@ func fakeBackup(ts *int64) *v1alpha1.Backup {
return backup
}
-func fakeLogBackup(startTS, checkPointTS *int64) *v1alpha1.Backup {
- logBackup := &v1alpha1.Backup{}
- if startTS == nil {
- return logBackup
- }
- logBackup.Status.CommitTs = getTSOStr(*startTS)
- if checkPointTS == nil {
- return logBackup
- }
- logBackup.Status.LogCheckpointTs = getTSOStr(*checkPointTS)
- return logBackup
-}
-
func getTSOStr(ts int64) string {
tso := getTSO(ts)
return strconv.FormatUint(tso, 10)
@@ -513,4 +390,3 @@ func getTSOStr(ts int64) string {
func getTSO(ts int64) uint64 {
return uint64((ts << 18) * 1000)
}
-
From e7617763edecf95f9a99f8bc3061eae21882a764 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Tue, 13 Jun 2023 21:52:18 +0800
Subject: [PATCH 05/20] *: fix license header format
Signed-off-by: BornChanger
---
.../backupschedule/backup_schedule_manager_test.go | 2 +-
.../fed_volume_backup_schedule_control_test.go | 5 +++--
.../backupschedule/backup_schedule_manager_test.go | 13 +++++++++++++
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/pkg/backup/backupschedule/backup_schedule_manager_test.go b/pkg/backup/backupschedule/backup_schedule_manager_test.go
index 97a80153e7..baa8d8c33e 100644
--- a/pkg/backup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/backup/backupschedule/backup_schedule_manager_test.go
@@ -1,4 +1,4 @@
-// Copyright 2020 PingCAP, Inc.
+// Copyright 2023 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
index 5c6bf541c5..eb58ae0ed7 100644
--- a/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
+++ b/pkg/controller/fedvolumebackupschedule/fed_volume_backup_schedule_control_test.go
@@ -1,15 +1,16 @@
-// Copyright 2019 PingCAP, Inc.
+// Copyright 2023 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
+
package fedvolumebackupschedule
import (
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
index c777a2b21d..7e72a8b56a 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
@@ -1,3 +1,16 @@
+// Copyright 2023 PingCAP, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
package backupschedule
import (
From ef1c6ecf2f456f2e0100808fcc28498c89b5706c Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Wed, 14 Jun 2023 11:27:24 +0800
Subject: [PATCH 06/20] *: clean case
Signed-off-by: BornChanger
---
.../backupschedule/backup_schedule_manager_test.go | 2 --
1 file changed, 2 deletions(-)
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
index 7e72a8b56a..a2d888773b 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
@@ -91,7 +91,6 @@ func TestManager(t *testing.T) {
for i := -9; i <= 0; i++ {
t.Log("loop id ", i)
m.now = func() time.Time { return now.AddDate(0, 0, i) }
- time.Sleep(1 * time.Second)
err = m.Sync(bs)
g.Expect(err).Should(BeNil())
bks := helper.checkBacklist(bs.Namespace, i+10)
@@ -103,7 +102,6 @@ func TestManager(t *testing.T) {
Type: v1alpha1.VolumeBackupComplete,
Status: v1.ConditionTrue,
})
- //deps.Clientset.FederationV1alpha1().VolumeBackups(bk.Namespace).Update(context.TODO(), bk, metav1.UpdateOptions{})
if changed {
bk.CreationTimestamp = metav1.Time{Time: m.now()}
From 53e36a6a9dc2a573243f88999a69afdc9137c58b Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Fri, 16 Jun 2023 00:39:16 +0800
Subject: [PATCH 07/20] *: add resilence code
Signed-off-by: BornChanger
---
pkg/apis/federation/pingcap/v1alpha1/types.go | 7 +++-
.../backupschedule/backup_schedule_manager.go | 35 ++++++++++++++++++-
2 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/pkg/apis/federation/pingcap/v1alpha1/types.go b/pkg/apis/federation/pingcap/v1alpha1/types.go
index b70bbcad1e..8c394463ae 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/types.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/types.go
@@ -95,7 +95,8 @@ type VolumeBackupMemberSpec struct {
// +optional
Env []corev1.EnvVar `json:"env,omitempty"`
// BRConfig is the configs for BR
- BR *BRConfig `json:"br,omitempty"`
+ BR *BRConfig `json:"br,omitempty"`
+ // StorageProvider configures where and how backups should be stored.
pingcapv1alpha1.StorageProvider `json:",inline"`
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
// ToolImage specifies the tool image used in `Backup`, which supports BR.
@@ -117,6 +118,10 @@ type VolumeBackupMemberSpec struct {
// BRConfig contains config for BR
// +k8s:openapi-gen=true
type BRConfig struct {
+ // ClusterName of backup/restore cluster
+ Cluster string `json:"cluster"`
+ // Namespace of backup/restore cluster
+ ClusterNamespace string `json:"clusterNamespace,omitempty"`
// Concurrency is the size of thread pool on each node that execute the backup task
Concurrency *uint32 `json:"concurrency,omitempty"`
// CheckRequirements specifies whether to check requirements
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index 7170e8ea03..355048fba2 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -15,7 +15,9 @@ package backupschedule
import (
"fmt"
+ "path"
"sort"
+ "strings"
"time"
perrors "github.com/pingcap/errors"
@@ -28,6 +30,7 @@ import (
"k8s.io/klog/v2"
"github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
+ nonfebv1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
"github.com/pingcap/tidb-operator/pkg/controller"
"github.com/pingcap/tidb-operator/pkg/fedvolumebackup"
)
@@ -63,7 +66,6 @@ func (bm *backupScheduleManager) Sync(vbs *v1alpha1.VolumeBackupSchedule) error
return err
}
- // TODO: do we need to delete last backup job also?
backup, err := createBackup(bm.deps.FedVolumeBackupControl, vbs, *scheduledTime)
if err != nil {
return err
@@ -149,6 +151,31 @@ func buildBackup(vbs *v1alpha1.VolumeBackupSchedule, timestamp time.Time) *v1alp
backupSpec := *vbs.Spec.BackupTemplate.DeepCopy()
bsLabel := util.CombineStringMap(label.NewBackupSchedule().Instance(bsName).BackupSchedule(bsName), vbs.Labels)
+
+ if backupSpec.Template.BR == nil {
+ klog.Errorf("Information on BR missing in template")
+ return nil
+ }
+
+ var pdAddress, clusterNamespace string
+ if backupSpec.Template.BR.ClusterNamespace == "" {
+ clusterNamespace = ns
+ } else {
+ clusterNamespace = backupSpec.Template.BR.ClusterNamespace
+ }
+ pdAddress = fmt.Sprintf("%s-pd.%s:%d", backupSpec.Template.BR.Cluster, clusterNamespace, nonfebv1alpha1.DefaultPDClientPort)
+
+ backupPrefix := strings.ReplaceAll(pdAddress, ":", "-") + "-" + timestamp.UTC().Format(nonfebv1alpha1.BackupNameTimeFormat)
+ if backupSpec.Template.S3 != nil {
+ backupSpec.Template.S3.Prefix = path.Join(backupSpec.Template.S3.Prefix, backupPrefix)
+ } else {
+ klog.Errorf("Information on S3 missing in template")
+ return nil
+ }
+
+ if vbs.Spec.BackupTemplate.Template.ImagePullSecrets != nil {
+ backupSpec.Template.ImagePullSecrets = vbs.Spec.BackupTemplate.Template.ImagePullSecrets
+ }
backup := &v1alpha1.VolumeBackup{
Spec: backupSpec,
ObjectMeta: metav1.ObjectMeta{
@@ -162,11 +189,17 @@ func buildBackup(vbs *v1alpha1.VolumeBackupSchedule, timestamp time.Time) *v1alp
},
}
+ klog.V(4).Infof("created backup is [%v], at time %v", backup, timestamp)
+
return backup
}
func createBackup(bkController controller.FedVolumeBackupControlInterface, vbs *v1alpha1.VolumeBackupSchedule, timestamp time.Time) (*v1alpha1.VolumeBackup, error) {
bk := buildBackup(vbs, timestamp)
+ if bk == nil {
+ return nil, controller.IgnoreErrorf("Invalid backup template for volume backup schedule [%s], BR or S3 information missing", vbs.GetName())
+ }
+
return bkController.CreateVolumeBackup(bk)
}
From 8b7c46cb7d473349782e7da7dfa9c5a4f999ed49 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Fri, 16 Jun 2023 21:53:21 +0800
Subject: [PATCH 08/20] *: polish code
Signed-off-by: BornChanger
---
docs/api-references/federation-docs.md | 1 +
pkg/apis/federation/pingcap/v1alpha1/types.go | 10 ++--------
.../v1alpha1/fake/fake_volumebackupschedule.go | 12 ++++++++++++
.../pingcap/v1alpha1/volumebackupschedule.go | 17 +++++++++++++++++
.../backupschedule/backup_schedule_manager.go | 12 +-----------
5 files changed, 33 insertions(+), 19 deletions(-)
diff --git a/docs/api-references/federation-docs.md b/docs/api-references/federation-docs.md
index 9e44ef8df9..15154e1a5f 100644
--- a/docs/api-references/federation-docs.md
+++ b/docs/api-references/federation-docs.md
@@ -619,6 +619,7 @@ github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1.StorageProvider
(Members of StorageProvider
are embedded into this type.)
+StorageProvider configures where and how backups should be stored.
diff --git a/pkg/apis/federation/pingcap/v1alpha1/types.go b/pkg/apis/federation/pingcap/v1alpha1/types.go
index 8c394463ae..6b449df856 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/types.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/types.go
@@ -118,10 +118,6 @@ type VolumeBackupMemberSpec struct {
// BRConfig contains config for BR
// +k8s:openapi-gen=true
type BRConfig struct {
- // ClusterName of backup/restore cluster
- Cluster string `json:"cluster"`
- // Namespace of backup/restore cluster
- ClusterNamespace string `json:"clusterNamespace,omitempty"`
// Concurrency is the size of thread pool on each node that execute the backup task
Concurrency *uint32 `json:"concurrency,omitempty"`
// CheckRequirements specifies whether to check requirements
@@ -210,7 +206,6 @@ const (
//
// +k8s:openapi-gen=true
// +kubebuilder:resource:shortName="vbks"
-// +genclient:noStatus
// +kubebuilder:printcolumn:name="Schedule",type=string,JSONPath=`.spec.schedule`,description="The cron format string used for backup scheduling"
// +kubebuilder:printcolumn:name="MaxBackups",type=integer,JSONPath=`.spec.maxBackups`,description="The max number of backups we want to keep"
// +kubebuilder:printcolumn:name="MaxReservedTime",type=string,JSONPath=`.spec.maxReservedTime`,description="How long backups we want to keep"
@@ -223,23 +218,22 @@ type VolumeBackupSchedule struct {
metav1.ObjectMeta `json:"metadata"`
Spec VolumeBackupScheduleSpec `json:"spec"`
-
// +k8s:openapi-gen=false
Status VolumeBackupScheduleStatus `json:"status,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
-// VolumeBackupScheduleList is VolumeBackupSchedule list
// +k8s:openapi-gen=true
+// VolumeBackupScheduleList is VolumeBackupSchedule list
type VolumeBackupScheduleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []VolumeBackupSchedule `json:"items"`
}
-// VolumeBackupScheduleSpec describes the attributes that a user creates on a volume backup schedule.
// +k8s:openapi-gen=true
+// VolumeBackupScheduleSpec describes the attributes that a user creates on a volume backup schedule.
type VolumeBackupScheduleSpec struct {
// Schedule specifies the cron string used for backup scheduling.
Schedule string `json:"schedule"`
diff --git a/pkg/client/federation/clientset/versioned/typed/pingcap/v1alpha1/fake/fake_volumebackupschedule.go b/pkg/client/federation/clientset/versioned/typed/pingcap/v1alpha1/fake/fake_volumebackupschedule.go
index 7431f7f560..f02aa0f12b 100644
--- a/pkg/client/federation/clientset/versioned/typed/pingcap/v1alpha1/fake/fake_volumebackupschedule.go
+++ b/pkg/client/federation/clientset/versioned/typed/pingcap/v1alpha1/fake/fake_volumebackupschedule.go
@@ -99,6 +99,18 @@ func (c *FakeVolumeBackupSchedules) Update(ctx context.Context, volumeBackupSche
return obj.(*v1alpha1.VolumeBackupSchedule), err
}
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+func (c *FakeVolumeBackupSchedules) UpdateStatus(ctx context.Context, volumeBackupSchedule *v1alpha1.VolumeBackupSchedule, opts v1.UpdateOptions) (*v1alpha1.VolumeBackupSchedule, error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateSubresourceAction(volumebackupschedulesResource, "status", c.ns, volumeBackupSchedule), &v1alpha1.VolumeBackupSchedule{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*v1alpha1.VolumeBackupSchedule), err
+}
+
// Delete takes name of the volumeBackupSchedule and deletes it. Returns an error if one occurs.
func (c *FakeVolumeBackupSchedules) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
diff --git a/pkg/client/federation/clientset/versioned/typed/pingcap/v1alpha1/volumebackupschedule.go b/pkg/client/federation/clientset/versioned/typed/pingcap/v1alpha1/volumebackupschedule.go
index 4c7d85845c..ca701242a5 100644
--- a/pkg/client/federation/clientset/versioned/typed/pingcap/v1alpha1/volumebackupschedule.go
+++ b/pkg/client/federation/clientset/versioned/typed/pingcap/v1alpha1/volumebackupschedule.go
@@ -37,6 +37,7 @@ type VolumeBackupSchedulesGetter interface {
type VolumeBackupScheduleInterface interface {
Create(ctx context.Context, volumeBackupSchedule *v1alpha1.VolumeBackupSchedule, opts v1.CreateOptions) (*v1alpha1.VolumeBackupSchedule, error)
Update(ctx context.Context, volumeBackupSchedule *v1alpha1.VolumeBackupSchedule, opts v1.UpdateOptions) (*v1alpha1.VolumeBackupSchedule, error)
+ UpdateStatus(ctx context.Context, volumeBackupSchedule *v1alpha1.VolumeBackupSchedule, opts v1.UpdateOptions) (*v1alpha1.VolumeBackupSchedule, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.VolumeBackupSchedule, error)
@@ -132,6 +133,22 @@ func (c *volumeBackupSchedules) Update(ctx context.Context, volumeBackupSchedule
return
}
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+func (c *volumeBackupSchedules) UpdateStatus(ctx context.Context, volumeBackupSchedule *v1alpha1.VolumeBackupSchedule, opts v1.UpdateOptions) (result *v1alpha1.VolumeBackupSchedule, err error) {
+ result = &v1alpha1.VolumeBackupSchedule{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("volumebackupschedules").
+ Name(volumeBackupSchedule.Name).
+ SubResource("status").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(volumeBackupSchedule).
+ Do(ctx).
+ Into(result)
+ return
+}
+
// Delete takes name of the volumeBackupSchedule and deletes it. Returns an error if one occurs.
func (c *volumeBackupSchedules) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index 355048fba2..dc7544a122 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -17,7 +17,6 @@ import (
"fmt"
"path"
"sort"
- "strings"
"time"
perrors "github.com/pingcap/errors"
@@ -157,17 +156,8 @@ func buildBackup(vbs *v1alpha1.VolumeBackupSchedule, timestamp time.Time) *v1alp
return nil
}
- var pdAddress, clusterNamespace string
- if backupSpec.Template.BR.ClusterNamespace == "" {
- clusterNamespace = ns
- } else {
- clusterNamespace = backupSpec.Template.BR.ClusterNamespace
- }
- pdAddress = fmt.Sprintf("%s-pd.%s:%d", backupSpec.Template.BR.Cluster, clusterNamespace, nonfebv1alpha1.DefaultPDClientPort)
-
- backupPrefix := strings.ReplaceAll(pdAddress, ":", "-") + "-" + timestamp.UTC().Format(nonfebv1alpha1.BackupNameTimeFormat)
if backupSpec.Template.S3 != nil {
- backupSpec.Template.S3.Prefix = path.Join(backupSpec.Template.S3.Prefix, backupPrefix)
+ backupSpec.Template.S3.Prefix = path.Join(backupSpec.Template.S3.Prefix, "-"+timestamp.UTC().Format(nonfebv1alpha1.BackupNameTimeFormat))
} else {
klog.Errorf("Information on S3 missing in template")
return nil
From 7244a4fb5f221afc6cdc6047ba198b4a5d808503 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Tue, 20 Jun 2023 15:51:25 +0800
Subject: [PATCH 09/20] *: Only GC complete or failed vbk
Signed-off-by: BornChanger
---
pkg/controller/controller_utils.go | 4 ++--
.../backupschedule/backup_schedule_manager.go | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/pkg/controller/controller_utils.go b/pkg/controller/controller_utils.go
index 615e101216..b708343732 100644
--- a/pkg/controller/controller_utils.go
+++ b/pkg/controller/controller_utils.go
@@ -191,8 +191,8 @@ func GetFedVolumeBackupScheduleOwnerRef(vbks *fedv1alpha1.VolumeBackupSchedule)
controller := true
blockOwnerDeletion := true
return metav1.OwnerReference{
- APIVersion: backupScheduleControllerKind.GroupVersion().String(),
- Kind: backupScheduleControllerKind.Kind,
+ APIVersion: FedVolumeBackupScheduleControllerKind.GroupVersion().String(),
+ Kind: FedVolumeBackupScheduleControllerKind.Kind,
Name: vbks.GetName(),
UID: vbks.GetUID(),
Controller: &controller,
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index dc7544a122..efae9f5ffc 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -254,7 +254,7 @@ func (bm *backupScheduleManager) backupGCByMaxReservedTime(vbs *v1alpha1.VolumeB
expiredBackups, err = calculateExpiredBackups(ascBackups, reservedTime)
if err != nil {
- klog.Errorf("caculate expired backups without log backup, err: %s", err)
+ klog.Errorf("calculate expired backups without log backup, err: %s", err)
return
}
@@ -278,8 +278,8 @@ func sortSnapshotBackups(backupsList []*v1alpha1.VolumeBackup) []*v1alpha1.Volum
var ascBackupList = make([]*v1alpha1.VolumeBackup, 0)
for _, backup := range backupsList {
- // the backup status CommitTs will be empty after created. without this, all newly created backups will be GC'ed
- if v1alpha1.IsVolumeBackupRunning(backup) {
+ // Only try to GC Completed or Failed VolumeBackup
+ if !(v1alpha1.IsVolumeBackupFailed(backup) || v1alpha1.IsVolumeBackupComplete(backup)) {
continue
}
ascBackupList = append(ascBackupList, backup)
From 626f6316099f021401ec0e6e3792b1e4411e6d00 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Tue, 20 Jun 2023 20:12:32 +0800
Subject: [PATCH 10/20] *: fix ut cases
Signed-off-by: BornChanger
---
.../backupschedule/backup_schedule_manager.go | 15 ++++++++++++++
.../backup_schedule_manager_test.go | 20 +++++++++----------
2 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index efae9f5ffc..903f5276ed 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -291,6 +291,21 @@ func sortSnapshotBackups(backupsList []*v1alpha1.VolumeBackup) []*v1alpha1.Volum
return ascBackupList
}
+// sortAllSnapshotBackups return all snapshot backups order by create time asc
+// it's for test only now
+func sortAllSnapshotBackups(backupsList []*v1alpha1.VolumeBackup) []*v1alpha1.VolumeBackup {
+ var ascBackupList = make([]*v1alpha1.VolumeBackup, 0)
+
+ for _, backup := range backupsList {
+ ascBackupList = append(ascBackupList, backup)
+ }
+
+ sort.Slice(ascBackupList, func(i, j int) bool {
+ return ascBackupList[i].CreationTimestamp.Unix() < ascBackupList[j].CreationTimestamp.Unix()
+ })
+ return ascBackupList
+}
+
func calculateExpiredBackups(backupsList []*v1alpha1.VolumeBackup, reservedTime time.Duration) ([]*v1alpha1.VolumeBackup, error) {
expiredTS := config.TSToTSO(time.Now().Add(-1 * reservedTime).Unix())
i := 0
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
index a2d888773b..3e26b38d86 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
@@ -16,6 +16,7 @@ package backupschedule
import (
"context"
"fmt"
+ old_v1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
"strconv"
"testing"
"time"
@@ -41,6 +42,8 @@ func TestManager(t *testing.T) {
bs := &v1alpha1.VolumeBackupSchedule{}
bs.Namespace = "ns"
bs.Name = "bsname"
+ bs.Spec.BackupTemplate.Template.BR = &v1alpha1.BRConfig{}
+ bs.Spec.BackupTemplate.Template.S3 = &old_v1alpha1.S3StorageProvider{}
// test pause
bs.Spec.Pause = true
@@ -199,20 +202,15 @@ func TestBuildBackup(t *testing.T) {
Spec: v1alpha1.VolumeBackupSpec{},
}
- // test BR == nil
- get = buildBackup(bs, now)
- if diff := cmp.Diff(bk, get); diff != "" {
- t.Errorf("unexpected (-want, +got): %s", diff)
- }
- get = buildBackup(bs, now)
- if diff := cmp.Diff(bk, get); diff != "" {
- t.Errorf("unexpected (-want, +got): %s", diff)
- }
-
// test BR != nil
bs.Spec.BackupTemplate.Template.BR = &v1alpha1.BRConfig{}
+ bs.Spec.BackupTemplate.Template.S3 = &old_v1alpha1.S3StorageProvider{}
+
bk.Spec.Template.BR = bs.Spec.BackupTemplate.Template.BR.DeepCopy()
+ bk.Spec.Template.S3 = bs.Spec.BackupTemplate.Template.S3.DeepCopy()
get = buildBackup(bs, now)
+ // have to reset the dynamic prefix
+ bk.Spec.Template.S3.Prefix = get.Spec.Template.S3.Prefix
if diff := cmp.Diff(bk, get); diff != "" {
t.Errorf("unexpected (-want, +got): %s", diff)
}
@@ -295,7 +293,7 @@ func (h *helper) checkBacklist(ns string, num int) (bks *v1alpha1.VolumeBackupLi
g := NewGomegaWithT(t)
check := func(backups []*v1alpha1.VolumeBackup) error {
- snapshotBackups := sortSnapshotBackups(backups)
+ snapshotBackups := sortAllSnapshotBackups(backups)
// check snapshot backup num
if len(snapshotBackups) != num {
var names []string
From 3a31dfa1b03f7dd6b57960222a0e866c7911baac Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Wed, 21 Jun 2023 10:23:59 +0800
Subject: [PATCH 11/20] *: fix compiler warning
Signed-off-by: BornChanger
---
.../backupschedule/backup_schedule_manager.go | 5 +----
.../backupschedule/backup_schedule_manager_test.go | 6 +++---
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index 903f5276ed..f0a89e3e4a 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -295,10 +295,7 @@ func sortSnapshotBackups(backupsList []*v1alpha1.VolumeBackup) []*v1alpha1.Volum
// it's for test only now
func sortAllSnapshotBackups(backupsList []*v1alpha1.VolumeBackup) []*v1alpha1.VolumeBackup {
var ascBackupList = make([]*v1alpha1.VolumeBackup, 0)
-
- for _, backup := range backupsList {
- ascBackupList = append(ascBackupList, backup)
- }
+ ascBackupList = append(ascBackupList, backupsList...)
sort.Slice(ascBackupList, func(i, j int) bool {
return ascBackupList[i].CreationTimestamp.Unix() < ascBackupList[j].CreationTimestamp.Unix()
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
index 3e26b38d86..43fd0e5102 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
@@ -16,7 +16,7 @@ package backupschedule
import (
"context"
"fmt"
- old_v1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
+ oldv1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
"strconv"
"testing"
"time"
@@ -43,7 +43,7 @@ func TestManager(t *testing.T) {
bs.Namespace = "ns"
bs.Name = "bsname"
bs.Spec.BackupTemplate.Template.BR = &v1alpha1.BRConfig{}
- bs.Spec.BackupTemplate.Template.S3 = &old_v1alpha1.S3StorageProvider{}
+ bs.Spec.BackupTemplate.Template.S3 = &oldv1alpha1.S3StorageProvider{}
// test pause
bs.Spec.Pause = true
@@ -204,7 +204,7 @@ func TestBuildBackup(t *testing.T) {
// test BR != nil
bs.Spec.BackupTemplate.Template.BR = &v1alpha1.BRConfig{}
- bs.Spec.BackupTemplate.Template.S3 = &old_v1alpha1.S3StorageProvider{}
+ bs.Spec.BackupTemplate.Template.S3 = &oldv1alpha1.S3StorageProvider{}
bk.Spec.Template.BR = bs.Spec.BackupTemplate.Template.BR.DeepCopy()
bk.Spec.Template.S3 = bs.Spec.BackupTemplate.Template.S3.DeepCopy()
From 85f39c2477ad24e0498f1d6da544dff3b90c8edf Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Wed, 21 Jun 2023 11:45:17 +0800
Subject: [PATCH 12/20] *: code format
Signed-off-by: BornChanger
---
go.mod | 16 ++++++++--------
go.sum | 16 ++++++++++++++++
.../backup_schedule_manager_test.go | 6 +++---
3 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/go.mod b/go.mod
index 163fd262d7..b099ea6712 100644
--- a/go.mod
+++ b/go.mod
@@ -52,7 +52,7 @@ require (
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489
go.uber.org/atomic v1.9.0
gocloud.dev v0.18.0
- golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
+ golang.org/x/sync v0.3.0
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
gomodules.xyz/jsonpatch/v2 v2.1.0
google.golang.org/grpc v1.27.1
@@ -182,15 +182,15 @@ require (
go.opencensus.io v0.22.3 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.23.0 // indirect
- golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect
+ golang.org/x/crypto v0.10.0 // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
- golang.org/x/net v0.7.0 // indirect
+ golang.org/x/mod v0.11.0 // indirect
+ golang.org/x/net v0.11.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
- golang.org/x/sys v0.5.0 // indirect
- golang.org/x/term v0.5.0 // indirect
- golang.org/x/text v0.7.0 // indirect
- golang.org/x/tools v0.1.12 // indirect
+ golang.org/x/sys v0.9.0 // indirect
+ golang.org/x/term v0.9.0 // indirect
+ golang.org/x/text v0.10.0 // indirect
+ golang.org/x/tools v0.10.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/api v0.20.0 // indirect
google.golang.org/appengine v1.6.6 // indirect
diff --git a/go.sum b/go.sum
index cf5e45fd1e..013516cd6e 100644
--- a/go.sum
+++ b/go.sum
@@ -856,6 +856,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
+golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -895,6 +897,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
+golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -936,6 +940,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
+golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -954,6 +960,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1019,11 +1027,15 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
+golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1034,6 +1046,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1090,6 +1104,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
+golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
index 43fd0e5102..cc72247e46 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
@@ -16,7 +16,7 @@ package backupschedule
import (
"context"
"fmt"
- oldv1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
+ pingcapv1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
"strconv"
"testing"
"time"
@@ -43,7 +43,7 @@ func TestManager(t *testing.T) {
bs.Namespace = "ns"
bs.Name = "bsname"
bs.Spec.BackupTemplate.Template.BR = &v1alpha1.BRConfig{}
- bs.Spec.BackupTemplate.Template.S3 = &oldv1alpha1.S3StorageProvider{}
+ bs.Spec.BackupTemplate.Template.S3 = &pingcapv1alpha1.S3StorageProvider{}
// test pause
bs.Spec.Pause = true
@@ -204,7 +204,7 @@ func TestBuildBackup(t *testing.T) {
// test BR != nil
bs.Spec.BackupTemplate.Template.BR = &v1alpha1.BRConfig{}
- bs.Spec.BackupTemplate.Template.S3 = &oldv1alpha1.S3StorageProvider{}
+ bs.Spec.BackupTemplate.Template.S3 = &pingcapv1alpha1.S3StorageProvider{}
bk.Spec.Template.BR = bs.Spec.BackupTemplate.Template.BR.DeepCopy()
bk.Spec.Template.S3 = bs.Spec.BackupTemplate.Template.S3.DeepCopy()
From 6f89595d1d86fda9800be2bc50327f64579f6091 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Wed, 21 Jun 2023 11:52:29 +0800
Subject: [PATCH 13/20] *: code format
Signed-off-by: BornChanger
---
go.sum | 16 ----------------
.../backup_schedule_manager_test.go | 3 ++-
2 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/go.sum b/go.sum
index 013516cd6e..49bda560f6 100644
--- a/go.sum
+++ b/go.sum
@@ -854,8 +854,6 @@ golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU=
-golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -895,8 +893,6 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -938,8 +934,6 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -958,8 +952,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1025,15 +1017,11 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1044,8 +1032,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1102,8 +1088,6 @@ golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
index cc72247e46..6ab06eb1b5 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager_test.go
@@ -16,11 +16,12 @@ package backupschedule
import (
"context"
"fmt"
- pingcapv1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
"strconv"
"testing"
"time"
+ pingcapv1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
+
"github.com/google/go-cmp/cmp"
. "github.com/onsi/gomega"
"github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
From d880516f4dd15374cd652527d3fdf45d0abd3374 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Wed, 21 Jun 2023 12:15:59 +0800
Subject: [PATCH 14/20] *: prompt library version
Signed-off-by: BornChanger
---
pkg/apis/go.mod | 4 ++--
pkg/apis/go.sum | 10 +++++-----
pkg/client/go.mod | 10 +++++-----
pkg/client/go.sum | 6 ++++++
.../backupschedule/backup_schedule_manager.go | 4 ++--
5 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/pkg/apis/go.mod b/pkg/apis/go.mod
index 0b99e5de45..adb38f2823 100644
--- a/pkg/apis/go.mod
+++ b/pkg/apis/go.mod
@@ -38,8 +38,8 @@ require (
github.com/mailru/easyjson v0.7.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
- golang.org/x/net v0.7.0 // indirect
- golang.org/x/text v0.7.0 // indirect
+ golang.org/x/net v0.11.0 // indirect
+ golang.org/x/text v0.10.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/pkg/apis/go.sum b/pkg/apis/go.sum
index fa709c5aed..fa219a1670 100644
--- a/pkg/apis/go.sum
+++ b/pkg/apis/go.sum
@@ -480,8 +480,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
+golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -538,7 +538,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -548,8 +548,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/pkg/client/go.mod b/pkg/client/go.mod
index 4c6a7e25ba..67a62dbc63 100644
--- a/pkg/client/go.mod
+++ b/pkg/client/go.mod
@@ -38,12 +38,12 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/prometheus v1.8.2 // indirect
- golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect
- golang.org/x/net v0.7.0 // indirect
+ golang.org/x/crypto v0.10.0 // indirect
+ golang.org/x/net v0.11.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
- golang.org/x/sys v0.5.0 // indirect
- golang.org/x/term v0.5.0 // indirect
- golang.org/x/text v0.7.0 // indirect
+ golang.org/x/sys v0.9.0 // indirect
+ golang.org/x/term v0.9.0 // indirect
+ golang.org/x/text v0.10.0 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/protobuf v1.26.0-rc.1 // indirect
diff --git a/pkg/client/go.sum b/pkg/client/go.sum
index 3e8bb0940e..0398572d36 100644
--- a/pkg/client/go.sum
+++ b/pkg/client/go.sum
@@ -420,6 +420,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
+golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -484,6 +486,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -541,10 +544,12 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -554,6 +559,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index f0a89e3e4a..7f2c8f6417 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -29,7 +29,7 @@ import (
"k8s.io/klog/v2"
"github.com/pingcap/tidb-operator/pkg/apis/federation/pingcap/v1alpha1"
- nonfebv1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
+ pingcapv1alpha1 "github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
"github.com/pingcap/tidb-operator/pkg/controller"
"github.com/pingcap/tidb-operator/pkg/fedvolumebackup"
)
@@ -157,7 +157,7 @@ func buildBackup(vbs *v1alpha1.VolumeBackupSchedule, timestamp time.Time) *v1alp
}
if backupSpec.Template.S3 != nil {
- backupSpec.Template.S3.Prefix = path.Join(backupSpec.Template.S3.Prefix, "-"+timestamp.UTC().Format(nonfebv1alpha1.BackupNameTimeFormat))
+ backupSpec.Template.S3.Prefix = path.Join(backupSpec.Template.S3.Prefix, "-"+timestamp.UTC().Format(pingcapv1alpha1.BackupNameTimeFormat))
} else {
klog.Errorf("Information on S3 missing in template")
return nil
From 67486dfd82c020efdb5df90217c997fa6cabf0c8 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Wed, 21 Jun 2023 19:23:20 +0800
Subject: [PATCH 15/20] *: revert unnecessary go.mod change
Signed-off-by: BornChanger
---
go.mod | 6 +++---
go.sum | 12 ++++++------
pkg/apis/go.mod | 4 ++--
pkg/apis/go.sum | 10 +++++-----
pkg/client/go.mod | 10 +++++-----
pkg/client/go.sum | 6 ------
6 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/go.mod b/go.mod
index b099ea6712..dde1afaa24 100644
--- a/go.mod
+++ b/go.mod
@@ -52,7 +52,7 @@ require (
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489
go.uber.org/atomic v1.9.0
gocloud.dev v0.18.0
- golang.org/x/sync v0.3.0
+ golang.org/x/sync v0.1.0
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
gomodules.xyz/jsonpatch/v2 v2.1.0
google.golang.org/grpc v1.27.1
@@ -184,13 +184,13 @@ require (
go.uber.org/zap v1.23.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
- golang.org/x/mod v0.11.0 // indirect
+ golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.11.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/term v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
- golang.org/x/tools v0.10.0 // indirect
+ golang.org/x/tools v0.6.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/api v0.20.0 // indirect
google.golang.org/appengine v1.6.6 // indirect
diff --git a/go.sum b/go.sum
index 49bda560f6..ebf260f663 100644
--- a/go.sum
+++ b/go.sum
@@ -893,8 +893,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
-golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -952,8 +952,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
-golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1088,8 +1088,8 @@ golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
-golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/pkg/apis/go.mod b/pkg/apis/go.mod
index adb38f2823..0b99e5de45 100644
--- a/pkg/apis/go.mod
+++ b/pkg/apis/go.mod
@@ -38,8 +38,8 @@ require (
github.com/mailru/easyjson v0.7.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
- golang.org/x/net v0.11.0 // indirect
- golang.org/x/text v0.10.0 // indirect
+ golang.org/x/net v0.7.0 // indirect
+ golang.org/x/text v0.7.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/pkg/apis/go.sum b/pkg/apis/go.sum
index fa219a1670..fa709c5aed 100644
--- a/pkg/apis/go.sum
+++ b/pkg/apis/go.sum
@@ -480,8 +480,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
-golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -538,7 +538,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -548,8 +548,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/pkg/client/go.mod b/pkg/client/go.mod
index 67a62dbc63..4c6a7e25ba 100644
--- a/pkg/client/go.mod
+++ b/pkg/client/go.mod
@@ -38,12 +38,12 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/prometheus v1.8.2 // indirect
- golang.org/x/crypto v0.10.0 // indirect
- golang.org/x/net v0.11.0 // indirect
+ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect
+ golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
- golang.org/x/sys v0.9.0 // indirect
- golang.org/x/term v0.9.0 // indirect
- golang.org/x/text v0.10.0 // indirect
+ golang.org/x/sys v0.5.0 // indirect
+ golang.org/x/term v0.5.0 // indirect
+ golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/protobuf v1.26.0-rc.1 // indirect
diff --git a/pkg/client/go.sum b/pkg/client/go.sum
index 0398572d36..3e8bb0940e 100644
--- a/pkg/client/go.sum
+++ b/pkg/client/go.sum
@@ -420,8 +420,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -486,7 +484,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -544,12 +541,10 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -559,7 +554,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
From a56706fb1636fe11ad1e7e11fd9a4f61a695231f Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Sat, 24 Jun 2023 22:12:00 +0800
Subject: [PATCH 16/20] *: fix go mod
Signed-off-by: BornChanger
---
go.mod | 2 +-
go.sum | 4 ++--
pkg/apis/go.mod | 4 ++--
pkg/client/go.mod | 10 +++++-----
pkg/client/go.sum | 20 ++++++++++----------
5 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/go.mod b/go.mod
index dde1afaa24..299d0d8786 100644
--- a/go.mod
+++ b/go.mod
@@ -185,7 +185,7 @@ require (
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/mod v0.8.0 // indirect
- golang.org/x/net v0.11.0 // indirect
+ golang.org/x/net v0.10.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/term v0.9.0 // indirect
diff --git a/go.sum b/go.sum
index ebf260f663..c33b168868 100644
--- a/go.sum
+++ b/go.sum
@@ -934,8 +934,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
-golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
diff --git a/pkg/apis/go.mod b/pkg/apis/go.mod
index 0b99e5de45..9e78094e9c 100644
--- a/pkg/apis/go.mod
+++ b/pkg/apis/go.mod
@@ -38,8 +38,8 @@ require (
github.com/mailru/easyjson v0.7.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
- golang.org/x/net v0.7.0 // indirect
- golang.org/x/text v0.7.0 // indirect
+ golang.org/x/net v0.10.0 // indirect
+ golang.org/x/text v0.10.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/pkg/client/go.mod b/pkg/client/go.mod
index 4c6a7e25ba..5806523650 100644
--- a/pkg/client/go.mod
+++ b/pkg/client/go.mod
@@ -38,12 +38,12 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/prometheus v1.8.2 // indirect
- golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect
- golang.org/x/net v0.7.0 // indirect
+ golang.org/x/crypto v0.10.0 // indirect
+ golang.org/x/net v0.10.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
- golang.org/x/sys v0.5.0 // indirect
- golang.org/x/term v0.5.0 // indirect
- golang.org/x/text v0.7.0 // indirect
+ golang.org/x/sys v0.9.0 // indirect
+ golang.org/x/term v0.9.0 // indirect
+ golang.org/x/text v0.10.0 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/protobuf v1.26.0-rc.1 // indirect
diff --git a/pkg/client/go.sum b/pkg/client/go.sum
index 3e8bb0940e..e6d7d7a1db 100644
--- a/pkg/client/go.sum
+++ b/pkg/client/go.sum
@@ -418,8 +418,8 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU=
-golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
+golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -482,8 +482,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -539,12 +539,12 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
+golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -552,8 +552,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
From 1e4d9f2045612863a4b68682989e2003ed79724c Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Sun, 25 Jun 2023 13:20:04 +0800
Subject: [PATCH 17/20] *: fix lint error
Signed-off-by: BornChanger
---
pkg/apis/go.sum | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/pkg/apis/go.sum b/pkg/apis/go.sum
index fa709c5aed..4403b31638 100644
--- a/pkg/apis/go.sum
+++ b/pkg/apis/go.sum
@@ -480,8 +480,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -538,7 +538,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -548,8 +548,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
From 39d2802b013f0790eda6a8ac12d5bcd8f225b9d2 Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Sun, 25 Jun 2023 17:05:18 +0800
Subject: [PATCH 18/20] *: address review comments
Signed-off-by: BornChanger
---
pkg/apis/federation/pingcap/v1alpha1/types.go | 2 -
pkg/backup/restore/restore_manager.go | 2 +-
.../backup_schedule_control_test.go | 56 +++++++++----------
.../fed_backup_schedule_status_updater.go | 2 +-
.../backupschedule/backup_schedule_manager.go | 15 ++---
5 files changed, 33 insertions(+), 44 deletions(-)
diff --git a/pkg/apis/federation/pingcap/v1alpha1/types.go b/pkg/apis/federation/pingcap/v1alpha1/types.go
index 6b449df856..62ce1bc95c 100644
--- a/pkg/apis/federation/pingcap/v1alpha1/types.go
+++ b/pkg/apis/federation/pingcap/v1alpha1/types.go
@@ -195,8 +195,6 @@ const (
VolumeBackupFailed VolumeBackupConditionType = "Failed"
// VolumeBackupCleaned means all the resources about VolumeBackup have cleaned
VolumeBackupCleaned VolumeBackupConditionType = "Cleaned"
- // VolumeBackupCleanFailed means the VolumeBackup cleanup is failed
- VolumeBackupCleanFailed VolumeBackupConditionType = "CleanFailed"
)
// +genclient
diff --git a/pkg/backup/restore/restore_manager.go b/pkg/backup/restore/restore_manager.go
index 1fedbabbff..e43f0a17c8 100644
--- a/pkg/backup/restore/restore_manager.go
+++ b/pkg/backup/restore/restore_manager.go
@@ -231,7 +231,7 @@ func (rm *restoreManager) syncRestoreJob(restore *v1alpha1.Restore) error {
}
// read cluster meta from external storage since k8s size limitation on annotation/configMap
-// after volume retore job complete, br output a meta file for controller to reconfig the tikvs
+// after volume restore job complete, br output a meta file for controller to reconfig the tikvs
// since the meta file may big, so we use remote storage as bridge to pass it from restore manager to controller
func (rm *restoreManager) readRestoreMetaFromExternalStorage(r *v1alpha1.Restore) (*snapshotter.CloudSnapBackup, string, error) {
// since the restore meta is small (~5M), assume 1 minutes is enough
diff --git a/pkg/controller/backupschedule/backup_schedule_control_test.go b/pkg/controller/backupschedule/backup_schedule_control_test.go
index 4d50ee814f..720c04faf2 100644
--- a/pkg/controller/backupschedule/backup_schedule_control_test.go
+++ b/pkg/controller/backupschedule/backup_schedule_control_test.go
@@ -61,38 +61,36 @@ func TestBackupScheduleControlUpdateBackupSchedule(t *testing.T) {
}
}
tests := []testcase{
- /*
- {
- name: "backup schedule sync error",
- update: nil,
- syncBsManagerErr: true,
- updateStatusErr: false,
- errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).To(HaveOccurred())
- g.Expect(strings.Contains(err.Error(), "backup schedule sync error")).To(Equal(true))
- },
+ {
+ name: "backup schedule sync error",
+ update: nil,
+ syncBsManagerErr: true,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).To(HaveOccurred())
+ g.Expect(strings.Contains(err.Error(), "backup schedule sync error")).To(Equal(true))
},
- {
- name: "backup schedule status is not updated",
- update: nil,
- syncBsManagerErr: false,
- updateStatusErr: false,
- errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).NotTo(HaveOccurred())
- },
+ },
+ {
+ name: "backup schedule status is not updated",
+ update: nil,
+ syncBsManagerErr: false,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).NotTo(HaveOccurred())
},
- {
- name: "normal",
- update: func(bs *v1alpha1.BackupSchedule) {
- bs.Status.LastBackupTime = &metav1.Time{Time: time.Now()}
- },
- syncBsManagerErr: false,
- updateStatusErr: false,
- errExpectFn: func(g *GomegaWithT, err error) {
- g.Expect(err).NotTo(HaveOccurred())
- },
+ },
+ {
+ name: "normal",
+ update: func(bs *v1alpha1.BackupSchedule) {
+ bs.Status.LastBackupTime = &metav1.Time{Time: time.Now()}
},
- */
+ syncBsManagerErr: false,
+ updateStatusErr: false,
+ errExpectFn: func(g *GomegaWithT, err error) {
+ g.Expect(err).NotTo(HaveOccurred())
+ },
+ },
{
name: "backup schedule status update failed",
update: func(bs *v1alpha1.BackupSchedule) {
diff --git a/pkg/controller/fed_backup_schedule_status_updater.go b/pkg/controller/fed_backup_schedule_status_updater.go
index 88613eb5b1..2277930a7a 100644
--- a/pkg/controller/fed_backup_schedule_status_updater.go
+++ b/pkg/controller/fed_backup_schedule_status_updater.go
@@ -58,7 +58,7 @@ func (u *realVolumeBackupScheduleStatusUpdater) UpdateBackupScheduleStatus(
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
_, updateErr := u.deps.Clientset.FederationV1alpha1().VolumeBackupSchedules(ns).Update(context.TODO(), bs, metav1.UpdateOptions{})
if updateErr == nil {
- klog.Infof("BackupSchedule: [%s/%s] updated successfully", ns, bsName)
+ klog.Infof("VolumeBackupSchedule: [%s/%s] updated successfully", ns, bsName)
return nil
}
if updated, err := u.deps.VolumeBackupScheduleLister.VolumeBackupSchedules(ns).Get(bsName); err == nil {
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index 7f2c8f6417..ea2b2a127e 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -345,10 +345,11 @@ func (bm *backupScheduleManager) backupGCByMaxBackups(vbs *v1alpha1.VolumeBackup
return
}
- sort.Sort(byCreateTimeDesc(backupsList))
+ //sort.Sort(byCreateTimeDesc(backupsList))
+ ascBackups := sortSnapshotBackups(backupsList)
var deleteCount int
- for i, backup := range backupsList {
+ for i, backup := range ascBackups {
if i < int(*vbs.Spec.MaxBackups) {
continue
}
@@ -361,7 +362,7 @@ func (bm *backupScheduleManager) backupGCByMaxBackups(vbs *v1alpha1.VolumeBackup
klog.Infof("backup schedule %s/%s gc backup %s success", ns, bsName, backup.GetName())
}
- if deleteCount == len(backupsList) && deleteCount > 0 {
+ if deleteCount == len(ascBackups) && deleteCount > 0 {
// All backups have been deleted, so the last backup information in the backupSchedule should be reset
bm.resetLastBackup(vbs)
}
@@ -373,14 +374,6 @@ func (bm *backupScheduleManager) resetLastBackup(vbs *v1alpha1.VolumeBackupSched
vbs.Status.AllBackupCleanTime = &metav1.Time{Time: bm.now()}
}
-type byCreateTimeDesc []*v1alpha1.VolumeBackup
-
-func (b byCreateTimeDesc) Len() int { return len(b) }
-func (b byCreateTimeDesc) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
-func (b byCreateTimeDesc) Less(i, j int) bool {
- return b[j].ObjectMeta.CreationTimestamp.Before(&b[i].ObjectMeta.CreationTimestamp)
-}
-
var _ fedvolumebackup.BackupScheduleManager = &backupScheduleManager{}
type FakeBackupScheduleManager struct {
From d9c892f2222b5c2b7044c1ff4256862ec57bf7bc Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Sun, 25 Jun 2023 17:11:58 +0800
Subject: [PATCH 19/20] *: revert go.mod
Signed-off-by: BornChanger
---
go.mod | 16 ++++++++--------
go.sum | 32 ++++++++++++++++----------------
pkg/apis/go.mod | 4 ++--
pkg/apis/go.sum | 10 +++++-----
pkg/client/go.mod | 10 +++++-----
pkg/client/go.sum | 20 ++++++++++----------
6 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/go.mod b/go.mod
index 299d0d8786..163fd262d7 100644
--- a/go.mod
+++ b/go.mod
@@ -52,7 +52,7 @@ require (
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489
go.uber.org/atomic v1.9.0
gocloud.dev v0.18.0
- golang.org/x/sync v0.1.0
+ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
gomodules.xyz/jsonpatch/v2 v2.1.0
google.golang.org/grpc v1.27.1
@@ -182,15 +182,15 @@ require (
go.opencensus.io v0.22.3 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.23.0 // indirect
- golang.org/x/crypto v0.10.0 // indirect
+ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
- golang.org/x/mod v0.8.0 // indirect
- golang.org/x/net v0.10.0 // indirect
+ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
+ golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
- golang.org/x/sys v0.9.0 // indirect
- golang.org/x/term v0.9.0 // indirect
- golang.org/x/text v0.10.0 // indirect
- golang.org/x/tools v0.6.0 // indirect
+ golang.org/x/sys v0.5.0 // indirect
+ golang.org/x/term v0.5.0 // indirect
+ golang.org/x/text v0.7.0 // indirect
+ golang.org/x/tools v0.1.12 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/api v0.20.0 // indirect
google.golang.org/appengine v1.6.6 // indirect
diff --git a/go.sum b/go.sum
index c33b168868..cf5e45fd1e 100644
--- a/go.sum
+++ b/go.sum
@@ -854,8 +854,8 @@ golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
+golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU=
+golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -893,8 +893,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -934,8 +934,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -952,8 +952,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1017,13 +1017,13 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210925032602-92d5a993a665/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210916214954-140adaaadfaf/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
-golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
+golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1032,8 +1032,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1088,8 +1088,8 @@ golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/pkg/apis/go.mod b/pkg/apis/go.mod
index 9e78094e9c..0b99e5de45 100644
--- a/pkg/apis/go.mod
+++ b/pkg/apis/go.mod
@@ -38,8 +38,8 @@ require (
github.com/mailru/easyjson v0.7.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
- golang.org/x/net v0.10.0 // indirect
- golang.org/x/text v0.10.0 // indirect
+ golang.org/x/net v0.7.0 // indirect
+ golang.org/x/text v0.7.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/pkg/apis/go.sum b/pkg/apis/go.sum
index 4403b31638..fa709c5aed 100644
--- a/pkg/apis/go.sum
+++ b/pkg/apis/go.sum
@@ -480,8 +480,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -538,7 +538,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -548,8 +548,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/pkg/client/go.mod b/pkg/client/go.mod
index 5806523650..4c6a7e25ba 100644
--- a/pkg/client/go.mod
+++ b/pkg/client/go.mod
@@ -38,12 +38,12 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/prometheus v1.8.2 // indirect
- golang.org/x/crypto v0.10.0 // indirect
- golang.org/x/net v0.10.0 // indirect
+ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect
+ golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
- golang.org/x/sys v0.9.0 // indirect
- golang.org/x/term v0.9.0 // indirect
- golang.org/x/text v0.10.0 // indirect
+ golang.org/x/sys v0.5.0 // indirect
+ golang.org/x/term v0.5.0 // indirect
+ golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/protobuf v1.26.0-rc.1 // indirect
diff --git a/pkg/client/go.sum b/pkg/client/go.sum
index e6d7d7a1db..3e8bb0940e 100644
--- a/pkg/client/go.sum
+++ b/pkg/client/go.sum
@@ -418,8 +418,8 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
+golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b h1:Qwe1rC8PSniVfAFPFJeyUkB+zcysC3RgJBAGk7eqBEU=
+golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -482,8 +482,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -539,12 +539,12 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
-golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
+golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -552,8 +552,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
From 9d9d12ef9603f535ab7eaebee920c9ca9fd4baab Mon Sep 17 00:00:00 2001
From: BornChanger
Date: Sun, 25 Jun 2023 19:29:27 +0800
Subject: [PATCH 20/20] *: fix unit test case
Signed-off-by: BornChanger
---
.../backupschedule/backup_schedule_manager.go | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
index ea2b2a127e..618097a175 100644
--- a/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
+++ b/pkg/fedvolumebackup/backupschedule/backup_schedule_manager.go
@@ -345,11 +345,9 @@ func (bm *backupScheduleManager) backupGCByMaxBackups(vbs *v1alpha1.VolumeBackup
return
}
- //sort.Sort(byCreateTimeDesc(backupsList))
- ascBackups := sortSnapshotBackups(backupsList)
-
+ sort.Sort(byCreateTimeDesc(backupsList))
var deleteCount int
- for i, backup := range ascBackups {
+ for i, backup := range backupsList {
if i < int(*vbs.Spec.MaxBackups) {
continue
}
@@ -362,7 +360,7 @@ func (bm *backupScheduleManager) backupGCByMaxBackups(vbs *v1alpha1.VolumeBackup
klog.Infof("backup schedule %s/%s gc backup %s success", ns, bsName, backup.GetName())
}
- if deleteCount == len(ascBackups) && deleteCount > 0 {
+ if deleteCount == len(backupsList) && deleteCount > 0 {
// All backups have been deleted, so the last backup information in the backupSchedule should be reset
bm.resetLastBackup(vbs)
}
@@ -374,6 +372,14 @@ func (bm *backupScheduleManager) resetLastBackup(vbs *v1alpha1.VolumeBackupSched
vbs.Status.AllBackupCleanTime = &metav1.Time{Time: bm.now()}
}
+type byCreateTimeDesc []*v1alpha1.VolumeBackup
+
+func (b byCreateTimeDesc) Len() int { return len(b) }
+func (b byCreateTimeDesc) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
+func (b byCreateTimeDesc) Less(i, j int) bool {
+ return b[j].ObjectMeta.CreationTimestamp.Before(&b[i].ObjectMeta.CreationTimestamp)
+}
+
var _ fedvolumebackup.BackupScheduleManager = &backupScheduleManager{}
type FakeBackupScheduleManager struct {