[lxc-devel] [lxd/master] lxd/backups: Attempt to delete storage on failure

stgraber on Github lxc-bot at linuxcontainers.org
Mon Mar 25 21:31:55 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 707 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190325/286283a1/attachment.bin>
-------------- next part --------------
From dab536190322adaeb10102fc5fd0e2aec23562bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 25 Mar 2019 17:08:19 -0400
Subject: [PATCH] lxd/backups: Attempt to delete storage on failure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This is rather ugly as there's no container struct around to pass to the
normal delete functions, but this will hopefully do the trick for now.

Once we get the new internal storage API, we should be able to change
this to returning a lower level storage driver and can then call its
delete function rather than ContainerDelete.

Closes #5597

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container.go       | 20 ++++++++++----------
 lxd/containers_post.go |  4 +++-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/lxd/container.go b/lxd/container.go
index 46aa085a95..89c94e95ac 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -705,7 +705,7 @@ func containerCreateAsEmpty(d *Daemon, args db.ContainerArgs) (container, error)
 }
 
 func containerCreateFromBackup(s *state.State, info backupInfo, data io.ReadSeeker,
-	customPool bool) error {
+	customPool bool) (storage, error) {
 	var pool storage
 	var fixBackupFile = false
 
@@ -713,31 +713,31 @@ func containerCreateFromBackup(s *state.State, info backupInfo, data io.ReadSeek
 	pool, storageErr := storagePoolInit(s, info.Pool)
 	if storageErr != nil && errors.Cause(storageErr) != db.ErrNoSuchObject {
 		// Unexpected error
-		return storageErr
+		return nil, storageErr
 	}
 
 	if errors.Cause(storageErr) == db.ErrNoSuchObject {
 		// The pool doesn't exist, and the backup is in binary format so we
 		// cannot alter the backup.yaml.
 		if info.HasBinaryFormat {
-			return storageErr
+			return nil, storageErr
 		}
 
 		// Get the default profile
 		_, profile, err := s.Cluster.ProfileGet(info.Project, "default")
 		if err != nil {
-			return errors.Wrap(err, "Failed to get default profile")
+			return nil, errors.Wrap(err, "Failed to get default profile")
 		}
 
 		_, v, err := shared.GetRootDiskDevice(profile.Devices)
 		if err != nil {
-			return errors.Wrap(err, "Failed to get root disk device")
+			return nil, errors.Wrap(err, "Failed to get root disk device")
 		}
 
 		// Use the default-profile's root pool
 		pool, err = storagePoolInit(s, v["pool"])
 		if err != nil {
-			return errors.Wrap(err, "Failed to initialize storage pool")
+			return nil, errors.Wrap(err, "Failed to initialize storage pool")
 		}
 
 		fixBackupFile = true
@@ -746,25 +746,25 @@ func containerCreateFromBackup(s *state.State, info backupInfo, data io.ReadSeek
 	// Find the compression algorithm
 	tarArgs, _, _, err := shared.DetectCompressionFile(data)
 	if err != nil {
-		return err
+		return nil, err
 	}
 	data.Seek(0, 0)
 
 	// Unpack tarball
 	err = pool.ContainerBackupLoad(info, data, tarArgs)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	if fixBackupFile || customPool {
 		// Update the pool
 		err = backupFixStoragePool(s.Cluster, info, !customPool)
 		if err != nil {
-			return err
+			return nil, err
 		}
 	}
 
-	return nil
+	return pool, nil
 }
 
 func containerCreateEmptySnapshot(s *state.State, args db.ContainerArgs) (container, error) {
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 34bc7bb0bc..3411aa2ca6 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -617,7 +617,7 @@ func createFromBackup(d *Daemon, project string, data io.Reader, pool string) Re
 
 		// Dump tarball to storage
 		f.Seek(0, 0)
-		err = containerCreateFromBackup(d.State(), *bInfo, f, pool != "")
+		cPool, err := containerCreateFromBackup(d.State(), *bInfo, f, pool != "")
 		if err != nil {
 			return errors.Wrap(err, "Create container from backup")
 		}
@@ -627,6 +627,7 @@ func createFromBackup(d *Daemon, project string, data io.Reader, pool string) Re
 			Force: true,
 		})
 		if err != nil {
+			cPool.ContainerDelete(&containerLXC{name: bInfo.Name, project: project})
 			return errors.Wrap(err, "Marshal internal import request")
 		}
 
@@ -639,6 +640,7 @@ func createFromBackup(d *Daemon, project string, data io.Reader, pool string) Re
 		resp := internalImport(d, req)
 
 		if resp.String() != "success" {
+			cPool.ContainerDelete(&containerLXC{name: bInfo.Name, project: project})
 			return fmt.Errorf("Internal import request: %v", resp.String())
 		}
 


More information about the lxc-devel mailing list