Skip to content

Commit db1ae11

Browse files
authored
[Feature] Fix backup retries (#1435)
1 parent ca26bc3 commit db1ae11

File tree

10 files changed

+241
-92
lines changed

10 files changed

+241
-92
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- (Maintenance) Remove support for RELATED_IMAGE_UBI, RELATED_IMAGE_DATABASE and RELATED_IMAGE_METRICSEXPORTER env vars
88
- (Bugfix) Fix numactl options
99
- (Maintenance) Bump Go to 1.20.10
10+
- (Bugfix) Fix ArangoBackup Create Backoff & ArangoBackupPolicy propagation
1011

1112
## [1.2.33](https://github.com/arangodb/kube-arangodb/tree/1.2.33) (2023-09-27)
1213
- (Maintenance) Bump golang.org/x/net to v0.13.0

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ update-vendor:
352352
@rm -Rf $(VENDORDIR)/k8s.io/code-generator
353353
@git clone --branch "kubernetes-1.$(KUBERNETES_VERSION_MINOR).$(KUBERNETES_VERSION_PATCH)" https://github.com/kubernetes/code-generator.git $(VENDORDIR)/k8s.io/code-generator
354354
@rm -Rf $(VENDORDIR)/k8s.io/code-generator/.git
355+
@(cd "$(VENDORDIR)/k8s.io/code-generator"; go mod download; go mod vendor)
355356

356357

357358
.PHONY: update-generated

pkg/apis/backup/v1/backup_policy.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2016-2023 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.
@@ -60,6 +60,8 @@ func (a *ArangoBackupPolicy) NewBackup(d *deployment.ArangoDeployment) *ArangoBa
6060
},
6161
Upload: a.Spec.BackupTemplate.Upload.DeepCopy(),
6262
Options: a.Spec.BackupTemplate.Options.DeepCopy(),
63+
Backoff: a.Spec.BackupTemplate.Backoff.DeepCopy(),
64+
Lifetime: a.Spec.BackupTemplate.Lifetime.DeepCopy(),
6365
PolicyName: &policyName,
6466
}
6567

pkg/apis/backup/v1/backup_policy_spec.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,9 @@ type ArangoBackupTemplate struct {
4949
Options *ArangoBackupSpecOptions `json:"options,omitempty"`
5050

5151
Upload *ArangoBackupSpecOperation `json:"upload,omitempty"`
52+
53+
Backoff *ArangoBackupSpecBackOff `json:"backoff,omitempty"`
54+
55+
// Lifetime is the time after which the backup will be deleted. Format: "1.5h" or "2h45m".
56+
Lifetime *meta.Duration `json:"lifetime,omitempty"`
5257
}

pkg/apis/backup/v1/backup_spec_backoff.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,7 @@ func (a *ArangoBackupSpecBackOff) Backoff(iteration int) time.Duration {
9292
return time.Duration(min+int(float64(iteration)/float64(maxIterations)*float64(max-min))) * time.Second
9393
}
9494
}
95+
96+
func (a *ArangoBackupSpecBackOff) Enabled() bool {
97+
return a != nil && a.MaxIterations != nil
98+
}

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

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

pkg/handlers/backup/state_create.go

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
package backup
2222

2323
import (
24-
"time"
25-
2624
"github.com/arangodb/go-driver"
2725

2826
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
@@ -69,22 +67,3 @@ func stateCreateHandler(h *handler, backup *backupApi.ArangoBackup) (*backupApi.
6967
cleanBackOff(),
7068
)
7169
}
72-
73-
func stateCreateErrorHandler(h *handler, backup *backupApi.ArangoBackup) (*backupApi.ArangoBackupStatus, error) {
74-
// no more retries - move to failed state
75-
if !backup.Status.Backoff.ShouldBackoff(backup.Spec.Backoff) {
76-
return wrapUpdateStatus(backup,
77-
updateStatusState(backupApi.ArangoBackupStateFailed, "out of Create retries"),
78-
cleanStatusJob())
79-
}
80-
81-
// if we should retry - move to create state
82-
if backup.Status.Backoff.ShouldBackoff(backup.Spec.Backoff) && !backup.Status.Backoff.GetNext().After(time.Now()) {
83-
return wrapUpdateStatus(backup,
84-
updateStatusState(backupApi.ArangoBackupStateCreate, ""),
85-
cleanStatusJob())
86-
}
87-
88-
// no ready to retry - wait (do not change state)
89-
return wrapUpdateStatus(backup)
90-
}

pkg/handlers/backup/state_create_test.go

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@ package backup
2222

2323
import (
2424
"testing"
25-
"time"
2625

2726
"github.com/stretchr/testify/require"
28-
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
2927

3028
"github.com/arangodb/go-driver"
3129

@@ -143,71 +141,3 @@ func Test_State_Create_CreateError(t *testing.T) {
143141
require.Nil(t, newObj.Status.Backup)
144142
require.False(t, newObj.Status.Available)
145143
}
146-
147-
func Test_State_CreateError_Retry(t *testing.T) {
148-
// Arrange
149-
handler, mock := newErrorsFakeHandler(mockErrorsArangoClientBackup{})
150-
151-
obj, deployment := newObjectSet(backupApi.ArangoBackupStateCreateError)
152-
153-
backupMeta, err := mock.Create()
154-
require.NoError(t, err)
155-
156-
obj.Status.Backup = &backupApi.ArangoBackupDetails{
157-
ID: string(backupMeta.ID),
158-
Version: backupMeta.Version,
159-
CreationTimestamp: meta.Now(),
160-
}
161-
162-
obj.Status.Time.Time = time.Now().Add(-2 * downloadDelay)
163-
164-
// Act
165-
createArangoDeployment(t, handler, deployment)
166-
createArangoBackup(t, handler, obj)
167-
168-
require.NoError(t, handler.Handle(newItemFromBackup(operation.Update, obj)))
169-
170-
// Assert
171-
newObj := refreshArangoBackup(t, handler, obj)
172-
require.Equal(t, newObj.Status.State, backupApi.ArangoBackupStateCreate)
173-
require.False(t, newObj.Status.Available)
174-
require.NotNil(t, newObj.Status.Backup)
175-
require.Equal(t, obj.Status.Backup, newObj.Status.Backup)
176-
}
177-
178-
func Test_State_CreateError_Transfer_To_Failed(t *testing.T) {
179-
// Arrange
180-
handler, mock := newErrorsFakeHandler(mockErrorsArangoClientBackup{})
181-
182-
obj, deployment := newObjectSet(backupApi.ArangoBackupStateCreateError)
183-
184-
backupMeta, err := mock.Create()
185-
require.NoError(t, err)
186-
187-
obj.Status.Backup = &backupApi.ArangoBackupDetails{
188-
ID: string(backupMeta.ID),
189-
Version: backupMeta.Version,
190-
CreationTimestamp: meta.Now(),
191-
}
192-
obj.Status.Backoff = &backupApi.ArangoBackupStatusBackOff{
193-
Iterations: 2,
194-
}
195-
196-
obj.Spec.Backoff = &backupApi.ArangoBackupSpecBackOff{
197-
Iterations: util.NewType[int](1),
198-
MaxIterations: util.NewType[int](2),
199-
}
200-
201-
obj.Status.Time.Time = time.Now().Add(-2 * downloadDelay)
202-
203-
// Act
204-
createArangoDeployment(t, handler, deployment)
205-
createArangoBackup(t, handler, obj)
206-
207-
require.NoError(t, handler.Handle(newItemFromBackup(operation.Update, obj)))
208-
209-
// Assert
210-
newObj := refreshArangoBackup(t, handler, obj)
211-
require.Equal(t, newObj.Status.State, backupApi.ArangoBackupStateFailed)
212-
require.Equal(t, newObj.Status.Message, "out of Create retries")
213-
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package backup
22+
23+
import (
24+
"time"
25+
26+
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
27+
)
28+
29+
func stateCreateErrorHandler(h *handler, backup *backupApi.ArangoBackup) (*backupApi.ArangoBackupStatus, error) {
30+
if !backup.Spec.Backoff.Enabled() {
31+
return wrapUpdateStatus(backup,
32+
updateStatusState(backupApi.ArangoBackupStateFailed, "retries are disabled"),
33+
cleanStatusJob())
34+
}
35+
36+
// no more retries - move to failed state
37+
if !backup.Status.Backoff.ShouldBackoff(backup.Spec.Backoff) {
38+
return wrapUpdateStatus(backup,
39+
updateStatusState(backupApi.ArangoBackupStateFailed, "out of Create retries"),
40+
cleanStatusJob())
41+
}
42+
43+
// if we should retry - move to create state
44+
if backup.Status.Backoff.ShouldBackoff(backup.Spec.Backoff) && !backup.Status.Backoff.GetNext().After(time.Now()) {
45+
return wrapUpdateStatus(backup,
46+
updateStatusState(backupApi.ArangoBackupStateCreate, ""),
47+
cleanStatusJob())
48+
}
49+
50+
// no ready to retry - wait (do not change state)
51+
return wrapUpdateStatus(backup)
52+
}

0 commit comments

Comments
 (0)