Refactoring the LibvirtComputingResource

- Adding LibvirtCreateCommandWrapper and LibvirtMaintainCommandWrapper
  - 4 unit tests added
  - KVM hypervisor plugin with 12.7% coverage
This commit is contained in:
wilderrodrigues 2015-04-29 16:05:44 +02:00
parent 6f757c6bf0
commit cb4670279f
5 changed files with 225 additions and 10 deletions

View File

@ -101,8 +101,6 @@ import com.cloud.agent.api.FenceCommand;
import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.GetStorageStatsCommand;
import com.cloud.agent.api.HostVmStateReportEntry;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.ManageSnapshotAnswer;
import com.cloud.agent.api.ManageSnapshotCommand;
import com.cloud.agent.api.ModifyStoragePoolAnswer;
@ -1305,9 +1303,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
try {
if (cmd instanceof MaintainCommand) {
return execute((MaintainCommand)cmd);
} else if (cmd instanceof CreateCommand) {
if (cmd instanceof CreateCommand) {
return execute((CreateCommand)cmd);
} else if (cmd instanceof DestroyCommand) {
return execute((DestroyCommand)cmd);
@ -1769,7 +1765,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
// this is much like PrimaryStorageDownloadCommand, but keeping it separate
protected KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid) {
public KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid) {
final int index = templateUrl.lastIndexOf("/");
final String mountpoint = templateUrl.substring(0, index);
String templateName = null;
@ -2866,10 +2862,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new Answer(cmd, result, "");
}
protected MaintainAnswer execute(final MaintainCommand cmd) {
return new MaintainAnswer(cmd);
}
protected PowerState convertToPowerState(final DomainState ps) {
final PowerState state = s_powerStatesTable.get(ps);
return state == null ? PowerState.PowerUnknown : state;

View File

@ -0,0 +1,83 @@
//
// 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.CreateAnswer;
import com.cloud.agent.api.storage.CreateCommand;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
import com.cloud.resource.CommandWrapper;
import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DiskProfile;
public final class LibvirtCreateCommandWrapper extends CommandWrapper<CreateCommand, Answer, LibvirtComputingResource> {
private static final Logger s_logger = Logger.getLogger(LibvirtCreateCommandWrapper.class);
@Override
public Answer execute(final CreateCommand command, final LibvirtComputingResource libvirtComputingResource) {
final StorageFilerTO pool = command.getPool();
final DiskProfile dskch = command.getDiskCharacteristics();
KVMPhysicalDisk baseVol = null;
KVMStoragePool primaryPool = null;
KVMPhysicalDisk vol = null;
long disksize;
try {
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid());
disksize = dskch.getSize();
if (command.getTemplateUrl() != null) {
if (primaryPool.getType() == StoragePoolType.CLVM) {
vol = libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primaryPool, dskch.getPath());
} else {
baseVol = primaryPool.getPhysicalDisk(command.getTemplateUrl());
vol = storagePoolMgr.createDiskFromTemplate(baseVol,
dskch.getPath(), dskch.getProvisioningType(), primaryPool, 0);
}
if (vol == null) {
return new Answer(command, false, " Can't create storage volume on storage pool");
}
} else {
vol = primaryPool.createPhysicalDisk(dskch.getPath(), dskch.getProvisioningType(), dskch.getSize());
}
final VolumeTO volume =
new VolumeTO(command.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(command, volume);
} catch (final CloudRuntimeException e) {
s_logger.debug("Failed to create volume: " + e.toString());
return new CreateAnswer(command, e);
}
}
}

View File

@ -0,0 +1,34 @@
//
// 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 com.cloud.agent.api.Answer;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
public final class LibvirtMaintainCommandWrapper extends CommandWrapper<MaintainCommand, Answer, LibvirtComputingResource> {
@Override
public Answer execute(final MaintainCommand command, final LibvirtComputingResource libvirtComputingResource) {
return new MaintainAnswer(command);
}
}

View File

@ -30,6 +30,7 @@ import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetVmDiskStatsCommand;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.ModifySshKeysCommand;
import com.cloud.agent.api.PingTestCommand;
@ -40,6 +41,7 @@ import com.cloud.agent.api.RebootRouterCommand;
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.hypervisor.kvm.resource.LibvirtComputingResource;
import com.cloud.resource.CommandWrapper;
import com.cloud.resource.RequestWrapper;
@ -80,6 +82,8 @@ public class LibvirtRequestWrapper extends RequestWrapper {
linbvirtCommands.put(CheckConsoleProxyLoadCommand.class, new LibvirtCheckConsoleProxyLoadCommandWrapper());
linbvirtCommands.put(GetVncPortCommand.class, new LibvirtGetVncPortCommandWrapper());
linbvirtCommands.put(ModifySshKeysCommand.class, new LibvirtModifySshKeysCommandWrapper());
linbvirtCommands.put(MaintainCommand.class, new LibvirtMaintainCommandWrapper());
linbvirtCommands.put(CreateCommand.class, new LibvirtCreateCommandWrapper());
resources.put(LibvirtComputingResource.class, linbvirtCommands);
}

View File

@ -72,6 +72,7 @@ import com.cloud.agent.api.GetHostStatsCommand;
import com.cloud.agent.api.GetVmDiskStatsCommand;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.ModifySshKeysCommand;
import com.cloud.agent.api.PingTestCommand;
@ -83,8 +84,10 @@ import com.cloud.agent.api.StopCommand;
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.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.resource.virtualnetwork.VirtualRoutingResource;
import com.cloud.exception.InternalErrorException;
@ -100,6 +103,7 @@ import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.Volume;
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
import com.cloud.utils.Pair;
import com.cloud.vm.DiskProfile;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.PowerState;
@ -1217,4 +1221,102 @@ public class LibvirtComputingResourceTest {
verify(libvirtComputingResource, times(1)).getTimeout();
}
@Test
public void testMaintainCommand() {
final MaintainCommand command = new MaintainCommand();
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
assertNotNull(wrapper);
final Answer answer = wrapper.execute(command, libvirtComputingResource);
assertTrue(answer.getResult());
}
@Test
public void testCreateCommandNoTemplate() {
final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
final boolean executeInSequence = false;
final CreateCommand command = new CreateCommand(diskCharacteristics, pool, executeInSequence );
final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
when(primary.createPhysicalDisk(diskCharacteristics.getPath(), diskCharacteristics.getProvisioningType(), diskCharacteristics.getSize())).thenReturn(vol);
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(pool.getType(), pool.getUuid());
}
@Test
public void testCreateCommand() {
final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
final String templateUrl = "http://template";
final boolean executeInSequence = false;
final CreateCommand command = new CreateCommand(diskCharacteristics, templateUrl, pool, executeInSequence );
final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
when(primary.getType()).thenReturn(StoragePoolType.CLVM);
when(libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primary, diskCharacteristics.getPath())).thenReturn(vol);
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(pool.getType(), pool.getUuid());
}
@Test
public void testCreateCommandCLVM() {
final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
final String templateUrl = "http://template";
final boolean executeInSequence = false;
final CreateCommand command = new CreateCommand(diskCharacteristics, templateUrl, pool, executeInSequence );
final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
final KVMPhysicalDisk baseVol = Mockito.mock(KVMPhysicalDisk.class);
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
when(primary.getPhysicalDisk(command.getTemplateUrl())).thenReturn(baseVol);
when(poolManager.createDiskFromTemplate(baseVol,
diskCharacteristics.getPath(), diskCharacteristics.getProvisioningType(), primary, 0)).thenReturn(vol);
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(pool.getType(), pool.getUuid());
}
}