From 2319853c6be659d60bcb75b7fdaa76c1264f1572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Peliz=C3=A4us?= Date: Fri, 6 Oct 2023 15:40:37 +0000 Subject: [PATCH] lxd/storage/drivers/powerflex: Add volume restore support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julian Pelizäus --- lxd/storage/drivers/driver_powerflex_utils.go | 17 ++++++++++++++ .../drivers/driver_powerflex_volumes.go | 22 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lxd/storage/drivers/driver_powerflex_utils.go b/lxd/storage/drivers/driver_powerflex_utils.go index af71d1580d08..3a5c67c9514a 100644 --- a/lxd/storage/drivers/driver_powerflex_utils.go +++ b/lxd/storage/drivers/driver_powerflex_utils.go @@ -413,6 +413,23 @@ func (p *powerFlexClient) setVolumeSize(volumeID string, size string) error { return nil } +// overwriteVolume overwrites the volumes contents behind volumeID with the given snapshot. +func (p *powerFlexClient) overwriteVolume(volumeID string, snapshotID string) error { + body, err := p.createBodyReader(map[string]any{ + "srcVolumeId": snapshotID, + }) + if err != nil { + return err + } + + err = p.requestAuthenticated(http.MethodPost, fmt.Sprintf("/api/instances/Volume::%s/action/overwriteVolumeContent", volumeID), body, nil) + if err != nil { + return fmt.Errorf("Failed to overwrite volume: %q: %w", volumeID, err) + } + + return nil +} + // createVolumeSnapshot creates a new volume snapshot under the given systemID for the volume behind volumeID. // The accessMode can be either ReadWrite or ReadOnly. // The returned string represents the ID of the snapshot. diff --git a/lxd/storage/drivers/driver_powerflex_volumes.go b/lxd/storage/drivers/driver_powerflex_volumes.go index 87d84fd9ae3a..e049f51d7e54 100644 --- a/lxd/storage/drivers/driver_powerflex_volumes.go +++ b/lxd/storage/drivers/driver_powerflex_volumes.go @@ -859,7 +859,27 @@ func (d *powerflex) VolumeSnapshots(vol Volume, op *operations.Operation) ([]str // RestoreVolume restores a volume from a snapshot. func (d *powerflex) RestoreVolume(vol Volume, snapshotName string, op *operations.Operation) error { - return ErrNotSupported + ourUnmount, err := d.UnmountVolume(vol, false, op) + if err != nil { + return err + } + + if ourUnmount { + defer func() { _ = d.MountVolume(vol, op) }() + } + + volumeID, err := d.powerFlex().getVolumeID(d.getVolumeName(vol, "")) + if err != nil { + return err + } + + snapVol := NewVolume(d, d.name, vol.volType, vol.contentType, fmt.Sprintf("%s/%s", vol.Name(), snapshotName), nil, nil) + snapshotID, err := d.powerFlex().getVolumeID(d.getVolumeName(snapVol, "")) + if err != nil { + return err + } + + return d.powerFlex().overwriteVolume(volumeID, snapshotID) } // RenameVolumeSnapshot renames a volume snapshot.