mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-09-20 06:54:32 +00:00
replace ark restic repo init cmd with automatic initialization of repos
Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
@@ -39,6 +40,8 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
const resticTimeout = time.Minute
|
||||
|
||||
type backupDeletionController struct {
|
||||
*genericController
|
||||
|
||||
@@ -239,13 +242,9 @@ func (c *backupDeletionController) processRequest(req *v1.DeleteBackupRequest) e
|
||||
|
||||
// Try to delete restic snapshots
|
||||
log.Info("Removing restic snapshots")
|
||||
if snapshots, err := restic.GetSnapshotsInBackup(backup, c.podvolumeBackupLister); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
} else {
|
||||
for _, snapshot := range snapshots {
|
||||
if err := c.resticMgr.Forget(snapshot); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
if deleteErrs := c.deleteResticSnapshots(backup); len(deleteErrs) > 0 {
|
||||
for _, err := range deleteErrs {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,6 +303,29 @@ func (c *backupDeletionController) processRequest(req *v1.DeleteBackupRequest) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *backupDeletionController) deleteResticSnapshots(backup *v1.Backup) []error {
|
||||
if c.resticMgr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
snapshots, err := restic.GetSnapshotsInBackup(backup, c.podvolumeBackupLister)
|
||||
if err != nil {
|
||||
return []error{err}
|
||||
}
|
||||
|
||||
ctx, cancelFunc := context.WithTimeout(context.Background(), resticTimeout)
|
||||
defer cancelFunc()
|
||||
|
||||
var errs []error
|
||||
for _, snapshot := range snapshots {
|
||||
if err := c.resticMgr.Forget(ctx, snapshot); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
const deleteBackupRequestMaxAge = 24 * time.Hour
|
||||
|
||||
func (c *backupDeletionController) deleteExpiredRequests() {
|
||||
|
||||
@@ -60,7 +60,7 @@ func NewPodVolumeBackupController(
|
||||
podVolumeBackupInformer informers.PodVolumeBackupInformer,
|
||||
podVolumeBackupClient arkv1client.PodVolumeBackupsGetter,
|
||||
podInformer cache.SharedIndexInformer,
|
||||
secretInformer corev1informers.SecretInformer,
|
||||
secretInformer cache.SharedIndexInformer,
|
||||
pvcInformer corev1informers.PersistentVolumeClaimInformer,
|
||||
nodeName string,
|
||||
) Interface {
|
||||
@@ -69,7 +69,7 @@ func NewPodVolumeBackupController(
|
||||
podVolumeBackupClient: podVolumeBackupClient,
|
||||
podVolumeBackupLister: podVolumeBackupInformer.Lister(),
|
||||
podLister: corev1listers.NewPodLister(podInformer.GetIndexer()),
|
||||
secretLister: secretInformer.Lister(),
|
||||
secretLister: corev1listers.NewSecretLister(secretInformer.GetIndexer()),
|
||||
pvcLister: pvcInformer.Lister(),
|
||||
nodeName: nodeName,
|
||||
}
|
||||
@@ -78,8 +78,8 @@ func NewPodVolumeBackupController(
|
||||
c.cacheSyncWaiters = append(
|
||||
c.cacheSyncWaiters,
|
||||
podVolumeBackupInformer.Informer().HasSynced,
|
||||
secretInformer.Informer().HasSynced,
|
||||
podInformer.HasSynced,
|
||||
secretInformer.HasSynced,
|
||||
pvcInformer.Informer().HasSynced,
|
||||
)
|
||||
c.processBackupFunc = c.processBackup
|
||||
@@ -194,7 +194,7 @@ func (c *podVolumeBackupController) processBackup(req *arkv1api.PodVolumeBackup)
|
||||
log.WithField("path", path).Debugf("Found path matching glob")
|
||||
|
||||
// temp creds
|
||||
file, err := restic.TempCredentialsFile(c.secretLister, req.Spec.Pod.Namespace)
|
||||
file, err := restic.TempCredentialsFile(c.secretLister, req.Namespace, req.Spec.Pod.Namespace)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Error creating temp restic credentials file")
|
||||
return c.fail(req, errors.Wrap(err, "error creating temp restic credentials file").Error(), log)
|
||||
|
||||
@@ -50,8 +50,8 @@ type podVolumeRestoreController struct {
|
||||
|
||||
podVolumeRestoreClient arkv1client.PodVolumeRestoresGetter
|
||||
podVolumeRestoreLister listers.PodVolumeRestoreLister
|
||||
secretLister corev1listers.SecretLister
|
||||
podLister corev1listers.PodLister
|
||||
secretLister corev1listers.SecretLister
|
||||
pvcLister corev1listers.PersistentVolumeClaimLister
|
||||
nodeName string
|
||||
|
||||
@@ -64,7 +64,7 @@ func NewPodVolumeRestoreController(
|
||||
podVolumeRestoreInformer informers.PodVolumeRestoreInformer,
|
||||
podVolumeRestoreClient arkv1client.PodVolumeRestoresGetter,
|
||||
podInformer cache.SharedIndexInformer,
|
||||
secretInformer corev1informers.SecretInformer,
|
||||
secretInformer cache.SharedIndexInformer,
|
||||
pvcInformer corev1informers.PersistentVolumeClaimInformer,
|
||||
nodeName string,
|
||||
) Interface {
|
||||
@@ -73,7 +73,7 @@ func NewPodVolumeRestoreController(
|
||||
podVolumeRestoreClient: podVolumeRestoreClient,
|
||||
podVolumeRestoreLister: podVolumeRestoreInformer.Lister(),
|
||||
podLister: corev1listers.NewPodLister(podInformer.GetIndexer()),
|
||||
secretLister: secretInformer.Lister(),
|
||||
secretLister: corev1listers.NewSecretLister(secretInformer.GetIndexer()),
|
||||
pvcLister: pvcInformer.Lister(),
|
||||
nodeName: nodeName,
|
||||
}
|
||||
@@ -82,8 +82,8 @@ func NewPodVolumeRestoreController(
|
||||
c.cacheSyncWaiters = append(
|
||||
c.cacheSyncWaiters,
|
||||
podVolumeRestoreInformer.Informer().HasSynced,
|
||||
secretInformer.Informer().HasSynced,
|
||||
podInformer.HasSynced,
|
||||
secretInformer.HasSynced,
|
||||
pvcInformer.Informer().HasSynced,
|
||||
)
|
||||
c.processRestoreFunc = c.processRestore
|
||||
@@ -270,7 +270,7 @@ func (c *podVolumeRestoreController) processRestore(req *arkv1api.PodVolumeResto
|
||||
return c.failRestore(req, errors.Wrap(err, "error getting volume directory name").Error(), log)
|
||||
}
|
||||
|
||||
credsFile, err := restic.TempCredentialsFile(c.secretLister, req.Spec.Pod.Namespace)
|
||||
credsFile, err := restic.TempCredentialsFile(c.secretLister, req.Namespace, req.Spec.Pod.Namespace)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Error creating temp restic credentials file")
|
||||
return c.failRestore(req, errors.Wrap(err, "error creating temp restic credentials file").Error(), log)
|
||||
|
||||
@@ -148,7 +148,7 @@ func (c *resticRepositoryController) initializeRepo(req *v1.ResticRepository, lo
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ensureRepo(req.Name, c.repositoryManager); err != nil {
|
||||
if err := ensureRepo(req.Name, req.Spec.ResticIdentifier, c.repositoryManager); err != nil {
|
||||
return c.patchResticRepository(req, repoNotReady(err.Error()))
|
||||
}
|
||||
|
||||
@@ -160,12 +160,12 @@ func (c *resticRepositoryController) initializeRepo(req *v1.ResticRepository, lo
|
||||
|
||||
// ensureRepo first checks the repo, and returns if check passes. If it fails,
|
||||
// attempts to init the repo, and returns the result.
|
||||
func ensureRepo(name string, repoManager restic.RepositoryManager) error {
|
||||
if repoManager.CheckRepo(name) == nil {
|
||||
func ensureRepo(name, identifier string, repoManager restic.RepositoryManager) error {
|
||||
if repoManager.CheckRepo(name, identifier) == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return repoManager.InitRepo(name)
|
||||
return repoManager.InitRepo(name, identifier)
|
||||
}
|
||||
|
||||
func (c *resticRepositoryController) runMaintenanceIfDue(req *v1.ResticRepository, log logrus.FieldLogger) error {
|
||||
@@ -181,14 +181,14 @@ func (c *resticRepositoryController) runMaintenanceIfDue(req *v1.ResticRepositor
|
||||
log.Info("Running maintenance on restic repository")
|
||||
|
||||
log.Debug("Checking repo before prune")
|
||||
if err := c.repositoryManager.CheckRepo(req.Name); err != nil {
|
||||
if err := c.repositoryManager.CheckRepo(req.Name, req.Spec.ResticIdentifier); err != nil {
|
||||
return c.patchResticRepository(req, repoNotReady(err.Error()))
|
||||
}
|
||||
|
||||
// prune failures should be displayed in the `.status.message` field but
|
||||
// should not cause the repo to move to `NotReady`.
|
||||
log.Debug("Pruning repo")
|
||||
if err := c.repositoryManager.PruneRepo(req.Name); err != nil {
|
||||
if err := c.repositoryManager.PruneRepo(req.Name, req.Spec.ResticIdentifier); err != nil {
|
||||
log.WithError(err).Warn("error pruning repository")
|
||||
if patchErr := c.patchResticRepository(req, func(r *v1.ResticRepository) {
|
||||
r.Status.Message = err.Error()
|
||||
@@ -198,7 +198,7 @@ func (c *resticRepositoryController) runMaintenanceIfDue(req *v1.ResticRepositor
|
||||
}
|
||||
|
||||
log.Debug("Checking repo after prune")
|
||||
if err := c.repositoryManager.CheckRepo(req.Name); err != nil {
|
||||
if err := c.repositoryManager.CheckRepo(req.Name, req.Spec.ResticIdentifier); err != nil {
|
||||
return c.patchResticRepository(req, repoNotReady(err.Error()))
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ func (c *resticRepositoryController) checkNotReadyRepo(req *v1.ResticRepository,
|
||||
|
||||
// we need to ensure it (first check, if check fails, attempt to init)
|
||||
// because we don't know if it's been successfully initialized yet.
|
||||
if err := ensureRepo(req.Name, c.repositoryManager); err != nil {
|
||||
if err := ensureRepo(req.Name, req.Spec.ResticIdentifier, c.repositoryManager); err != nil {
|
||||
return c.patchResticRepository(req, repoNotReady(err.Error()))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user