Skip to content

Commit 35aea8d

Browse files
MerceaOtnielAMecea
authored andcommitted
Add a function to delete backups logic
1 parent d4df7de commit 35aea8d

File tree

7 files changed

+99
-8
lines changed

7 files changed

+99
-8
lines changed

deploy/mysqlclusters.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ spec:
2525
description: Specify under crontab format interval to take backups leave
2626
it empty to deactivate the backup process Defaults to ""
2727
type: string
28+
backupScheduleJobsHistoryLimit:
29+
description: If set keeps last BackupScheduleJobsHistoryLimit Backups
30+
format: int32
31+
type: integer
2832
backupSecretName:
2933
type: string
3034
backupUri:

examples/example-cluster.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ kind: MysqlCluster
33
metadata:
44
name: foo
55
spec:
6-
replicas: 3
6+
replicas: 1
77
secretName: the-secret
88
# mysqlVersion: 5.7
99
# initBucketUri: gs://bucket_name/backup.xtrabackup.gz
@@ -16,6 +16,8 @@ spec:
1616
# backupSchedule:
1717
# backupUri: s3://bucket_name/
1818
# backupSecretName:
19+
# backupScheduleJobsHistoryLimit:
20+
1921

2022
## Configs that will be added to my.cnf for cluster
2123
# mysqlConf:

pkg/apis/mysql/v1alpha1/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ type ClusterSpec struct {
8282
BackupUri string `json:"backupUri,omitempty"`
8383
BackupSecretName string `json:"backupSecretName,omitempty"`
8484

85+
// If set keeps last BackupScheduleJobsHistoryLimit Backups
86+
// +optional
87+
BackupScheduleJobsHistoryLimit *int `json:"backupScheduleJobsHistoryLimit"`
88+
8589
// A map[string]string that will be passed to my.cnf file.
8690
// +optional
8791
MysqlConf MysqlConf `json:"mysqlConf,omitempty"`

pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
111111
**out = **in
112112
}
113113
}
114+
if in.BackupScheduleJobsHistoryLimit != nil {
115+
in, out := &in.BackupScheduleJobsHistoryLimit, &out.BackupScheduleJobsHistoryLimit
116+
if *in == nil {
117+
*out = nil
118+
} else {
119+
*out = new(int)
120+
**out = **in
121+
}
122+
}
114123
if in.MysqlConf != nil {
115124
in, out := &in.MysqlConf, &out.MysqlConf
116125
*out = make(MysqlConf, len(*in))

pkg/controller/clustercontroller/backups.go

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ type job struct {
4848

4949
lock *sync.Mutex
5050
myClient myclientset.Interface
51+
52+
BackupScheduleJobsHistoryLimit *int
5153
}
5254

5355
func (c *Controller) registerClusterInBackupCron(cluster *api.MysqlCluster) error {
@@ -86,17 +88,23 @@ func (c *Controller) registerClusterInBackupCron(cluster *api.MysqlCluster) erro
8688
myClient: c.myClient,
8789
BackupRunning: new(bool),
8890
lock: new(sync.Mutex),
91+
BackupScheduleJobsHistoryLimit: cluster.Spec.BackupScheduleJobsHistoryLimit,
8992
}, cluster.Name)
9093

9194
return nil
9295
}
9396

9497
func (j job) Run() {
9598
backupName := fmt.Sprintf("%s-auto-backup-%s", j.Name, time.Now().Format("2006-01-02t15-04-05"))
96-
glog.Infof("Schedul backup job started. Creating backup %s..", backupName)
99+
glog.Infof("Scheduled backup job started for %s/%s ", j.Namespace, backupName)
100+
101+
if j.BackupScheduleJobsHistoryLimit != nil {
102+
defer j.backupGC()
103+
}
97104

98105
// Wrap backup creation to ensure that lock is released when backup is
99106
// created
107+
100108
created := func() bool {
101109
j.lock.Lock()
102110
defer j.lock.Unlock()
@@ -121,7 +129,6 @@ func (j job) Run() {
121129
ClusterName: j.Name,
122130
},
123131
})
124-
125132
if err == nil {
126133
break
127134
}
@@ -140,7 +147,6 @@ func (j job) Run() {
140147
*j.BackupRunning = true
141148
return true
142149
}()
143-
144150
if !created {
145151
return
146152
}
@@ -170,3 +176,39 @@ func (j job) Run() {
170176
backupName, j.Name, err)
171177
}
172178
}
179+
180+
func (j *job) backupGC() {
181+
182+
var err error
183+
184+
backups, err := j.myClient.Mysql().MysqlBackups(j.Namespace).List(metav1.ListOptions{
185+
LabelSelector: fmt.Sprintf("recurrent=true"),
186+
})
187+
188+
var clusterBackups []api.MysqlBackup
189+
190+
for i := 0; i < len(backups.Items); i++ {
191+
if backups.Items[i].Spec.ClusterName == j.Name {
192+
clusterBackups = append(clusterBackups, backups.Items[i])
193+
}
194+
}
195+
196+
if err != nil {
197+
glog.Infof("Failed to obtain backup list for %s/%s, error:%s", j.Namespace, j.Name, err)
198+
return
199+
}
200+
var size = len(clusterBackups)
201+
202+
if size > *j.BackupScheduleJobsHistoryLimit {
203+
for i := 0; i < size-(*j.BackupScheduleJobsHistoryLimit); i++ {
204+
205+
err := j.myClient.Mysql().MysqlBackups(j.Namespace).Delete(clusterBackups[i].Name, &(metav1.DeleteOptions{}))
206+
207+
if err != nil {
208+
glog.Warningf("Failed to remove backup %s/%s", clusterBackups[i].Name, err)
209+
}
210+
}
211+
clusterBackups = clusterBackups[(size - (*j.BackupScheduleJobsHistoryLimit)):]
212+
}
213+
214+
}

pkg/controller/clustercontroller/backups_test.go

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
/*
22
Copyright 2018 Pressinfra SRL
3-
43
Licensed under the Apache License, Version 2.0 (the "License");
54
you may not use this file except in compliance with the License.
65
You may obtain a copy of the License at
7-
86
http://www.apache.org/licenses/LICENSE-2.0
9-
107
Unless required by applicable law or agreed to in writing, software
118
distributed under the License is distributed on an "AS IS" BASIS,
129
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -56,6 +53,8 @@ var _ = Describe("Test cluster reconciliation queue", func() {
5653
controller = newController(stop, client, myClient, rec)
5754
backupPollingTime = 10 * time.Millisecond
5855
backupWatchTimeout = time.Second
56+
two := 2
57+
cluster.Spec.BackupScheduleJobsHistoryLimit = &two
5958

6059
})
6160

@@ -67,6 +66,7 @@ var _ = Describe("Test cluster reconciliation queue", func() {
6766
Context("cluster with schedule backups", func() {
6867
It("try to register multiple times", func() {
6968
cluster.Spec.BackupSchedule = "0 * * * *"
69+
7070
_, err := myClient.MysqlV1alpha1().MysqlClusters(tutil.Namespace).Create(cluster)
7171
Expect(err).To(Succeed())
7272

@@ -113,15 +113,16 @@ var _ = Describe("Test cluster reconciliation queue", func() {
113113
myClient: myClient,
114114
BackupRunning: new(bool),
115115
lock: new(sync.Mutex),
116+
BackupScheduleJobsHistoryLimit: cluster.Spec.BackupScheduleJobsHistoryLimit,
116117
}
117118

118119
go j.Run()
119-
120120
Eventually(func() bool {
121121
j.lock.Lock() // avoid a data race
122122
defer j.lock.Unlock()
123123
return *j.BackupRunning
124124
}).Should(Equal(true))
125+
125126
Eventually(func() []api.MysqlBackup {
126127
bs, _ := myClient.Mysql().MysqlBackups(j.Namespace).List(metav1.ListOptions{})
127128
return bs.Items
@@ -139,6 +140,28 @@ var _ = Describe("Test cluster reconciliation queue", func() {
139140
return *j.BackupRunning
140141
}).Should(Equal(false))
141142
})
143+
144+
It("start jobs to schedule backups", func() {
145+
146+
j := job{
147+
Name: cluster.Name,
148+
Namespace: cluster.Namespace,
149+
myClient: myClient,
150+
BackupRunning: new(bool),
151+
lock: new(sync.Mutex),
152+
BackupScheduleJobsHistoryLimit: cluster.Spec.BackupScheduleJobsHistoryLimit,
153+
}
154+
155+
for i := 0; i < *(j.BackupScheduleJobsHistoryLimit)+1; i++ {
156+
j.Run()
157+
}
158+
159+
Eventually(func() []api.MysqlBackup {
160+
bs, _ := myClient.Mysql().MysqlBackups(j.Namespace).List(metav1.ListOptions{})
161+
return bs.Items
162+
}).Should(HaveLen(*j.BackupScheduleJobsHistoryLimit))
163+
164+
})
142165
})
143166
})
144167
})

pkg/openapi/openapi_generated.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,13 @@ func schema_pkg_apis_mysql_v1alpha1_ClusterSpec(ref common.ReferenceCallback) co
317317
Format: "",
318318
},
319319
},
320+
"backupScheduleJobsHistoryLimit": {
321+
SchemaProps: spec.SchemaProps{
322+
Description: "If set keeps last BackupScheduleJobsHistoryLimit Backups",
323+
Type: []string{"integer"},
324+
Format: "int32",
325+
},
326+
},
320327
"mysqlConf": {
321328
SchemaProps: spec.SchemaProps{
322329
Description: "A map[string]string that will be passed to my.cnf file.",

0 commit comments

Comments
 (0)