The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/4817

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) ===
Closes #4792 
From e5978642a44c84b636c0c757591d0e40cc8bcf66 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Fri, 20 Jul 2018 15:58:37 +0200
Subject: [PATCH 1/2] Allow deleting storage pools that only contain image
 volumes

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 lxd/storage_pools.go   | 34 +++++++++++++++++++++++++++++++++-
 test/suites/storage.sh | 14 ++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/lxd/storage_pools.go b/lxd/storage_pools.go
index 192f20afd..4f3799715 100644
--- a/lxd/storage_pools.go
+++ b/lxd/storage_pools.go
@@ -557,6 +557,18 @@ func storagePoolDelete(d *Daemon, r *http.Request) 
Response {
                return EmptySyncResponse
        }
 
+       volumeNames, err := d.cluster.StoragePoolVolumesGetNames(poolID)
+       if err != nil {
+               return InternalError(err)
+       }
+
+       for _, volume := range volumeNames {
+               err = d.cluster.StoragePoolVolumeDelete(volume, 
storagePoolVolumeTypeImage, poolID)
+               if err != nil {
+                       return InternalError(err)
+               }
+       }
+
        err = s.StoragePoolDelete()
        if err != nil {
                return InternalError(err)
@@ -605,7 +617,27 @@ func storagePoolDeleteCheckPreconditions(cluster 
*db.Cluster, poolName string, p
        }
 
        if len(volumeNames) > 0 {
-               return BadRequest(fmt.Errorf("storage pool \"%s\" has volumes 
attached to it", poolName))
+               volumes, err := cluster.StoragePoolVolumesGet(poolID, 
supportedVolumeTypes)
+               if err != nil {
+                       return InternalError(err)
+               }
+
+               for _, volume := range volumes {
+                       if volume.Type != "image" {
+                               return BadRequest(fmt.Errorf("storage pool 
\"%s\" has volumes attached to it", poolName))
+                       }
+
+                       pools, err := cluster.ImageGetPools(volume.Name)
+                       if err != nil {
+                               return InternalError(err)
+                       }
+
+                       // The pool volume/image is used by this pool only. We 
should fail
+                       // here since we don't actually want to have to remove 
images.
+                       if len(pools) == 1 {
+                               return BadRequest(fmt.Errorf("storage pool 
\"%s\" has volumes attached to it", poolName))
+                       }
+               }
        }
 
        // Check if the storage pool is still referenced in any profiles.
diff --git a/test/suites/storage.sh b/test/suites/storage.sh
index 88ba169b3..1e9e1b6a1 100644
--- a/test/suites/storage.sh
+++ b/test/suites/storage.sh
@@ -794,6 +794,20 @@ test_storage() {
     lxc delete -f quota3
   fi
 
+  # Test removing storage pools only containing image volumes
+  # shellcheck disable=SC2031
+  LXD_DIR="${LXD_DIR}"
+  storage_pool="lxdtest-$(basename "${LXD_DIR}")-pool26"
+  lxc storage create "$storage_pool" "$lxd_backend"
+  lxc init -s "${storage_pool}" testimage c1
+  # The storage pool will not be removed since it has c1 attached to it
+  ! lxc storage delete "${storage_pool}"
+  lxc delete c1
+  # The storage pool will be deleted since the testimage is also attached to
+  # the default pool
+  lxc storage delete "${storage_pool}"
+  lxc image show testimage
+
   # shellcheck disable=SC2031
   LXD_DIR="${LXD_DIR}"
   kill_lxd "${LXD_STORAGE_DIR}"

From c9fe01dde87d5bc8f4480e69aaf39a964c3a69e7 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@canonical.com>
Date: Fri, 20 Jul 2018 17:24:03 +0200
Subject: [PATCH 2/2] lxd/storage: Remove image on pool deletion

Signed-off-by: Thomas Hipp <thomas.h...@canonical.com>
---
 lxd/storage_pools.go | 53 ++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 12 deletions(-)

diff --git a/lxd/storage_pools.go b/lxd/storage_pools.go
index 4f3799715..605daf9e3 100644
--- a/lxd/storage_pools.go
+++ b/lxd/storage_pools.go
@@ -15,6 +15,7 @@ import (
        "github.com/lxc/lxd/lxd/util"
        "github.com/lxc/lxd/shared"
        "github.com/lxc/lxd/shared/api"
+       "github.com/lxc/lxd/shared/logger"
        "github.com/lxc/lxd/shared/version"
 )
 
@@ -563,10 +564,49 @@ func storagePoolDelete(d *Daemon, r *http.Request) 
Response {
        }
 
        for _, volume := range volumeNames {
-               err = d.cluster.StoragePoolVolumeDelete(volume, 
storagePoolVolumeTypeImage, poolID)
+               pools, err := d.cluster.ImageGetPools(volume)
                if err != nil {
                        return InternalError(err)
                }
+
+               if len(pools) == 1 {
+                       imgID, imgInfo, err := d.cluster.ImageGet(volume, 
false, false)
+                       if err != nil {
+                               return InternalError(err)
+                       }
+
+                       err = doDeleteImageFromPool(d.State(), 
imgInfo.Fingerprint, poolName)
+                       if err != nil {
+                               return InternalError(err)
+                       }
+
+                       // Remove main image file.
+                       fname := shared.VarPath("images", imgInfo.Fingerprint)
+                       if shared.PathExists(fname) {
+                               err = os.Remove(fname)
+                               if err != nil {
+                                       logger.Debugf("Error deleting image 
file %s: %s", fname, err)
+                               }
+                       }
+
+                       // Remove the rootfs file for the image.
+                       fname = shared.VarPath("images", imgInfo.Fingerprint) + 
".rootfs"
+                       if shared.PathExists(fname) {
+                               err = os.Remove(fname)
+                               if err != nil {
+                                       logger.Debugf("Error deleting image 
file %s: %s", fname, err)
+                               }
+                       }
+
+                       // Remove the database entry for the image.
+                       d.cluster.ImageDelete(imgID)
+               } else if len(pools) > 1 {
+                       // Remove DB entry
+                       err = d.cluster.StoragePoolVolumeDelete(volume, 
storagePoolVolumeTypeImage, poolID)
+                       if err != nil {
+                               return InternalError(err)
+                       }
+               }
        }
 
        err = s.StoragePoolDelete()
@@ -626,17 +666,6 @@ func storagePoolDeleteCheckPreconditions(cluster 
*db.Cluster, poolName string, p
                        if volume.Type != "image" {
                                return BadRequest(fmt.Errorf("storage pool 
\"%s\" has volumes attached to it", poolName))
                        }
-
-                       pools, err := cluster.ImageGetPools(volume.Name)
-                       if err != nil {
-                               return InternalError(err)
-                       }
-
-                       // The pool volume/image is used by this pool only. We 
should fail
-                       // here since we don't actually want to have to remove 
images.
-                       if len(pools) == 1 {
-                               return BadRequest(fmt.Errorf("storage pool 
\"%s\" has volumes attached to it", poolName))
-                       }
                }
        }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to