Skip to content

Commit

Permalink
Merge branch 'main' into remove_snapshot_client_from_backup_controller
Browse files Browse the repository at this point in the history
Signed-off-by: Xun Jiang/Bruce Jiang <[email protected]>
Signed-off-by: Xun Jiang <[email protected]>
  • Loading branch information
blackpiglet authored and Xun Jiang committed Sep 23, 2022
2 parents cbf50a8 + b7f5cbd commit 4589cfb
Show file tree
Hide file tree
Showing 121 changed files with 1,599 additions and 1,109 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/5279-ywk253100
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support pause/unpause schedules
1 change: 1 addition & 0 deletions changelogs/unreleased/5312-sseago
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
RestoreItemAction v1 refactoring for plugin api versioning
1 change: 1 addition & 0 deletions changelogs/unreleased/5318-sseago
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
plugin versioning v1 refactor for VolumeSnapshotter
1 change: 1 addition & 0 deletions changelogs/unreleased/5350-blackpiglet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Clarify the help message for the default value of parameter --snapshot-volumes, when it's not set.
1 change: 1 addition & 0 deletions changelogs/unreleased/5353-cleverhu
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add useOwnerReferencesInBackup field doc for schedule.
1 change: 1 addition & 0 deletions changelogs/unreleased/5359-lyndon
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a repoEnsurer problem introduced by the refactor - The repoEnsurer didn't check "" state of BackupRepository, as a result, the function GetBackupRepository always returns without an error even though the ensreReady is specified.
1 change: 1 addition & 0 deletions changelogs/unreleased/5370-lyndon
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pod Volume Backup/Restore Refactor: Rename parameters in CRDs and commands to remove "Restic" word
12 changes: 10 additions & 2 deletions config/crd/v1/bases/velero.io_backups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,17 @@ spec:
CSI VolumeSnapshot status turns to ReadyToUse during creation, before
returning error as timeout. The default value is 10 minute.
type: string
defaultVolumesToFsBackup:
description: DefaultVolumesToFsBackup specifies whether pod volume
file system backup should be used for all volumes by default.
nullable: true
type: boolean
defaultVolumesToRestic:
description: DefaultVolumesToRestic specifies whether restic should
be used to take a backup of all pod volumes by default.
description: "DefaultVolumesToRestic specifies whether restic should
be used to take a backup of all pod volumes by default. \n Deprecated:
this field is no longer used and will be removed entirely in future.
Use DefaultVolumesToFsBackup instead."
nullable: true
type: boolean
excludedNamespaces:
description: ExcludedNamespaces contains a list of namespaces that
Expand Down
18 changes: 16 additions & 2 deletions config/crd/v1/bases/velero.io_schedules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .spec.paused
name: Paused
type: boolean
name: v1
schema:
openAPIV3Schema:
Expand All @@ -53,6 +56,9 @@ spec:
spec:
description: ScheduleSpec defines the specification for a Velero schedule
properties:
paused:
description: Paused specifies whether the schedule is paused or not
type: boolean
schedule:
description: Schedule is a Cron expression defining when to run the
Backup.
Expand All @@ -66,9 +72,17 @@ spec:
for CSI VolumeSnapshot status turns to ReadyToUse during creation,
before returning error as timeout. The default value is 10 minute.
type: string
defaultVolumesToFsBackup:
description: DefaultVolumesToFsBackup specifies whether pod volume
file system backup should be used for all volumes by default.
nullable: true
type: boolean
defaultVolumesToRestic:
description: DefaultVolumesToRestic specifies whether restic should
be used to take a backup of all pod volumes by default.
description: "DefaultVolumesToRestic specifies whether restic
should be used to take a backup of all pod volumes by default.
\n Deprecated: this field is no longer used and will be removed
entirely in future. Use DefaultVolumesToFsBackup instead."
nullable: true
type: boolean
excludedNamespaces:
description: ExcludedNamespaces contains a list of namespaces
Expand Down
4 changes: 2 additions & 2 deletions config/crd/v1/crds/crds.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ 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 v1
package restartabletest

import (
"reflect"
Expand All @@ -28,56 +28,56 @@ import (
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
)

type mockRestartableProcess struct {
type MockRestartableProcess struct {
mock.Mock
}

func (rp *mockRestartableProcess) AddReinitializer(key process.KindAndName, r process.Reinitializer) {
func (rp *MockRestartableProcess) AddReinitializer(key process.KindAndName, r process.Reinitializer) {
rp.Called(key, r)
}

func (rp *mockRestartableProcess) Reset() error {
func (rp *MockRestartableProcess) Reset() error {
args := rp.Called()
return args.Error(0)
}

func (rp *mockRestartableProcess) ResetIfNeeded() error {
func (rp *MockRestartableProcess) ResetIfNeeded() error {
args := rp.Called()
return args.Error(0)
}

func (rp *mockRestartableProcess) GetByKindAndName(key process.KindAndName) (interface{}, error) {
func (rp *MockRestartableProcess) GetByKindAndName(key process.KindAndName) (interface{}, error) {
args := rp.Called(key)
return args.Get(0), args.Error(1)
}

func (rp *mockRestartableProcess) Stop() {
func (rp *MockRestartableProcess) Stop() {
rp.Called()
}

type restartableDelegateTest struct {
function string
inputs []interface{}
expectedErrorOutputs []interface{}
expectedDelegateOutputs []interface{}
type RestartableDelegateTest struct {
Function string
Inputs []interface{}
ExpectedErrorOutputs []interface{}
ExpectedDelegateOutputs []interface{}
}

type mockable interface {
type Mockable interface {
Test(t mock.TestingT)
On(method string, args ...interface{}) *mock.Call
AssertExpectations(t mock.TestingT) bool
}

func runRestartableDelegateTests(
func RunRestartableDelegateTests(
t *testing.T,
kind common.PluginKind,
newRestartable func(key process.KindAndName, p process.RestartableProcess) interface{},
newMock func() mockable,
tests ...restartableDelegateTest,
newMock func() Mockable,
tests ...RestartableDelegateTest,
) {
for _, tc := range tests {
t.Run(tc.function, func(t *testing.T) {
p := new(mockRestartableProcess)
t.Run(tc.Function, func(t *testing.T) {
p := new(MockRestartableProcess)
p.Test(t)
defer p.AssertExpectations(t)

Expand All @@ -88,19 +88,19 @@ func runRestartableDelegateTests(
r := newRestartable(key, p)

// Get the method we're going to call using reflection
method := reflect.ValueOf(r).MethodByName(tc.function)
method := reflect.ValueOf(r).MethodByName(tc.Function)
require.NotEmpty(t, method)

// Convert the test case inputs ([]interface{}) to []reflect.Value
var inputValues []reflect.Value
for i := range tc.inputs {
inputValues = append(inputValues, reflect.ValueOf(tc.inputs[i]))
for i := range tc.Inputs {
inputValues = append(inputValues, reflect.ValueOf(tc.Inputs[i]))
}

// Invoke the method being tested
actual := method.Call(inputValues)

// This function asserts that the actual outputs match the expected outputs
// This Function asserts that the actual outputs match the expected outputs
checkOutputs := func(expected []interface{}, actual []reflect.Value) {
require.Equal(t, len(expected), len(actual))

Expand All @@ -118,7 +118,7 @@ func runRestartableDelegateTests(
continue
}

// If function returns nil as struct return type, we cannot just
// If Function returns nil as struct return type, we cannot just
// compare the interface to nil as its type will not be nil,
// only the value will be
if expected[i] == nil && reflect.ValueOf(a).Kind() == reflect.Ptr {
Expand All @@ -132,7 +132,7 @@ func runRestartableDelegateTests(
}

// Make sure we get what we expected when getDelegate returned an error
checkOutputs(tc.expectedErrorOutputs, actual)
checkOutputs(tc.ExpectedErrorOutputs, actual)

// Invoke delegate, make sure all returned values are passed through
p.On("ResetIfNeeded").Return(nil)
Expand All @@ -144,13 +144,13 @@ func runRestartableDelegateTests(
p.On("GetByKindAndName", key).Return(delegate, nil)

// Set up the mocked method in the delegate
delegate.On(tc.function, tc.inputs...).Return(tc.expectedDelegateOutputs...)
delegate.On(tc.Function, tc.Inputs...).Return(tc.ExpectedDelegateOutputs...)

// Invoke the method being tested
actual = method.Call(inputValues)

// Make sure we get what we expected when invoking the delegate
checkOutputs(tc.expectedDelegateOutputs, actual)
checkOutputs(tc.ExpectedDelegateOutputs, actual)
})
}
}
10 changes: 9 additions & 1 deletion pkg/apis/velero/v1/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,18 @@ type BackupSpec struct {

// DefaultVolumesToRestic specifies whether restic should be used to take a
// backup of all pod volumes by default.
//
// Deprecated: this field is no longer used and will be removed entirely in future. Use DefaultVolumesToFsBackup instead.
// +optional
// + nullable
// +nullable
DefaultVolumesToRestic *bool `json:"defaultVolumesToRestic,omitempty"`

// DefaultVolumesToFsBackup specifies whether pod volume file system backup should be used
// for all volumes by default.
// +optional
// +nullable
DefaultVolumesToFsBackup *bool `json:"defaultVolumesToFsBackup,omitempty"`

// OrderedResources specifies the backup order of resources of specific Kind.
// The map key is the Kind name and value is a list of resource names separated by commas.
// Each resource name has format "namespace/resourcename". For cluster resources, simply use "resourcename".
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/velero/v1/schedule_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ type ScheduleSpec struct {
// +optional
// +nullable
UseOwnerReferencesInBackup *bool `json:"useOwnerReferencesInBackup,omitempty"`

// Paused specifies whether the schedule is paused or not
// +optional
Paused bool `json:"paused,omitempty"`
}

// SchedulePhase is a string representation of the lifecycle phase
Expand Down Expand Up @@ -87,6 +91,7 @@ type ScheduleStatus struct {
// +kubebuilder:printcolumn:name="Schedule",type="string",JSONPath=".spec.schedule",description="A Cron expression defining when to run the Backup"
// +kubebuilder:printcolumn:name="LastBackup",type="date",JSONPath=".status.lastBackup",description="The last time a Backup was run for this schedule"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:printcolumn:name="Paused",type="boolean",JSONPath=".spec.paused"

// Schedule is a Velero resource that represents a pre-scheduled or
// periodic Backup that should be run.
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/velero/v1/zz_generated.deepcopy.go

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

44 changes: 22 additions & 22 deletions pkg/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ import (
velerov1client "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
"github.com/vmware-tanzu/velero/pkg/kuberesource"
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
"github.com/vmware-tanzu/velero/pkg/podexec"
"github.com/vmware-tanzu/velero/pkg/podvolume"
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
Expand All @@ -71,15 +71,15 @@ type Backupper interface {

// kubernetesBackupper implements Backupper.
type kubernetesBackupper struct {
backupClient velerov1client.BackupsGetter
dynamicFactory client.DynamicFactory
discoveryHelper discovery.Helper
podCommandExecutor podexec.PodCommandExecutor
resticBackupperFactory podvolume.BackupperFactory
resticTimeout time.Duration
defaultVolumesToRestic bool
clientPageSize int
uploaderType string
backupClient velerov1client.BackupsGetter
dynamicFactory client.DynamicFactory
discoveryHelper discovery.Helper
podCommandExecutor podexec.PodCommandExecutor
resticBackupperFactory podvolume.BackupperFactory
resticTimeout time.Duration
defaultVolumesToFsBackup bool
clientPageSize int
uploaderType string
}

func (i *itemKey) String() string {
Expand All @@ -104,20 +104,20 @@ func NewKubernetesBackupper(
podCommandExecutor podexec.PodCommandExecutor,
resticBackupperFactory podvolume.BackupperFactory,
resticTimeout time.Duration,
defaultVolumesToRestic bool,
defaultVolumesToFsBackup bool,
clientPageSize int,
uploaderType string,
) (Backupper, error) {
return &kubernetesBackupper{
backupClient: backupClient,
discoveryHelper: discoveryHelper,
dynamicFactory: dynamicFactory,
podCommandExecutor: podCommandExecutor,
resticBackupperFactory: resticBackupperFactory,
resticTimeout: resticTimeout,
defaultVolumesToRestic: defaultVolumesToRestic,
clientPageSize: clientPageSize,
uploaderType: uploaderType,
backupClient: backupClient,
discoveryHelper: discoveryHelper,
dynamicFactory: dynamicFactory,
podCommandExecutor: podCommandExecutor,
resticBackupperFactory: resticBackupperFactory,
resticTimeout: resticTimeout,
defaultVolumesToFsBackup: defaultVolumesToFsBackup,
clientPageSize: clientPageSize,
uploaderType: uploaderType,
}, nil
}

Expand Down Expand Up @@ -165,7 +165,7 @@ func getResourceHook(hookSpec velerov1api.BackupResourceHookSpec, discoveryHelpe
}

type VolumeSnapshotterGetter interface {
GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error)
GetVolumeSnapshotter(name string) (vsv1.VolumeSnapshotter, error)
}

// Backup backs up the items specified in the Backup, placing them in a gzip-compressed tar file
Expand Down Expand Up @@ -205,7 +205,7 @@ func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger,
backupRequest.ResourceIncludesExcludes = collections.GetResourceIncludesExcludes(kb.discoveryHelper, backupRequest.Spec.IncludedResources, backupRequest.Spec.ExcludedResources)
log.Infof("Including resources: %s", backupRequest.ResourceIncludesExcludes.IncludesString())
log.Infof("Excluding resources: %s", backupRequest.ResourceIncludesExcludes.ExcludesString())
log.Infof("Backing up all pod volumes using Restic: %t", boolptr.IsSetToTrue(backupRequest.Backup.Spec.DefaultVolumesToRestic))
log.Infof("Backing up all volumes using pod volume backup: %t", boolptr.IsSetToTrue(backupRequest.Backup.Spec.DefaultVolumesToFsBackup))

var err error
backupRequest.ResourceHooks, err = getResourceHooks(backupRequest.Spec.Hooks.Resources, kb.discoveryHelper)
Expand Down
Loading

0 comments on commit 4589cfb

Please sign in to comment.