[lxc-devel] [lxd/master] Allow deleting storage pools that only contain image volumes
monstermunchkin on Github
lxc-bot at linuxcontainers.org
Fri Jul 20 16:07:03 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 314 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180720/291d8360/attachment.bin>
-------------- next part --------------
From e5978642a44c84b636c0c757591d0e40cc8bcf66 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at 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.hipp at 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.hipp at 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.hipp at 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))
- }
}
}
More information about the lxc-devel
mailing list