The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6680
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
From 993886156574bdf1bb62530acc6bddbf3bb925ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Wed, 8 Jan 2020 15:57:05 -0500 Subject: [PATCH] lxd/storage: Support deleting snapshots during restore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/storage/backend_lxd.go | 60 ++++++++++++++++++++++++++++++++++- lxd/storage/drivers/errors.go | 9 ++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 89f6882817..1ec8fc2025 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -1699,6 +1699,35 @@ func (b *lxdBackend) RestoreInstanceSnapshot(inst instance.Instance, src instanc vol := b.newVolume(volType, contentType, volStorageName, rootDiskConf) err = b.driver.RestoreVolume(vol, snapshotName, op) if err != nil { + snapErr, ok := err.(drivers.ErrDeleteSnapshots) + if ok { + // We need to delete some snapshots and try again. + snaps, err := inst.Snapshots() + if err != nil { + return err + } + + // Go through all the snapshots. + for _, snap := range snaps { + _, snapName, _ := shared.InstanceGetParentAndSnapshotName(src.Name()) + if !shared.StringInSlice(snapName, snapErr.Snapshots) { + continue + } + + // Delete if listed. + err := b.DeleteInstanceSnapshot(snap, op) + if err != nil { + return err + } + } + + // Now try again. + err = b.driver.RestoreVolume(vol, snapshotName, op) + if err != nil { + return err + } + } + return err } @@ -2607,6 +2636,7 @@ func (b *lxdBackend) RestoreCustomVolume(volName string, snapshotName string, op logger.Debug("RestoreCustomVolume started") defer logger.Debug("RestoreCustomVolume finished") + // Sanity checks. if shared.IsSnapshot(volName) { return fmt.Errorf("Volume cannot be snapshot") } @@ -2615,6 +2645,7 @@ func (b *lxdBackend) RestoreCustomVolume(volName string, snapshotName string, op return fmt.Errorf("Invalid snapshot name") } + // Check that the volume isn't in use. usingVolume, err := VolumeUsedByInstancesWithProfiles(b.state, b.Name(), volName, db.StoragePoolVolumeTypeNameCustom, true) if err != nil { return err @@ -2624,8 +2655,35 @@ func (b *lxdBackend) RestoreCustomVolume(volName string, snapshotName string, op return fmt.Errorf("Cannot restore custom volume used by running instances") } - err = b.driver.RestoreVolume(b.newVolume(drivers.VolumeTypeCustom, drivers.ContentTypeFS, volName, nil), snapshotName, op) + // Get the volume config. + _, dbVol, err := b.state.Cluster.StoragePoolNodeVolumeGetTypeByProject("default", volName, db.StoragePoolVolumeTypeCustom, b.ID()) + if err != nil { + if err == db.ErrNoSuchObject { + return fmt.Errorf("Volume doesn't exist") + } + + return err + } + + err = b.driver.RestoreVolume(b.newVolume(drivers.VolumeTypeCustom, drivers.ContentTypeFS, volName, dbVol.Config), snapshotName, op) if err != nil { + snapErr, ok := err.(drivers.ErrDeleteSnapshots) + if ok { + // We need to delete some snapshots and try again. + for _, snapName := range snapErr.Snapshots { + err := b.DeleteCustomVolumeSnapshot(fmt.Sprintf("%s/%s", volName, snapName), op) + if err != nil { + return err + } + } + + // Now try again. + err = b.driver.RestoreVolume(b.newVolume(drivers.VolumeTypeCustom, drivers.ContentTypeFS, volName, dbVol.Config), snapshotName, op) + if err != nil { + return err + } + } + return err } diff --git a/lxd/storage/drivers/errors.go b/lxd/storage/drivers/errors.go index e9fb157bc6..cae5eba16a 100644 --- a/lxd/storage/drivers/errors.go +++ b/lxd/storage/drivers/errors.go @@ -12,3 +12,12 @@ var ErrUnknownDriver = fmt.Errorf("Unknown driver") // ErrNotSupported is the "Not supported" error var ErrNotSupported = fmt.Errorf("Not supported") + +// ErrDeleteSnapshots is a special error used to tell the backend to delete more recent snapshots +type ErrDeleteSnapshots struct { + Snapshots []string +} + +func (e ErrDeleteSnapshots) Error() string { + return fmt.Sprintf("More recent snapshots must be deleted: %+v", e.Snapshots) +}
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel