Skip to content

Commit e9bee97

Browse files
authored
[Feature] Add Backup Retries Until (#1873)
1 parent f326dc8 commit e9bee97

18 files changed

+449
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- (Feature) (Platform) Docs and Installer improvements
1313
- (Feature) Promote RestartPolicy Always Feature
1414
- (Maintenance) Update Dependencies
15+
- (Feature) Backup Retry Until and BackupPolicy Until Propagation feature
1516

1617
## [1.2.47](https://github.com/arangodb/kube-arangodb/tree/1.2.47) (2025-03-28)
1718
- (Bugfix) Use Profile Annotations

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ Flags:
164164
--deployment.feature.all Enable ALL Features
165165
--deployment.feature.async-backup-creation Create backups asynchronously to avoid blocking the operator and reaching the timeout - Required ArangoDB >= 3.8.0 (default true)
166166
--deployment.feature.backup-cleanup Cleanup imported backups if required - Required ArangoDB >= 3.8.0
167+
--deployment.feature.backup-policy-until-propagation Sets Until field in the Backup based on next schedule time - Required ArangoDB >= 3.8.0 (default true)
167168
--deployment.feature.deployment-spec-defaults-restore Restore defaults from last accepted state of deployment - Required ArangoDB >= 3.8.0 (default true)
168169
--deployment.feature.enforced-resign-leadership Enforce ResignLeadership and ensure that Leaders are moved from restarted DBServer - Required ArangoDB >= 3.8.0 (default true)
169170
--deployment.feature.ephemeral-volumes Enables ephemeral volumes for apps and tmp directory - Required ArangoDB >= 3.8.0

docs/api/ArangoBackup.V1.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,45 @@ title: ArangoBackup V1
1010

1111
### .spec.backoff.iterations
1212

13-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L31)</sup>
13+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L38)</sup>
1414

1515
Iterations defines number of iterations before reaching MaxDelay. Default to 5
1616

17+
Default Value: `5`
18+
1719
***
1820

1921
### .spec.backoff.max_delay
2022

21-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L29)</sup>
23+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L35)</sup>
2224

2325
MaxDelay defines maximum delay in seconds. Default to 600
2426

27+
Default Value: `600`
28+
2529
***
2630

2731
### .spec.backoff.max_iterations
2832

29-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L33)</sup>
33+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L40)</sup>
3034

3135
MaxIterations defines maximum number of iterations after backoff will be disabled. Default to nil (no limit)
3236

3337
***
3438

3539
### .spec.backoff.min_delay
3640

37-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L27)</sup>
41+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L32)</sup>
3842

3943
MinDelay defines minimum delay in seconds. Default to 30
4044

45+
Default Value: `30`
46+
4147
***
4248

4349
### .spec.deployment.name
4450

45-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L54)</sup>
51+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L55)</sup>
4652

4753
Name of the ArangoDeployment Custom Resource within same namespace as ArangoBackup Custom Resource.
4854

@@ -52,7 +58,7 @@ This field is **immutable**: can't be changed after backup creation
5258

5359
### .spec.download.autoDelete
5460

55-
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L84)</sup>
61+
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L85)</sup>
5662

5763
AutoDelete removes the ArangoBackup resource (which removes the backup from the cluster) after successful upload
5864

@@ -62,7 +68,7 @@ Default Value: `false`
6268

6369
### .spec.download.credentialsSecretName
6470

65-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L81)</sup>
71+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L82)</sup>
6672

6773
CredentialsSecretName is the name of the secret used while accessing repository
6874

@@ -75,7 +81,7 @@ This field is **immutable**: can't be changed after backup creation
7581

7682
### .spec.download.id
7783

78-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L92)</sup>
84+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L93)</sup>
7985

8086
ID of the ArangoBackup to be downloaded
8187

@@ -85,7 +91,7 @@ This field is **immutable**: can't be changed after backup creation
8591

8692
### .spec.download.repositoryURL
8793

88-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L77)</sup>
94+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L78)</sup>
8995

9096
RepositoryURL is the URL path for file storage
9197
Same repositoryURL needs to be defined in `credentialsSecretName` if protocol is other than local.
@@ -106,15 +112,15 @@ This field is **immutable**: can't be changed after backup creation
106112

107113
### .spec.lifetime
108114

109-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L47)</sup>
115+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L48)</sup>
110116

111117
Lifetime is the time after which the backup will be deleted. Format: "1.5h" or "2h45m".
112118

113119
***
114120

115121
### .spec.options.allowInconsistent
116122

117-
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L66)</sup>
123+
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L67)</sup>
118124

119125
AllowInconsistent flag for Backup creation request.
120126
If this value is set to true, backup is taken even if we are not able to acquire lock.
@@ -127,7 +133,7 @@ This field is **immutable**: can't be changed after backup creation
127133

128134
### .spec.options.timeout
129135

130-
Type: `number` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L61)</sup>
136+
Type: `number` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L62)</sup>
131137

132138
Timeout for Backup creation request in seconds. Works only when AsyncBackupCreation feature is set to false.
133139

@@ -149,7 +155,7 @@ This field is **immutable**: can't be changed after backup creation
149155

150156
### .spec.upload.autoDelete
151157

152-
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L84)</sup>
158+
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L85)</sup>
153159

154160
AutoDelete removes the ArangoBackup resource (which removes the backup from the cluster) after successful upload
155161

@@ -159,7 +165,7 @@ Default Value: `false`
159165

160166
### .spec.upload.credentialsSecretName
161167

162-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L81)</sup>
168+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L82)</sup>
163169

164170
CredentialsSecretName is the name of the secret used while accessing repository
165171

@@ -172,7 +178,7 @@ This field is **immutable**: can't be changed after backup creation
172178

173179
### .spec.upload.repositoryURL
174180

175-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L77)</sup>
181+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L78)</sup>
176182

177183
RepositoryURL is the URL path for file storage
178184
Same repositoryURL needs to be defined in `credentialsSecretName` if protocol is other than local.

docs/api/ArangoBackupPolicy.V1.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,34 +51,40 @@ Links:
5151

5252
### .spec.template.backoff.iterations
5353

54-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L31)</sup>
54+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L38)</sup>
5555

5656
Iterations defines number of iterations before reaching MaxDelay. Default to 5
5757

58+
Default Value: `5`
59+
5860
***
5961

6062
### .spec.template.backoff.max_delay
6163

62-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L29)</sup>
64+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L35)</sup>
6365

6466
MaxDelay defines maximum delay in seconds. Default to 600
6567

68+
Default Value: `600`
69+
6670
***
6771

6872
### .spec.template.backoff.max_iterations
6973

70-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L33)</sup>
74+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L40)</sup>
7175

7276
MaxIterations defines maximum number of iterations after backoff will be disabled. Default to nil (no limit)
7377

7478
***
7579

7680
### .spec.template.backoff.min_delay
7781

78-
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L27)</sup>
82+
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec_backoff.go#L32)</sup>
7983

8084
MinDelay defines minimum delay in seconds. Default to 30
8185

86+
Default Value: `30`
87+
8288
***
8389

8490
### .spec.template.lifetime
@@ -91,7 +97,7 @@ Lifetime is the time after which the backup will be deleted. Format: "1.5h" or "
9197

9298
### .spec.template.options.allowInconsistent
9399

94-
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L66)</sup>
100+
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L67)</sup>
95101

96102
AllowInconsistent flag for Backup creation request.
97103
If this value is set to true, backup is taken even if we are not able to acquire lock.
@@ -104,7 +110,7 @@ This field is **immutable**: can't be changed after backup creation
104110

105111
### .spec.template.options.timeout
106112

107-
Type: `number` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L61)</sup>
113+
Type: `number` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L62)</sup>
108114

109115
Timeout for Backup creation request in seconds. Works only when AsyncBackupCreation feature is set to false.
110116

@@ -116,7 +122,7 @@ This field is **immutable**: can't be changed after backup creation
116122

117123
### .spec.template.upload.autoDelete
118124

119-
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L84)</sup>
125+
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L85)</sup>
120126

121127
AutoDelete removes the ArangoBackup resource (which removes the backup from the cluster) after successful upload
122128

@@ -126,7 +132,7 @@ Default Value: `false`
126132

127133
### .spec.template.upload.credentialsSecretName
128134

129-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L81)</sup>
135+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L82)</sup>
130136

131137
CredentialsSecretName is the name of the secret used while accessing repository
132138

@@ -139,7 +145,7 @@ This field is **immutable**: can't be changed after backup creation
139145

140146
### .spec.template.upload.repositoryURL
141147

142-
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L77)</sup>
148+
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.47/pkg/apis/backup/v1/backup_spec.go#L78)</sup>
143149

144150
RepositoryURL is the URL path for file storage
145151
Same repositoryURL needs to be defined in `credentialsSecretName` if protocol is other than local.

docs/cli/arangodb_operator.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Flags:
4747
--deployment.feature.all Enable ALL Features
4848
--deployment.feature.async-backup-creation Create backups asynchronously to avoid blocking the operator and reaching the timeout - Required ArangoDB >= 3.8.0 (default true)
4949
--deployment.feature.backup-cleanup Cleanup imported backups if required - Required ArangoDB >= 3.8.0
50+
--deployment.feature.backup-policy-until-propagation Sets Until field in the Backup based on next schedule time - Required ArangoDB >= 3.8.0 (default true)
5051
--deployment.feature.deployment-spec-defaults-restore Restore defaults from last accepted state of deployment - Required ArangoDB >= 3.8.0 (default true)
5152
--deployment.feature.enforced-resign-leadership Enforce ResignLeadership and ensure that Leaders are moved from restarted DBServer - Required ArangoDB >= 3.8.0 (default true)
5253
--deployment.feature.ephemeral-volumes Enables ephemeral volumes for apps and tmp directory - Required ArangoDB >= 3.8.0

pkg/apis/backup/v1/backup_spec.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2016-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@ type ArangoBackupSpec struct {
4141
// +doc/immutable: can't be changed after backup creation
4242
PolicyName *string `json:"policyName,omitempty"`
4343

44+
// Backoff define the operation backoff policy
4445
Backoff *ArangoBackupSpecBackOff `json:"backoff,omitempty"`
4546

4647
// Lifetime is the time after which the backup will be deleted. Format: "1.5h" or "2h45m".

pkg/apis/backup/v1/backup_spec_backoff.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2016-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -20,17 +20,26 @@
2020

2121
package v1
2222

23-
import "time"
23+
import (
24+
"time"
25+
26+
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
)
2428

2529
type ArangoBackupSpecBackOff struct {
2630
// MinDelay defines minimum delay in seconds. Default to 30
31+
// +doc/default: 30
2732
MinDelay *int `json:"min_delay,omitempty"`
2833
// MaxDelay defines maximum delay in seconds. Default to 600
34+
// +doc/default: 600
2935
MaxDelay *int `json:"max_delay,omitempty"`
3036
// Iterations defines number of iterations before reaching MaxDelay. Default to 5
37+
// +doc/default: 5
3138
Iterations *int `json:"iterations,omitempty"`
3239
// MaxIterations defines maximum number of iterations after backoff will be disabled. Default to nil (no limit)
3340
MaxIterations *int `json:"max_iterations,omitempty"`
41+
// Until defines the deadline of the retry mechanism in UTC
42+
Until *meta.Time `json:"until,omitempty"`
3443
}
3544

3645
func (a *ArangoBackupSpecBackOff) GetMaxDelay() int {

pkg/apis/backup/v1/backup_status_backoff.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2016-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -52,7 +52,21 @@ func (a *ArangoBackupStatusBackOff) GetNext() meta.Time {
5252
}
5353

5454
func (a *ArangoBackupStatusBackOff) ShouldBackoff(spec *ArangoBackupSpecBackOff) bool {
55-
return spec == nil || spec.MaxIterations == nil || a.GetIterations() < *spec.MaxIterations
55+
if spec != nil {
56+
if u := spec.Until; u != nil && !u.IsZero() {
57+
if time.Now().After(u.Time) {
58+
return false
59+
}
60+
}
61+
62+
if u := spec.MaxIterations; u != nil {
63+
if a.GetIterations() >= *u {
64+
return false
65+
}
66+
}
67+
}
68+
69+
return true
5670
}
5771

5872
func (a *ArangoBackupStatusBackOff) Backoff(spec *ArangoBackupSpecBackOff) *ArangoBackupStatusBackOff {
@@ -64,8 +78,18 @@ func (a *ArangoBackupStatusBackOff) Backoff(spec *ArangoBackupSpecBackOff) *Aran
6478
}
6579
}
6680

81+
next := time.Now().Add(spec.Backoff(a.GetIterations()))
82+
83+
if spec != nil {
84+
if u := spec.Until; u != nil && !u.IsZero() {
85+
if next.After(u.Time) {
86+
next = u.Time
87+
}
88+
}
89+
}
90+
6791
return &ArangoBackupStatusBackOff{
6892
Iterations: a.GetIterations() + 1,
69-
Next: meta.Time{Time: time.Now().Add(spec.Backoff(a.GetIterations()))},
93+
Next: meta.Time{Time: next},
7094
}
7195
}

pkg/apis/backup/v1/zz_generated.deepcopy.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/crd/crds/backups-backup.schema.generated.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ v1:
44
spec:
55
properties:
66
backoff:
7+
description: Backoff define the operation backoff policy
78
properties:
89
iterations:
910
description: Iterations defines number of iterations before reaching MaxDelay. Default to 5
@@ -21,6 +22,10 @@ v1:
2122
description: MinDelay defines minimum delay in seconds. Default to 30
2223
format: int32
2324
type: integer
25+
until:
26+
description: Until defines the deadline of the retry mechanism in UTC
27+
format: date-time
28+
type: string
2429
type: object
2530
deployment:
2631
description: Deployment describes the deployment which should have a backup

0 commit comments

Comments
 (0)