diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index 6b9e52c3e26..c0f6e44cddd 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -773,6 +773,42 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } } + private boolean destroyStoragePool(Connect conn, String uuid) throws LibvirtException { + StoragePool sp; + try { + sp = conn.storagePoolLookupByUUIDString(uuid); + } catch (LibvirtException exc) { + logger.warn("Storage pool " + uuid + " doesn't exist in libvirt. Assuming it is already removed"); + logger.warn(exc.getStackTrace()); + return true; + } + + if (sp != null) { + if (sp.isPersistent() == 1) { + sp.destroy(); + sp.undefine(); + } else { + sp.destroy(); + } + sp.free(); + + return true; + } else { + logger.warn("Storage pool " + uuid + " doesn't exist in libvirt. Assuming it is already removed"); + return false; + } + } + + private boolean destroyStoragePoolHandleException(Connect conn, String uuid) + { + try { + return destroyStoragePool(conn, uuid); + } catch (LibvirtException e) { + logger.error(String.format("Failed to destroy libvirt pool %s: %s", uuid, e)); + } + return false; + } + @Override public boolean deleteStoragePool(String uuid) { logger.info("Attempting to remove storage pool " + uuid + " from libvirt"); @@ -783,16 +819,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { throw new CloudRuntimeException(e.toString()); } - StoragePool sp = null; Secret s = null; - try { - sp = conn.storagePoolLookupByUUIDString(uuid); - } catch (LibvirtException e) { - logger.warn("Storage pool " + uuid + " doesn't exist in libvirt. Assuming it is already removed"); - return true; - } - /* * Some storage pools, like RBD also have 'secret' information stored in libvirt * Destroy them if they exist @@ -804,13 +832,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } try { - if (sp.isPersistent() == 1) { - sp.destroy(); - sp.undefine(); - } else { - sp.destroy(); - } - sp.free(); + destroyStoragePool(conn, uuid); if (s != null) { s.undefine(); s.free(); @@ -828,6 +850,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { String result = Script.runSimpleBashScript("sleep 5 && umount " + targetPath); if (result == null) { logger.info("Succeeded in unmounting " + targetPath); + destroyStoragePoolHandleException(conn, uuid); return true; } logger.error("Failed to unmount " + targetPath); diff --git a/test/integration/component/test_acl_sharednetwork_deployVM-impersonation.py b/test/integration/component/test_acl_sharednetwork_deployVM-impersonation.py index 609af80b66c..212320c2c2f 100644 --- a/test/integration/component/test_acl_sharednetwork_deployVM-impersonation.py +++ b/test/integration/component/test_acl_sharednetwork_deployVM-impersonation.py @@ -1171,7 +1171,7 @@ class TestSharedNetworkImpersonation(cloudstackTestCase): self.fail("Domain admin is NOT able to deploy a VM for user in ROOT domain in a shared network with scope=all") except Exception as e: self.debug("When a Domain admin user deploys a VM for ROOT user in a shared network with scope=all %s" % e) - if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_SOURCE): self.fail("Error message validation failed when Domain admin is NOT able to deploy a VM for user in ROOT domain in a shared network with scope=all") @attr("simulator_only", tags=["advanced"], required_hardware="false") @@ -1199,7 +1199,7 @@ class TestSharedNetworkImpersonation(cloudstackTestCase): self.fail("Domain admin user is able to Deploy VM for a domain user, but there is no access to in a shared network with scope=domain with no subdomain access ") except Exception as e: self.debug("When a Domain admin user deploys a VM for a domain user, but there is no access to in a shared network with scope=domain with no subdomain access %s" % e) - if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_SOURCE): self.fail( "Error mesage validation failed when Domain admin user tries to Deploy VM for a domain user, but there is no access to in a shared network with scope=domain with no subdomain access ") @@ -1405,7 +1405,7 @@ class TestSharedNetworkImpersonation(cloudstackTestCase): self.fail("Domain admin is able to deploy a VM for user in ROOT domain in a shared network with scope=Domain and no subdomain access") except Exception as e: self.debug("When a regular user from ROOT domain deploys a VM in a shared network with scope=domain with no subdomain access %s" % e) - if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_SOURCE): self.fail( "Error message validation failed when Domain admin tries to deploy a VM for user in ROOT domain in a shared network with scope=Domain and no subdomain access") @@ -1601,7 +1601,7 @@ class TestSharedNetworkImpersonation(cloudstackTestCase): self.fail("Domain admin is able to deploy a VM for user in ROOT domain in a shared network with scope=Domain and subdomain access") except Exception as e: self.debug("When a user from ROOT domain deploys a VM in a shared network with scope=domain with subdomain access %s" % e) - if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_SOURCE): self.fail( "Error message validation failed when Domain admin tries to deploy a VM for user in ROOT domain in a shared network with scope=Domain and subdomain access") @@ -1717,7 +1717,7 @@ class TestSharedNetworkImpersonation(cloudstackTestCase): self.fail("Domain admin is able to deploy a VM for an regular user from a differnt domain in a shared network with scope=account") except Exception as e: self.debug("When a user from different domain deploys a VM in a shared network with scope=account %s" % e) - if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_SOURCE): self.fail( "Error message validation failed when Domain admin tries to deploy a VM for an regular user from a differnt domain in a shared network with scope=account") @@ -1746,7 +1746,7 @@ class TestSharedNetworkImpersonation(cloudstackTestCase): self.fail("Domain admin is able to deploy a VM for an regular user in ROOT domain in a shared network with scope=account") except Exception as e: self.debug("When a user from ROOT domain deploys a VM in a shared network with scope=account %s" % e) - if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_SOURCE): self.fail("Error message validation failed when Domain admin tries to deploy a VM for an regular user in ROOT domain in a shared network with scope=account") ## Test cases relating to deploying Virtual Machine as Regular user for other users in shared network with scope=all @@ -1776,7 +1776,7 @@ class TestSharedNetworkImpersonation(cloudstackTestCase): self.fail("Regular user is allowed to deploy a VM for another user in the same domain in a shared network with scope=all") except Exception as e: self.debug("When a regular user deploys a VM for another user in the same domain in a shared network with scope=all %s" % e) - if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_SOURCE): self.fail("Error message validation failed when Regular user tries to deploy a VM for another user in the same domain in a shared network with scope=all") @attr("simulator_only", tags=["advanced"], required_hardware="false") @@ -1804,7 +1804,7 @@ class TestSharedNetworkImpersonation(cloudstackTestCase): self.fail("Regular user is allowed to deploy a VM for another user in the same domain in a shared network with scope=all") except Exception as e: self.debug("When a regular user deploys a VM for another user in the same domain in a shared network with scope=all %s" % e) - if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + if not CloudstackAclException.verifyMsginException(e, CloudstackAclException.NO_PERMISSION_TO_OPERATE_SOURCE): self.fail("Error message validation failed when Regular user tries to deploy a VM for another user in the same domain in a shared network with scope=all") @staticmethod diff --git a/tools/marvin/marvin/cloudstackException.py b/tools/marvin/marvin/cloudstackException.py index 477a61829fb..cfd11d0678c 100644 --- a/tools/marvin/marvin/cloudstackException.py +++ b/tools/marvin/marvin/cloudstackException.py @@ -77,6 +77,7 @@ class CloudstackAclException(): UNABLE_TO_LIST_NETWORK_ACCOUNT = "Can't create/list resources for account" NO_PERMISSION_TO_ACCESS_ACCOUNT = "does not have permission to access resource Acct" NOT_AVAILABLE_IN_DOMAIN = "not available in domain" + NO_PERMISSION_TO_OPERATE_SOURCE = "does not have permission to operate with provided resource" @staticmethod def verifyMsginException(e,message):