Refactoring the LibvirtComputingResource

- Adding LibvirtDestroyCommandWrapper
  - 2 unit tests added
  - KVM hypervisor plugin with 12.9% coverage
This commit is contained in:
wilderrodrigues 2015-04-29 17:19:57 +02:00
parent cb4670279f
commit 4472cade2f
4 changed files with 112 additions and 61 deletions

View File

@ -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*)");

View File

@ -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<DestroyCommand, Answer, LibvirtComputingResource> {
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());
}
}
}

View File

@ -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);
}

View File

@ -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());
}
}