Skip to content

Commit

Permalink
Add timeout method
Browse files Browse the repository at this point in the history
Signed-off-by: Md. Ishtiaq Islam <[email protected]>
  • Loading branch information
ishtiaqhimel committed Sep 16, 2024
1 parent fb72a4b commit cb37ad0
Show file tree
Hide file tree
Showing 15 changed files with 106 additions and 36 deletions.
5 changes: 3 additions & 2 deletions apis/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ const (
KubeStashAppRefKind = "kubestash.com/app-ref-kind"
KubeStashAppRefNamespace = "kubestash.com/app-ref-namespace"
KubeStashAppRefName = "kubestash.com/app-ref-name"
KubeDBAppVersion = "kubedb.com/db-version"
)

// Keys for structure logging
Expand Down Expand Up @@ -154,6 +153,8 @@ const (
DirRepository = "repository"
)

// Annotations
const (
KeyRestoreSessionBeneficiary = "restoresession.kubestash.com/beneficiary"
AnnKubeDBAppVersion = "kubedb.com/db-version"
AnnRestoreSessionBeneficiary = "restoresession.kubestash.com/beneficiary"
)
4 changes: 2 additions & 2 deletions apis/core/v1alpha1/backupconfiguration_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ type SessionConfig struct {
// +optional
RetryConfig *RetryConfig `json:"retryConfig,omitempty"`

// Timeout specifies the maximum duration of backup. BackupSession will be considered Failed
// if backup does not complete within this time limit. By default, KubeStash don't set any timeout for backup.
// Timeout specifies the maximum duration of backup. Backup will be considered Failed
// if backup tasks do not complete within this time limit. By default, KubeStash don't set any timeout for backup.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`

Expand Down
11 changes: 11 additions & 0 deletions apis/core/v1alpha1/backupsession_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,14 @@ func (b *BackupSession) checkFailureInRetentionPolicy() (bool, string) {
}
return false, ""
}

func (b *BackupSession) GetRemainingTimeoutDuration() (*metav1.Duration, error) {
if b.Spec.Timeout == nil || b.Status.Deadline == nil {
return nil, nil
}
currentTime := metav1.Now()
if b.Status.Deadline.Before(&currentTime) {
return nil, fmt.Errorf("deadline exceeded")
}
return &metav1.Duration{Duration: b.Status.Deadline.Sub(currentTime.Time)}, nil
}
7 changes: 6 additions & 1 deletion apis/core/v1alpha1/backupsession_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type BackupSessionSpec struct {
RetryLeft int32 `json:"retryLeft,omitempty"`

// Timeout specifies the maximum duration of backup. Backup will be considered Failed
// if backup does not complete within this time limit. By default, KubeStash don't set any timeout for backup.
// if backup tasks do not complete within this time limit. By default, KubeStash don't set any timeout for backup.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
}
Expand All @@ -80,6 +80,11 @@ type BackupSessionStatus struct {
// +optional
Duration string `json:"duration,omitempty"`

// Deadline specifies the deadline of backup. Backup will be
// considered Failed if it does not complete within this deadline
// +optional
Deadline *metav1.Time `json:"backupDeadline,omitempty"`

// TotalSnapshots specifies the total number of snapshots created for this backupSession.
// +optional
TotalSnapshots *int32 `json:"totalSnapshots,omitempty"`
Expand Down
12 changes: 12 additions & 0 deletions apis/core/v1alpha1/restoresession_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1

import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kmapi "kmodules.xyz/client-go/api/v1"
"kubestash.dev/apimachinery/apis"
Expand Down Expand Up @@ -180,3 +181,14 @@ func (rs *RestoreSession) GetDataSourceNamespace() string {
}
return rs.Spec.DataSource.Namespace
}

func (rs *RestoreSession) GetRemainingTimeoutDuration() (*metav1.Duration, error) {
if rs.Spec.Timeout == nil || rs.Status.Deadline == nil {
return nil, nil
}
currentTime := metav1.Now()
if rs.Status.Deadline.Before(&currentTime) {
return nil, fmt.Errorf("deadline exceeded")
}
return &metav1.Duration{Duration: rs.Status.Deadline.Sub(currentTime.Time)}, nil
}
19 changes: 0 additions & 19 deletions apis/core/v1alpha1/restoresession_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,25 +230,6 @@ func TestRestoreSessionPhaseIsFailedIfRestoreExecutorEnsuredConditionIsFalse(t *
assert.Equal(t, RestoreFailed, rs.CalculatePhase())
}

func TestRestoreSessionPhaseIsFailedIfDeadlineExceededConditionIsTrue(t *testing.T) {
rs := sampleRestoreSession(func(r *RestoreSession) {
r.Status.Conditions = append(r.Status.Conditions,
kmapi.Condition{
Type: TypeDeadlineExceeded,
Status: metav1.ConditionTrue,
Reason: ReasonFailedToCompleteWithinDeadline,
},
kmapi.Condition{
Type: TypeMetricsPushed,
Status: metav1.ConditionTrue,
Reason: ReasonSuccessfullyPushedMetrics,
},
)
})

assert.Equal(t, RestoreFailed, rs.CalculatePhase())
}

func TestRestoreSessionPhaseIsRunningIfPostRestoreHooksNotExecuted(test *testing.T) {
rs := sampleRestoreSession(func(r *RestoreSession) {
r.Status.Components = map[string]ComponentRestoreStatus{
Expand Down
7 changes: 6 additions & 1 deletion apis/core/v1alpha1/restoresession_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type RestoreSessionSpec struct {
Hooks *RestoreHooks `json:"hooks,omitempty"`

// Timeout specifies a duration that KubeStash should wait for the restore to be completed.
// If the restore does not finish within this time period, KubeStash will consider this restore as a failure.
// If the restore tasks do not finish within this time period, KubeStash will consider this restore as a failure.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`

Expand Down Expand Up @@ -278,6 +278,11 @@ type RestoreSessionStatus struct {
// +optional
Duration string `json:"duration,omitempty"`

// Deadline specifies the deadline of restore. Restore will be
// considered Failed if it does not complete within this deadline
// +optional
Deadline *metav1.Time `json:"restoreDeadline,omitempty"`

// TotalComponents represents the number of total components for this RestoreSession
// +optional
TotalComponents int32 `json:"totalComponents,omitempty"`
Expand Down
8 changes: 8 additions & 0 deletions apis/core/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions crds/core.kubestash.com_backupbatches.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36196,9 +36196,9 @@ spec:
type: array
timeout:
description: Timeout specifies the maximum duration of backup.
BackupSession will be considered Failed if backup does not
complete within this time limit. By default, KubeStash don't
set any timeout for backup.
Backup will be considered Failed if backup tasks do not complete
within this time limit. By default, KubeStash don't set any
timeout for backup.
type: string
type: object
type: array
Expand Down
4 changes: 2 additions & 2 deletions crds/core.kubestash.com_backupblueprints.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37241,8 +37241,8 @@ spec:
type: integer
timeout:
description: Timeout specifies the maximum duration of backup.
BackupSession will be considered Failed if backup does
not complete within this time limit. By default, KubeStash
Backup will be considered Failed if backup tasks do not
complete within this time limit. By default, KubeStash
don't set any timeout for backup.
type: string
type: object
Expand Down
6 changes: 3 additions & 3 deletions crds/core.kubestash.com_backupconfigurations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34375,9 +34375,9 @@ spec:
type: integer
timeout:
description: Timeout specifies the maximum duration of backup.
BackupSession will be considered Failed if backup does not
complete within this time limit. By default, KubeStash don't
set any timeout for backup.
Backup will be considered Failed if backup tasks do not complete
within this time limit. By default, KubeStash don't set any
timeout for backup.
type: string
type: object
type: array
Expand Down
10 changes: 8 additions & 2 deletions crds/core.kubestash.com_backupsessions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,19 @@ spec:
type: string
timeout:
description: Timeout specifies the maximum duration of backup. Backup
will be considered Failed if backup does not complete within this
time limit. By default, KubeStash don't set any timeout for backup.
will be considered Failed if backup tasks do not complete within
this time limit. By default, KubeStash don't set any timeout for
backup.
type: string
type: object
status:
description: BackupSessionStatus defines the observed state of BackupSession
properties:
backupDeadline:
description: Deadline specifies the deadline of backup. Backup will
be considered Failed if it does not complete within this deadline
format: date-time
type: string
conditions:
description: Conditions represents list of conditions regarding this
BackupSession
Expand Down
7 changes: 6 additions & 1 deletion crds/core.kubestash.com_restoresessions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24469,7 +24469,7 @@ spec:
type: object
timeout:
description: Timeout specifies a duration that KubeStash should wait
for the restore to be completed. If the restore does not finish
for the restore to be completed. If the restore tasks do not finish
within this time period, KubeStash will consider this restore as
a failure.
type: string
Expand Down Expand Up @@ -24661,6 +24661,11 @@ spec:
- Invalid
- Unknown
type: string
restoreDeadline:
description: Deadline specifies the deadline of restore. Restore will
be considered Failed if it does not complete within this deadline
format: date-time
type: string
targetFound:
description: TargetFound specifies whether the restore target exist
or not
Expand Down
3 changes: 3 additions & 0 deletions pkg/restic/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,9 @@ func (w *ResticWrapper) run(commands ...Command) ([]byte, error) {
func formatError(err error, stdErr string) error {
parts := strings.Split(strings.TrimSuffix(stdErr, "\n"), "\n")
if len(parts) > 1 {
if strings.Contains(parts[1], "signal terminated") {
return errors.New(strings.Join(append([]string{"deadline exceeded or signal terminated"}, parts[2:]...), " "))
}
return errors.New(strings.Join(parts[1:], " "))
}
return err
Expand Down
33 changes: 33 additions & 0 deletions pkg/restic/restic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"testing"
"time"
)

var (
Expand Down Expand Up @@ -462,6 +463,38 @@ func TestBackupRestoreWithArgs(t *testing.T) {
}
}

func TestBackupWithTimeout(t *testing.T) {
tempDir, err := os.MkdirTemp("", "stash-unit-test-")
if err != nil {
t.Error(err)
return
}

w, err := setupTest(tempDir)
if err != nil {
t.Error(err)
return
}
defer cleanup(tempDir)

// Initialize Repository
err = w.InitializeRepository()
if err != nil {
t.Error(err)
return
}

duration := metav1.Duration{Duration: 10 * time.Millisecond}
w.config.Timeout = &duration

backupOpt := BackupOptions{
StdinPipeCommands: []Command{stdinPipeCommand},
StdinFileName: fileName,
}
_, err = w.RunBackup(backupOpt)
assert.Error(t, err, "Timeout error")
}

func TestVerifyRepositoryIntegrity(t *testing.T) {
tempDir, err := os.MkdirTemp("", "stash-unit-test-")
if err != nil {
Expand Down

0 comments on commit cb37ad0

Please sign in to comment.