diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 3c959ef70b8..4abc04880f6 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -145,10 +145,7 @@ import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; -import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; @@ -161,7 +158,6 @@ import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.dc.Vlan; @@ -225,7 +221,6 @@ import com.cloud.utils.script.OutputInterpreter; import com.cloud.utils.script.OutputInterpreter.AllLinesParser; import com.cloud.utils.script.Script; import com.cloud.utils.ssh.SshHelper; -import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; @@ -1303,11 +1298,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof CreateCommand) { - return execute((CreateCommand)cmd); - } else if (cmd instanceof DestroyCommand) { - return execute((DestroyCommand)cmd); - } else if (cmd instanceof PrimaryStorageDownloadCommand) { + if (cmd instanceof PrimaryStorageDownloadCommand) { return execute((PrimaryStorageDownloadCommand)cmd); } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) { return execute((CreatePrivateTemplateFromVolumeCommand)cmd); @@ -1725,45 +1716,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return Storage.StorageResourceType.STORAGE_POOL; } - protected Answer execute(final CreateCommand cmd) { - final StorageFilerTO pool = cmd.getPool(); - final DiskProfile dskch = cmd.getDiskCharacteristics(); - KVMPhysicalDisk BaseVol = null; - KVMStoragePool primaryPool = null; - KVMPhysicalDisk vol = null; - long disksize; - try { - primaryPool = _storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid()); - disksize = dskch.getSize(); - - if (cmd.getTemplateUrl() != null) { - if (primaryPool.getType() == StoragePoolType.CLVM) { - vol = templateToPrimaryDownload(cmd.getTemplateUrl(), primaryPool, dskch.getPath()); - } else { - BaseVol = primaryPool.getPhysicalDisk(cmd.getTemplateUrl()); - vol = _storagePoolMgr.createDiskFromTemplate(BaseVol, - dskch.getPath(), dskch.getProvisioningType(), primaryPool, 0); - } - if (vol == null) { - return new Answer(cmd, false, " Can't create storage volume on storage pool"); - } - } else { - vol = primaryPool.createPhysicalDisk(dskch.getPath(), dskch.getProvisioningType(), dskch.getSize()); - } - final VolumeTO volume = - new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), pool.getPath(), vol.getName(), vol.getName(), disksize, null); - volume.setBytesReadRate(dskch.getBytesReadRate()); - volume.setBytesWriteRate(dskch.getBytesWriteRate()); - volume.setIopsReadRate(dskch.getIopsReadRate()); - volume.setIopsWriteRate(dskch.getIopsWriteRate()); - volume.setCacheMode(dskch.getCacheMode()); - return new CreateAnswer(cmd, volume); - } catch (final CloudRuntimeException e) { - s_logger.debug("Failed to create volume: " + e.toString()); - return new CreateAnswer(cmd, e); - } - } - // this is much like PrimaryStorageDownloadCommand, but keeping it separate public KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid) { final int index = templateUrl.lastIndexOf("/"); @@ -1915,18 +1867,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } - public Answer execute(final DestroyCommand cmd) { - final VolumeTO vol = cmd.getVolume(); - try { - final KVMStoragePool pool = _storagePoolMgr.getStoragePool(vol.getPoolType(), vol.getPoolUuid()); - pool.deletePhysicalDisk(vol.getPath(), null); - return new Answer(cmd, true, "Success"); - } catch (final CloudRuntimeException e) { - s_logger.debug("Failed to delete volume: " + e.toString()); - return new Answer(cmd, false, e.toString()); - } - } - private String getBroadcastUriFromBridge(final String brName) { final String pif = matchPifFileInDirectory(brName); final Pattern pattern = Pattern.compile("(\\D+)(\\d+)(\\D*)(\\d*)"); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDestroyCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDestroyCommandWrapper.java new file mode 100644 index 00000000000..d8792951685 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDestroyCommandWrapper.java @@ -0,0 +1,50 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +package com.cloud.hypervisor.kvm.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.DestroyCommand; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.storage.KVMStoragePool; +import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.exception.CloudRuntimeException; + +public final class LibvirtDestroyCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtDestroyCommandWrapper.class); + + @Override + public Answer execute(final DestroyCommand command, final LibvirtComputingResource libvirtComputingResource) { + final VolumeTO vol = command.getVolume(); + try { + KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + final KVMStoragePool pool = storagePoolMgr.getStoragePool(vol.getPoolType(), vol.getPoolUuid()); + pool.deletePhysicalDisk(vol.getPath(), null); + return new Answer(command, true, "Success"); + } catch (final CloudRuntimeException e) { + s_logger.debug("Failed to delete volume: " + e.toString()); + return new Answer(command, false, e.toString()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java index bced7f88d8a..eb8d569e234 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java @@ -42,6 +42,7 @@ import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.storage.CreateCommand; +import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.resource.CommandWrapper; import com.cloud.resource.RequestWrapper; @@ -84,6 +85,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(ModifySshKeysCommand.class, new LibvirtModifySshKeysCommandWrapper()); linbvirtCommands.put(MaintainCommand.class, new LibvirtMaintainCommandWrapper()); linbvirtCommands.put(CreateCommand.class, new LibvirtCreateCommandWrapper()); + linbvirtCommands.put(DestroyCommand.class, new LibvirtDestroyCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java index 22fa80863e4..0865fb59e8b 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java @@ -85,10 +85,12 @@ import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.storage.CreateCommand; +import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; @@ -100,9 +102,11 @@ import com.cloud.hypervisor.kvm.storage.KVMStoragePool; import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; import com.cloud.network.Networks.TrafficType; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; @@ -1319,4 +1323,59 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid()); } + + @Test + public void testDestroyCommand() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final Volume volume = Mockito.mock(Volume.class); + final String vmName = "Test"; + + final DestroyCommand command = new DestroyCommand(pool, volume, vmName); + + final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); + + final VolumeTO vol = command.getVolume(); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager); + when(poolManager.getStoragePool(vol.getPoolType(), vol.getPoolUuid())).thenReturn(primary); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(poolManager, times(1)).getStoragePool(vol.getPoolType(), vol.getPoolUuid()); + } + + @SuppressWarnings("unchecked") + @Test + public void testDestroyCommandError() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final Volume volume = Mockito.mock(Volume.class); + final String vmName = "Test"; + + final DestroyCommand command = new DestroyCommand(pool, volume, vmName); + + final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); + + final VolumeTO vol = command.getVolume(); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager); + when(poolManager.getStoragePool(vol.getPoolType(), vol.getPoolUuid())).thenReturn(primary); + + when(primary.deletePhysicalDisk(vol.getPath(), null)).thenThrow(CloudRuntimeException.class); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(poolManager, times(1)).getStoragePool(vol.getPoolType(), vol.getPoolUuid()); + } } \ No newline at end of file