Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 41 additions & 6 deletions api/v1beta2/foundationdbbackup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
// +kubebuilder:metadata:annotations="foundationdb.org/release=v2.14.0"
// +kubebuilder:printcolumn:name="Generation",type="integer",JSONPath=".metadata.generation",description="Latest generation of the spec",priority=0
// +kubebuilder:printcolumn:name="Reconciled",type="integer",JSONPath=".status.generations.reconciled",description="Last reconciled generation of the spec",priority=0
// +kubebuilder:printcolumn:name="Restorable",type="boolean",JSONPath=".status.backupDetails.restorable",description="If the backup is restorable",priority=0
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:storageversion

Expand Down Expand Up @@ -134,6 +135,15 @@ type FoundationDBBackupSpec struct {
// +kubebuilder:validation:Enum=noop;stop;cleanup
// +kubebuilder:default:=noop
DeletionPolicy *BackupDeletionPolicy `json:"deletionPolicy,omitempty"`

// BackupMode defines the backup mode that should be used for the backup. When the BackupMode is set to
// BackupModeOneTime, the backup will create a single snapshot and then stop. When set to BackupModeContinuous,
// the backup will run continuously, creating snapshots at regular intervals defined by SnapshotPeriodSeconds.
// Default: "Continuous".
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Enum=continuous;oneTime
// +kubebuilder:default:=continuous
BackupMode *BackupMode `json:"backupMode,omitempty"`
}

// BackupType defines the backup type that should be used for the backup.
Expand Down Expand Up @@ -165,6 +175,18 @@ const (
BackupDeletionPolicyCleanup BackupDeletionPolicy = "cleanup"
)

// BackupMode defines the mode of backup operation.
// +kubebuilder:validation:MaxLength=64
type BackupMode string

const (
// BackupModeContinuous indicates that the backup should run continuously, taking snapshots at regular intervals.
BackupModeContinuous BackupMode = "continuous"

// BackupModeOneTime indicates that the backup should create a single snapshot and then stop.
BackupModeOneTime BackupMode = "oneTime"
)

// FoundationDBBackupStatus describes the current status of the backup for a cluster.
type FoundationDBBackupStatus struct {
// AgentCount provides the number of agents that are up-to-date, ready,
Expand All @@ -191,6 +213,7 @@ type FoundationDBBackupStatusBackupDetails struct {
Running bool `json:"running,omitempty"`
Paused bool `json:"paused,omitempty"`
SnapshotPeriodSeconds int `json:"snapshotTime,omitempty"`
Restorable bool `json:"restorable,omitempty"`
}

// BackupGenerationStatus stores information on which generations have reached
Expand Down Expand Up @@ -265,6 +288,13 @@ type BlobStoreConfiguration struct {

// ShouldRun determines whether a backup should be running.
func (backup *FoundationDBBackup) ShouldRun() bool {
// For one-time backups, don't run if already completed
backupDetails := backup.Status.BackupDetails
if backup.GetBackupMode() == BackupModeOneTime && backupDetails != nil &&
backupDetails.Restorable {
return false
}

return backup.Spec.BackupState == "" || backup.Spec.BackupState == BackupStateRunning ||
backup.Spec.BackupState == BackupStatePaused
}
Expand Down Expand Up @@ -318,19 +348,19 @@ type FoundationDBLiveBackupStatus struct {

// BackupAgentsPaused describes whether the backup agents are paused.
BackupAgentsPaused bool `json:"BackupAgentsPaused,omitempty"`

// Restorable if true, the backup can be restored
Restorable *bool `json:"Restorable,omitempty"`

// LatestRestorablePoint contains information about the latest restorable point if any exists.
LatestRestorablePoint *LatestRestorablePoint `json:"LatestRestorablePoint,omitempty"`
}

// FoundationDBLiveBackupStatusState provides the state of a backup in the
// backup status.
type FoundationDBLiveBackupStatusState struct {
// Running determines whether the backup is currently running.
Running bool `json:"Running,omitempty"`

// Restorable if true, the backup can be restored
Restorable *bool `json:"Restorable,omitempty"`

// LatestRestorablePoint contains information about the latest restorable point if any exists.
LatestRestorablePoint *LatestRestorablePoint `json:"LatestRestorablePoint,omitempty"`
}

// LatestRestorablePoint contains information about the latest restorable point if any exists.
Expand Down Expand Up @@ -429,6 +459,11 @@ func (backup *FoundationDBBackup) GetDeletionPolicy() BackupDeletionPolicy {
return ptr.Deref(backup.Spec.DeletionPolicy, BackupDeletionPolicyNoop)
}

// GetBackupMode will return the backup mode for this backup.
func (backup *FoundationDBBackup) GetBackupMode() BackupMode {
return ptr.Deref(backup.Spec.BackupMode, BackupModeContinuous)
}

// UseUnifiedImage returns true if the unified image should be used.
func (backup *FoundationDBBackup) UseUnifiedImage() bool {
imageType := ImageTypeUnified
Expand Down
48 changes: 48 additions & 0 deletions api/v1beta2/foundationdbbackup_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,4 +471,52 @@ var _ = Describe("[api] FoundationDBBackup", func() {
),
)
})

When("testing backup mode functionality", func() {
Context("GetBackupMode method", func() {
It("should return continuous as default when BackupMode is nil", func() {
backup.Spec.BackupMode = nil
Expect(backup.GetBackupMode()).To(Equal(BackupModeContinuous))
})

It("should return continuous when explicitly set", func() {
mode := BackupModeContinuous
backup.Spec.BackupMode = &mode
Expect(backup.GetBackupMode()).To(Equal(BackupModeContinuous))
})

It("should return one-time when explicitly set", func() {
mode := BackupModeOneTime
backup.Spec.BackupMode = &mode
Expect(backup.GetBackupMode()).To(Equal(BackupModeOneTime))
})
})

Context("ShouldRun method for different backup modes", func() {
It("should run continuous backup by default", func() {
backup.Spec.BackupState = BackupStateRunning
Expect(backup.ShouldRun()).To(BeTrue())
})

It("should not run completed one-time backup", func() {
mode := BackupModeOneTime
backup.Spec.BackupMode = &mode
backup.Spec.BackupState = BackupStateRunning
backup.Status.BackupDetails = &FoundationDBBackupStatusBackupDetails{
Restorable: true,
}
Expect(backup.ShouldRun()).To(BeFalse())
})

It("should run uncompleted one-time backup", func() {
mode := BackupModeOneTime
backup.Spec.BackupMode = &mode
backup.Spec.BackupState = BackupStateRunning
backup.Status.BackupDetails = &FoundationDBBackupStatusBackupDetails{
Restorable: false,
}
Expect(backup.ShouldRun()).To(BeTrue())
})
})
})
})
1 change: 1 addition & 0 deletions api/v1beta2/foundationdbcluster_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ var _ = Describe("[api] FoundationDBCluster", func() {
Status: FoundationDBLiveBackupStatusState{
Running: true,
},
Restorable: ptr.To(false),
}))
})
})
Expand Down
27 changes: 16 additions & 11 deletions api/v1beta2/zz_generated.deepcopy.go

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

13 changes: 13 additions & 0 deletions config/crd/bases/apps.foundationdb.org_foundationdbbackups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ spec:
jsonPath: .status.generations.reconciled
name: Reconciled
type: integer
- description: If the backup is restorable
jsonPath: .status.backupDetails.restorable
name: Restorable
type: boolean
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
Expand Down Expand Up @@ -65,6 +69,13 @@ spec:
namespace:
type: string
type: object
backupMode:
default: continuous
enum:
- continuous
- oneTime
maxLength: 64
type: string
backupState:
enum:
- Running
Expand Down Expand Up @@ -3869,6 +3880,8 @@ spec:
properties:
paused:
type: boolean
restorable:
type: boolean
running:
type: boolean
snapshotTime:
Expand Down
4 changes: 3 additions & 1 deletion controllers/modify_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ func (s modifyBackup) reconcile(
return nil
}

if backup.NeedsBackupReconfiguration() {
// The modify command is only required for continuous backups.
if backup.NeedsBackupReconfiguration() &&
backup.GetBackupMode() == fdbv1beta2.BackupModeContinuous {
adminClient, err := r.adminClientForBackup(ctx, backup)
if err != nil {
return &requeue{curError: err}
Expand Down
8 changes: 5 additions & 3 deletions controllers/update_backup_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ package controllers
import (
"context"

"github.com/FoundationDB/fdb-kubernetes-operator/v2/internal"
"k8s.io/apimachinery/pkg/api/equality"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/utils/ptr"

fdbv1beta2 "github.com/FoundationDB/fdb-kubernetes-operator/v2/api/v1beta2"
"github.com/FoundationDB/fdb-kubernetes-operator/v2/internal"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/api/equality"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -115,6 +116,7 @@ func (s updateBackupStatus) reconcile(
Running: liveStatus.Status.Running,
Paused: liveStatus.BackupAgentsPaused,
SnapshotPeriodSeconds: liveStatus.SnapshotIntervalSeconds,
Restorable: ptr.Deref(liveStatus.Restorable, false),
}

originalStatus := backup.Status.DeepCopy()
Expand Down
12 changes: 10 additions & 2 deletions docs/backup_spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ BackupGenerationStatus stores information on which generations have reached diff

[Back to TOC](#table-of-contents)

## BackupMode

BackupMode defines the mode of backup operation.

[Back to TOC](#table-of-contents)

## BackupState

BackupState defines the desired state of a backup
Expand Down Expand Up @@ -108,6 +114,7 @@ FoundationDBBackupSpec describes the desired state of the backup for a cluster.
| imageType | ImageType defines the image type that should be used for the FoundationDBCluster deployment. When the type is set to \"unified\" the deployment will use the new fdb-kubernetes-monitor. Otherwise the main container and the sidecar container will use different images. Default: split | *ImageType | false |
| backupType | BackupType defines the backup type that should be used for the backup. When the BackupType is set to BackupTypePartitionedLog, it's expected that the FoundationDBCluster creates and manages the additional backup worker processes. A migration to a different backup type is not yet supported in the operator. Default: \"backup_agent\". | *[BackupType](#backuptype) | false |
| deletionPolicy | DeletionPolicy defines the deletion policy for this backup. The BackupDeletionPolicy defines the actions that should be taken when the FoundationDBBackup resource has a deletion timestamp. | *[BackupDeletionPolicy](#backupdeletionpolicy) | false |
| backupMode | BackupMode defines the backup mode that should be used for the backup. When the BackupMode is set to BackupModeOneTime, the backup will create a single snapshot and then stop. When set to BackupModeContinuous, the backup will run continuously, creating snapshots at regular intervals defined by SnapshotPeriodSeconds. Default: \"Continuous\". | *[BackupMode](#backupmode) | false |

[Back to TOC](#table-of-contents)

Expand All @@ -134,6 +141,7 @@ FoundationDBBackupStatusBackupDetails provides information about the state of th
| running | | bool | false |
| paused | | bool | false |
| snapshotTime | | int | false |
| restorable | | bool | false |

[Back to TOC](#table-of-contents)

Expand All @@ -147,6 +155,8 @@ FoundationDBLiveBackupStatus describes the live status of the backup for a clust
| SnapshotIntervalSeconds | SnapshotIntervalSeconds provides the interval of the snapshots. | int | false |
| Status | Status provides the current state of the backup. | [FoundationDBLiveBackupStatusState](#foundationdblivebackupstatusstate) | false |
| BackupAgentsPaused | BackupAgentsPaused describes whether the backup agents are paused. | bool | false |
| Restorable | Restorable if true, the backup can be restored | *bool | false |
| LatestRestorablePoint | LatestRestorablePoint contains information about the latest restorable point if any exists. | *[LatestRestorablePoint](#latestrestorablepoint) | false |

[Back to TOC](#table-of-contents)

Expand All @@ -157,8 +167,6 @@ FoundationDBLiveBackupStatusState provides the state of a backup in the backup s
| Field | Description | Scheme | Required |
| ----- | ----------- | ------ | -------- |
| Running | Running determines whether the backup is currently running. | bool | false |
| Restorable | Restorable if true, the backup can be restored | *bool | false |
| LatestRestorablePoint | LatestRestorablePoint contains information about the latest restorable point if any exists. | *[LatestRestorablePoint](#latestrestorablepoint) | false |

[Back to TOC](#table-of-contents)

Expand Down
Loading