mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-05 13:05:17 +00:00
Reduces ~140 indirect imports for plugin/framework importers (#8208)
* Avoid plugin framework importers from needing cloud provider imports Signed-off-by: Tiger Kaovilai <tkaovila@redhat.com>
This commit is contained in:
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/cmd/util/flag"
|
||||
"github.com/vmware-tanzu/velero/pkg/constant"
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume"
|
||||
podvolumeconfigs "github.com/vmware-tanzu/velero/pkg/podvolume/configs"
|
||||
"github.com/vmware-tanzu/velero/pkg/types"
|
||||
"github.com/vmware-tanzu/velero/pkg/uploader"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||
@@ -198,7 +198,7 @@ func GetDefaultConfig() *Config {
|
||||
ResourceTerminatingTimeout: defaultResourceTerminatingTimeout,
|
||||
LogLevel: logging.LogLevelFlag(logrus.InfoLevel),
|
||||
LogFormat: logging.NewFormatFlag(),
|
||||
DefaultVolumesToFsBackup: podvolume.DefaultVolumesToFsBackup,
|
||||
DefaultVolumesToFsBackup: podvolumeconfigs.DefaultVolumesToFsBackup,
|
||||
UploaderType: uploader.ResticType,
|
||||
MaxConcurrentK8SConnections: defaultMaxConcurrentK8SConnections,
|
||||
DefaultSnapshotMoveData: false,
|
||||
|
||||
@@ -78,6 +78,7 @@ import (
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
repokey "github.com/vmware-tanzu/velero/pkg/repository/keys"
|
||||
repomanager "github.com/vmware-tanzu/velero/pkg/repository/manager"
|
||||
"github.com/vmware-tanzu/velero/pkg/restore"
|
||||
"github.com/vmware-tanzu/velero/pkg/uploader"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
||||
@@ -147,7 +148,7 @@ type server struct {
|
||||
logger logrus.FieldLogger
|
||||
logLevel logrus.Level
|
||||
pluginRegistry process.Registry
|
||||
repoManager repository.Manager
|
||||
repoManager repomanager.Manager
|
||||
repoLocker *repository.RepoLocker
|
||||
repoEnsurer *repository.Ensurer
|
||||
metrics *metrics.ServerMetrics
|
||||
@@ -469,7 +470,7 @@ func (s *server) initRepoManager() error {
|
||||
s.repoLocker = repository.NewRepoLocker()
|
||||
s.repoEnsurer = repository.NewEnsurer(s.mgr.GetClient(), s.logger, s.config.ResourceTimeout)
|
||||
|
||||
s.repoManager = repository.NewManager(
|
||||
s.repoManager = repomanager.NewManager(
|
||||
s.namespace,
|
||||
s.mgr.GetClient(),
|
||||
s.repoLocker,
|
||||
|
||||
@@ -49,6 +49,8 @@ import (
|
||||
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
repomanager "github.com/vmware-tanzu/velero/pkg/repository/manager"
|
||||
repotypes "github.com/vmware-tanzu/velero/pkg/repository/types"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||
@@ -62,7 +64,7 @@ type backupDeletionReconciler struct {
|
||||
client.Client
|
||||
logger logrus.FieldLogger
|
||||
backupTracker BackupTracker
|
||||
repoMgr repository.Manager
|
||||
repoMgr repomanager.Manager
|
||||
metrics *metrics.ServerMetrics
|
||||
clock clock.Clock
|
||||
discoveryHelper discovery.Helper
|
||||
@@ -77,7 +79,7 @@ func NewBackupDeletionReconciler(
|
||||
logger logrus.FieldLogger,
|
||||
client client.Client,
|
||||
backupTracker BackupTracker,
|
||||
repoMgr repository.Manager,
|
||||
repoMgr repomanager.Manager,
|
||||
metrics *metrics.ServerMetrics,
|
||||
helper discovery.Helper,
|
||||
newPluginManager func(logrus.FieldLogger) clientmgmt.Manager,
|
||||
@@ -524,7 +526,7 @@ func (r *backupDeletionReconciler) deleteMovedSnapshots(ctx context.Context, bac
|
||||
return []error{errors.Wrapf(err, "failed to retrieve config for snapshot info")}
|
||||
}
|
||||
var errs []error
|
||||
directSnapshots := map[string][]repository.SnapshotIdentifier{}
|
||||
directSnapshots := map[string][]repotypes.SnapshotIdentifier{}
|
||||
for i := range list.Items {
|
||||
cm := list.Items[i]
|
||||
if cm.Data == nil || len(cm.Data) == 0 {
|
||||
@@ -538,7 +540,7 @@ func (r *backupDeletionReconciler) deleteMovedSnapshots(ctx context.Context, bac
|
||||
continue
|
||||
}
|
||||
|
||||
snapshot := repository.SnapshotIdentifier{}
|
||||
snapshot := repotypes.SnapshotIdentifier{}
|
||||
if err := json.Unmarshal(b, &snapshot); err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "failed to unmarshal snapshot info"))
|
||||
continue
|
||||
@@ -550,7 +552,7 @@ func (r *backupDeletionReconciler) deleteMovedSnapshots(ctx context.Context, bac
|
||||
}
|
||||
|
||||
if directSnapshots[snapshot.VolumeNamespace] == nil {
|
||||
directSnapshots[snapshot.VolumeNamespace] = []repository.SnapshotIdentifier{}
|
||||
directSnapshots[snapshot.VolumeNamespace] = []repotypes.SnapshotIdentifier{}
|
||||
}
|
||||
|
||||
directSnapshots[snapshot.VolumeNamespace] = append(directSnapshots[snapshot.VolumeNamespace], snapshot)
|
||||
@@ -618,7 +620,7 @@ func (r *backupDeletionReconciler) patchBackup(ctx context.Context, backup *vele
|
||||
|
||||
// getSnapshotsInBackup returns a list of all pod volume snapshot ids associated with
|
||||
// a given Velero backup.
|
||||
func getSnapshotsInBackup(ctx context.Context, backup *velerov1api.Backup, kbClient client.Client) (map[string][]repository.SnapshotIdentifier, error) {
|
||||
func getSnapshotsInBackup(ctx context.Context, backup *velerov1api.Backup, kbClient client.Client) (map[string][]repotypes.SnapshotIdentifier, error) {
|
||||
podVolumeBackups := &velerov1api.PodVolumeBackupList{}
|
||||
options := &client.ListOptions{
|
||||
LabelSelector: labels.Set(map[string]string{
|
||||
@@ -634,8 +636,8 @@ func getSnapshotsInBackup(ctx context.Context, backup *velerov1api.Backup, kbCli
|
||||
return podvolume.GetSnapshotIdentifier(podVolumeBackups), nil
|
||||
}
|
||||
|
||||
func batchDeleteSnapshots(ctx context.Context, repoEnsurer *repository.Ensurer, repoMgr repository.Manager,
|
||||
directSnapshots map[string][]repository.SnapshotIdentifier, backup *velerov1api.Backup, logger logrus.FieldLogger) []error {
|
||||
func batchDeleteSnapshots(ctx context.Context, repoEnsurer *repository.Ensurer, repoMgr repomanager.Manager,
|
||||
directSnapshots map[string][]repotypes.SnapshotIdentifier, backup *velerov1api.Backup, logger logrus.FieldLogger) []error {
|
||||
var errs []error
|
||||
for volumeNamespace, snapshots := range directSnapshots {
|
||||
batchForget := []string{}
|
||||
|
||||
@@ -55,7 +55,9 @@ import (
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
repomanager "github.com/vmware-tanzu/velero/pkg/repository/manager"
|
||||
repomocks "github.com/vmware-tanzu/velero/pkg/repository/mocks"
|
||||
repotypes "github.com/vmware-tanzu/velero/pkg/repository/types"
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
)
|
||||
|
||||
@@ -698,13 +700,13 @@ func TestGetSnapshotsInBackup(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
podVolumeBackups []velerov1api.PodVolumeBackup
|
||||
expected map[string][]repository.SnapshotIdentifier
|
||||
expected map[string][]repotypes.SnapshotIdentifier
|
||||
longBackupNameEnabled bool
|
||||
}{
|
||||
{
|
||||
name: "no pod volume backups",
|
||||
podVolumeBackups: nil,
|
||||
expected: map[string][]repository.SnapshotIdentifier{},
|
||||
expected: map[string][]repotypes.SnapshotIdentifier{},
|
||||
},
|
||||
{
|
||||
name: "no pod volume backups with matching label",
|
||||
@@ -724,7 +726,7 @@ func TestGetSnapshotsInBackup(t *testing.T) {
|
||||
Status: velerov1api.PodVolumeBackupStatus{SnapshotID: "snap-2"},
|
||||
},
|
||||
},
|
||||
expected: map[string][]repository.SnapshotIdentifier{},
|
||||
expected: map[string][]repotypes.SnapshotIdentifier{},
|
||||
},
|
||||
{
|
||||
name: "some pod volume backups with matching label",
|
||||
@@ -765,7 +767,7 @@ func TestGetSnapshotsInBackup(t *testing.T) {
|
||||
Status: velerov1api.PodVolumeBackupStatus{SnapshotID: ""},
|
||||
},
|
||||
},
|
||||
expected: map[string][]repository.SnapshotIdentifier{
|
||||
expected: map[string][]repotypes.SnapshotIdentifier{
|
||||
"ns-1": {
|
||||
{
|
||||
VolumeNamespace: "ns-1",
|
||||
@@ -820,7 +822,7 @@ func TestGetSnapshotsInBackup(t *testing.T) {
|
||||
Status: velerov1api.PodVolumeBackupStatus{SnapshotID: ""},
|
||||
},
|
||||
},
|
||||
expected: map[string][]repository.SnapshotIdentifier{
|
||||
expected: map[string][]repotypes.SnapshotIdentifier{
|
||||
"ns-1": {
|
||||
{
|
||||
VolumeNamespace: "ns-1",
|
||||
@@ -856,18 +858,18 @@ func TestGetSnapshotsInBackup(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func batchDeleteSucceed(ctx context.Context, repoEnsurer *repository.Ensurer, repoMgr repository.Manager, directSnapshots map[string][]repository.SnapshotIdentifier, backup *velerov1api.Backup, logger logrus.FieldLogger) []error {
|
||||
func batchDeleteSucceed(ctx context.Context, repoEnsurer *repository.Ensurer, repoMgr repomanager.Manager, directSnapshots map[string][]repotypes.SnapshotIdentifier, backup *velerov1api.Backup, logger logrus.FieldLogger) []error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func batchDeleteFail(ctx context.Context, repoEnsurer *repository.Ensurer, repoMgr repository.Manager, directSnapshots map[string][]repository.SnapshotIdentifier, backup *velerov1api.Backup, logger logrus.FieldLogger) []error {
|
||||
func batchDeleteFail(ctx context.Context, repoEnsurer *repository.Ensurer, repoMgr repomanager.Manager, directSnapshots map[string][]repotypes.SnapshotIdentifier, backup *velerov1api.Backup, logger logrus.FieldLogger) []error {
|
||||
return []error{
|
||||
errors.New("fake-delete-1"),
|
||||
errors.New("fake-delete-2"),
|
||||
}
|
||||
}
|
||||
|
||||
func generateSnapshotData(snapshot *repository.SnapshotIdentifier) (map[string]string, error) {
|
||||
func generateSnapshotData(snapshot *repotypes.SnapshotIdentifier) (map[string]string, error) {
|
||||
if snapshot == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -888,10 +890,10 @@ func generateSnapshotData(snapshot *repository.SnapshotIdentifier) (map[string]s
|
||||
func TestDeleteMovedSnapshots(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
repoMgr repository.Manager
|
||||
repoMgr repomanager.Manager
|
||||
batchDeleteSucceed bool
|
||||
backupName string
|
||||
snapshots []*repository.SnapshotIdentifier
|
||||
snapshots []*repotypes.SnapshotIdentifier
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
@@ -905,14 +907,14 @@ func TestDeleteMovedSnapshots(t *testing.T) {
|
||||
name: "bad cm info",
|
||||
repoMgr: repomocks.NewManager(t),
|
||||
backupName: "backup-01",
|
||||
snapshots: []*repository.SnapshotIdentifier{nil},
|
||||
snapshots: []*repotypes.SnapshotIdentifier{nil},
|
||||
expected: []string{"no snapshot info in config"},
|
||||
},
|
||||
{
|
||||
name: "invalid snapshots",
|
||||
repoMgr: repomocks.NewManager(t),
|
||||
backupName: "backup-01",
|
||||
snapshots: []*repository.SnapshotIdentifier{
|
||||
snapshots: []*repotypes.SnapshotIdentifier{
|
||||
{
|
||||
RepositoryType: "repo-1",
|
||||
VolumeNamespace: "ns-1",
|
||||
@@ -937,7 +939,7 @@ func TestDeleteMovedSnapshots(t *testing.T) {
|
||||
name: "batch delete succeed",
|
||||
repoMgr: repomocks.NewManager(t),
|
||||
backupName: "backup-01",
|
||||
snapshots: []*repository.SnapshotIdentifier{
|
||||
snapshots: []*repotypes.SnapshotIdentifier{
|
||||
|
||||
{
|
||||
SnapshotID: "snapshot-1",
|
||||
@@ -952,7 +954,7 @@ func TestDeleteMovedSnapshots(t *testing.T) {
|
||||
name: "batch delete fail",
|
||||
repoMgr: repomocks.NewManager(t),
|
||||
backupName: "backup-01",
|
||||
snapshots: []*repository.SnapshotIdentifier{
|
||||
snapshots: []*repotypes.SnapshotIdentifier{
|
||||
{
|
||||
RepositoryType: "repo-1",
|
||||
VolumeNamespace: "ns-1",
|
||||
|
||||
@@ -35,14 +35,14 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/constant"
|
||||
"github.com/vmware-tanzu/velero/pkg/label"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
repoconfig "github.com/vmware-tanzu/velero/pkg/repository/config"
|
||||
repomanager "github.com/vmware-tanzu/velero/pkg/repository/manager"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -57,11 +57,11 @@ type BackupRepoReconciler struct {
|
||||
clock clocks.WithTickerAndDelayedExecution
|
||||
maintenanceFrequency time.Duration
|
||||
backupRepoConfig string
|
||||
repositoryManager repository.Manager
|
||||
repositoryManager repomanager.Manager
|
||||
}
|
||||
|
||||
func NewBackupRepoReconciler(namespace string, logger logrus.FieldLogger, client client.Client,
|
||||
maintenanceFrequency time.Duration, backupRepoConfig string, repositoryManager repository.Manager) *BackupRepoReconciler {
|
||||
maintenanceFrequency time.Duration, backupRepoConfig string, repositoryManager repomanager.Manager) *BackupRepoReconciler {
|
||||
c := &BackupRepoReconciler{
|
||||
client,
|
||||
namespace,
|
||||
@@ -294,7 +294,7 @@ func (r *BackupRepoReconciler) getRepositoryMaintenanceFrequency(req *velerov1ap
|
||||
|
||||
// ensureRepo calls repo manager's PrepareRepo to ensure the repo is ready for use.
|
||||
// An error is returned if the repository can't be connected to or initialized.
|
||||
func ensureRepo(repo *velerov1api.BackupRepository, repoManager repository.Manager) error {
|
||||
func ensureRepo(repo *velerov1api.BackupRepository, repoManager repomanager.Manager) error {
|
||||
return repoManager.PrepareRepo(repo)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ import (
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
repomokes "github.com/vmware-tanzu/velero/pkg/repository/mocks"
|
||||
repotypes "github.com/vmware-tanzu/velero/pkg/repository/types"
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
|
||||
clientFake "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
@@ -210,7 +210,7 @@ func TestBackupRepoReconcile(t *testing.T) {
|
||||
func TestGetRepositoryMaintenanceFrequency(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mgr repository.Manager
|
||||
mgr repotypes.SnapshotIdentifier
|
||||
repo *velerov1api.BackupRepository
|
||||
freqReturn time.Duration
|
||||
freqError error
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
repotypes "github.com/vmware-tanzu/velero/pkg/repository/types"
|
||||
)
|
||||
|
||||
type DataUploadDeleteAction struct {
|
||||
@@ -52,7 +52,7 @@ func genConfigmap(bak *velerov1.Backup, du velerov2alpha1.DataUpload) *corev1api
|
||||
if !IsBuiltInUploader(du.Spec.DataMover) || du.Status.SnapshotID == "" {
|
||||
return nil
|
||||
}
|
||||
snapshot := repository.SnapshotIdentifier{
|
||||
snapshot := repotypes.SnapshotIdentifier{
|
||||
VolumeNamespace: du.Spec.SourceNamespace,
|
||||
BackupStorageLocation: bak.Spec.StorageLocation,
|
||||
SnapshotID: du.Status.SnapshotID,
|
||||
|
||||
53
pkg/install/import_test.go
Normal file
53
pkg/install/import_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// test that this package do not import cloud provider
|
||||
|
||||
// Prevent https://github.com/vmware-tanzu/velero/issues/8207 and https://github.com/vmware-tanzu/velero/issues/8157
|
||||
func TestPkgImportNoCloudProvider(t *testing.T) {
|
||||
_, filename, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
t.Fatalf("No caller information")
|
||||
}
|
||||
t.Logf("Current test file path: %s", filename)
|
||||
t.Logf("Current test directory: %s", filepath.Dir(filename)) // should be this package name
|
||||
// go list -f {{.Deps}} ./<path-to-this-package-dir>
|
||||
cmd := exec.Command(
|
||||
"go",
|
||||
"list",
|
||||
"-f",
|
||||
"{{.Deps}}",
|
||||
".",
|
||||
)
|
||||
// set cmd.Dir to this package even if executed from different dir
|
||||
cmd.Dir = filepath.Dir(filename)
|
||||
output, err := cmd.Output()
|
||||
require.NoError(t, err)
|
||||
// split dep by line, replace space with newline
|
||||
deps := strings.ReplaceAll(string(output), " ", "\n")
|
||||
require.NotEmpty(t, deps)
|
||||
// ignore k8s.io
|
||||
k8sio, err := regexp.Compile("^k8s.io")
|
||||
require.NoError(t, err)
|
||||
cloudProvider, err := regexp.Compile("aws|cloud.google.com|azure")
|
||||
require.NoError(t, err)
|
||||
cloudProviderDeps := []string{}
|
||||
for _, dep := range strings.Split(deps, "\n") {
|
||||
if !k8sio.MatchString(dep) {
|
||||
if cloudProvider.MatchString(dep) {
|
||||
cloudProviderDeps = append(cloudProviderDeps, dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
require.Empty(t, cloudProviderDeps)
|
||||
}
|
||||
53
pkg/plugin/framework/import_test.go
Normal file
53
pkg/plugin/framework/import_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package framework
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// test that this package do not import cloud provider
|
||||
|
||||
// Prevent https://github.com/vmware-tanzu/velero/issues/8207 and https://github.com/vmware-tanzu/velero/issues/8157
|
||||
func TestPkgImportNoCloudProvider(t *testing.T) {
|
||||
_, filename, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
t.Fatalf("No caller information")
|
||||
}
|
||||
t.Logf("Current test file path: %s", filename)
|
||||
t.Logf("Current test directory: %s", filepath.Dir(filename)) // should be this package name
|
||||
// go list -f {{.Deps}} ./<path-to-this-package-dir>
|
||||
cmd := exec.Command(
|
||||
"go",
|
||||
"list",
|
||||
"-f",
|
||||
"{{.Deps}}",
|
||||
".",
|
||||
)
|
||||
// set cmd.Dir to this package even if executed from different dir
|
||||
cmd.Dir = filepath.Dir(filename)
|
||||
output, err := cmd.Output()
|
||||
require.NoError(t, err)
|
||||
// split dep by line, replace space with newline
|
||||
deps := strings.ReplaceAll(string(output), " ", "\n")
|
||||
require.NotEmpty(t, deps)
|
||||
// ignore k8s.io
|
||||
k8sio, err := regexp.Compile("^k8s.io")
|
||||
require.NoError(t, err)
|
||||
cloudProvider, err := regexp.Compile("aws|cloud.google.com|azure")
|
||||
require.NoError(t, err)
|
||||
cloudProviderDeps := []string{}
|
||||
for _, dep := range strings.Split(deps, "\n") {
|
||||
if !k8sio.MatchString(dep) {
|
||||
if cloudProvider.MatchString(dep) {
|
||||
cloudProviderDeps = append(cloudProviderDeps, dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
require.Empty(t, cloudProviderDeps)
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
veleroclient "github.com/vmware-tanzu/velero/pkg/client"
|
||||
"github.com/vmware-tanzu/velero/pkg/label"
|
||||
"github.com/vmware-tanzu/velero/pkg/nodeagent"
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume/configs"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
"github.com/vmware-tanzu/velero/pkg/uploader"
|
||||
uploaderutil "github.com/vmware-tanzu/velero/pkg/uploader/util"
|
||||
@@ -419,7 +420,7 @@ func newPodVolumeBackup(backup *velerov1api.Backup, pod *corev1api.Pod, volume c
|
||||
// this annotation is used in pkg/restore to identify if a PVC
|
||||
// has a pod volume backup.
|
||||
pvb.Annotations = map[string]string{
|
||||
PVCNameAnnotation: pvc.Name,
|
||||
configs.PVCNameAnnotation: pvc.Name,
|
||||
}
|
||||
|
||||
// this label is used by the pod volume backup controller to tell
|
||||
|
||||
11
pkg/podvolume/configs/configs.go
Normal file
11
pkg/podvolume/configs/configs.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package configs
|
||||
|
||||
const (
|
||||
// PVCNameAnnotation is the key for the annotation added to
|
||||
// pod volume backups when they're for a PVC.
|
||||
PVCNameAnnotation = "velero.io/pvc-name"
|
||||
|
||||
// DefaultVolumesToFsBackup specifies whether pod volume backup should be used, by default, to
|
||||
// take backup of all pod volumes.
|
||||
DefaultVolumesToFsBackup = false
|
||||
)
|
||||
@@ -23,23 +23,15 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
repotypes "github.com/vmware-tanzu/velero/pkg/repository/types"
|
||||
"github.com/vmware-tanzu/velero/pkg/uploader"
|
||||
)
|
||||
|
||||
const (
|
||||
// PVCNameAnnotation is the key for the annotation added to
|
||||
// pod volume backups when they're for a PVC.
|
||||
PVCNameAnnotation = "velero.io/pvc-name"
|
||||
|
||||
// Deprecated.
|
||||
//
|
||||
// TODO(2.0): remove
|
||||
podAnnotationPrefix = "snapshot.velero.io/"
|
||||
|
||||
// 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
|
||||
@@ -122,20 +114,20 @@ func getVolumeBackupInfoForPod(podVolumeBackups []*velerov1api.PodVolumeBackup,
|
||||
}
|
||||
|
||||
// GetSnapshotIdentifier returns the snapshots represented by SnapshotIdentifier for the given PVBs
|
||||
func GetSnapshotIdentifier(podVolumeBackups *velerov1api.PodVolumeBackupList) map[string][]repository.SnapshotIdentifier {
|
||||
res := map[string][]repository.SnapshotIdentifier{}
|
||||
func GetSnapshotIdentifier(podVolumeBackups *velerov1api.PodVolumeBackupList) map[string][]repotypes.SnapshotIdentifier {
|
||||
res := map[string][]repotypes.SnapshotIdentifier{}
|
||||
for _, item := range podVolumeBackups.Items {
|
||||
if item.Status.SnapshotID == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if res[item.Spec.Pod.Namespace] == nil {
|
||||
res[item.Spec.Pod.Namespace] = []repository.SnapshotIdentifier{}
|
||||
res[item.Spec.Pod.Namespace] = []repotypes.SnapshotIdentifier{}
|
||||
}
|
||||
|
||||
snapshots := res[item.Spec.Pod.Namespace]
|
||||
|
||||
snapshots = append(snapshots, repository.SnapshotIdentifier{
|
||||
snapshots = append(snapshots, repotypes.SnapshotIdentifier{
|
||||
VolumeNamespace: item.Spec.Pod.Namespace,
|
||||
BackupStorageLocation: item.Spec.BackupStorageLocation,
|
||||
SnapshotID: item.Status.SnapshotID,
|
||||
|
||||
@@ -50,7 +50,7 @@ type JobConfigs struct {
|
||||
PodResources *kube.PodResources `json:"podResources,omitempty"`
|
||||
}
|
||||
|
||||
func generateJobName(repo string) string {
|
||||
func GenerateJobName(repo string) string {
|
||||
millisecond := time.Now().UTC().UnixMilli() // millisecond
|
||||
|
||||
jobName := fmt.Sprintf("%s-maintain-job-%d", repo, millisecond)
|
||||
@@ -61,8 +61,8 @@ func generateJobName(repo string) string {
|
||||
return jobName
|
||||
}
|
||||
|
||||
// deleteOldMaintenanceJobs deletes old maintenance jobs and keeps the latest N jobs
|
||||
func deleteOldMaintenanceJobs(cli client.Client, repo string, keep int) error {
|
||||
// DeleteOldMaintenanceJobs deletes old maintenance jobs and keeps the latest N jobs
|
||||
func DeleteOldMaintenanceJobs(cli client.Client, repo string, keep int) error {
|
||||
// Get the maintenance job list by label
|
||||
jobList := &batchv1.JobList{}
|
||||
err := cli.List(context.TODO(), jobList, client.MatchingLabels(map[string]string{RepositoryNameLabel: repo}))
|
||||
@@ -86,7 +86,7 @@ func deleteOldMaintenanceJobs(cli client.Client, repo string, keep int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func waitForJobComplete(ctx context.Context, client client.Client, job *batchv1.Job) error {
|
||||
func WaitForJobComplete(ctx context.Context, client client.Client, job *batchv1.Job) error {
|
||||
return wait.PollUntilContextCancel(ctx, 1, true, func(ctx context.Context) (bool, error) {
|
||||
err := client.Get(ctx, types.NamespacedName{Namespace: job.Namespace, Name: job.Name}, job)
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
@@ -104,7 +104,7 @@ func waitForJobComplete(ctx context.Context, client client.Client, job *batchv1.
|
||||
})
|
||||
}
|
||||
|
||||
func getMaintenanceResultFromJob(cli client.Client, job *batchv1.Job) (string, error) {
|
||||
func GetMaintenanceResultFromJob(cli client.Client, job *batchv1.Job) (string, error) {
|
||||
// Get the maintenance job related pod by label selector
|
||||
podList := &v1.PodList{}
|
||||
err := cli.List(context.TODO(), podList, client.InNamespace(job.Namespace), client.MatchingLabels(map[string]string{"job-name": job.Name}))
|
||||
@@ -120,7 +120,7 @@ func getMaintenanceResultFromJob(cli client.Client, job *batchv1.Job) (string, e
|
||||
return podList.Items[0].Status.ContainerStatuses[0].State.Terminated.Message, nil
|
||||
}
|
||||
|
||||
func getLatestMaintenanceJob(cli client.Client, ns string) (*batchv1.Job, error) {
|
||||
func GetLatestMaintenanceJob(cli client.Client, ns string) (*batchv1.Job, error) {
|
||||
// Get the maintenance job list by label
|
||||
jobList := &batchv1.JobList{}
|
||||
err := cli.List(context.TODO(), jobList, &client.ListOptions{
|
||||
@@ -145,7 +145,7 @@ func getLatestMaintenanceJob(cli client.Client, ns string) (*batchv1.Job, error)
|
||||
return &jobList.Items[0], nil
|
||||
}
|
||||
|
||||
// getMaintenanceJobConfig is called to get the Maintenance Job Config for the
|
||||
// GetMaintenanceJobConfig is called to get the Maintenance Job Config for the
|
||||
// BackupRepository specified by the repo parameter.
|
||||
//
|
||||
// Params:
|
||||
@@ -156,7 +156,7 @@ func getLatestMaintenanceJob(cli client.Client, ns string) (*batchv1.Job, error)
|
||||
// veleroNamespace: the Velero-installed namespace. It's used to retrieve the BackupRepository.
|
||||
// repoMaintenanceJobConfig: the repository maintenance job ConfigMap name.
|
||||
// repo: the BackupRepository needs to run the maintenance Job.
|
||||
func getMaintenanceJobConfig(
|
||||
func GetMaintenanceJobConfig(
|
||||
ctx context.Context,
|
||||
client client.Client,
|
||||
logger logrus.FieldLogger,
|
||||
|
||||
@@ -56,7 +56,7 @@ func TestGenerateJobName1(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.repo, func(t *testing.T) {
|
||||
// Call the function to test
|
||||
jobName := generateJobName(tc.repo)
|
||||
jobName := GenerateJobName(tc.repo)
|
||||
|
||||
// Check if the generated job name starts with the expected prefix
|
||||
if !strings.HasPrefix(jobName, tc.expectedStart) {
|
||||
@@ -108,7 +108,7 @@ func TestDeleteOldMaintenanceJobs(t *testing.T) {
|
||||
cli := fake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...).Build()
|
||||
|
||||
// Call the function
|
||||
err := deleteOldMaintenanceJobs(cli, repo, keep)
|
||||
err := DeleteOldMaintenanceJobs(cli, repo, keep)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get the remaining jobs
|
||||
@@ -167,7 +167,7 @@ func TestWaitForJobComplete(t *testing.T) {
|
||||
// Create a fake Kubernetes client
|
||||
cli := fake.NewClientBuilder().WithObjects(job).Build()
|
||||
// Call the function
|
||||
err := waitForJobComplete(context.Background(), cli, job)
|
||||
err := WaitForJobComplete(context.Background(), cli, job)
|
||||
|
||||
// Check if the error matches the expectation
|
||||
if tc.expectError {
|
||||
@@ -212,7 +212,7 @@ func TestGetMaintenanceResultFromJob(t *testing.T) {
|
||||
cli := fake.NewClientBuilder().WithObjects(job, pod).Build()
|
||||
|
||||
// Call the function
|
||||
result, err := getMaintenanceResultFromJob(cli, job)
|
||||
result, err := GetMaintenanceResultFromJob(cli, job)
|
||||
|
||||
// Check if the result and error match the expectation
|
||||
assert.NoError(t, err)
|
||||
@@ -256,7 +256,7 @@ func TestGetLatestMaintenanceJob(t *testing.T) {
|
||||
cli := fake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...).Build()
|
||||
|
||||
// Call the function
|
||||
job, err := getLatestMaintenanceJob(cli, "default")
|
||||
job, err := GetLatestMaintenanceJob(cli, "default")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// We expect the returned job to be the newer job
|
||||
@@ -419,7 +419,7 @@ func TestGetMaintenanceJobConfig(t *testing.T) {
|
||||
fakeClient = velerotest.NewFakeControllerRuntimeClient(t)
|
||||
}
|
||||
|
||||
jobConfig, err := getMaintenanceJobConfig(
|
||||
jobConfig, err := GetMaintenanceJobConfig(
|
||||
ctx,
|
||||
fakeClient,
|
||||
logger,
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository/provider"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||
@@ -39,35 +40,6 @@ import (
|
||||
veleroutil "github.com/vmware-tanzu/velero/pkg/util/velero"
|
||||
)
|
||||
|
||||
// SnapshotIdentifier uniquely identifies a snapshot
|
||||
// taken by Velero.
|
||||
type SnapshotIdentifier struct {
|
||||
// VolumeNamespace is the namespace of the pod/volume that
|
||||
// the snapshot is for.
|
||||
VolumeNamespace string `json:"volumeNamespace"`
|
||||
|
||||
// BackupStorageLocation is the backup's storage location
|
||||
// name.
|
||||
BackupStorageLocation string `json:"backupStorageLocation"`
|
||||
|
||||
// SnapshotID is the short ID of the snapshot.
|
||||
SnapshotID string `json:"snapshotID"`
|
||||
|
||||
// RepositoryType is the type of the repository where the
|
||||
// snapshot is stored
|
||||
RepositoryType string `json:"repositoryType"`
|
||||
|
||||
// Source is the source of the data saved in the repo by the snapshot
|
||||
Source string `json:"source"`
|
||||
|
||||
// UploaderType is the type of uploader which saved the snapshot data
|
||||
UploaderType string `json:"uploaderType"`
|
||||
|
||||
// RepoIdentifier is the identifier of the repository where the
|
||||
// snapshot is stored
|
||||
RepoIdentifier string `json:"repoIdentifier"`
|
||||
}
|
||||
|
||||
// Manager manages backup repositories.
|
||||
type Manager interface {
|
||||
// InitRepo initializes a repo with the specified name and identifier.
|
||||
@@ -105,8 +77,8 @@ type manager struct {
|
||||
// client is the Velero controller manager's client.
|
||||
// It's limited to resources in the Velero namespace.
|
||||
client client.Client
|
||||
repoLocker *RepoLocker
|
||||
repoEnsurer *Ensurer
|
||||
repoLocker *repository.RepoLocker
|
||||
repoEnsurer *repository.Ensurer
|
||||
fileSystem filesystem.Interface
|
||||
repoMaintenanceJobConfig string
|
||||
podResources kube.PodResources
|
||||
@@ -120,8 +92,8 @@ type manager struct {
|
||||
func NewManager(
|
||||
namespace string,
|
||||
client client.Client,
|
||||
repoLocker *RepoLocker,
|
||||
repoEnsurer *Ensurer,
|
||||
repoLocker *repository.RepoLocker,
|
||||
repoEnsurer *repository.Ensurer,
|
||||
credentialFileStore credentials.FileStore,
|
||||
credentialSecretStore credentials.SecretStore,
|
||||
repoMaintenanceJobConfig string,
|
||||
@@ -216,7 +188,7 @@ func (m *manager) PruneRepo(repo *velerov1api.BackupRepository) error {
|
||||
"repo UID": param.BackupRepo.UID,
|
||||
})
|
||||
|
||||
job, err := getLatestMaintenanceJob(m.client, m.namespace)
|
||||
job, err := repository.GetLatestMaintenanceJob(m.client, m.namespace)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
@@ -226,7 +198,7 @@ func (m *manager) PruneRepo(repo *velerov1api.BackupRepository) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
jobConfig, err := getMaintenanceJobConfig(
|
||||
jobConfig, err := repository.GetMaintenanceJobConfig(
|
||||
context.Background(),
|
||||
m.client,
|
||||
m.log,
|
||||
@@ -259,7 +231,7 @@ func (m *manager) PruneRepo(repo *velerov1api.BackupRepository) error {
|
||||
log.Debug("Creating maintenance job")
|
||||
|
||||
defer func() {
|
||||
if err := deleteOldMaintenanceJobs(
|
||||
if err := repository.DeleteOldMaintenanceJobs(
|
||||
m.client,
|
||||
param.BackupRepo.Name,
|
||||
m.keepLatestMaintenanceJobs,
|
||||
@@ -269,12 +241,12 @@ func (m *manager) PruneRepo(repo *velerov1api.BackupRepository) error {
|
||||
}()
|
||||
|
||||
var jobErr error
|
||||
if err := waitForJobComplete(context.TODO(), m.client, maintenanceJob); err != nil {
|
||||
if err := repository.WaitForJobComplete(context.TODO(), m.client, maintenanceJob); err != nil {
|
||||
log.WithError(err).Error("Error to wait for maintenance job complete")
|
||||
jobErr = err // we won't return here for job may failed by maintenance failure, we want return the actual error
|
||||
}
|
||||
|
||||
result, err := getMaintenanceResultFromJob(m.client, maintenanceJob)
|
||||
result, err := repository.GetMaintenanceResultFromJob(m.client, maintenanceJob)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error to get maintenance job result")
|
||||
}
|
||||
@@ -383,7 +355,7 @@ func (m *manager) assembleRepoParam(repo *velerov1api.BackupRepository) (provide
|
||||
}
|
||||
|
||||
func (m *manager) buildMaintenanceJob(
|
||||
config *JobConfigs,
|
||||
config *repository.JobConfigs,
|
||||
param provider.RepoParam,
|
||||
) (*batchv1.Job, error) {
|
||||
// Get the Velero server deployment
|
||||
@@ -435,10 +407,10 @@ func (m *manager) buildMaintenanceJob(
|
||||
// build the maintenance job
|
||||
job := &batchv1.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: generateJobName(param.BackupRepo.Name),
|
||||
Name: repository.GenerateJobName(param.BackupRepo.Name),
|
||||
Namespace: param.BackupRepo.Namespace,
|
||||
Labels: map[string]string{
|
||||
RepositoryNameLabel: param.BackupRepo.Name,
|
||||
repository.RepositoryNameLabel: param.BackupRepo.Name,
|
||||
},
|
||||
},
|
||||
Spec: batchv1.JobSpec{
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
|
||||
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository/provider"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/logging"
|
||||
@@ -63,7 +64,7 @@ func TestGetRepositoryProvider(t *testing.T) {
|
||||
func TestBuildMaintenanceJob(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
m *JobConfigs
|
||||
m *repository.JobConfigs
|
||||
deploy *appsv1.Deployment
|
||||
logLevel logrus.Level
|
||||
logFormat *logging.FormatFlag
|
||||
@@ -72,7 +73,7 @@ func TestBuildMaintenanceJob(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "Valid maintenance job",
|
||||
m: &JobConfigs{
|
||||
m: &repository.JobConfigs{
|
||||
PodResources: &kube.PodResources{
|
||||
CPURequest: "100m",
|
||||
MemoryRequest: "128Mi",
|
||||
@@ -105,7 +106,7 @@ func TestBuildMaintenanceJob(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "Error getting Velero server deployment",
|
||||
m: &JobConfigs{
|
||||
m: &repository.JobConfigs{
|
||||
PodResources: &kube.PodResources{
|
||||
CPURequest: "100m",
|
||||
MemoryRequest: "128Mi",
|
||||
@@ -179,7 +180,7 @@ func TestBuildMaintenanceJob(t *testing.T) {
|
||||
assert.NotNil(t, job)
|
||||
assert.Contains(t, job.Name, tc.expectedJobName)
|
||||
assert.Equal(t, param.BackupRepo.Namespace, job.Namespace)
|
||||
assert.Equal(t, param.BackupRepo.Name, job.Labels[RepositoryNameLabel])
|
||||
assert.Equal(t, param.BackupRepo.Name, job.Labels[repository.RepositoryNameLabel])
|
||||
|
||||
// Check container
|
||||
assert.Len(t, job.Spec.Template.Spec.Containers, 1)
|
||||
30
pkg/repository/types/snapshotidentifier.go
Normal file
30
pkg/repository/types/snapshotidentifier.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package types
|
||||
|
||||
// SnapshotIdentifier uniquely identifies a snapshot
|
||||
// taken by Velero.
|
||||
type SnapshotIdentifier struct {
|
||||
// VolumeNamespace is the namespace of the pod/volume that
|
||||
// the snapshot is for.
|
||||
VolumeNamespace string `json:"volumeNamespace"`
|
||||
|
||||
// BackupStorageLocation is the backup's storage location
|
||||
// name.
|
||||
BackupStorageLocation string `json:"backupStorageLocation"`
|
||||
|
||||
// SnapshotID is the short ID of the snapshot.
|
||||
SnapshotID string `json:"snapshotID"`
|
||||
|
||||
// RepositoryType is the type of the repository where the
|
||||
// snapshot is stored
|
||||
RepositoryType string `json:"repositoryType"`
|
||||
|
||||
// Source is the source of the data saved in the repo by the snapshot
|
||||
Source string `json:"source"`
|
||||
|
||||
// UploaderType is the type of uploader which saved the snapshot data
|
||||
UploaderType string `json:"uploaderType"`
|
||||
|
||||
// RepoIdentifier is the identifier of the repository where the
|
||||
// snapshot is stored
|
||||
RepoIdentifier string `json:"repoIdentifier"`
|
||||
}
|
||||
@@ -68,6 +68,7 @@ import (
|
||||
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/podexec"
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume"
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume/configs"
|
||||
"github.com/vmware-tanzu/velero/pkg/types"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/collections"
|
||||
@@ -2025,7 +2026,7 @@ func hasPodVolumeBackup(unstructuredPV *unstructured.Unstructured, ctx *restoreC
|
||||
|
||||
var found bool
|
||||
for _, pvb := range ctx.podVolumeBackups {
|
||||
if pvb.Spec.Pod.Namespace == pv.Spec.ClaimRef.Namespace && pvb.GetAnnotations()[podvolume.PVCNameAnnotation] == pv.Spec.ClaimRef.Name {
|
||||
if pvb.Spec.Pod.Namespace == pv.Spec.ClaimRef.Namespace && pvb.GetAnnotations()[configs.PVCNameAnnotation] == pv.Spec.ClaimRef.Name {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user