Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support filesystem backup as well as blob store backup #1

Open
wants to merge 1 commit into
base: 1.52.0
Choose a base branch
from
Open
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
26 changes: 25 additions & 1 deletion api/v1beta1/foundationdbbackup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ type FoundationDBBackupSpec struct {

// This is the configuration of the target blobstore for this backup.
BlobStoreConfiguration *BlobStoreConfiguration `json:"blobStoreConfiguration,omitempty"`
// This is the configuration of the target filesystem for this backup.
FSConfiguration *FSConfiguration `json:"fsConfiguration,omitempty"`
}

// FoundationDBBackupStatus describes the current status of the backup for a cluster.
Expand Down Expand Up @@ -209,6 +211,19 @@ type BlobStoreConfiguration struct {
URLParameters []URLParamater `json:"urlParameters,omitempty"`
}

// FSConfiguration describes the blob store configuration.
type FSConfiguration struct {
// The name for the backup.
// If empty defaults to .metadata.name.
// +kubebuilder:validation:MaxLength=1024
BackupName string `json:"backupName,omitempty"`

// The url to use with the backup destination.
// +kubebuilder:validation:MaxLength=255
// +kubebuilder:validation:Required
URL string `json:"url"`
}

// ShouldRun determines whether a backup should be running.
func (backup *FoundationDBBackup) ShouldRun() bool {
return backup.Spec.BackupState == "" || backup.Spec.BackupState == BackupStateRunning || backup.Spec.BackupState == BackupStatePaused
Expand Down Expand Up @@ -236,14 +251,18 @@ func (backup *FoundationDBBackup) Bucket() string {
// BackupName gets the name of the backup in the destination.
// This will fill in a default value if the backup name in the spec is empty.
func (backup *FoundationDBBackup) BackupName() string {
if backup.Spec.BackupName == "" && (backup.Spec.BlobStoreConfiguration == nil || backup.Spec.BlobStoreConfiguration.BackupName == "") {
if backup.Spec.BackupName == "" && (backup.Spec.BlobStoreConfiguration == nil || backup.Spec.BlobStoreConfiguration.BackupName == "") && (backup.Spec.FSConfiguration == nil || backup.Spec.FSConfiguration.BackupName == "") {
return backup.ObjectMeta.Name
}

if backup.Spec.BlobStoreConfiguration != nil && backup.Spec.BlobStoreConfiguration.BackupName != "" {
return backup.Spec.BlobStoreConfiguration.BackupName
}

if backup.Spec.FSConfiguration != nil && backup.Spec.FSConfiguration.BackupName != "" {
return backup.Spec.FSConfiguration.BackupName
}

return backup.Spec.BackupName
}

Expand All @@ -253,6 +272,11 @@ func (backup *FoundationDBBackup) BackupURL() string {
return backup.Spec.BlobStoreConfiguration.getURL(backup.BackupName(), backup.Bucket())
}

// mpatou: should we use file:// ?
if backup.Spec.FSConfiguration != nil {
return fmt.Sprintf("%s/%s", backup.Spec.FSConfiguration.URL, backup.BackupName())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is a filesystem path, you should use

Suggested change
return fmt.Sprintf("%s/%s", backup.Spec.FSConfiguration.URL, backup.BackupName())
return path.Join(backup.Spec.FSConfiguration.URL, backup.BackupName())

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation of fdb indicates that you can use file:// I don't think it would work ?

}

return fmt.Sprintf("blobstore://%s/%s?bucket=%s", backup.Spec.AccountName, backup.BackupName(), backup.Bucket())
}

Expand Down
33 changes: 33 additions & 0 deletions api/v1beta1/foundationdbbackup_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,39 @@ var _ = Describe("[api] FoundationDBBackup", func() {
},
},
"blobstore://account@account/mybackup?bucket=fdb-backups&secure_connection=0"),
Entry("A backup with a fs config and a backup name",
FoundationDBBackup{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBBackupSpec{
FSConfiguration: &FSConfiguration{
URL: "/some/path",
BackupName: "backup",
},
},
},
"/some/path/backup"),
Entry("A backup with a fs config and no specific name",
FoundationDBBackup{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBBackupSpec{
FSConfiguration: &FSConfiguration{
URL: "/some/path",
},
},
},
"/some/path/mybackup"),
Entry("A backup with just a metadata name will return a generic URL based on the backup name",
FoundationDBBackup{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBBackupSpec{},
},
"blobstore:///mybackup?bucket=fdb-backups"),
)
})
})
17 changes: 14 additions & 3 deletions api/v1beta1/foundationdbrestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package v1beta1

import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -63,6 +64,8 @@ type FoundationDBRestoreSpec struct {

// This is the configuration of the target blobstore for this backup.
BlobStoreConfiguration *BlobStoreConfiguration `json:"blobStoreConfiguration,omitempty"`
// This is the configuration of the target filesystem for this backup.
FSConfiguration *FSConfiguration `json:"fsConfiguration,omitempty"`

// CustomParameters defines additional parameters to pass to the backup
// agents.
Expand Down Expand Up @@ -93,18 +96,26 @@ type FoundationDBKeyRange struct {
// BackupName gets the name of the backup for the source backup.
// This will fill in a default value if the backup name in the spec is empty.
func (restore *FoundationDBRestore) BackupName() string {
if restore.Spec.BlobStoreConfiguration == nil || restore.Spec.BlobStoreConfiguration.BackupName == "" {
return restore.ObjectMeta.Name

if restore.Spec.BlobStoreConfiguration != nil && restore.Spec.BlobStoreConfiguration.BackupName != "" {
return restore.Spec.BlobStoreConfiguration.BackupName
}

if restore.Spec.FSConfiguration != nil && restore.Spec.FSConfiguration.BackupName != "" {
return restore.Spec.FSConfiguration.BackupName
}

return restore.Spec.BlobStoreConfiguration.BackupName
return restore.ObjectMeta.Name
}

// BackupURL gets the destination url of the backup.
func (restore *FoundationDBRestore) BackupURL() string {
if restore.Spec.BlobStoreConfiguration != nil {
return restore.Spec.BlobStoreConfiguration.getURL(restore.BackupName(), restore.Spec.BlobStoreConfiguration.BucketName())
}
if restore.Spec.FSConfiguration != nil {
return fmt.Sprintf("%s/%s", restore.Spec.FSConfiguration.URL, restore.BackupName())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is a filesystem path, you should use

Suggested change
return fmt.Sprintf("%s/%s", restore.Spec.FSConfiguration.URL, restore.BackupName())
return path.Join(restore.Spec.FSConfiguration.URL, restore.BackupName())

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above ?

}

return restore.Spec.BackupURL
}
67 changes: 50 additions & 17 deletions api/v1beta1/foundationdbrestore_types_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
/*
* foundationdbbrestore_types_test.go
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2020-2021 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* foundationdbbrestore_types_test.go
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2020-2021 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package v1beta1
Expand Down Expand Up @@ -126,6 +126,39 @@ var _ = Describe("[api] FoundationDBRestore", func() {
},
},
"blobstore://account@account/mybackup?bucket=fdb-backups&secure_connection=0"),
Entry("A restore with a fs config and a backup name",
FoundationDBRestore{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBRestoreSpec{
FSConfiguration: &FSConfiguration{
URL: "/some/path",
BackupName: "backup",
},
},
},
"/some/path/backup"),
Entry("A restore with a fs config and no specific name",
FoundationDBRestore{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBRestoreSpec{
FSConfiguration: &FSConfiguration{
URL: "/some/path",
},
},
},
"/some/path/mybackup"),
Entry("A restore with just a metadata name will return an empty name",
FoundationDBRestore{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBRestoreSpec{},
},
""),
)
})
})
36 changes: 31 additions & 5 deletions api/v1beta2/foundationdbbackup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ type FoundationDBBackupSpec struct {

// This is the configuration of the target blobstore for this backup.
BlobStoreConfiguration *BlobStoreConfiguration `json:"blobStoreConfiguration,omitempty"`
// This is the configuration of the target filesystem for this backup.
FSConfiguration *FSConfiguration `json:"fsConfiguration,omitempty"`

// MainContainer defines customization for the foundationdb container.
MainContainer ContainerOverrides `json:"mainContainer,omitempty"`
Expand Down Expand Up @@ -211,6 +213,19 @@ type BlobStoreConfiguration struct {
URLParameters []URLParameter `json:"urlParameters,omitempty"`
}

// FSConfiguration describes the blob store configuration.
type FSConfiguration struct {
// The name for the backup.
// If empty defaults to .metadata.name.
// +kubebuilder:validation:MaxLength=1024
BackupName string `json:"backupName,omitempty"`

// The url to use with the backup destination.
// +kubebuilder:validation:MaxLength=255
// +kubebuilder:validation:Required
URL string `json:"url"`
}

// ShouldRun determines whether a backup should be running.
func (backup *FoundationDBBackup) ShouldRun() bool {
return backup.Spec.BackupState == "" || backup.Spec.BackupState == BackupStateRunning || backup.Spec.BackupState == BackupStatePaused
Expand All @@ -224,7 +239,7 @@ func (backup *FoundationDBBackup) ShouldBePaused() bool {
// Bucket gets the bucket this backup will use.
// This will fill in a default value if the bucket in the spec is empty.
func (backup *FoundationDBBackup) Bucket() string {
if backup.Spec.BlobStoreConfiguration.Bucket == "" {
if backup.Spec.BlobStoreConfiguration == nil || backup.Spec.BlobStoreConfiguration.Bucket == "" {
return "fdb-backups"
}

Expand All @@ -234,16 +249,27 @@ func (backup *FoundationDBBackup) Bucket() string {
// BackupName gets the name of the backup in the destination.
// This will fill in a default value if the backup name in the spec is empty.
func (backup *FoundationDBBackup) BackupName() string {
if backup.Spec.BlobStoreConfiguration.BackupName == "" {
return backup.ObjectMeta.Name
if backup.Spec.BlobStoreConfiguration != nil && backup.Spec.BlobStoreConfiguration.BackupName != "" {
return backup.Spec.BlobStoreConfiguration.BackupName
}

if backup.Spec.FSConfiguration != nil && backup.Spec.FSConfiguration.BackupName != "" {
return backup.Spec.FSConfiguration.BackupName
}

return backup.Spec.BlobStoreConfiguration.BackupName
return backup.ObjectMeta.Name
}

// BackupURL gets the destination url of the backup.
func (backup *FoundationDBBackup) BackupURL() string {
return backup.Spec.BlobStoreConfiguration.getURL(backup.BackupName(), backup.Bucket())
if backup.Spec.BlobStoreConfiguration != nil {
return backup.Spec.BlobStoreConfiguration.getURL(backup.BackupName(), backup.Bucket())
}
// mpatou: should we use file:// ?
if backup.Spec.FSConfiguration != nil {
return fmt.Sprintf("%s/%s", backup.Spec.FSConfiguration.URL, backup.BackupName())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is a filesystem path, you should use

Suggested change
return fmt.Sprintf("%s/%s", backup.Spec.FSConfiguration.URL, backup.BackupName())
return path.Join(backup.Spec.FSConfiguration.URL, backup.BackupName())

}
return ""
}

// SnapshotPeriodSeconds gets the period between snapshots for a backup.
Expand Down
25 changes: 22 additions & 3 deletions api/v1beta2/foundationdbrestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1beta2

import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -55,6 +56,8 @@ type FoundationDBRestoreSpec struct {

// This is the configuration of the target blobstore for this backup.
BlobStoreConfiguration *BlobStoreConfiguration `json:"blobStoreConfiguration,omitempty"`
// This is the configuration of the target filesystem for this backup.
FSConfiguration *FSConfiguration `json:"fsConfiguration,omitempty"`

// CustomParameters defines additional parameters to pass to the backup
// agents.
Expand Down Expand Up @@ -85,16 +88,32 @@ type FoundationDBKeyRange struct {
// BackupName gets the name of the backup for the source backup.
// This will fill in a default value if the backup name in the spec is empty.
func (restore *FoundationDBRestore) BackupName() string {
if restore.Spec.BlobStoreConfiguration == nil || restore.Spec.BlobStoreConfiguration.BackupName == "" {
if (restore.Spec.BlobStoreConfiguration == nil || restore.Spec.BlobStoreConfiguration.BackupName == "") && (restore.Spec.FSConfiguration == nil || restore.Spec.FSConfiguration.BackupName == "") {
return restore.ObjectMeta.Name
}

return restore.Spec.BlobStoreConfiguration.BackupName
if restore.Spec.BlobStoreConfiguration != nil && restore.Spec.BlobStoreConfiguration.BackupName != "" {
return restore.Spec.BlobStoreConfiguration.BackupName
}

if restore.Spec.FSConfiguration != nil && restore.Spec.FSConfiguration.BackupName != "" {
return restore.Spec.FSConfiguration.BackupName
}

return ""
}

// BackupURL gets the destination url of the backup.
func (restore *FoundationDBRestore) BackupURL() string {
return restore.Spec.BlobStoreConfiguration.getURL(restore.BackupName(), restore.Spec.BlobStoreConfiguration.BucketName())
if restore.Spec.BlobStoreConfiguration != nil {
return restore.Spec.BlobStoreConfiguration.getURL(restore.BackupName(), restore.Spec.BlobStoreConfiguration.BucketName())
}

if restore.Spec.FSConfiguration != nil {
return fmt.Sprintf("%s/%s", restore.Spec.FSConfiguration.URL, restore.BackupName())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as previous

}

return ""
}

func init() {
Expand Down
33 changes: 33 additions & 0 deletions api/v1beta2/foundationdbrestore_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,39 @@ var _ = Describe("[api] FoundationDBRestore", func() {
},
},
"blobstore://account@account:80/mybackup?bucket=fdb-backups&secure_connection=0"),
Entry("A restore with a fs config and a backup name",
FoundationDBRestore{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBRestoreSpec{
FSConfiguration: &FSConfiguration{
URL: "/some/path",
BackupName: "backup",
},
},
},
"/some/path/backup"),
Entry("A restore with a fs config and no specific name",
FoundationDBRestore{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBRestoreSpec{
FSConfiguration: &FSConfiguration{
URL: "/some/path",
},
},
},
"/some/path/mybackup"),
Entry("A restore with just a metadata name will return an empty name",
FoundationDBRestore{
ObjectMeta: metav1.ObjectMeta{
Name: "mybackup",
},
Spec: FoundationDBRestoreSpec{},
},
""),
)
})
})
Loading