rename pvbr param (#5370)

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
pull/5390/head
lyndon 2022-09-23 09:13:36 +08:00 committed by GitHub
parent 100d462ec0
commit c81f0db886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 491 additions and 334 deletions

View File

@ -0,0 +1 @@
Pod Volume Backup/Restore Refactor: Rename parameters in CRDs and commands to remove "Restic" word

View File

@ -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

View File

@ -72,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

File diff suppressed because one or more lines are too long

View File

@ -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".

View File

@ -337,6 +337,11 @@ func (in *BackupSpec) DeepCopyInto(out *BackupSpec) {
*out = new(bool)
**out = **in
}
if in.DefaultVolumesToFsBackup != nil {
in, out := &in.DefaultVolumesToFsBackup, &out.DefaultVolumesToFsBackup
*out = new(bool)
**out = **in
}
if in.OrderedResources != nil {
in, out := &in.OrderedResources, &out.OrderedResources
*out = make(map[string]string, len(*in))

View File

@ -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 {
@ -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
}
@ -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)

View File

@ -2806,7 +2806,7 @@ func newSnapshotLocation(ns, name, provider string) *velerov1.VolumeSnapshotLoca
}
func defaultBackup() *builder.BackupBuilder {
return builder.ForBackup(velerov1.DefaultNamespace, "backup-1").DefaultVolumesToRestic(false)
return builder.ForBackup(velerov1.DefaultNamespace, "backup-1").DefaultVolumesToFsBackup(false)
}
func toUnstructuredOrFail(t *testing.T, obj interface{}) map[string]interface{} {

View File

@ -146,10 +146,10 @@ func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstr
// nil it on error since it's not valid
pod = nil
} else {
// Get the list of volumes to back up using restic from the pod's annotations. Remove from this list
// Get the list of volumes to back up using pod volume backup from the pod's annotations. Remove from this list
// any volumes that use a PVC that we've already backed up (this would be in a read-write-many scenario,
// where it's been backed up from another pod), since we don't need >1 backup per PVC.
for _, volume := range podvolume.GetPodVolumesUsingRestic(pod, boolptr.IsSetToTrue(ib.backupRequest.Spec.DefaultVolumesToRestic)) {
for _, volume := range podvolume.GetVolumesByPod(pod, boolptr.IsSetToTrue(ib.backupRequest.Spec.DefaultVolumesToFsBackup)) {
if found, pvcName := ib.resticSnapshotTracker.HasPVCForPodVolume(pod, volume); found {
log.WithFields(map[string]interface{}{
"podVolume": volume,

View File

@ -174,6 +174,12 @@ func (b *BackupBuilder) SnapshotVolumes(val bool) *BackupBuilder {
return b
}
// DefaultVolumesToFsBackup sets the Backup's "DefaultVolumesToFsBackup" flag.
func (b *BackupBuilder) DefaultVolumesToFsBackup(val bool) *BackupBuilder {
b.object.Spec.DefaultVolumesToFsBackup = &val
return b
}
// DefaultVolumesToRestic sets the Backup's "DefaultVolumesToRestic" flag.
func (b *BackupBuilder) DefaultVolumesToRestic(val bool) *BackupBuilder {
b.object.Spec.DefaultVolumesToRestic = &val

View File

@ -82,23 +82,23 @@ func NewCreateCommand(f client.Factory, use string) *cobra.Command {
}
type CreateOptions struct {
Name string
TTL time.Duration
SnapshotVolumes flag.OptionalBool
DefaultVolumesToRestic flag.OptionalBool
IncludeNamespaces flag.StringArray
ExcludeNamespaces flag.StringArray
IncludeResources flag.StringArray
ExcludeResources flag.StringArray
Labels flag.Map
Selector flag.LabelSelector
IncludeClusterResources flag.OptionalBool
Wait bool
StorageLocation string
SnapshotLocations []string
FromSchedule string
OrderedResources string
CSISnapshotTimeout time.Duration
Name string
TTL time.Duration
SnapshotVolumes flag.OptionalBool
DefaultVolumesToFsBackup flag.OptionalBool
IncludeNamespaces flag.StringArray
ExcludeNamespaces flag.StringArray
IncludeResources flag.StringArray
ExcludeResources flag.StringArray
Labels flag.Map
Selector flag.LabelSelector
IncludeClusterResources flag.OptionalBool
Wait bool
StorageLocation string
SnapshotLocations []string
FromSchedule string
OrderedResources string
CSISnapshotTimeout time.Duration
client veleroclient.Interface
}
@ -132,7 +132,7 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) {
f = flags.VarPF(&o.IncludeClusterResources, "include-cluster-resources", "", "Include cluster-scoped resources in the backup")
f.NoOptDefVal = "true"
f = flags.VarPF(&o.DefaultVolumesToRestic, "default-volumes-to-restic", "", "Use restic by default to backup all pod volumes")
f = flags.VarPF(&o.DefaultVolumesToFsBackup, "default-volumes-to-fs-backup", "", "Use pod volume file system backup by default for volumes")
f.NoOptDefVal = "true"
}
@ -350,8 +350,8 @@ func (o *CreateOptions) BuildBackup(namespace string) (*velerov1api.Backup, erro
if o.IncludeClusterResources.Value != nil {
backupBuilder.IncludeClusterResources(*o.IncludeClusterResources.Value)
}
if o.DefaultVolumesToRestic.Value != nil {
backupBuilder.DefaultVolumesToRestic(*o.DefaultVolumesToRestic.Value)
if o.DefaultVolumesToFsBackup.Value != nil {
backupBuilder.DefaultVolumesToFsBackup(*o.DefaultVolumesToFsBackup.Value)
}
}

View File

@ -43,40 +43,40 @@ import (
// InstallOptions collects all the options for installing Velero into a Kubernetes cluster.
type InstallOptions struct {
Namespace string
Image string
BucketName string
Prefix string
ProviderName string
PodAnnotations flag.Map
PodLabels flag.Map
ServiceAccountAnnotations flag.Map
VeleroPodCPURequest string
VeleroPodMemRequest string
VeleroPodCPULimit string
VeleroPodMemLimit string
ResticPodCPURequest string
ResticPodMemRequest string
ResticPodCPULimit string
ResticPodMemLimit string
RestoreOnly bool
SecretFile string
NoSecret bool
DryRun bool
BackupStorageConfig flag.Map
VolumeSnapshotConfig flag.Map
UseRestic bool
Wait bool
UseVolumeSnapshots bool
DefaultResticMaintenanceFrequency time.Duration
GarbageCollectionFrequency time.Duration
Plugins flag.StringArray
NoDefaultBackupLocation bool
CRDsOnly bool
CACertFile string
Features string
DefaultVolumesToRestic bool
UploaderType string
Namespace string
Image string
BucketName string
Prefix string
ProviderName string
PodAnnotations flag.Map
PodLabels flag.Map
ServiceAccountAnnotations flag.Map
VeleroPodCPURequest string
VeleroPodMemRequest string
VeleroPodCPULimit string
VeleroPodMemLimit string
ResticPodCPURequest string
ResticPodMemRequest string
ResticPodCPULimit string
ResticPodMemLimit string
RestoreOnly bool
SecretFile string
NoSecret bool
DryRun bool
BackupStorageConfig flag.Map
VolumeSnapshotConfig flag.Map
UseRestic bool
Wait bool
UseVolumeSnapshots bool
DefaultRepoMaintenanceFrequency time.Duration
GarbageCollectionFrequency time.Duration
Plugins flag.StringArray
NoDefaultBackupLocation bool
CRDsOnly bool
CACertFile string
Features string
DefaultVolumesToFsBackup bool
UploaderType string
}
// BindFlags adds command line values to the options struct.
@ -106,13 +106,13 @@ func (o *InstallOptions) BindFlags(flags *pflag.FlagSet) {
flags.BoolVar(&o.DryRun, "dry-run", o.DryRun, "Generate resources, but don't send them to the cluster. Use with -o. Optional.")
flags.BoolVar(&o.UseRestic, "use-restic", o.UseRestic, "Create restic daemonset. Optional.")
flags.BoolVar(&o.Wait, "wait", o.Wait, "Wait for Velero deployment to be ready. Optional.")
flags.DurationVar(&o.DefaultResticMaintenanceFrequency, "default-restic-prune-frequency", o.DefaultResticMaintenanceFrequency, "How often 'restic prune' is run for restic repositories by default. Optional.")
flags.DurationVar(&o.DefaultRepoMaintenanceFrequency, "default-repo-maintain-frequency", o.DefaultRepoMaintenanceFrequency, "How often 'maintain' is run for backup repositories by default. Optional.")
flags.DurationVar(&o.GarbageCollectionFrequency, "garbage-collection-frequency", o.GarbageCollectionFrequency, "How often the garbage collection runs for expired backups.(default 1h)")
flags.Var(&o.Plugins, "plugins", "Plugin container images to install into the Velero Deployment")
flags.BoolVar(&o.CRDsOnly, "crds-only", o.CRDsOnly, "Only generate CustomResourceDefinition resources. Useful for updating CRDs for an existing Velero install.")
flags.StringVar(&o.CACertFile, "cacert", o.CACertFile, "File containing a certificate bundle to use when verifying TLS connections to the object store. Optional.")
flags.StringVar(&o.Features, "features", o.Features, "Comma separated list of Velero feature flags to be set on the Velero deployment and the restic daemonset, if restic is enabled")
flags.BoolVar(&o.DefaultVolumesToRestic, "default-volumes-to-restic", o.DefaultVolumesToRestic, "Bool flag to configure Velero server to use restic by default to backup all pod volumes on all backups. Optional.")
flags.BoolVar(&o.DefaultVolumesToFsBackup, "default-volumes-to-fs-backup", o.DefaultVolumesToFsBackup, "Bool flag to configure Velero server to use pod volume file system backup by default for all volumes on all backups. Optional.")
flags.StringVar(&o.UploaderType, "uploader-type", o.UploaderType, fmt.Sprintf("The type of uploader to transfer the data of pod volumes, the supported values are '%s', '%s'", uploader.ResticType, uploader.KopiaType))
}
@ -135,11 +135,11 @@ func NewInstallOptions() *InstallOptions {
ResticPodCPULimit: install.DefaultResticPodCPULimit,
ResticPodMemLimit: install.DefaultResticPodMemLimit,
// Default to creating a VSL unless we're told otherwise
UseVolumeSnapshots: true,
NoDefaultBackupLocation: false,
CRDsOnly: false,
DefaultVolumesToRestic: false,
UploaderType: uploader.ResticType,
UseVolumeSnapshots: true,
NoDefaultBackupLocation: false,
CRDsOnly: false,
DefaultVolumesToFsBackup: false,
UploaderType: uploader.ResticType,
}
}
@ -177,30 +177,30 @@ func (o *InstallOptions) AsVeleroOptions() (*install.VeleroOptions, error) {
}
return &install.VeleroOptions{
Namespace: o.Namespace,
Image: o.Image,
ProviderName: o.ProviderName,
Bucket: o.BucketName,
Prefix: o.Prefix,
PodAnnotations: o.PodAnnotations.Data(),
PodLabels: o.PodLabels.Data(),
ServiceAccountAnnotations: o.ServiceAccountAnnotations.Data(),
VeleroPodResources: veleroPodResources,
ResticPodResources: resticPodResources,
SecretData: secretData,
RestoreOnly: o.RestoreOnly,
UseRestic: o.UseRestic,
UseVolumeSnapshots: o.UseVolumeSnapshots,
BSLConfig: o.BackupStorageConfig.Data(),
VSLConfig: o.VolumeSnapshotConfig.Data(),
DefaultResticMaintenanceFrequency: o.DefaultResticMaintenanceFrequency,
GarbageCollectionFrequency: o.GarbageCollectionFrequency,
Plugins: o.Plugins,
NoDefaultBackupLocation: o.NoDefaultBackupLocation,
CACertData: caCertData,
Features: strings.Split(o.Features, ","),
DefaultVolumesToRestic: o.DefaultVolumesToRestic,
UploaderType: o.UploaderType,
Namespace: o.Namespace,
Image: o.Image,
ProviderName: o.ProviderName,
Bucket: o.BucketName,
Prefix: o.Prefix,
PodAnnotations: o.PodAnnotations.Data(),
PodLabels: o.PodLabels.Data(),
ServiceAccountAnnotations: o.ServiceAccountAnnotations.Data(),
VeleroPodResources: veleroPodResources,
ResticPodResources: resticPodResources,
SecretData: secretData,
RestoreOnly: o.RestoreOnly,
UseRestic: o.UseRestic,
UseVolumeSnapshots: o.UseVolumeSnapshots,
BSLConfig: o.BackupStorageConfig.Data(),
VSLConfig: o.VolumeSnapshotConfig.Data(),
DefaultRepoMaintenanceFrequency: o.DefaultRepoMaintenanceFrequency,
GarbageCollectionFrequency: o.GarbageCollectionFrequency,
Plugins: o.Plugins,
NoDefaultBackupLocation: o.NoDefaultBackupLocation,
CACertData: caCertData,
Features: strings.Split(o.Features, ","),
DefaultVolumesToFsBackup: o.DefaultVolumesToFsBackup,
UploaderType: o.UploaderType,
}, nil
}
@ -393,8 +393,8 @@ func (o *InstallOptions) Validate(c *cobra.Command, args []string, f client.Fact
}
}
if o.DefaultVolumesToRestic && !o.UseRestic {
return errors.New("--use-restic is required when using --default-volumes-to-restic")
if o.DefaultVolumesToFsBackup && !o.UseRestic {
return errors.New("--use-restic is required when using --default-volumes-to-fs-backup")
}
switch {
@ -404,8 +404,8 @@ func (o *InstallOptions) Validate(c *cobra.Command, args []string, f client.Fact
return errors.New("Cannot use both --secret-file and --no-secret")
}
if o.DefaultResticMaintenanceFrequency < 0 {
return errors.New("--default-restic-prune-frequency must be non-negative")
if o.DefaultRepoMaintenanceFrequency < 0 {
return errors.New("--default-repo-maintain-frequency must be non-negative")
}
if o.GarbageCollectionFrequency < 0 {

View File

@ -135,19 +135,19 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
},
Spec: api.ScheduleSpec{
Template: api.BackupSpec{
IncludedNamespaces: o.BackupOptions.IncludeNamespaces,
ExcludedNamespaces: o.BackupOptions.ExcludeNamespaces,
IncludedResources: o.BackupOptions.IncludeResources,
ExcludedResources: o.BackupOptions.ExcludeResources,
IncludeClusterResources: o.BackupOptions.IncludeClusterResources.Value,
LabelSelector: o.BackupOptions.Selector.LabelSelector,
SnapshotVolumes: o.BackupOptions.SnapshotVolumes.Value,
TTL: metav1.Duration{Duration: o.BackupOptions.TTL},
StorageLocation: o.BackupOptions.StorageLocation,
VolumeSnapshotLocations: o.BackupOptions.SnapshotLocations,
DefaultVolumesToRestic: o.BackupOptions.DefaultVolumesToRestic.Value,
OrderedResources: orders,
CSISnapshotTimeout: metav1.Duration{Duration: o.BackupOptions.CSISnapshotTimeout},
IncludedNamespaces: o.BackupOptions.IncludeNamespaces,
ExcludedNamespaces: o.BackupOptions.ExcludeNamespaces,
IncludedResources: o.BackupOptions.IncludeResources,
ExcludedResources: o.BackupOptions.ExcludeResources,
IncludeClusterResources: o.BackupOptions.IncludeClusterResources.Value,
LabelSelector: o.BackupOptions.Selector.LabelSelector,
SnapshotVolumes: o.BackupOptions.SnapshotVolumes.Value,
TTL: metav1.Duration{Duration: o.BackupOptions.TTL},
StorageLocation: o.BackupOptions.StorageLocation,
VolumeSnapshotLocations: o.BackupOptions.SnapshotLocations,
DefaultVolumesToFsBackup: o.BackupOptions.DefaultVolumesToFsBackup.Value,
OrderedResources: orders,
CSISnapshotTimeout: metav1.Duration{Duration: o.BackupOptions.CSISnapshotTimeout},
},
Schedule: o.Schedule,
UseOwnerReferencesInBackup: &o.UseOwnerReferencesInBackup,

View File

@ -71,7 +71,6 @@ import (
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt/process"
"github.com/vmware-tanzu/velero/pkg/podexec"
"github.com/vmware-tanzu/velero/pkg/restic"
"github.com/vmware-tanzu/velero/pkg/restore"
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
"github.com/vmware-tanzu/velero/pkg/util/logging"
@ -133,7 +132,7 @@ type serverConfig struct {
formatFlag *logging.FormatFlag
repoMaintenanceFrequency time.Duration
garbageCollectionFrequency time.Duration
defaultVolumesToRestic bool
defaultVolumesToFsBackup bool
uploaderType string
}
@ -163,7 +162,7 @@ func NewCommand(f client.Factory) *cobra.Command {
profilerAddress: defaultProfilerAddress,
resourceTerminatingTimeout: defaultResourceTerminatingTimeout,
formatFlag: logging.NewFormatFlag(),
defaultVolumesToRestic: restic.DefaultVolumesToRestic,
defaultVolumesToFsBackup: podvolume.DefaultVolumesToFsBackup,
uploaderType: uploader.ResticType,
}
)
@ -214,7 +213,7 @@ func NewCommand(f client.Factory) *cobra.Command {
command.Flags().StringVar(&config.pluginDir, "plugin-dir", config.pluginDir, "Directory containing Velero plugins")
command.Flags().StringVar(&config.metricsAddress, "metrics-address", config.metricsAddress, "The address to expose prometheus metrics")
command.Flags().DurationVar(&config.backupSyncPeriod, "backup-sync-period", config.backupSyncPeriod, "How often to ensure all Velero backups in object storage exist as Backup API objects in the cluster. This is the default sync period if none is explicitly specified for a backup storage location.")
command.Flags().DurationVar(&config.podVolumeOperationTimeout, "restic-timeout", config.podVolumeOperationTimeout, "How long backups/restores of pod volumes should be allowed to run before timing out.")
command.Flags().DurationVar(&config.podVolumeOperationTimeout, "fs-backup-timeout", config.podVolumeOperationTimeout, "How long pod volume file system backups/restores should be allowed to run before timing out.")
command.Flags().BoolVar(&config.restoreOnly, "restore-only", config.restoreOnly, "Run in a mode where only restores are allowed; backups, schedules, and garbage-collection are all disabled. DEPRECATED: this flag will be removed in v2.0. Use read-only backup storage locations instead.")
command.Flags().StringSliceVar(&config.disabledControllers, "disable-controllers", config.disabledControllers, fmt.Sprintf("List of controllers to disable on startup. Valid values are %s", strings.Join(controller.DisableableControllers, ",")))
command.Flags().StringSliceVar(&config.restoreResourcePriorities, "restore-resource-priorities", config.restoreResourcePriorities, "Desired order of resource restores; any resource not in the list will be restored alphabetically after the prioritized resources.")
@ -227,9 +226,9 @@ func NewCommand(f client.Factory) *cobra.Command {
command.Flags().StringVar(&config.profilerAddress, "profiler-address", config.profilerAddress, "The address to expose the pprof profiler.")
command.Flags().DurationVar(&config.resourceTerminatingTimeout, "terminating-resource-timeout", config.resourceTerminatingTimeout, "How long to wait on persistent volumes and namespaces to terminate during a restore before timing out.")
command.Flags().DurationVar(&config.defaultBackupTTL, "default-backup-ttl", config.defaultBackupTTL, "How long to wait by default before backups can be garbage collected.")
command.Flags().DurationVar(&config.repoMaintenanceFrequency, "default-restic-prune-frequency", config.repoMaintenanceFrequency, "How often 'prune' is run for backup repositories by default.")
command.Flags().DurationVar(&config.repoMaintenanceFrequency, "default-repo-maintain-frequency", config.repoMaintenanceFrequency, "How often 'maintain' is run for backup repositories by default.")
command.Flags().DurationVar(&config.garbageCollectionFrequency, "garbage-collection-frequency", config.garbageCollectionFrequency, "How often garbage collection is run for expired backups.")
command.Flags().BoolVar(&config.defaultVolumesToRestic, "default-volumes-to-restic", config.defaultVolumesToRestic, "Backup all volumes with restic by default.")
command.Flags().BoolVar(&config.defaultVolumesToFsBackup, "default-volumes-to-fs-backup", config.defaultVolumesToFsBackup, "Backup all volumes with pod volume file system backup by default.")
command.Flags().StringVar(&config.uploaderType, "uploader-type", config.uploaderType, "Type of uploader to handle the transfer of data of pod volumes")
return command
@ -622,7 +621,7 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
s.kubeClient.CoreV1(), s.kubeClient.CoreV1(),
s.sharedInformerFactory.Velero().V1().BackupRepositories().Informer().HasSynced, s.logger),
s.config.podVolumeOperationTimeout,
s.config.defaultVolumesToRestic,
s.config.defaultVolumesToFsBackup,
s.config.clientPageSize,
s.config.uploaderType,
)
@ -639,7 +638,7 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
backupTracker,
s.mgr.GetClient(),
s.config.defaultBackupLocation,
s.config.defaultVolumesToRestic,
s.config.defaultVolumesToFsBackup,
s.config.defaultBackupTTL,
s.config.defaultCSISnapshotTimeout,
s.sharedInformerFactory.Velero().V1().VolumeSnapshotLocations().Lister(),

View File

@ -86,7 +86,7 @@ type backupController struct {
newPluginManager func(logrus.FieldLogger) clientmgmt.Manager
backupTracker BackupTracker
defaultBackupLocation string
defaultVolumesToRestic bool
defaultVolumesToFsBackup bool
defaultBackupTTL time.Duration
defaultCSISnapshotTimeout time.Duration
snapshotLocationLister velerov1listers.VolumeSnapshotLocationLister
@ -112,7 +112,7 @@ func NewBackupController(
backupTracker BackupTracker,
kbClient kbclient.Client,
defaultBackupLocation string,
defaultVolumesToRestic bool,
defaultVolumesToFsBackup bool,
defaultBackupTTL time.Duration,
defaultCSISnapshotTimeout time.Duration,
volumeSnapshotLocationLister velerov1listers.VolumeSnapshotLocationLister,
@ -138,7 +138,7 @@ func NewBackupController(
backupTracker: backupTracker,
kbClient: kbClient,
defaultBackupLocation: defaultBackupLocation,
defaultVolumesToRestic: defaultVolumesToRestic,
defaultVolumesToFsBackup: defaultVolumesToFsBackup,
defaultBackupTTL: defaultBackupTTL,
defaultCSISnapshotTimeout: defaultCSISnapshotTimeout,
snapshotLocationLister: volumeSnapshotLocationLister,
@ -263,7 +263,7 @@ func (c *backupController) processBackup(key string) error {
}
log.Debug("Preparing backup request")
request := c.prepareBackupRequest(original)
request := c.prepareBackupRequest(original, log)
if len(request.Status.ValidationErrors) > 0 {
request.Status.Phase = velerov1api.BackupPhaseFailedValidation
} else {
@ -349,7 +349,7 @@ func patchBackup(original, updated *velerov1api.Backup, client velerov1client.Ba
return res, nil
}
func (c *backupController) prepareBackupRequest(backup *velerov1api.Backup) *pkgbackup.Request {
func (c *backupController) prepareBackupRequest(backup *velerov1api.Backup, logger logrus.FieldLogger) *pkgbackup.Request {
request := &pkgbackup.Request{
Backup: backup.DeepCopy(), // don't modify items in the cache
}
@ -373,8 +373,15 @@ func (c *backupController) prepareBackupRequest(backup *velerov1api.Backup) *pkg
// calculate expiration
request.Status.Expiration = &metav1.Time{Time: c.clock.Now().Add(request.Spec.TTL.Duration)}
if request.Spec.DefaultVolumesToRestic == nil {
request.Spec.DefaultVolumesToRestic = &c.defaultVolumesToRestic
// TODO: post v1.10. Remove this code block after DefaultVolumesToRestic is removed from CRD
// For now, for CRs created by old versions, we need to respect the DefaultVolumesToRestic value if it is set true
if boolptr.IsSetToTrue(request.Spec.DefaultVolumesToRestic) {
logger.Warn("DefaultVolumesToRestic field will be deprecated, use DefaultVolumesToFsBackup instead. Automatically remap it to DefaultVolumesToFsBackup")
request.Spec.DefaultVolumesToFsBackup = request.Spec.DefaultVolumesToRestic
}
if request.Spec.DefaultVolumesToFsBackup == nil {
request.Spec.DefaultVolumesToFsBackup = &c.defaultVolumesToFsBackup
}
// find which storage location to use

View File

@ -280,7 +280,7 @@ func TestBackupLocationLabel(t *testing.T) {
formatFlag: formatFlag,
}
res := c.prepareBackupRequest(test.backup)
res := c.prepareBackupRequest(test.backup, logger)
assert.NotNil(t, res)
assert.Equal(t, test.expectedBackupLocation, res.Labels[velerov1api.StorageLocationLabel])
})
@ -342,7 +342,7 @@ func TestDefaultBackupTTL(t *testing.T) {
formatFlag: formatFlag,
}
res := c.prepareBackupRequest(test.backup)
res := c.prepareBackupRequest(test.backup, logger)
assert.NotNil(t, res)
assert.Equal(t, test.expectedTTL, res.Spec.TTL)
assert.Equal(t, test.expectedExpiration, *res.Status.Expiration)
@ -350,6 +350,121 @@ func TestDefaultBackupTTL(t *testing.T) {
}
}
func TestDefaultVolumesToResticDeprecation(t *testing.T) {
tests := []struct {
name string
backup *velerov1api.Backup
globalVal bool
expectGlobal bool
expectRemap bool
expectVal bool
}{
{
name: "DefaultVolumesToRestic is not set, DefaultVolumesToFsBackup is not set",
backup: defaultBackup().Result(),
globalVal: true,
expectGlobal: true,
expectVal: true,
},
{
name: "DefaultVolumesToRestic is not set, DefaultVolumesToFsBackup is set to false",
backup: defaultBackup().DefaultVolumesToFsBackup(false).Result(),
globalVal: true,
expectVal: false,
},
{
name: "DefaultVolumesToRestic is not set, DefaultVolumesToFsBackup is set to true",
backup: defaultBackup().DefaultVolumesToFsBackup(true).Result(),
globalVal: false,
expectVal: true,
},
{
name: "DefaultVolumesToRestic is set to false, DefaultVolumesToFsBackup is not set",
backup: defaultBackup().DefaultVolumesToRestic(false).Result(),
globalVal: false,
expectGlobal: true,
expectVal: false,
},
{
name: "DefaultVolumesToRestic is set to false, DefaultVolumesToFsBackup is set to true",
backup: defaultBackup().DefaultVolumesToRestic(false).DefaultVolumesToFsBackup(true).Result(),
globalVal: false,
expectVal: true,
},
{
name: "DefaultVolumesToRestic is set to false, DefaultVolumesToFsBackup is set to false",
backup: defaultBackup().DefaultVolumesToRestic(false).DefaultVolumesToFsBackup(false).Result(),
globalVal: true,
expectVal: false,
},
{
name: "DefaultVolumesToRestic is set to true, DefaultVolumesToFsBackup is not set",
backup: defaultBackup().DefaultVolumesToRestic(true).Result(),
globalVal: false,
expectRemap: true,
expectVal: true,
},
{
name: "DefaultVolumesToRestic is set to true, DefaultVolumesToFsBackup is set to false",
backup: defaultBackup().DefaultVolumesToRestic(true).DefaultVolumesToFsBackup(false).Result(),
globalVal: false,
expectRemap: true,
expectVal: true,
},
{
name: "DefaultVolumesToRestic is set to true, DefaultVolumesToFsBackup is set to true",
backup: defaultBackup().DefaultVolumesToRestic(true).DefaultVolumesToFsBackup(true).Result(),
globalVal: false,
expectRemap: true,
expectVal: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
formatFlag := logging.FormatText
var (
clientset = fake.NewSimpleClientset(test.backup)
sharedInformers = informers.NewSharedInformerFactory(clientset, 0)
logger = logging.DefaultLogger(logrus.DebugLevel, formatFlag)
fakeClient = velerotest.NewFakeControllerRuntimeClient(t)
)
apiServer := velerotest.NewAPIServer(t)
discoveryHelper, err := discovery.NewHelper(apiServer.DiscoveryClient, logger)
require.NoError(t, err)
c := &backupController{
genericController: newGenericController("backup-test", logger),
discoveryHelper: discoveryHelper,
client: clientset.VeleroV1(),
lister: sharedInformers.Velero().V1().Backups().Lister(),
kbClient: fakeClient,
snapshotLocationLister: sharedInformers.Velero().V1().VolumeSnapshotLocations().Lister(),
clock: &clock.RealClock{},
formatFlag: formatFlag,
defaultVolumesToFsBackup: test.globalVal,
}
res := c.prepareBackupRequest(test.backup, logger)
assert.NotNil(t, res)
assert.NotNil(t, res.Spec.DefaultVolumesToFsBackup)
if test.expectRemap {
assert.Equal(t, res.Spec.DefaultVolumesToRestic, res.Spec.DefaultVolumesToFsBackup)
} else if test.expectGlobal {
assert.False(t, res.Spec.DefaultVolumesToRestic == res.Spec.DefaultVolumesToFsBackup)
assert.Equal(t, &c.defaultVolumesToFsBackup, res.Spec.DefaultVolumesToFsBackup)
} else {
assert.False(t, res.Spec.DefaultVolumesToRestic == res.Spec.DefaultVolumesToFsBackup)
assert.False(t, &c.defaultVolumesToFsBackup == res.Spec.DefaultVolumesToFsBackup)
}
assert.Equal(t, test.expectVal, *res.Spec.DefaultVolumesToFsBackup)
})
}
}
func TestProcessBackupCompletions(t *testing.T) {
defaultBackupLocation := builder.ForBackupStorageLocation("velero", "loc-1").Default(true).Bucket("store-1").Result()
@ -359,20 +474,20 @@ func TestProcessBackupCompletions(t *testing.T) {
timestamp := metav1.NewTime(now)
tests := []struct {
name string
backup *velerov1api.Backup
backupLocation *velerov1api.BackupStorageLocation
defaultVolumesToRestic bool
expectedResult *velerov1api.Backup
backupExists bool
existenceCheckError error
name string
backup *velerov1api.Backup
backupLocation *velerov1api.BackupStorageLocation
defaultVolumesToFsBackup bool
expectedResult *velerov1api.Backup
backupExists bool
existenceCheckError error
}{
// Completed
{
name: "backup with no backup location gets the default",
backup: defaultBackup().Result(),
backupLocation: defaultBackupLocation,
defaultVolumesToRestic: true,
name: "backup with no backup location gets the default",
backup: defaultBackup().Result(),
backupLocation: defaultBackupLocation,
defaultVolumesToFsBackup: true,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -391,8 +506,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.True(),
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.True(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -405,10 +520,10 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
{
name: "backup with a specific backup location keeps it",
backup: defaultBackup().StorageLocation("alt-loc").Result(),
backupLocation: builder.ForBackupStorageLocation("velero", "alt-loc").Bucket("store-1").Result(),
defaultVolumesToRestic: false,
name: "backup with a specific backup location keeps it",
backup: defaultBackup().StorageLocation("alt-loc").Result(),
backupLocation: builder.ForBackupStorageLocation("velero", "alt-loc").Bucket("store-1").Result(),
defaultVolumesToFsBackup: false,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -427,8 +542,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: "alt-loc",
DefaultVolumesToRestic: boolptr.False(),
StorageLocation: "alt-loc",
DefaultVolumesToFsBackup: boolptr.False(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -447,7 +562,7 @@ func TestProcessBackupCompletions(t *testing.T) {
Bucket("store-1").
AccessMode(velerov1api.BackupStorageLocationAccessModeReadWrite).
Result(),
defaultVolumesToRestic: true,
defaultVolumesToFsBackup: true,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -466,8 +581,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: "read-write",
DefaultVolumesToRestic: boolptr.True(),
StorageLocation: "read-write",
DefaultVolumesToFsBackup: boolptr.True(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -480,10 +595,10 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
{
name: "backup with a TTL has expiration set",
backup: defaultBackup().TTL(10 * time.Minute).Result(),
backupLocation: defaultBackupLocation,
defaultVolumesToRestic: false,
name: "backup with a TTL has expiration set",
backup: defaultBackup().TTL(10 * time.Minute).Result(),
backupLocation: defaultBackupLocation,
defaultVolumesToFsBackup: false,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -502,9 +617,9 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
TTL: metav1.Duration{Duration: 10 * time.Minute},
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.False(),
TTL: metav1.Duration{Duration: 10 * time.Minute},
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.False(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -517,11 +632,11 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
{
name: "backup without an existing backup will succeed",
backupExists: false,
backup: defaultBackup().Result(),
backupLocation: defaultBackupLocation,
defaultVolumesToRestic: true,
name: "backup without an existing backup will succeed",
backupExists: false,
backup: defaultBackup().Result(),
backupLocation: defaultBackupLocation,
defaultVolumesToFsBackup: true,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -540,8 +655,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.True(),
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.True(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -554,12 +669,12 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
{
name: "backup specifying a false value for 'DefaultVolumesToRestic' keeps it",
name: "backup specifying a false value for 'DefaultVolumesToFsBackup' keeps it",
backupExists: false,
backup: defaultBackup().DefaultVolumesToRestic(false).Result(),
backup: defaultBackup().DefaultVolumesToFsBackup(false).Result(),
backupLocation: defaultBackupLocation,
// value set in the controller is different from that specified in the backup
defaultVolumesToRestic: true,
defaultVolumesToFsBackup: true,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -578,8 +693,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.False(),
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.False(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -592,12 +707,12 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
{
name: "backup specifying a true value for 'DefaultVolumesToRestic' keeps it",
name: "backup specifying a true value for 'DefaultVolumesToFsBackup' keeps it",
backupExists: false,
backup: defaultBackup().DefaultVolumesToRestic(true).Result(),
backup: defaultBackup().DefaultVolumesToFsBackup(true).Result(),
backupLocation: defaultBackupLocation,
// value set in the controller is different from that specified in the backup
defaultVolumesToRestic: false,
defaultVolumesToFsBackup: false,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -616,8 +731,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.True(),
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.True(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -630,12 +745,12 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
{
name: "backup specifying no value for 'DefaultVolumesToRestic' gets the default true value",
name: "backup specifying no value for 'DefaultVolumesToFsBackup' gets the default true value",
backupExists: false,
backup: defaultBackup().Result(),
backupLocation: defaultBackupLocation,
// value set in the controller is different from that specified in the backup
defaultVolumesToRestic: true,
defaultVolumesToFsBackup: true,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -654,8 +769,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.True(),
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.True(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -668,12 +783,12 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
{
name: "backup specifying no value for 'DefaultVolumesToRestic' gets the default false value",
name: "backup specifying no value for 'DefaultVolumesToFsBackup' gets the default false value",
backupExists: false,
backup: defaultBackup().Result(),
backupLocation: defaultBackupLocation,
// value set in the controller is different from that specified in the backup
defaultVolumesToRestic: false,
defaultVolumesToFsBackup: false,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -692,8 +807,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.False(),
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.False(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseCompleted,
@ -708,11 +823,11 @@ func TestProcessBackupCompletions(t *testing.T) {
// Failed
{
name: "backup with existing backup will fail",
backupExists: true,
backup: defaultBackup().Result(),
backupLocation: defaultBackupLocation,
defaultVolumesToRestic: true,
name: "backup with existing backup will fail",
backupExists: true,
backup: defaultBackup().Result(),
backupLocation: defaultBackupLocation,
defaultVolumesToFsBackup: true,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -731,8 +846,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.True(),
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.True(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseFailed,
@ -746,11 +861,11 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
{
name: "error when checking if backup exists will cause backup to fail",
backup: defaultBackup().Result(),
existenceCheckError: errors.New("Backup already exists in object storage"),
backupLocation: defaultBackupLocation,
defaultVolumesToRestic: true,
name: "error when checking if backup exists will cause backup to fail",
backup: defaultBackup().Result(),
existenceCheckError: errors.New("Backup already exists in object storage"),
backupLocation: defaultBackupLocation,
defaultVolumesToFsBackup: true,
expectedResult: &velerov1api.Backup{
TypeMeta: metav1.TypeMeta{
Kind: "Backup",
@ -769,8 +884,8 @@ func TestProcessBackupCompletions(t *testing.T) {
},
},
Spec: velerov1api.BackupSpec{
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToRestic: boolptr.True(),
StorageLocation: defaultBackupLocation.Name,
DefaultVolumesToFsBackup: boolptr.True(),
},
Status: velerov1api.BackupStatus{
Phase: velerov1api.BackupPhaseFailed,
@ -823,21 +938,21 @@ func TestProcessBackupCompletions(t *testing.T) {
require.NoError(t, err)
c := &backupController{
genericController: newGenericController("backup-test", logger),
discoveryHelper: discoveryHelper,
client: clientset.VeleroV1(),
lister: sharedInformers.Velero().V1().Backups().Lister(),
kbClient: fakeClient,
snapshotLocationLister: sharedInformers.Velero().V1().VolumeSnapshotLocations().Lister(),
defaultBackupLocation: defaultBackupLocation.Name,
defaultVolumesToRestic: test.defaultVolumesToRestic,
backupTracker: NewBackupTracker(),
metrics: metrics.NewServerMetrics(),
clock: clock.NewFakeClock(now),
newPluginManager: func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager },
backupStoreGetter: NewFakeSingleObjectBackupStoreGetter(backupStore),
backupper: backupper,
formatFlag: formatFlag,
genericController: newGenericController("backup-test", logger),
discoveryHelper: discoveryHelper,
client: clientset.VeleroV1(),
lister: sharedInformers.Velero().V1().Backups().Lister(),
kbClient: fakeClient,
snapshotLocationLister: sharedInformers.Velero().V1().VolumeSnapshotLocations().Lister(),
defaultBackupLocation: defaultBackupLocation.Name,
defaultVolumesToFsBackup: test.defaultVolumesToFsBackup,
backupTracker: NewBackupTracker(),
metrics: metrics.NewServerMetrics(),
clock: clock.NewFakeClock(now),
newPluginManager: func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager },
backupStoreGetter: NewFakeSingleObjectBackupStoreGetter(backupStore),
backupper: backupper,
formatFlag: formatFlag,
}
pluginManager.On("GetBackupItemActions").Return(nil, nil)

View File

@ -32,19 +32,19 @@ import (
type podTemplateOption func(*podTemplateConfig)
type podTemplateConfig struct {
image string
envVars []corev1.EnvVar
restoreOnly bool
annotations map[string]string
labels map[string]string
resources corev1.ResourceRequirements
withSecret bool
defaultResticMaintenanceFrequency time.Duration
garbageCollectionFrequency time.Duration
plugins []string
features []string
defaultVolumesToRestic bool
uploaderType string
image string
envVars []corev1.EnvVar
restoreOnly bool
annotations map[string]string
labels map[string]string
resources corev1.ResourceRequirements
withSecret bool
defaultRepoMaintenanceFrequency time.Duration
garbageCollectionFrequency time.Duration
plugins []string
features []string
defaultVolumesToFsBackup bool
uploaderType string
}
func WithImage(image string) podTemplateOption {
@ -99,9 +99,9 @@ func WithResources(resources corev1.ResourceRequirements) podTemplateOption {
}
}
func WithDefaultResticMaintenanceFrequency(val time.Duration) podTemplateOption {
func WithDefaultRepoMaintenanceFrequency(val time.Duration) podTemplateOption {
return func(c *podTemplateConfig) {
c.defaultResticMaintenanceFrequency = val
c.defaultRepoMaintenanceFrequency = val
}
}
@ -129,9 +129,9 @@ func WithUploaderType(t string) podTemplateOption {
}
}
func WithDefaultVolumesToRestic() podTemplateOption {
func WithDefaultVolumesToFsBackup() podTemplateOption {
return func(c *podTemplateConfig) {
c.defaultVolumesToRestic = true
c.defaultVolumesToFsBackup = true
}
}
@ -157,8 +157,8 @@ func Deployment(namespace string, opts ...podTemplateOption) *appsv1.Deployment
args = append(args, fmt.Sprintf("--features=%s", strings.Join(c.features, ",")))
}
if c.defaultVolumesToRestic {
args = append(args, "--default-volumes-to-restic=true")
if c.defaultVolumesToFsBackup {
args = append(args, "--default-volumes-to-fs-backup=true")
}
if len(c.uploaderType) > 0 {
@ -288,8 +288,8 @@ func Deployment(namespace string, opts ...podTemplateOption) *appsv1.Deployment
deployment.Spec.Template.Spec.Containers[0].Args = append(deployment.Spec.Template.Spec.Containers[0].Args, "--restore-only")
}
if c.defaultResticMaintenanceFrequency > 0 {
deployment.Spec.Template.Spec.Containers[0].Args = append(deployment.Spec.Template.Spec.Containers[0].Args, fmt.Sprintf("--default-restic-prune-frequency=%v", c.defaultResticMaintenanceFrequency))
if c.defaultRepoMaintenanceFrequency > 0 {
deployment.Spec.Template.Spec.Containers[0].Args = append(deployment.Spec.Template.Spec.Containers[0].Args, fmt.Sprintf("--default-repo-maintain-frequency=%v", c.defaultRepoMaintenanceFrequency))
}
if c.garbageCollectionFrequency > 0 {

View File

@ -46,9 +46,9 @@ func TestDeployment(t *testing.T) {
assert.Equal(t, 7, len(deploy.Spec.Template.Spec.Containers[0].Env))
assert.Equal(t, 3, len(deploy.Spec.Template.Spec.Volumes))
deploy = Deployment("velero", WithDefaultResticMaintenanceFrequency(24*time.Hour))
deploy = Deployment("velero", WithDefaultRepoMaintenanceFrequency(24*time.Hour))
assert.Len(t, deploy.Spec.Template.Spec.Containers[0].Args, 2)
assert.Equal(t, "--default-restic-prune-frequency=24h0m0s", deploy.Spec.Template.Spec.Containers[0].Args[1])
assert.Equal(t, "--default-repo-maintain-frequency=24h0m0s", deploy.Spec.Template.Spec.Containers[0].Args[1])
deploy = Deployment("velero", WithGarbageCollectionFrequency(24*time.Hour))
assert.Len(t, deploy.Spec.Template.Spec.Containers[0].Args, 2)

View File

@ -209,30 +209,30 @@ func appendUnstructured(list *unstructured.UnstructuredList, obj runtime.Object)
}
type VeleroOptions struct {
Namespace string
Image string
ProviderName string
Bucket string
Prefix string
PodAnnotations map[string]string
PodLabels map[string]string
ServiceAccountAnnotations map[string]string
VeleroPodResources corev1.ResourceRequirements
ResticPodResources corev1.ResourceRequirements
SecretData []byte
RestoreOnly bool
UseRestic bool
UseVolumeSnapshots bool
BSLConfig map[string]string
VSLConfig map[string]string
DefaultResticMaintenanceFrequency time.Duration
GarbageCollectionFrequency time.Duration
Plugins []string
NoDefaultBackupLocation bool
CACertData []byte
Features []string
DefaultVolumesToRestic bool
UploaderType string
Namespace string
Image string
ProviderName string
Bucket string
Prefix string
PodAnnotations map[string]string
PodLabels map[string]string
ServiceAccountAnnotations map[string]string
VeleroPodResources corev1.ResourceRequirements
ResticPodResources corev1.ResourceRequirements
SecretData []byte
RestoreOnly bool
UseRestic bool
UseVolumeSnapshots bool
BSLConfig map[string]string
VSLConfig map[string]string
DefaultRepoMaintenanceFrequency time.Duration
GarbageCollectionFrequency time.Duration
Plugins []string
NoDefaultBackupLocation bool
CACertData []byte
Features []string
DefaultVolumesToFsBackup bool
UploaderType string
}
func AllCRDs() *unstructured.UnstructuredList {
@ -272,7 +272,7 @@ func AllResources(o *VeleroOptions) *unstructured.UnstructuredList {
appendUnstructured(resources, bsl)
}
// A snapshot location may not be desirable for users relying on restic
// A snapshot location may not be desirable for users relying on pod volume backup/restore
if o.UseVolumeSnapshots {
vsl := VolumeSnapshotLocation(o.Namespace, o.ProviderName, o.VSLConfig)
appendUnstructured(resources, vsl)
@ -286,7 +286,7 @@ func AllResources(o *VeleroOptions) *unstructured.UnstructuredList {
WithImage(o.Image),
WithResources(o.VeleroPodResources),
WithSecret(secretPresent),
WithDefaultResticMaintenanceFrequency(o.DefaultResticMaintenanceFrequency),
WithDefaultRepoMaintenanceFrequency(o.DefaultRepoMaintenanceFrequency),
WithGarbageCollectionFrequency(o.GarbageCollectionFrequency),
WithUploaderType(o.UploaderType),
}
@ -303,8 +303,8 @@ func AllResources(o *VeleroOptions) *unstructured.UnstructuredList {
deployOpts = append(deployOpts, WithPlugins(o.Plugins))
}
if o.DefaultVolumesToRestic {
deployOpts = append(deployOpts, WithDefaultVolumesToRestic())
if o.DefaultVolumesToFsBackup {
deployOpts = append(deployOpts, WithDefaultVolumesToFsBackup())
}
deploy := Deployment(o.Namespace, deployOpts...)

View File

@ -48,6 +48,10 @@ const (
// InitContainer is the name of the init container added
// to workload pods to help with restores.
InitContainer = "restic-wait"
// DefaultVolumesToFsBackup specifies whether pod volume backup should be used, by default, to
// take backup of all pod volumes.
DefaultVolumesToFsBackup = false
)
// volumeBackupInfo describes the backup info of a volume backed up by PodVolumeBackups
@ -253,9 +257,9 @@ func contains(list []string, k string) bool {
return false
}
// GetPodVolumesUsingRestic returns a list of volume names to backup for the provided pod.
func GetPodVolumesUsingRestic(pod *corev1api.Pod, defaultVolumesToRestic bool) []string {
if !defaultVolumesToRestic {
// GetVolumesByPod returns a list of volume names to backup for the provided pod.
func GetVolumesByPod(pod *corev1api.Pod, defaultVolumesToFsBackup bool) []string {
if !defaultVolumesToFsBackup {
return GetVolumesToBackup(pod)
}

View File

@ -348,16 +348,16 @@ func TestGetVolumesToBackup(t *testing.T) {
}
}
func TestGetPodVolumesUsingRestic(t *testing.T) {
func TestGetVolumesByPod(t *testing.T) {
testCases := []struct {
name string
pod *corev1api.Pod
expected []string
defaultVolumesToRestic bool
name string
pod *corev1api.Pod
expected []string
defaultVolumesToFsBackup bool
}{
{
name: "should get PVs from VolumesToBackupAnnotation when defaultVolumesToRestic is false",
defaultVolumesToRestic: false,
name: "should get PVs from VolumesToBackupAnnotation when defaultVolumesToFsBackup is false",
defaultVolumesToFsBackup: false,
pod: &corev1api.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
@ -368,8 +368,8 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
expected: []string{"resticPV1", "resticPV2", "resticPV3"},
},
{
name: "should get all pod volumes when defaultVolumesToRestic is true and no PVs are excluded",
defaultVolumesToRestic: true,
name: "should get all pod volumes when defaultVolumesToFsBackup is true and no PVs are excluded",
defaultVolumesToFsBackup: true,
pod: &corev1api.Pod{
Spec: corev1api.PodSpec{
Volumes: []corev1api.Volume{
@ -381,8 +381,8 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
expected: []string{"resticPV1", "resticPV2", "resticPV3"},
},
{
name: "should get all pod volumes except ones excluded when defaultVolumesToRestic is true",
defaultVolumesToRestic: true,
name: "should get all pod volumes except ones excluded when defaultVolumesToFsBackup is true",
defaultVolumesToFsBackup: true,
pod: &corev1api.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
@ -401,8 +401,8 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
expected: []string{"resticPV1", "resticPV2", "resticPV3"},
},
{
name: "should exclude default service account token from restic backup",
defaultVolumesToRestic: true,
name: "should exclude default service account token from restic backup",
defaultVolumesToFsBackup: true,
pod: &corev1api.Pod{
Spec: corev1api.PodSpec{
Volumes: []corev1api.Volume{
@ -416,8 +416,8 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
expected: []string{"resticPV1", "resticPV2", "resticPV3"},
},
{
name: "should exclude host path volumes from restic backups",
defaultVolumesToRestic: true,
name: "should exclude host path volumes from restic backups",
defaultVolumesToFsBackup: true,
pod: &corev1api.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
@ -438,8 +438,8 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
expected: []string{"resticPV1", "resticPV2", "resticPV3"},
},
{
name: "should exclude volumes mounting secrets",
defaultVolumesToRestic: true,
name: "should exclude volumes mounting secrets",
defaultVolumesToFsBackup: true,
pod: &corev1api.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
@ -460,8 +460,8 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
expected: []string{"resticPV1", "resticPV2", "resticPV3"},
},
{
name: "should exclude volumes mounting config maps",
defaultVolumesToRestic: true,
name: "should exclude volumes mounting config maps",
defaultVolumesToFsBackup: true,
pod: &corev1api.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
@ -482,8 +482,8 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
expected: []string{"resticPV1", "resticPV2", "resticPV3"},
},
{
name: "should exclude projected volumes",
defaultVolumesToRestic: true,
name: "should exclude projected volumes",
defaultVolumesToFsBackup: true,
pod: &corev1api.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
@ -517,8 +517,8 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
expected: []string{"resticPV1", "resticPV2", "resticPV3"},
},
{
name: "should exclude DownwardAPI volumes",
defaultVolumesToRestic: true,
name: "should exclude DownwardAPI volumes",
defaultVolumesToFsBackup: true,
pod: &corev1api.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
@ -553,7 +553,7 @@ func TestGetPodVolumesUsingRestic(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actual := GetPodVolumesUsingRestic(tc.pod, tc.defaultVolumesToRestic)
actual := GetVolumesByPod(tc.pod, tc.defaultVolumesToFsBackup)
sort.Strings(tc.expected)
sort.Strings(actual)

View File

@ -37,10 +37,6 @@ const (
// at which restic prune is run.
DefaultMaintenanceFrequency = 7 * 24 * time.Hour
// DefaultVolumesToRestic specifies whether restic should be used, by default, to
// take backup of all pod volumes.
DefaultVolumesToRestic = false
// insecureSkipTLSVerifyKey is the flag in BackupStorageLocation's config
// to indicate whether to skip TLS verify to setup insecure HTTPS connection.
insecureSkipTLSVerifyKey = "insecureSkipTLSVerify"

View File

@ -57,7 +57,7 @@ func (n *NamespaceMapping) StartRun() error {
n.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", n.BackupName,
"--include-namespaces", strings.Join(*n.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
n.RestoreArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "restore", n.RestoreName,

View File

@ -81,7 +81,7 @@ func (m *MultiNSBackup) StartRun() error {
m.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", m.BackupName,
"--exclude-namespaces", strings.Join(*m.NSExcluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
m.RestoreArgs = []string{

View File

@ -56,7 +56,7 @@ func (n *NSAnnotationCase) Init() error {
n.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", n.BackupName,
"--include-namespaces", strings.Join(*n.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
n.RestoreArgs = []string{

View File

@ -71,7 +71,7 @@ func (r *RBACCase) Init() error {
r.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", r.BackupName,
"--include-namespaces", strings.Join(*r.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
r.RestoreArgs = []string{

View File

@ -127,7 +127,7 @@ func (o *OrderedResources) Init() error {
}
o.ScheduleArgs = []string{"--schedule", "@every 1m",
"--include-namespaces", o.Namespace, "--default-volumes-to-restic", "--ordered-resources"}
"--include-namespaces", o.Namespace, "--default-volumes-to-fs-backup", "--ordered-resources"}
var orderStr string
for kind, resource := range o.OrderMap {
orderStr += fmt.Sprintf("%s=%s;", kind, resource)

View File

@ -53,7 +53,7 @@ func (f *FilteringCase) Init() error {
f.NamespacesTotal = 3
f.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", f.BackupName,
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
f.RestoreArgs = []string{

View File

@ -65,7 +65,7 @@ func (e *ExcludeFromBackup) Init() error {
e.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", e.BackupName,
"--include-namespaces", e.NSBaseName,
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
e.RestoreArgs = []string{

View File

@ -83,7 +83,7 @@ func (e *ExcludeNamespaces) Init() error {
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", e.BackupName,
"--exclude-namespaces", strings.Join(*e.nsExcluded, ","),
"--include-namespaces", strings.Join(*e.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
e.RestoreArgs = []string{
@ -96,7 +96,7 @@ func (e *ExcludeNamespaces) Init() error {
e.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", e.BackupName,
"--include-namespaces", strings.Join(*e.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
e.RestoreArgs = []string{

View File

@ -66,7 +66,7 @@ func (e *ExcludeResources) Init() error {
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", e.BackupName,
"--include-namespaces", strings.Join(*e.NSIncluded, ","),
"--exclude-resources", "secrets",
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
e.RestoreArgs = []string{
@ -86,7 +86,7 @@ func (e *ExcludeResources) Init() error {
e.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", e.BackupName,
"--include-namespaces", strings.Join(*e.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
e.RestoreArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "restore", e.RestoreName,

View File

@ -73,7 +73,7 @@ func (i *IncludeNamespaces) Init() error {
i.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", i.BackupName,
"--include-namespaces", strings.Join(*i.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
i.RestoreArgs = []string{
@ -92,7 +92,7 @@ func (i *IncludeNamespaces) Init() error {
i.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", i.BackupName,
"--include-namespaces", strings.Join(*i.allTestNamespaces, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
i.RestoreArgs = []string{

View File

@ -63,7 +63,7 @@ func (i *IncludeResources) Init() error {
i.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", i.BackupName,
"--include-resources", "deployments,configmaps",
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
i.RestoreArgs = []string{
@ -81,7 +81,7 @@ func (i *IncludeResources) Init() error {
i.BackupArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", i.BackupName,
"--include-namespaces", strings.Join(*i.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
i.RestoreArgs = []string{
"create", "--namespace", VeleroCfg.VeleroNamespace, "restore", i.RestoreName,

View File

@ -64,7 +64,7 @@ func (l *LabelSelector) Init() error {
"create", "--namespace", VeleroCfg.VeleroNamespace, "backup", l.BackupName,
"--selector", "resourcefiltering=true",
"--include-namespaces", strings.Join(*l.NSIncluded, ","),
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
l.RestoreArgs = []string{

View File

@ -323,10 +323,10 @@ func VeleroBackupNamespace(ctx context.Context, veleroCLI, veleroNamespace strin
if backupCfg.UseVolumeSnapshots {
args = append(args, "--snapshot-volumes")
} else {
args = append(args, "--default-volumes-to-restic")
args = append(args, "--default-volumes-to-fs-backup")
// To workaround https://github.com/vmware-tanzu/velero-plugin-for-vsphere/issues/347 for vsphere plugin v1.1.1
// if the "--snapshot-volumes=false" isn't specified explicitly, the vSphere plugin will always take snapshots
// for the volumes even though the "--default-volumes-to-restic" is specified
// for the volumes even though the "--default-volumes-to-fs-backup" is specified
// TODO This can be removed if the logic of vSphere plugin bump up to 1.3
args = append(args, "--snapshot-volumes=false")
}
@ -362,7 +362,7 @@ func VeleroBackupExcludeNamespaces(ctx context.Context, veleroCLI string, velero
args := []string{
"--namespace", veleroNamespace, "create", "backup", backupName,
"--exclude-namespaces", namespaces,
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
return VeleroBackupExec(ctx, veleroCLI, veleroNamespace, backupName, args)
}
@ -373,7 +373,7 @@ func VeleroBackupIncludeNamespaces(ctx context.Context, veleroCLI string, velero
args := []string{
"--namespace", veleroNamespace, "create", "backup", backupName,
"--include-namespaces", namespaces,
"--default-volumes-to-restic", "--wait",
"--default-volumes-to-fs-backup", "--wait",
}
return VeleroBackupExec(ctx, veleroCLI, veleroNamespace, backupName, args)
}