Merge pull request #8166 from ywk253100/240705_plugin_args

Pass Velero server command args to the plugins
This commit is contained in:
Daniel Jiang
2024-09-06 14:29:42 +08:00
committed by GitHub
22 changed files with 500 additions and 483 deletions

View File

@@ -54,6 +54,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/util/signals"
"github.com/vmware-tanzu/velero/pkg/constant"
"github.com/vmware-tanzu/velero/pkg/controller"
"github.com/vmware-tanzu/velero/pkg/datapath"
"github.com/vmware-tanzu/velero/pkg/metrics"
@@ -286,7 +287,7 @@ func (s *nodeAgentServer) run() {
credentialGetter, s.nodeName, s.mgr.GetScheme(), s.metrics, s.logger)
if err := pvbReconciler.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.PodVolumeBackup)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerPodVolumeBackup)
}
if err = controller.NewPodVolumeRestoreReconciler(s.mgr.GetClient(), s.dataPathMgr, repoEnsurer, credentialGetter, s.logger).SetupWithManager(s.mgr); err != nil {

View File

@@ -0,0 +1,248 @@
package config
import (
"fmt"
"strings"
"time"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"github.com/vmware-tanzu/velero/pkg/cmd/util/flag"
"github.com/vmware-tanzu/velero/pkg/constant"
"github.com/vmware-tanzu/velero/pkg/podvolume"
"github.com/vmware-tanzu/velero/pkg/repository"
"github.com/vmware-tanzu/velero/pkg/types"
"github.com/vmware-tanzu/velero/pkg/uploader"
"github.com/vmware-tanzu/velero/pkg/util/logging"
)
const (
// the port where prometheus metrics are exposed
defaultMetricsAddress = ":8085"
defaultBackupSyncPeriod = time.Minute
defaultStoreValidationFrequency = time.Minute
defaultPodVolumeOperationTimeout = 240 * time.Minute
defaultResourceTerminatingTimeout = 10 * time.Minute
// server's client default qps and burst
defaultClientQPS float32 = 100.0
defaultClientBurst int = 100
defaultClientPageSize int = 500
defaultProfilerAddress = "localhost:6060"
// the default TTL for a backup
defaultBackupTTL = 30 * 24 * time.Hour
defaultCSISnapshotTimeout = 10 * time.Minute
defaultItemOperationTimeout = 4 * time.Hour
resourceTimeout = 10 * time.Minute
defaultMaxConcurrentK8SConnections = 30
defaultDisableInformerCache = false
// defaultCredentialsDirectory is the path on disk where credential
// files will be written to
defaultCredentialsDirectory = "/tmp/credentials"
)
var (
// DisableableControllers is a list of controllers that can be disabled
DisableableControllers = []string{
constant.ControllerBackup,
constant.ControllerBackupOperations,
constant.ControllerBackupDeletion,
constant.ControllerBackupFinalizer,
constant.ControllerBackupSync,
constant.ControllerDownloadRequest,
constant.ControllerGarbageCollection,
constant.ControllerBackupRepo,
constant.ControllerRestore,
constant.ControllerRestoreOperations,
constant.ControllerSchedule,
constant.ControllerServerStatusRequest,
constant.ControllerRestoreFinalizer,
}
/*
High priorities:
- Custom Resource Definitions come before Custom Resource so that they can be
restored with their corresponding CRD.
- Namespaces go second because all namespaced resources depend on them.
- Storage Classes are needed to create PVs and PVCs correctly.
- VolumeSnapshotClasses are needed to provision volumes using volumesnapshots
- VolumeSnapshotContents are needed as they contain the handle to the volume snapshot in the
storage provider
- VolumeSnapshots are needed to create PVCs using the VolumeSnapshot as their data source.
- DataUploads need to restore before PVC for Snapshot DataMover to work, because PVC needs the DataUploadResults to create DataDownloads.
- PVs go before PVCs because PVCs depend on them.
- PVCs go before pods or controllers so they can be mounted as volumes.
- Service accounts go before secrets so service account token secrets can be filled automatically.
- Secrets and ConfigMaps go before pods or controllers so they can be mounted
as volumes.
- Limit ranges go before pods or controllers so pods can use them.
- Pods go before controllers so they can be explicitly restored and potentially
have pod volume restores run before controllers adopt the pods.
- Replica sets go before deployments/other controllers so they can be explicitly
restored and be adopted by controllers.
- CAPI ClusterClasses go before Clusters.
- Endpoints go before Services so no new Endpoints will be created
- Services go before Clusters so they can be adopted by AKO-operator and no new Services will be created
for the same clusters
Low priorities:
- Tanzu ClusterBootstraps go last as it can reference any other kind of resources.
- ClusterBootstraps go before CAPI Clusters otherwise a new default ClusterBootstrap object is created for the cluster
- CAPI Clusters come before ClusterResourceSets because failing to do so means the CAPI controller-manager will panic.
Both Clusters and ClusterResourceSets need to come before ClusterResourceSetBinding in order to properly restore workload clusters.
See https://github.com/kubernetes-sigs/cluster-api/issues/4105
*/
defaultRestorePriorities = types.Priorities{
HighPriorities: []string{
"customresourcedefinitions",
"namespaces",
"storageclasses",
"volumesnapshotclass.snapshot.storage.k8s.io",
"volumesnapshotcontents.snapshot.storage.k8s.io",
"volumesnapshots.snapshot.storage.k8s.io",
"datauploads.velero.io",
"persistentvolumes",
"persistentvolumeclaims",
"serviceaccounts",
"secrets",
"configmaps",
"limitranges",
"pods",
// we fully qualify replicasets.apps because prior to Kubernetes 1.16, replicasets also
// existed in the extensions API group, but we back up replicasets from "apps" so we want
// to ensure that we prioritize restoring from "apps" too, since this is how they're stored
// in the backup.
"replicasets.apps",
"clusterclasses.cluster.x-k8s.io",
"endpoints",
"services",
},
LowPriorities: []string{
"clusterbootstraps.run.tanzu.vmware.com",
"clusters.cluster.x-k8s.io",
"clusterresourcesets.addons.cluster.x-k8s.io",
},
}
)
type Config struct {
PluginDir string
MetricsAddress string
DefaultBackupLocation string // TODO(2.0) Deprecate defaultBackupLocation
BackupSyncPeriod time.Duration
PodVolumeOperationTimeout time.Duration
ResourceTerminatingTimeout time.Duration
DefaultBackupTTL time.Duration
StoreValidationFrequency time.Duration
DefaultCSISnapshotTimeout time.Duration
DefaultItemOperationTimeout time.Duration
ResourceTimeout time.Duration
RestoreResourcePriorities types.Priorities
DefaultVolumeSnapshotLocations flag.Map
RestoreOnly bool
DisabledControllers []string
ClientQPS float32
ClientBurst int
ClientPageSize int
ProfilerAddress string
LogLevel *logging.LevelFlag
LogFormat *logging.FormatFlag
RepoMaintenanceFrequency time.Duration
GarbageCollectionFrequency time.Duration
ItemOperationSyncFrequency time.Duration
DefaultVolumesToFsBackup bool
UploaderType string
MaxConcurrentK8SConnections int
DefaultSnapshotMoveData bool
DisableInformerCache bool
ScheduleSkipImmediately bool
MaintenanceCfg repository.MaintenanceConfig
BackukpRepoConfig string
CredentialsDirectory string
}
func GetDefaultConfig() *Config {
config := &Config{
PluginDir: "/plugins",
MetricsAddress: defaultMetricsAddress,
DefaultBackupLocation: "default",
DefaultVolumeSnapshotLocations: flag.NewMap().WithKeyValueDelimiter(':'),
BackupSyncPeriod: defaultBackupSyncPeriod,
DefaultBackupTTL: defaultBackupTTL,
DefaultCSISnapshotTimeout: defaultCSISnapshotTimeout,
DefaultItemOperationTimeout: defaultItemOperationTimeout,
ResourceTimeout: resourceTimeout,
StoreValidationFrequency: defaultStoreValidationFrequency,
PodVolumeOperationTimeout: defaultPodVolumeOperationTimeout,
RestoreResourcePriorities: defaultRestorePriorities,
ClientQPS: defaultClientQPS,
ClientBurst: defaultClientBurst,
ClientPageSize: defaultClientPageSize,
ProfilerAddress: defaultProfilerAddress,
ResourceTerminatingTimeout: defaultResourceTerminatingTimeout,
LogLevel: logging.LogLevelFlag(logrus.InfoLevel),
LogFormat: logging.NewFormatFlag(),
DefaultVolumesToFsBackup: podvolume.DefaultVolumesToFsBackup,
UploaderType: uploader.ResticType,
MaxConcurrentK8SConnections: defaultMaxConcurrentK8SConnections,
DefaultSnapshotMoveData: false,
DisableInformerCache: defaultDisableInformerCache,
ScheduleSkipImmediately: false,
CredentialsDirectory: defaultCredentialsDirectory,
}
config.MaintenanceCfg = repository.MaintenanceConfig{
KeepLatestMaitenanceJobs: repository.DefaultKeepLatestMaitenanceJobs,
// maintenance job log setting inherited from velero server
FormatFlag: config.LogFormat,
LogLevelFlag: config.LogLevel,
}
return config
}
func (c *Config) BindFlags(flags *pflag.FlagSet) {
flags.Var(c.LogLevel, "log-level", fmt.Sprintf("The level at which to log. Valid values are %s.", strings.Join(c.LogLevel.AllowedValues(), ", ")))
flags.Var(c.LogFormat, "log-format", fmt.Sprintf("The format for log output. Valid values are %s.", strings.Join(c.LogFormat.AllowedValues(), ", ")))
flags.StringVar(&c.PluginDir, "plugin-dir", c.PluginDir, "Directory containing Velero plugins")
flags.StringVar(&c.MetricsAddress, "metrics-address", c.MetricsAddress, "The address to expose prometheus metrics")
flags.DurationVar(&c.BackupSyncPeriod, "backup-sync-period", c.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.")
flags.DurationVar(&c.PodVolumeOperationTimeout, "fs-backup-timeout", c.PodVolumeOperationTimeout, "How long pod volume file system backups/restores should be allowed to run before timing out.")
flags.BoolVar(&c.RestoreOnly, "restore-only", c.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.")
flags.StringSliceVar(&c.DisabledControllers, "disable-controllers", c.DisabledControllers, fmt.Sprintf("List of controllers to disable on startup. Valid values are %s", strings.Join(DisableableControllers, ",")))
flags.Var(&c.RestoreResourcePriorities, "restore-resource-priorities", "Desired order of resource restores, the priority list contains two parts which are split by \"-\" element. The resources before \"-\" element are restored first as high priorities, the resources after \"-\" element are restored last as low priorities, and any resource not in the list will be restored alphabetically between the high and low priorities.")
flags.StringVar(&c.DefaultBackupLocation, "default-backup-storage-location", c.DefaultBackupLocation, "Name of the default backup storage location. DEPRECATED: this flag will be removed in v2.0. Use \"velero backup-location set --default\" instead.")
flags.DurationVar(&c.StoreValidationFrequency, "store-validation-frequency", c.StoreValidationFrequency, "How often to verify if the storage is valid. Optional. Set this to `0s` to disable sync. Default 1 minute.")
flags.Float32Var(&c.ClientQPS, "client-qps", c.ClientQPS, "Maximum number of requests per second by the server to the Kubernetes API once the burst limit has been reached.")
flags.IntVar(&c.ClientBurst, "client-burst", c.ClientBurst, "Maximum number of requests by the server to the Kubernetes API in a short period of time.")
flags.IntVar(&c.ClientPageSize, "client-page-size", c.ClientPageSize, "Page size of requests by the server to the Kubernetes API when listing objects during a backup. Set to 0 to disable paging.")
flags.StringVar(&c.ProfilerAddress, "profiler-address", c.ProfilerAddress, "The address to expose the pprof profiler.")
flags.DurationVar(&c.ResourceTerminatingTimeout, "terminating-resource-timeout", c.ResourceTerminatingTimeout, "How long to wait on persistent volumes and namespaces to terminate during a restore before timing out.")
flags.DurationVar(&c.DefaultBackupTTL, "default-backup-ttl", c.DefaultBackupTTL, "How long to wait by default before backups can be garbage collected.")
flags.DurationVar(&c.RepoMaintenanceFrequency, "default-repo-maintain-frequency", c.RepoMaintenanceFrequency, "How often 'maintain' is run for backup repositories by default.")
flags.DurationVar(&c.GarbageCollectionFrequency, "garbage-collection-frequency", c.GarbageCollectionFrequency, "How often garbage collection is run for expired backups.")
flags.DurationVar(&c.ItemOperationSyncFrequency, "item-operation-sync-frequency", c.ItemOperationSyncFrequency, "How often to check status on backup/restore operations after backup/restore processing. Default is 10 seconds")
flags.BoolVar(&c.DefaultVolumesToFsBackup, "default-volumes-to-fs-backup", c.DefaultVolumesToFsBackup, "Backup all volumes with pod volume file system backup by default.")
flags.StringVar(&c.UploaderType, "uploader-type", c.UploaderType, "Type of uploader to handle the transfer of data of pod volumes")
flags.DurationVar(&c.DefaultItemOperationTimeout, "default-item-operation-timeout", c.DefaultItemOperationTimeout, "How long to wait on asynchronous BackupItemActions and RestoreItemActions to complete before timing out. Default is 4 hours")
flags.DurationVar(&c.ResourceTimeout, "resource-timeout", c.ResourceTimeout, "How long to wait for resource processes which are not covered by other specific timeout parameters. Default is 10 minutes.")
flags.IntVar(&c.MaxConcurrentK8SConnections, "max-concurrent-k8s-connections", c.MaxConcurrentK8SConnections, "Max concurrent connections number that Velero can create with kube-apiserver. Default is 30.")
flags.BoolVar(&c.DefaultSnapshotMoveData, "default-snapshot-move-data", c.DefaultSnapshotMoveData, "Move data by default for all snapshots supporting data movement.")
flags.BoolVar(&c.DisableInformerCache, "disable-informer-cache", c.DisableInformerCache, "Disable informer cache for Get calls on restore. With this enabled, it will speed up restore in cases where there are backup resources which already exist in the cluster, but for very large clusters this will increase velero memory usage. Default is false (don't disable).")
flags.BoolVar(&c.ScheduleSkipImmediately, "schedule-skip-immediately", c.ScheduleSkipImmediately, "Skip the first scheduled backup immediately after creating a schedule. Default is false (don't skip).")
flags.IntVar(&c.MaintenanceCfg.KeepLatestMaitenanceJobs, "keep-latest-maintenance-jobs", c.MaintenanceCfg.KeepLatestMaitenanceJobs, "Number of latest maintenance jobs to keep each repository. Optional.")
flags.StringVar(&c.MaintenanceCfg.CPURequest, "maintenance-job-cpu-request", c.MaintenanceCfg.CPURequest, "CPU request for maintenance job. Default is no limit.")
flags.StringVar(&c.MaintenanceCfg.MemRequest, "maintenance-job-mem-request", c.MaintenanceCfg.MemRequest, "Memory request for maintenance job. Default is no limit.")
flags.StringVar(&c.MaintenanceCfg.CPULimit, "maintenance-job-cpu-limit", c.MaintenanceCfg.CPULimit, "CPU limit for maintenance job. Default is no limit.")
flags.StringVar(&c.MaintenanceCfg.MemLimit, "maintenance-job-mem-limit", c.MaintenanceCfg.MemLimit, "Memory limit for maintenance job. Default is no limit.")
flags.StringVar(&c.BackukpRepoConfig, "backup-repository-config", c.BackukpRepoConfig, "The name of configMap containing backup repository configurations.")
flags.Var(&c.DefaultVolumeSnapshotLocations, "default-volume-snapshot-locations", "List of unique volume providers and default volume snapshot location (provider1:location-01,provider2:location-02,...)")
}

View File

@@ -0,0 +1,19 @@
package config
import (
"testing"
"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
)
func TestGetDefaultConfig(t *testing.T) {
config := GetDefaultConfig()
assert.Equal(t, "info", config.MaintenanceCfg.LogLevelFlag.String())
}
func TestBindFlags(t *testing.T) {
config := GetDefaultConfig()
config.BindFlags(pflag.CommandLine)
assert.Equal(t, "info", config.MaintenanceCfg.LogLevelFlag.String())
}

View File

@@ -45,6 +45,9 @@ func NewCommand(f client.Factory) *cobra.Command {
Hidden: true,
Short: "INTERNAL COMMAND ONLY - not intended to be run directly by users",
Run: func(c *cobra.Command, args []string) {
config := pluginServer.GetConfig()
f.SetClientQPS(config.ClientQPS)
f.SetClientBurst(config.ClientBurst)
pluginServer = pluginServer.
RegisterBackupItemAction(
"velero.io/pv",
@@ -197,6 +200,9 @@ func NewCommand(f client.Factory) *cobra.Command {
}
pluginServer.Serve()
},
FParseErrWhitelist: cobra.FParseErrWhitelist{ // Velero.io word list : ignore
UnknownFlags: true,
},
}
pluginServer.BindFlags(c.Flags())
return c

View File

@@ -62,8 +62,9 @@ import (
"github.com/vmware-tanzu/velero/pkg/buildinfo"
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/util/flag"
"github.com/vmware-tanzu/velero/pkg/cmd/server/config"
"github.com/vmware-tanzu/velero/pkg/cmd/util/signals"
"github.com/vmware-tanzu/velero/pkg/constant"
"github.com/vmware-tanzu/velero/pkg/controller"
velerodiscovery "github.com/vmware-tanzu/velero/pkg/discovery"
"github.com/vmware-tanzu/velero/pkg/features"
@@ -83,100 +84,8 @@ import (
"github.com/vmware-tanzu/velero/pkg/util/logging"
)
const (
// the port where prometheus metrics are exposed
defaultMetricsAddress = ":8085"
defaultBackupSyncPeriod = time.Minute
defaultStoreValidationFrequency = time.Minute
defaultPodVolumeOperationTimeout = 240 * time.Minute
defaultResourceTerminatingTimeout = 10 * time.Minute
// server's client default qps and burst
defaultClientQPS float32 = 100.0
defaultClientBurst int = 100
defaultClientPageSize int = 500
defaultProfilerAddress = "localhost:6060"
// the default TTL for a backup
defaultBackupTTL = 30 * 24 * time.Hour
defaultCSISnapshotTimeout = 10 * time.Minute
defaultItemOperationTimeout = 4 * time.Hour
resourceTimeout = 10 * time.Minute
// defaultCredentialsDirectory is the path on disk where credential
// files will be written to
defaultCredentialsDirectory = "/tmp/credentials"
defaultMaxConcurrentK8SConnections = 30
defaultDisableInformerCache = false
)
type serverConfig struct {
// TODO(2.0) Deprecate defaultBackupLocation
pluginDir, metricsAddress, defaultBackupLocation string
backupSyncPeriod, podVolumeOperationTimeout, resourceTerminatingTimeout time.Duration
defaultBackupTTL, storeValidationFrequency, defaultCSISnapshotTimeout time.Duration
defaultItemOperationTimeout, resourceTimeout time.Duration
restoreResourcePriorities restore.Priorities
defaultVolumeSnapshotLocations map[string]string
restoreOnly bool
disabledControllers []string
clientQPS float32
clientBurst int
clientPageSize int
profilerAddress string
formatFlag *logging.FormatFlag
repoMaintenanceFrequency time.Duration
garbageCollectionFrequency time.Duration
itemOperationSyncFrequency time.Duration
defaultVolumesToFsBackup bool
uploaderType string
maxConcurrentK8SConnections int
defaultSnapshotMoveData bool
disableInformerCache bool
scheduleSkipImmediately bool
maintenanceCfg repository.MaintenanceConfig
backukpRepoConfig string
}
func NewCommand(f client.Factory) *cobra.Command {
var (
volumeSnapshotLocations = flag.NewMap().WithKeyValueDelimiter(':')
logLevelFlag = logging.LogLevelFlag(logrus.InfoLevel)
config = serverConfig{
pluginDir: "/plugins",
metricsAddress: defaultMetricsAddress,
defaultBackupLocation: "default",
defaultVolumeSnapshotLocations: make(map[string]string),
backupSyncPeriod: defaultBackupSyncPeriod,
defaultBackupTTL: defaultBackupTTL,
defaultCSISnapshotTimeout: defaultCSISnapshotTimeout,
defaultItemOperationTimeout: defaultItemOperationTimeout,
resourceTimeout: resourceTimeout,
storeValidationFrequency: defaultStoreValidationFrequency,
podVolumeOperationTimeout: defaultPodVolumeOperationTimeout,
restoreResourcePriorities: defaultRestorePriorities,
clientQPS: defaultClientQPS,
clientBurst: defaultClientBurst,
clientPageSize: defaultClientPageSize,
profilerAddress: defaultProfilerAddress,
resourceTerminatingTimeout: defaultResourceTerminatingTimeout,
formatFlag: logging.NewFormatFlag(),
defaultVolumesToFsBackup: podvolume.DefaultVolumesToFsBackup,
uploaderType: uploader.ResticType,
maxConcurrentK8SConnections: defaultMaxConcurrentK8SConnections,
defaultSnapshotMoveData: false,
disableInformerCache: defaultDisableInformerCache,
scheduleSkipImmediately: false,
maintenanceCfg: repository.MaintenanceConfig{
KeepLatestMaitenanceJobs: repository.DefaultKeepLatestMaitenanceJobs,
},
}
)
config := config.GetDefaultConfig()
var command = &cobra.Command{
Use: "server",
@@ -188,8 +97,8 @@ func NewCommand(f client.Factory) *cobra.Command {
// set its output to stdout.
log.SetOutput(os.Stdout)
logLevel := logLevelFlag.Parse()
format := config.formatFlag.Parse()
logLevel := config.LogLevel.Parse()
format := config.LogFormat.Parse()
// Make sure we log to stdout so cloud log dashboards don't show this as an error.
logrus.SetOutput(os.Stdout)
@@ -206,10 +115,6 @@ func NewCommand(f client.Factory) *cobra.Command {
logger.Info("No feature flags enabled")
}
if volumeSnapshotLocations.Data() != nil {
config.defaultVolumeSnapshotLocations = volumeSnapshotLocations.Data()
}
f.SetBasename(fmt.Sprintf("%s-%s", c.Parent().Name(), c.Name()))
s, err := newServer(f, config, logger)
@@ -219,46 +124,8 @@ func NewCommand(f client.Factory) *cobra.Command {
},
}
command.Flags().Var(logLevelFlag, "log-level", fmt.Sprintf("The level at which to log. Valid values are %s.", strings.Join(logLevelFlag.AllowedValues(), ", ")))
command.Flags().Var(config.formatFlag, "log-format", fmt.Sprintf("The format for log output. Valid values are %s.", strings.Join(config.formatFlag.AllowedValues(), ", ")))
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, "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().Var(&config.restoreResourcePriorities, "restore-resource-priorities", "Desired order of resource restores, the priority list contains two parts which are split by \"-\" element. The resources before \"-\" element are restored first as high priorities, the resources after \"-\" element are restored last as low priorities, and any resource not in the list will be restored alphabetically between the high and low priorities.")
command.Flags().StringVar(&config.defaultBackupLocation, "default-backup-storage-location", config.defaultBackupLocation, "Name of the default backup storage location. DEPRECATED: this flag will be removed in v2.0. Use \"velero backup-location set --default\" instead.")
command.Flags().DurationVar(&config.storeValidationFrequency, "store-validation-frequency", config.storeValidationFrequency, "How often to verify if the storage is valid. Optional. Set this to `0s` to disable sync. Default 1 minute.")
command.Flags().Var(&volumeSnapshotLocations, "default-volume-snapshot-locations", "List of unique volume providers and default volume snapshot location (provider1:location-01,provider2:location-02,...)")
command.Flags().Float32Var(&config.clientQPS, "client-qps", config.clientQPS, "Maximum number of requests per second by the server to the Kubernetes API once the burst limit has been reached.")
command.Flags().IntVar(&config.clientBurst, "client-burst", config.clientBurst, "Maximum number of requests by the server to the Kubernetes API in a short period of time.")
command.Flags().IntVar(&config.clientPageSize, "client-page-size", config.clientPageSize, "Page size of requests by the server to the Kubernetes API when listing objects during a backup. Set to 0 to disable paging.")
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-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().DurationVar(&config.itemOperationSyncFrequency, "item-operation-sync-frequency", config.itemOperationSyncFrequency, "How often to check status on backup/restore operations after backup/restore processing. Default is 10 seconds")
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")
command.Flags().DurationVar(&config.defaultItemOperationTimeout, "default-item-operation-timeout", config.defaultItemOperationTimeout, "How long to wait on asynchronous BackupItemActions and RestoreItemActions to complete before timing out. Default is 4 hours")
command.Flags().DurationVar(&config.resourceTimeout, "resource-timeout", config.resourceTimeout, "How long to wait for resource processes which are not covered by other specific timeout parameters. Default is 10 minutes.")
command.Flags().IntVar(&config.maxConcurrentK8SConnections, "max-concurrent-k8s-connections", config.maxConcurrentK8SConnections, "Max concurrent connections number that Velero can create with kube-apiserver. Default is 30.")
command.Flags().BoolVar(&config.defaultSnapshotMoveData, "default-snapshot-move-data", config.defaultSnapshotMoveData, "Move data by default for all snapshots supporting data movement.")
command.Flags().BoolVar(&config.disableInformerCache, "disable-informer-cache", config.disableInformerCache, "Disable informer cache for Get calls on restore. With this enabled, it will speed up restore in cases where there are backup resources which already exist in the cluster, but for very large clusters this will increase velero memory usage. Default is false (don't disable).")
command.Flags().BoolVar(&config.scheduleSkipImmediately, "schedule-skip-immediately", config.scheduleSkipImmediately, "Skip the first scheduled backup immediately after creating a schedule. Default is false (don't skip).")
command.Flags().IntVar(&config.maintenanceCfg.KeepLatestMaitenanceJobs, "keep-latest-maintenance-jobs", config.maintenanceCfg.KeepLatestMaitenanceJobs, "Number of latest maintenance jobs to keep each repository. Optional.")
command.Flags().StringVar(&config.maintenanceCfg.CPURequest, "maintenance-job-cpu-request", config.maintenanceCfg.CPURequest, "CPU request for maintenance job. Default is no limit.")
command.Flags().StringVar(&config.maintenanceCfg.MemRequest, "maintenance-job-mem-request", config.maintenanceCfg.MemRequest, "Memory request for maintenance job. Default is no limit.")
command.Flags().StringVar(&config.maintenanceCfg.CPULimit, "maintenance-job-cpu-limit", config.maintenanceCfg.CPULimit, "CPU limit for maintenance job. Default is no limit.")
command.Flags().StringVar(&config.maintenanceCfg.MemLimit, "maintenance-job-mem-limit", config.maintenanceCfg.MemLimit, "Memory limit for maintenance job. Default is no limit.")
config.BindFlags(command.Flags())
command.Flags().StringVar(&config.backukpRepoConfig, "backup-repository-config", config.backukpRepoConfig, "The name of configMap containing backup repository configurations.")
// maintenance job log setting inherited from velero server
config.maintenanceCfg.FormatFlag = config.formatFlag
config.maintenanceCfg.LogLevelFlag = logLevelFlag
return command
}
@@ -284,30 +151,30 @@ type server struct {
repoLocker *repository.RepoLocker
repoEnsurer *repository.Ensurer
metrics *metrics.ServerMetrics
config serverConfig
config *config.Config
mgr manager.Manager
credentialFileStore credentials.FileStore
credentialSecretStore credentials.SecretStore
}
func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*server, error) {
if msg, err := uploader.ValidateUploaderType(config.uploaderType); err != nil {
func newServer(f client.Factory, config *config.Config, logger *logrus.Logger) (*server, error) {
if msg, err := uploader.ValidateUploaderType(config.UploaderType); err != nil {
return nil, err
} else if msg != "" {
logger.Warn(msg)
}
if config.clientQPS < 0.0 {
if config.ClientQPS < 0.0 {
return nil, errors.New("client-qps must be positive")
}
f.SetClientQPS(config.clientQPS)
f.SetClientQPS(config.ClientQPS)
if config.clientBurst <= 0 {
if config.ClientBurst <= 0 {
return nil, errors.New("client-burst must be positive")
}
f.SetClientBurst(config.clientBurst)
f.SetClientBurst(config.ClientBurst)
if config.clientPageSize < 0 {
if config.ClientPageSize < 0 {
return nil, errors.New("client-page-size must not be negative")
}
@@ -326,7 +193,7 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s
return nil, err
}
pluginRegistry := process.NewRegistry(config.pluginDir, logger, logger.Level)
pluginRegistry := process.NewRegistry(config.PluginDir, logger, logger.Level)
if err := pluginRegistry.DiscoverPlugins(); err != nil {
return nil, err
}
@@ -387,7 +254,7 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s
credentialFileStore, err := credentials.NewNamespacedFileStore(
mgr.GetClient(),
f.Namespace(),
defaultCredentialsDirectory,
config.CredentialsDirectory,
filesystem.NewFileSystem(),
)
if err != nil {
@@ -409,7 +276,7 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s
s := &server{
namespace: f.Namespace(),
metricsAddress: config.metricsAddress,
metricsAddress: config.MetricsAddress,
kubeClientConfig: clientConfig,
kubeClient: kubeClient,
discoveryClient: discoveryClient,
@@ -432,7 +299,7 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s
func (s *server) run() error {
signals.CancelOnShutdown(s.cancelFunc, s.logger)
if s.config.profilerAddress != "" {
if s.config.ProfilerAddress != "" {
go s.runProfiler()
}
@@ -461,7 +328,7 @@ func (s *server) run() error {
return err
}
if err := s.runControllers(s.config.defaultVolumeSnapshotLocations); err != nil {
if err := s.runControllers(s.config.DefaultVolumeSnapshotLocations.Data()); err != nil {
return err
}
@@ -478,7 +345,7 @@ func (s *server) setupBeforeControllerRun() error {
markInProgressCRsFailed(s.ctx, client, s.namespace, s.logger)
if err := setDefaultBackupLocation(s.ctx, client, s.namespace, s.config.defaultBackupLocation, s.logger); err != nil {
if err := setDefaultBackupLocation(s.ctx, client, s.namespace, s.config.DefaultBackupLocation, s.logger); err != nil {
return err
}
return nil
@@ -584,71 +451,6 @@ func (s *server) veleroResourcesExist() error {
return nil
}
/*
High priorities:
- Custom Resource Definitions come before Custom Resource so that they can be
restored with their corresponding CRD.
- Namespaces go second because all namespaced resources depend on them.
- Storage Classes are needed to create PVs and PVCs correctly.
- VolumeSnapshotClasses are needed to provision volumes using volumesnapshots
- VolumeSnapshotContents are needed as they contain the handle to the volume snapshot in the
storage provider
- VolumeSnapshots are needed to create PVCs using the VolumeSnapshot as their data source.
- DataUploads need to restore before PVC for Snapshot DataMover to work, because PVC needs the DataUploadResults to create DataDownloads.
- PVs go before PVCs because PVCs depend on them.
- PVCs go before pods or controllers so they can be mounted as volumes.
- Service accounts go before secrets so service account token secrets can be filled automatically.
- Secrets and ConfigMaps go before pods or controllers so they can be mounted
as volumes.
- Limit ranges go before pods or controllers so pods can use them.
- Pods go before controllers so they can be explicitly restored and potentially
have pod volume restores run before controllers adopt the pods.
- Replica sets go before deployments/other controllers so they can be explicitly
restored and be adopted by controllers.
- CAPI ClusterClasses go before Clusters.
- Endpoints go before Services so no new Endpoints will be created
- Services go before Clusters so they can be adopted by AKO-operator and no new Services will be created
for the same clusters
Low priorities:
- Tanzu ClusterBootstraps go last as it can reference any other kind of resources.
- ClusterBootstraps go before CAPI Clusters otherwise a new default ClusterBootstrap object is created for the cluster
- CAPI Clusters come before ClusterResourceSets because failing to do so means the CAPI controller-manager will panic.
Both Clusters and ClusterResourceSets need to come before ClusterResourceSetBinding in order to properly restore workload clusters.
See https://github.com/kubernetes-sigs/cluster-api/issues/4105
*/
var defaultRestorePriorities = restore.Priorities{
HighPriorities: []string{
"customresourcedefinitions",
"namespaces",
"storageclasses",
"volumesnapshotclass.snapshot.storage.k8s.io",
"volumesnapshotcontents.snapshot.storage.k8s.io",
"volumesnapshots.snapshot.storage.k8s.io",
"datauploads.velero.io",
"persistentvolumes",
"persistentvolumeclaims",
"serviceaccounts",
"secrets",
"configmaps",
"limitranges",
"pods",
// we fully qualify replicasets.apps because prior to Kubernetes 1.16, replicasets also
// existed in the extensions API group, but we back up replicasets from "apps" so we want
// to ensure that we prioritize restoring from "apps" too, since this is how they're stored
// in the backup.
"replicasets.apps",
"clusterclasses.cluster.x-k8s.io",
"endpoints",
"services",
},
LowPriorities: []string{
"clusterbootstraps.run.tanzu.vmware.com",
"clusters.cluster.x-k8s.io",
"clusterresourcesets.addons.cluster.x-k8s.io",
},
}
func (s *server) checkNodeAgent() {
// warn if node agent does not exist
if err := nodeagent.IsRunning(s.ctx, s.kubeClient, s.namespace); err == nodeagent.ErrDaemonSetNotFound {
@@ -665,9 +467,9 @@ func (s *server) initRepoManager() error {
}
s.repoLocker = repository.NewRepoLocker()
s.repoEnsurer = repository.NewEnsurer(s.mgr.GetClient(), s.logger, s.config.resourceTimeout)
s.repoEnsurer = repository.NewEnsurer(s.mgr.GetClient(), s.logger, s.config.ResourceTimeout)
s.repoManager = repository.NewManager(s.namespace, s.mgr.GetClient(), s.repoLocker, s.repoEnsurer, s.credentialFileStore, s.credentialSecretStore, s.config.maintenanceCfg, s.logger)
s.repoManager = repository.NewManager(s.namespace, s.mgr.GetClient(), s.repoLocker, s.repoEnsurer, s.credentialFileStore, s.credentialSecretStore, s.config.MaintenanceCfg, s.logger)
return nil
}
@@ -707,36 +509,36 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
// and BSL controller is mandatory for Velero to work.
// Note: all runtime type controllers that can be disabled are grouped separately, below:
enabledRuntimeControllers := map[string]struct{}{
controller.Backup: {},
controller.BackupDeletion: {},
controller.BackupFinalizer: {},
controller.BackupOperations: {},
controller.BackupRepo: {},
controller.BackupSync: {},
controller.DownloadRequest: {},
controller.GarbageCollection: {},
controller.Restore: {},
controller.RestoreOperations: {},
controller.Schedule: {},
controller.ServerStatusRequest: {},
controller.RestoreFinalizer: {},
constant.ControllerBackup: {},
constant.ControllerBackupDeletion: {},
constant.ControllerBackupFinalizer: {},
constant.ControllerBackupOperations: {},
constant.ControllerBackupRepo: {},
constant.ControllerBackupSync: {},
constant.ControllerDownloadRequest: {},
constant.ControllerGarbageCollection: {},
constant.ControllerRestore: {},
constant.ControllerRestoreOperations: {},
constant.ControllerSchedule: {},
constant.ControllerServerStatusRequest: {},
constant.ControllerRestoreFinalizer: {},
}
if s.config.restoreOnly {
if s.config.RestoreOnly {
s.logger.Info("Restore only mode - not starting the backup, schedule, delete-backup, or GC controllers")
s.config.disabledControllers = append(s.config.disabledControllers,
controller.Backup,
controller.BackupDeletion,
controller.BackupFinalizer,
controller.BackupOperations,
controller.GarbageCollection,
controller.Schedule,
s.config.DisabledControllers = append(s.config.DisabledControllers,
constant.ControllerBackup,
constant.ControllerBackupDeletion,
constant.ControllerBackupFinalizer,
constant.ControllerBackupOperations,
constant.ControllerGarbageCollection,
constant.ControllerSchedule,
)
}
// Remove disabled controllers so they are not initialized. If a match is not found we want
// to halt the system so the user knows this operation was not possible.
if err := removeControllers(s.config.disabledControllers, enabledRuntimeControllers, s.logger); err != nil {
if err := removeControllers(s.config.DisabledControllers, enabledRuntimeControllers, s.logger); err != nil {
log.Fatal(err, "unable to disable a controller")
}
@@ -745,15 +547,15 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
s.ctx,
s.mgr.GetClient(),
storage.DefaultBackupLocationInfo{
StorageLocation: s.config.defaultBackupLocation,
ServerValidationFrequency: s.config.storeValidationFrequency,
StorageLocation: s.config.DefaultBackupLocation,
ServerValidationFrequency: s.config.StoreValidationFrequency,
},
newPluginManager,
backupStoreGetter,
s.logger,
)
if err := bslr.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupStorageLocation)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerBackupStorageLocation)
}
pvbInformer, err := s.mgr.GetCache().GetInformer(s.ctx, &velerov1api.PodVolumeBackup{})
@@ -761,7 +563,7 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
s.logger.Fatal(err, "fail to get controller-runtime informer from manager for PVB")
}
if _, ok := enabledRuntimeControllers[controller.Backup]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerBackup]; ok {
backupper, err := backup.NewKubernetesBackupper(
s.crClient,
s.discoveryHelper,
@@ -774,10 +576,10 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
pvbInformer,
s.logger,
),
s.config.podVolumeOperationTimeout,
s.config.defaultVolumesToFsBackup,
s.config.clientPageSize,
s.config.uploaderType,
s.config.PodVolumeOperationTimeout,
s.config.DefaultVolumesToFsBackup,
s.config.ClientPageSize,
s.config.UploaderType,
newPluginManager,
backupStoreGetter,
)
@@ -791,26 +593,26 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
newPluginManager,
backupTracker,
s.mgr.GetClient(),
s.config.defaultBackupLocation,
s.config.defaultVolumesToFsBackup,
s.config.defaultBackupTTL,
s.config.defaultCSISnapshotTimeout,
s.config.resourceTimeout,
s.config.defaultItemOperationTimeout,
s.config.DefaultBackupLocation,
s.config.DefaultVolumesToFsBackup,
s.config.DefaultBackupTTL,
s.config.DefaultCSISnapshotTimeout,
s.config.ResourceTimeout,
s.config.DefaultItemOperationTimeout,
defaultVolumeSnapshotLocations,
s.metrics,
backupStoreGetter,
s.config.formatFlag.Parse(),
s.config.LogFormat.Parse(),
s.credentialFileStore,
s.config.maxConcurrentK8SConnections,
s.config.defaultSnapshotMoveData,
s.config.MaxConcurrentK8SConnections,
s.config.DefaultSnapshotMoveData,
s.crClient,
).SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.Backup)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerBackup)
}
}
if _, ok := enabledRuntimeControllers[controller.BackupDeletion]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerBackupDeletion]; ok {
if err := controller.NewBackupDeletionReconciler(
s.logger,
s.mgr.GetClient(),
@@ -823,27 +625,27 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
s.credentialFileStore,
s.repoEnsurer,
).SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupDeletion)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerBackupDeletion)
}
}
backupOpsMap := itemoperationmap.NewBackupItemOperationsMap()
if _, ok := enabledRuntimeControllers[controller.BackupOperations]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerBackupOperations]; ok {
r := controller.NewBackupOperationsReconciler(
s.logger,
s.mgr.GetClient(),
s.config.itemOperationSyncFrequency,
s.config.ItemOperationSyncFrequency,
newPluginManager,
backupStoreGetter,
s.metrics,
backupOpsMap,
)
if err := r.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupOperations)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerBackupOperations)
}
}
if _, ok := enabledRuntimeControllers[controller.BackupFinalizer]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerBackupFinalizer]; ok {
backupper, err := backup.NewKubernetesBackupper(
s.mgr.GetClient(),
s.discoveryHelper,
@@ -856,10 +658,10 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
pvbInformer,
s.logger,
),
s.config.podVolumeOperationTimeout,
s.config.defaultVolumesToFsBackup,
s.config.clientPageSize,
s.config.uploaderType,
s.config.PodVolumeOperationTimeout,
s.config.DefaultVolumesToFsBackup,
s.config.ClientPageSize,
s.config.UploaderType,
newPluginManager,
backupStoreGetter,
)
@@ -876,18 +678,18 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
s.metrics,
)
if err := r.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupFinalizer)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerBackupFinalizer)
}
}
if _, ok := enabledRuntimeControllers[controller.BackupRepo]; ok {
if err := controller.NewBackupRepoReconciler(s.namespace, s.logger, s.mgr.GetClient(), s.config.repoMaintenanceFrequency, s.config.backukpRepoConfig, s.repoManager).SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.BackupRepo)
if _, ok := enabledRuntimeControllers[constant.ControllerBackupRepo]; ok {
if err := controller.NewBackupRepoReconciler(s.namespace, s.logger, s.mgr.GetClient(), s.config.RepoMaintenanceFrequency, s.config.BackukpRepoConfig, s.repoManager).SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerBackupRepo)
}
}
if _, ok := enabledRuntimeControllers[controller.BackupSync]; ok {
syncPeriod := s.config.backupSyncPeriod
if _, ok := enabledRuntimeControllers[constant.ControllerBackupSync]; ok {
syncPeriod := s.config.BackupSyncPeriod
if syncPeriod <= 0 {
syncPeriod = time.Minute
}
@@ -901,28 +703,28 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
s.logger,
)
if err := backupSyncReconciler.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, " unable to create controller ", "controller ", controller.BackupSync)
s.logger.Fatal(err, " unable to create controller ", "controller ", constant.ControllerBackupSync)
}
}
restoreOpsMap := itemoperationmap.NewRestoreItemOperationsMap()
if _, ok := enabledRuntimeControllers[controller.RestoreOperations]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerRestoreOperations]; ok {
r := controller.NewRestoreOperationsReconciler(
s.logger,
s.namespace,
s.mgr.GetClient(),
s.config.itemOperationSyncFrequency,
s.config.ItemOperationSyncFrequency,
newPluginManager,
backupStoreGetter,
s.metrics,
restoreOpsMap,
)
if err := r.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.RestoreOperations)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerRestoreOperations)
}
}
if _, ok := enabledRuntimeControllers[controller.DownloadRequest]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerDownloadRequest]; ok {
r := controller.NewDownloadRequestReconciler(
s.mgr.GetClient(),
clock.RealClock{},
@@ -933,14 +735,14 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
restoreOpsMap,
)
if err := r.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.DownloadRequest)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerDownloadRequest)
}
}
if _, ok := enabledRuntimeControllers[controller.GarbageCollection]; ok {
r := controller.NewGCReconciler(s.logger, s.mgr.GetClient(), s.config.garbageCollectionFrequency)
if _, ok := enabledRuntimeControllers[constant.ControllerGarbageCollection]; ok {
r := controller.NewGCReconciler(s.logger, s.mgr.GetClient(), s.config.GarbageCollectionFrequency)
if err := r.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.GarbageCollection)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerGarbageCollection)
}
}
@@ -951,11 +753,11 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
multiHookTracker := hook.NewMultiHookTracker()
if _, ok := enabledRuntimeControllers[controller.Restore]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerRestore]; ok {
restorer, err := restore.NewKubernetesRestorer(
s.discoveryHelper,
client.NewDynamicFactory(s.dynamicClient),
s.config.restoreResourcePriorities,
s.config.RestoreResourcePriorities,
s.kubeClient.CoreV1().Namespaces(),
podvolume.NewRestorerFactory(
s.repoLocker,
@@ -965,9 +767,9 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
pvrInformer,
s.logger,
),
s.config.podVolumeOperationTimeout,
s.config.resourceTerminatingTimeout,
s.config.resourceTimeout,
s.config.PodVolumeOperationTimeout,
s.config.ResourceTerminatingTimeout,
s.config.ResourceTimeout,
s.logger,
podexec.NewPodCommandExecutor(s.kubeClientConfig, s.kubeClient.CoreV1().RESTClient()),
s.kubeClient.CoreV1().RESTClient(),
@@ -988,24 +790,24 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
newPluginManager,
backupStoreGetter,
s.metrics,
s.config.formatFlag.Parse(),
s.config.defaultItemOperationTimeout,
s.config.disableInformerCache,
s.config.LogFormat.Parse(),
s.config.DefaultItemOperationTimeout,
s.config.DisableInformerCache,
s.crClient,
)
if err = r.SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "fail to create controller", "controller", controller.Restore)
s.logger.Fatal(err, "fail to create controller", "controller", constant.ControllerRestore)
}
}
if _, ok := enabledRuntimeControllers[controller.Schedule]; ok {
if err := controller.NewScheduleReconciler(s.namespace, s.logger, s.mgr.GetClient(), s.metrics, s.config.scheduleSkipImmediately).SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.Schedule)
if _, ok := enabledRuntimeControllers[constant.ControllerSchedule]; ok {
if err := controller.NewScheduleReconciler(s.namespace, s.logger, s.mgr.GetClient(), s.metrics, s.config.ScheduleSkipImmediately).SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerSchedule)
}
}
if _, ok := enabledRuntimeControllers[controller.ServerStatusRequest]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerServerStatusRequest]; ok {
if err := controller.NewServerStatusRequestReconciler(
s.ctx,
s.mgr.GetClient(),
@@ -1013,11 +815,11 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
clock.RealClock{},
s.logger,
).SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.ServerStatusRequest)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerServerStatusRequest)
}
}
if _, ok := enabledRuntimeControllers[controller.RestoreFinalizer]; ok {
if _, ok := enabledRuntimeControllers[constant.ControllerRestoreFinalizer]; ok {
if err := controller.NewRestoreFinalizerReconciler(
s.logger,
s.namespace,
@@ -1027,9 +829,9 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string
s.metrics,
s.crClient,
multiHookTracker,
s.config.resourceTimeout,
s.config.ResourceTimeout,
).SetupWithManager(s.mgr); err != nil {
s.logger.Fatal(err, "unable to create controller", "controller", controller.RestoreFinalizer)
s.logger.Fatal(err, "unable to create controller", "controller", constant.ControllerRestoreFinalizer)
}
}
@@ -1050,7 +852,7 @@ func removeControllers(disabledControllers []string, enabledRuntimeControllers m
logger.Infof("Disabling controller: %s", controllerName)
delete(enabledRuntimeControllers, controllerName)
} else {
msg := fmt.Sprintf("Invalid value for --disable-controllers flag provided: %s. Valid values are: %s", controllerName, strings.Join(controller.DisableableControllers, ","))
msg := fmt.Sprintf("Invalid value for --disable-controllers flag provided: %s. Valid values are: %s", controllerName, strings.Join(config.DisableableControllers, ","))
return errors.New(msg)
}
}
@@ -1066,7 +868,7 @@ func (s *server) runProfiler() {
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
server := &http.Server{
Addr: s.config.profilerAddress,
Addr: s.config.ProfilerAddress,
Handler: mux,
ReadHeaderTimeout: 3 * time.Second,
}

View File

@@ -35,7 +35,8 @@ import (
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
"github.com/vmware-tanzu/velero/pkg/client/mocks"
"github.com/vmware-tanzu/velero/pkg/controller"
"github.com/vmware-tanzu/velero/pkg/cmd/server/config"
"github.com/vmware-tanzu/velero/pkg/constant"
discovery_mocks "github.com/vmware-tanzu/velero/pkg/discovery/mocks"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
"github.com/vmware-tanzu/velero/pkg/uploader"
@@ -112,31 +113,31 @@ func TestRemoveControllers(t *testing.T) {
{
name: "Remove one disable controller",
disabledControllers: []string{
controller.Backup,
constant.ControllerBackup,
},
errorExpected: false,
},
{
name: "Remove all disable controllers",
disabledControllers: []string{
controller.BackupOperations,
controller.Backup,
controller.BackupDeletion,
controller.BackupSync,
controller.DownloadRequest,
controller.GarbageCollection,
controller.BackupRepo,
controller.Restore,
controller.Schedule,
controller.ServerStatusRequest,
constant.ControllerBackupOperations,
constant.ControllerBackup,
constant.ControllerBackupDeletion,
constant.ControllerBackupSync,
constant.ControllerDownloadRequest,
constant.ControllerGarbageCollection,
constant.ControllerBackupRepo,
constant.ControllerRestore,
constant.ControllerSchedule,
constant.ControllerServerStatusRequest,
},
errorExpected: false,
},
{
name: "Remove with a non-disable controller included",
disabledControllers: []string{
controller.Backup,
controller.BackupStorageLocation,
constant.ControllerBackup,
constant.ControllerBackupStorageLocation,
},
errorExpected: true,
},
@@ -151,16 +152,16 @@ func TestRemoveControllers(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
enabledRuntimeControllers := map[string]struct{}{
controller.BackupSync: {},
controller.Backup: {},
controller.GarbageCollection: {},
controller.Restore: {},
controller.ServerStatusRequest: {},
controller.Schedule: {},
controller.BackupDeletion: {},
controller.BackupRepo: {},
controller.DownloadRequest: {},
controller.BackupOperations: {},
constant.ControllerBackupSync: {},
constant.ControllerBackup: {},
constant.ControllerGarbageCollection: {},
constant.ControllerRestore: {},
constant.ControllerServerStatusRequest: {},
constant.ControllerSchedule: {},
constant.ControllerBackupDeletion: {},
constant.ControllerBackupRepo: {},
constant.ControllerDownloadRequest: {},
constant.ControllerBackupOperations: {},
}
totalNumOriginalControllers := len(enabledRuntimeControllers)
@@ -191,42 +192,42 @@ func Test_newServer(t *testing.T) {
logger := logrus.New()
// invalid uploader type
_, err := newServer(factory, serverConfig{
uploaderType: "invalid",
_, err := newServer(factory, &config.Config{
UploaderType: "invalid",
}, logger)
assert.Error(t, err)
// invalid clientQPS
_, err = newServer(factory, serverConfig{
uploaderType: uploader.KopiaType,
clientQPS: -1,
_, err = newServer(factory, &config.Config{
UploaderType: uploader.KopiaType,
ClientQPS: -1,
}, logger)
assert.Error(t, err)
// invalid clientQPS Restic uploader
_, err = newServer(factory, serverConfig{
uploaderType: uploader.ResticType,
clientQPS: -1,
_, err = newServer(factory, &config.Config{
UploaderType: uploader.ResticType,
ClientQPS: -1,
}, logger)
assert.Error(t, err)
// invalid clientBurst
factory.On("SetClientQPS", mock.Anything).Return()
_, err = newServer(factory, serverConfig{
uploaderType: uploader.KopiaType,
clientQPS: 1,
clientBurst: -1,
_, err = newServer(factory, &config.Config{
UploaderType: uploader.KopiaType,
ClientQPS: 1,
ClientBurst: -1,
}, logger)
assert.Error(t, err)
// invalid clientBclientPageSizeurst
factory.On("SetClientQPS", mock.Anything).Return().
On("SetClientBurst", mock.Anything).Return()
_, err = newServer(factory, serverConfig{
uploaderType: uploader.KopiaType,
clientQPS: 1,
clientBurst: 1,
clientPageSize: -1,
_, err = newServer(factory, &config.Config{
UploaderType: uploader.KopiaType,
ClientQPS: 1,
ClientBurst: 1,
ClientPageSize: -1,
}, logger)
assert.Error(t, err)
@@ -236,11 +237,11 @@ func Test_newServer(t *testing.T) {
On("KubeClient").Return(nil, nil).
On("Client").Return(nil, nil).
On("DynamicClient").Return(nil, errors.New("error"))
_, err = newServer(factory, serverConfig{
uploaderType: uploader.KopiaType,
clientQPS: 1,
clientBurst: 1,
clientPageSize: 100,
_, err = newServer(factory, &config.Config{
UploaderType: uploader.KopiaType,
ClientQPS: 1,
ClientBurst: 1,
ClientPageSize: 100,
}, logger)
assert.Error(t, err)
}