From 508f10527fc199a45900e456899893fb776e50da Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 22 Apr 2015 11:35:57 +0200 Subject: [PATCH 01/36] Refactoring the LibvirtComputingResource - Adding LibvirtStopCommandWrapper - LibvirtRequestWrapper - 1 unit tests Refactored the RequestWrapper to make it better. - Changes also applied to the CitrixRequestWrapper --- .../com/cloud/resource/RequestWrapper.java | 79 + .../resource/LibvirtComputingResource.java | 1762 +++++++++-------- .../wrapper/LibvirtRequestWrapper.java | 72 + .../wrapper/LibvirtStopCommandWrapper.java | 86 + .../LibvirtComputingResourceTest.java | 197 +- .../wrapper/CitrixRequestWrapper.java | 74 - .../wrapper/CitrixRequestWrapperTest.java | 4 +- 7 files changed, 1242 insertions(+), 1032 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java diff --git a/core/src/com/cloud/resource/RequestWrapper.java b/core/src/com/cloud/resource/RequestWrapper.java index 6fd1c668855..0311e2543ce 100644 --- a/core/src/com/cloud/resource/RequestWrapper.java +++ b/core/src/com/cloud/resource/RequestWrapper.java @@ -19,14 +19,93 @@ package com.cloud.resource; +import java.util.Hashtable; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; public abstract class RequestWrapper { + @SuppressWarnings("rawtypes") + protected Hashtable, Hashtable, CommandWrapper>> resources = new Hashtable, Hashtable, CommandWrapper>>(); + /** * @param command to be executed. * @return an Answer for the executed command. */ public abstract Answer execute(Command command, ServerResource serverResource); + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Hashtable, CommandWrapper> retrieveResource(final Command command, final Class resourceClass) { + Class keepResourceClass = resourceClass; + Hashtable, CommandWrapper> resource = resources.get(keepResourceClass); + while (resource == null) { + try { + final Class keepResourceClass2 = (Class) keepResourceClass.getSuperclass(); + resource = resources.get(keepResourceClass2); + + keepResourceClass = keepResourceClass2; + } catch (final ClassCastException e) { + throw new NullPointerException("No key found for '" + command.getClass() + "' in the Map!"); + } + } + return resource; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected CommandWrapper retrieveCommands(final Class commandClass, + final Hashtable, CommandWrapper> resourceCommands) { + + Class keepCommandClass = commandClass; + CommandWrapper commandWrapper = resourceCommands.get(keepCommandClass); + while (commandWrapper == null) { + try { + final Class commandClass2 = (Class) keepCommandClass.getSuperclass(); + + if (commandClass2 == null) { + throw new NullPointerException("All the COMMAND hierarchy tree has been visited but no compliant key has been found for '" + commandClass + "'."); + } + + commandWrapper = resourceCommands.get(commandClass2); + + keepCommandClass = commandClass2; + } catch (final NullPointerException e) { + // Will now traverse all the resource hierarchy. Returning null + // is not a problem. + // It is all being nicely checked and in case we do not have a + // resource, an Unsupported answer will be thrown by the base + // class. + return null; + } + } + return commandWrapper; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected CommandWrapper retryWhenAllFails(final Command command, final Class resourceClass, + final Hashtable, CommandWrapper> resourceCommands) { + + Class keepResourceClass = resourceClass; + CommandWrapper commandWrapper = resourceCommands.get(command.getClass()); + while (commandWrapper == null) { + // Could not find the command in the given resource, will traverse + // the family tree. + try { + final Class resourceClass2 = (Class) keepResourceClass.getSuperclass(); + + if (resourceClass2 == null) { + throw new NullPointerException("All the SERVER-RESOURCE hierarchy tree has been visited but no compliant key has been found for '" + command.getClass() + "'."); + } + + final Hashtable, CommandWrapper> resourceCommands2 = retrieveResource(command, + (Class) keepResourceClass.getSuperclass()); + keepResourceClass = resourceClass2; + + commandWrapper = retrieveCommands(command.getClass(), resourceCommands2); + } catch (final NullPointerException e) { + throw e; + } + } + return commandWrapper; + } } \ No newline at end of file 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 2bd584e6f9b..892e9063688 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 @@ -61,6 +61,13 @@ import java.util.regex.Pattern; import javax.ejb.Local; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.utils.qemu.QemuImg; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.cloudstack.utils.qemu.QemuImgException; +import org.apache.cloudstack.utils.qemu.QemuImgFile; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; @@ -81,15 +88,6 @@ import com.ceph.rados.RadosException; import com.ceph.rbd.Rbd; import com.ceph.rbd.RbdException; import com.ceph.rbd.RbdImage; - -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; -import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.cloudstack.utils.qemu.QemuImg; -import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; -import org.apache.cloudstack.utils.qemu.QemuImgException; -import org.apache.cloudstack.utils.qemu.QemuImgFile; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; @@ -232,6 +230,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VirtioSerialDef; +import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; import com.cloud.hypervisor.kvm.storage.KVMStoragePool; import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; @@ -334,12 +333,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver"; @Override - public ExecutionResult executeInVR(String routerIp, String script, String args) { + public ExecutionResult executeInVR(final String routerIp, final String script, final String args) { return executeInVR(routerIp, script, args, _timeout / 1000); } @Override - public ExecutionResult executeInVR(String routerIp, String script, String args, int timeout) { + public ExecutionResult executeInVR(final String routerIp, final String script, final String args, final int timeout) { final Script command = new Script(_routerProxyPath, timeout * 1000, s_logger); final AllLinesParser parser = new AllLinesParser(); command.add(script); @@ -355,13 +354,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } @Override - public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) { - File permKey = new File("/root/.ssh/id_rsa.cloud"); + public ExecutionResult createFileInVR(final String routerIp, final String path, final String filename, final String content) { + final File permKey = new File("/root/.ssh/id_rsa.cloud"); String error = null; try { SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e); error = e.getMessage(); } @@ -369,7 +368,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } @Override - public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + public ExecutionResult prepareCommand(final NetworkElementCommand cmd) { //Update IP used to access router cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); assert cmd.getRouterAccessIp() != null; @@ -387,7 +386,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } @Override - public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) { if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) { return cleanupNetworkElementCommand((IpAssocCommand)cmd); } @@ -398,11 +397,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private final Map map = new HashMap(); @Override - public String interpret(BufferedReader reader) throws IOException { + public String interpret(final BufferedReader reader) throws IOException { String line = null; int numLines = 0; while ((line = reader.readLine()) != null) { - String[] toks = line.trim().split("="); + final String[] toks = line.trim().split("="); if (toks.length < 2) { s_logger.warn("Failed to parse Script output: " + line); } else { @@ -491,13 +490,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected StorageSubsystemCommandHandler storageHandler; - private String getEndIpFromStartIp(String startIp, int numIps) { - String[] tokens = startIp.split("[.]"); - assert (tokens.length == 4); + private String getEndIpFromStartIp(final String startIp, final int numIps) { + final String[] tokens = startIp.split("[.]"); + assert tokens.length == 4; int lastbyte = Integer.parseInt(tokens[3]); lastbyte = lastbyte + numIps; tokens[3] = Integer.toString(lastbyte); - StringBuilder end = new StringBuilder(15); + final StringBuilder end = new StringBuilder(15); end.append(tokens[0]).append(".").append(tokens[1]).append(".").append(tokens[2]).append(".").append(tokens[3]); return end.toString(); } @@ -511,14 +510,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.info("developer.properties found at " + file.getAbsolutePath()); try { - Properties properties = PropertiesUtil.loadFromFile(file); + final Properties properties = PropertiesUtil.loadFromFile(file); - String startMac = (String)properties.get("private.macaddr.start"); + final String startMac = (String)properties.get("private.macaddr.start"); if (startMac == null) { throw new ConfigurationException("Developers must specify start mac for private ip range"); } - String startIp = (String)properties.get("private.ipaddr.start"); + final String startIp = (String)properties.get("private.ipaddr.start"); if (startIp == null) { throw new ConfigurationException("Developers must specify start ip for private ip range"); } @@ -562,7 +561,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } @Override - public boolean configure(String name, Map params) throws ConfigurationException { + public boolean configure(final String name, final Map params) throws ConfigurationException { boolean success = super.configure(name, params); if (!success) { return false; @@ -591,7 +590,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv storageScriptsDir = getDefaultStorageScriptsDir(); } - String bridgeType = (String)params.get("network.bridge.type"); + final String bridgeType = (String)params.get("network.bridge.type"); if (bridgeType == null) { _bridgeType = BridgeType.NATIVE; } else { @@ -690,7 +689,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } String value = (String)params.get("developer"); - boolean isDeveloper = Boolean.parseBoolean(value); + final boolean isDeveloper = Boolean.parseBoolean(value); if (isDeveloper) { params.putAll(getDeveloperProperties()); @@ -701,7 +700,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv _pool = "/root"; } - String instance = (String)params.get("instance"); + final String instance = (String)params.get("instance"); _hypervisorType = HypervisorType.getType((String)params.get("hypervisor.type")); if (_hypervisorType == HypervisorType.None) { @@ -780,7 +779,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv _localStoragePath = "/var/lib/libvirt/images/"; } - File storagePath = new File(_localStoragePath); + final File storagePath = new File(_localStoragePath); _localStoragePath = storagePath.getAbsolutePath(); _localStorageUUID = (String)params.get("local.storage.uuid"); @@ -812,7 +811,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv value = (String) params.get("kvmclock.disable"); if (Boolean.parseBoolean(value)) { _noKvmClock = true; - } else if(HypervisorType.LXC.equals(_hypervisorType) && (value == null)){ + } else if(HypervisorType.LXC.equals(_hypervisorType) && value == null){ //Disable kvmclock by default for LXC _noKvmClock = true; } @@ -823,11 +822,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv conn = LibvirtConnection.getConnection(); if (_bridgeType == BridgeType.OPENVSWITCH) { - if (conn.getLibVirVersion() < (10 * 1000 + 0)) { + if (conn.getLibVirVersion() < 10 * 1000 + 0) { throw new ConfigurationException("LibVirt version 0.10.0 required for openvswitch support, but version " + conn.getLibVirVersion() + " detected"); } } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { throw new CloudRuntimeException(e.getMessage()); } @@ -842,10 +841,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv _hypervisorPath = getHypervisorPath(conn); try { _hvVersion = conn.getVersion(); - _hvVersion = (_hvVersion % 1000000) / 1000; + _hvVersion = _hvVersion % 1000000 / 1000; _hypervisorLibvirtVersion = conn.getLibVirVersion(); _hypervisorQemuVersion = conn.getVersion(); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } @@ -853,7 +852,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (_guestCpuMode != null) { _guestCpuModel = (String)params.get("guest.cpu.model"); - if (_hypervisorLibvirtVersion < (9 * 1000 + 10)) { + if (_hypervisorLibvirtVersion < 9 * 1000 + 10) { s_logger.warn("LibVirt version 0.9.10 required for guest cpu mode, but version " + prettyVersion(_hypervisorLibvirtVersion) + " detected, so it will be disabled"); _guestCpuMode = ""; @@ -863,28 +862,28 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv params.put("guest.cpu.model", _guestCpuModel); } - String cpuFeatures = (String)params.get("guest.cpu.features"); + final String cpuFeatures = (String)params.get("guest.cpu.features"); if (cpuFeatures != null) { _cpuFeatures = new ArrayList(); - for (String feature: cpuFeatures.split(" ")) { + for (final String feature: cpuFeatures.split(" ")) { if (!feature.isEmpty()) { _cpuFeatures.add(feature); } } } - String[] info = NetUtils.getNetworkParams(_privateNic); + final String[] info = NetUtils.getNetworkParams(_privateNic); _monitor = new KVMHAMonitor(null, info[0], _heartBeatPath); - Thread ha = new Thread(_monitor); + final Thread ha = new Thread(_monitor); ha.start(); _storagePoolMgr = new KVMStoragePoolManager(_storage, _monitor); _sysvmISOPath = (String)params.get("systemvm.iso.path"); if (_sysvmISOPath == null) { - String[] isoPaths = {"/usr/share/cloudstack-common/vms/systemvm.iso"}; - for (String isoPath : isoPaths) { + final String[] isoPaths = {"/usr/share/cloudstack-common/vms/systemvm.iso"}; + for (final String isoPath : isoPaths) { if (_storage.exists(isoPath)) { _sysvmISOPath = isoPath; break; @@ -939,13 +938,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (_migrateSpeed == -1) { //get guest network device speed _migrateSpeed = 0; - String speed = Script.runSimpleBashScript("ethtool " + _pifs.get("public") + " |grep Speed | cut -d \\ -f 2"); + final String speed = Script.runSimpleBashScript("ethtool " + _pifs.get("public") + " |grep Speed | cut -d \\ -f 2"); if (speed != null) { - String[] tokens = speed.split("M"); + final String[] tokens = speed.split("M"); if (tokens.length == 2) { try { _migrateSpeed = Integer.parseInt(tokens[0]); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { s_logger.trace("Ignoring migrateSpeed extraction error.", e); } s_logger.debug("device " + _pifs.get("public") + " has speed: " + String.valueOf(_migrateSpeed)); @@ -954,7 +953,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv params.put("vm.migrate.speed", String.valueOf(_migrateSpeed)); } - Map bridges = new HashMap(); + final Map bridges = new HashMap(); bridges.put("linklocal", _linkLocalBridgeName); bridges.put("public", _publicBridgeName); bridges.put("private", _privBridgeName); @@ -968,12 +967,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv configureVifDrivers(params); - KVMStorageProcessor storageProcessor = new KVMStorageProcessor(_storagePoolMgr, this); + final KVMStorageProcessor storageProcessor = new KVMStorageProcessor(_storagePoolMgr, this); storageProcessor.configure(name, params); storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); - String unameKernelVersion = Script.runSimpleBashScript("uname -r"); - String[] kernelVersions = unameKernelVersion.split("[\\.\\-]"); + final String unameKernelVersion = Script.runSimpleBashScript("uname -r"); + final String[] kernelVersions = unameKernelVersion.split("[\\.\\-]"); _kernelVersion = Integer.parseInt(kernelVersions[0]) * 1000 * 1000 + (long)Integer.parseInt(kernelVersions[1]) * 1000 + Integer.parseInt(kernelVersions[2]); /* Disable this, the code using this is pretty bad and non portable @@ -982,7 +981,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - protected void configureVifDrivers(Map params) throws ConfigurationException { + protected void configureVifDrivers(final Map params) throws ConfigurationException { final String LIBVIRT_VIF_DRIVER = "libvirt.vif.driver"; _trafficTypeVifDrivers = new HashMap(); @@ -1001,19 +1000,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv _defaultVifDriver = getVifDriverClass(defaultVifDriverName, params); // Load any per-traffic-type vif drivers - for (Map.Entry entry : params.entrySet()) { - String k = entry.getKey(); - String vifDriverPrefix = LIBVIRT_VIF_DRIVER + "."; + for (final Map.Entry entry : params.entrySet()) { + final String k = entry.getKey(); + final String vifDriverPrefix = LIBVIRT_VIF_DRIVER + "."; if (k.startsWith(vifDriverPrefix)) { // Get trafficType - String trafficTypeSuffix = k.substring(vifDriverPrefix.length()); + final String trafficTypeSuffix = k.substring(vifDriverPrefix.length()); // Does this suffix match a real traffic type? - TrafficType trafficType = TrafficType.getTrafficType(trafficTypeSuffix); + final TrafficType trafficType = TrafficType.getTrafficType(trafficTypeSuffix); if (!trafficType.equals(TrafficType.None)) { // Get vif driver class name - String vifDriverClassName = (String)entry.getValue(); + final String vifDriverClassName = (String)entry.getValue(); // if value is null, ignore if (vifDriverClassName != null) { // add traffic type to vif driver mapping to Map @@ -1024,24 +1023,24 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected VifDriver getVifDriverClass(String vifDriverClassName, Map params) throws ConfigurationException { + protected VifDriver getVifDriverClass(final String vifDriverClassName, final Map params) throws ConfigurationException { VifDriver vifDriver; try { - Class clazz = Class.forName(vifDriverClassName); + final Class clazz = Class.forName(vifDriverClassName); vifDriver = (VifDriver)clazz.newInstance(); vifDriver.configure(params); - } catch (ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { throw new ConfigurationException("Unable to find class for libvirt.vif.driver " + e); - } catch (InstantiationException e) { + } catch (final InstantiationException e) { throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { throw new ConfigurationException("Unable to instantiate class for libvirt.vif.driver " + e); } return vifDriver; } - protected VifDriver getVifDriver(TrafficType trafficType) { + protected VifDriver getVifDriver(final TrafficType trafficType) { VifDriver vifDriver = _trafficTypeVifDrivers.get(trafficType); if (vifDriver == null) { @@ -1051,24 +1050,24 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return vifDriver; } - protected List getAllVifDrivers() { - Set vifDrivers = new HashSet(); + public List getAllVifDrivers() { + final Set vifDrivers = new HashSet(); vifDrivers.add(_defaultVifDriver); vifDrivers.addAll(_trafficTypeVifDrivers.values()); - ArrayList vifDriverList = new ArrayList(vifDrivers); + final ArrayList vifDriverList = new ArrayList(vifDrivers); return vifDriverList; } private void getPifs() { - File dir = new File("/sys/devices/virtual/net"); - File[] netdevs = dir.listFiles(); - List bridges = new ArrayList(); + final File dir = new File("/sys/devices/virtual/net"); + final File[] netdevs = dir.listFiles(); + final List bridges = new ArrayList(); for (int i = 0; i < netdevs.length; i++) { - File isbridge = new File(netdevs[i].getAbsolutePath() + "/bridge"); - String netdevName = netdevs[i].getName(); + final File isbridge = new File(netdevs[i].getAbsolutePath() + "/bridge"); + final String netdevName = netdevs[i].getName(); s_logger.debug("looking in file " + netdevs[i].getAbsolutePath() + "/bridge"); if (isbridge.exists()) { s_logger.debug("Found bridge " + netdevName); @@ -1076,9 +1075,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - for (String bridge : bridges) { + for (final String bridge : bridges) { s_logger.debug("looking for pif for bridge " + bridge); - String pif = getPif(bridge); + final String pif = getPif(bridge); if (_publicBridgeName != null && bridge.equals(_publicBridgeName)) { _pifs.put("public", pif); } @@ -1092,7 +1091,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label if (_pifs.get("private") == null) { s_logger.debug("guest(private) traffic label '" + _guestBridgeName + "' not found as bridge, looking for physical interface"); - File dev = new File("/sys/class/net/" + _guestBridgeName); + final File dev = new File("/sys/class/net/" + _guestBridgeName); if (dev.exists()) { s_logger.debug("guest(private) traffic label '" + _guestBridgeName + "' found as a physical device"); _pifs.put("private", _guestBridgeName); @@ -1103,7 +1102,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv // This addresses the unnecessary requirement of someone to create an unused bridge just for traffic label if (_pifs.get("public") == null) { s_logger.debug("public traffic label '" + _publicBridgeName+ "' not found as bridge, looking for physical interface"); - File dev = new File("/sys/class/net/" + _publicBridgeName); + final File dev = new File("/sys/class/net/" + _publicBridgeName); if (dev.exists()) { s_logger.debug("public traffic label '" + _publicBridgeName + "' found as a physical device"); _pifs.put("public", _publicBridgeName); @@ -1114,15 +1113,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } private void getOvsPifs() { - String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'"); + final String cmdout = Script.runSimpleBashScript("ovs-vsctl list-br | sed '{:q;N;s/\\n/%/g;t q}'"); s_logger.debug("cmdout was " + cmdout); - List bridges = Arrays.asList(cmdout.split("%")); - for (String bridge : bridges) { + final List bridges = Arrays.asList(cmdout.split("%")); + for (final String bridge : bridges) { s_logger.debug("looking for pif for bridge " + bridge); // String pif = getOvsPif(bridge); // Not really interested in the pif name at this point for ovs // bridges - String pif = bridge; + final String pif = bridge; if (_publicBridgeName != null && bridge.equals(_publicBridgeName)) { _pifs.put("public", pif); } @@ -1134,9 +1133,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.debug("done looking for pifs, no more bridges"); } - private String getPif(String bridge) { + private String getPif(final String bridge) { String pif = matchPifFileInDirectory(bridge); - File vlanfile = new File("/proc/net/vlan/" + pif); + final File vlanfile = new File("/proc/net/vlan/" + pif); if (vlanfile.isFile()) { pif = Script.runSimpleBashScript("grep ^Device\\: /proc/net/vlan/" + pif + " | awk {'print $2'}"); @@ -1145,11 +1144,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return pif; } - private String matchPifFileInDirectory(String bridgeName) { - File brif = new File("/sys/devices/virtual/net/" + bridgeName + "/brif"); + private String matchPifFileInDirectory(final String bridgeName) { + final File brif = new File("/sys/devices/virtual/net/" + bridgeName + "/brif"); if (!brif.isDirectory()) { - File pif = new File("/sys/class/net/" + bridgeName); + final File pif = new File("/sys/class/net/" + bridgeName); if (pif.isDirectory()) { // if bridgeName already refers to a pif, return it as-is return bridgeName; @@ -1158,10 +1157,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return ""; } - File[] interfaces = brif.listFiles(); + final File[] interfaces = brif.listFiles(); for (int i = 0; i < interfaces.length; i++) { - String fname = interfaces[i].getName(); + final String fname = interfaces[i].getName(); s_logger.debug("matchPifFileInDirectory: file name '" + fname + "'"); if (fname.startsWith("eth") || fname.startsWith("bond") || fname.startsWith("vlan") || fname.startsWith("vx") || fname.startsWith("em") || fname.matches("^p\\d+p\\d+.*")) { @@ -1173,7 +1172,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return ""; } - private boolean checkNetwork(String networkName) { + private boolean checkNetwork(final String networkName) { if (networkName == null) { return true; } @@ -1185,12 +1184,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private boolean checkBridgeNetwork(String networkName) { + private boolean checkBridgeNetwork(final String networkName) { if (networkName == null) { return true; } - String name = matchPifFileInDirectory(networkName); + final String name = matchPifFileInDirectory(networkName); if (name == null || name.isEmpty()) { return false; @@ -1199,19 +1198,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private boolean checkOvsNetwork(String networkName) { + private boolean checkOvsNetwork(final String networkName) { s_logger.debug("Checking if network " + networkName + " exists as openvswitch bridge"); if (networkName == null) { return true; } - Script command = new Script("/bin/sh", _timeout); + final Script command = new Script("/bin/sh", _timeout); command.add("-c"); command.add("ovs-vsctl br-exists " + networkName); return "0".equals(command.execute(null)); } - private boolean passCmdLine(String vmName, String cmdLine) throws InternalErrorException { + private boolean passCmdLine(final String vmName, final String cmdLine) throws InternalErrorException { final Script command = new Script(_patchViaSocketPath, 5 * 1000, s_logger); String result; command.add("-n", vmName); @@ -1224,20 +1223,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - boolean isDirectAttachedNetwork(String type) { + boolean isDirectAttachedNetwork(final String type) { if ("untagged".equalsIgnoreCase(type)) { return true; } else { try { Long.valueOf(type); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { return true; } return false; } } - protected String startVM(Connect conn, String vmName, String domainXML) throws LibvirtException, InternalErrorException { + protected String startVM(final Connect conn, final String vmName, final String domainXML) throws LibvirtException, InternalErrorException { try { /* We create a transient domain here. When this method gets @@ -1257,7 +1256,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv // this is safe because it doesn't stop running VMs dm.undefine(); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { // this is what we want, no domain found } finally { if (dm != null) { @@ -1275,9 +1274,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv @Override public boolean stop() { try { - Connect conn = LibvirtConnection.getConnection(); + final Connect conn = LibvirtConnection.getConnection(); conn.close(); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } @@ -1285,12 +1284,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } @Override - public Answer executeRequest(Command cmd) { + public Answer executeRequest(final Command cmd) { + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + try { + return wrapper.execute(cmd, this); + } catch (final Exception e) { + //[TODO] ignore for now, we still need to finish the other commands. + //return Answer.createUnsupportedCommandAnswer(cmd); + } try { - if (cmd instanceof StopCommand) { - return execute((StopCommand)cmd); - } else if (cmd instanceof GetVmStatsCommand) { + if (cmd instanceof GetVmStatsCommand) { return execute((GetVmStatsCommand)cmd); } else if (cmd instanceof GetVmDiskStatsCommand) { return execute((GetVmDiskStatsCommand)cmd); @@ -1411,17 +1416,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private OvsFetchInterfaceAnswer execute(OvsFetchInterfaceCommand cmd) { - String label = cmd.getLabel(); + private OvsFetchInterfaceAnswer execute(final OvsFetchInterfaceCommand cmd) { + final String label = cmd.getLabel(); s_logger.debug("Will look for network with name-label:" + label); try { - String ipadd = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'"); - String mask = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f4"); - String mac = Script.runSimpleBashScript("ifconfig " + label + " | grep HWaddr | awk -F \" \" '{print $5}'"); + final String ipadd = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'"); + final String mask = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f4"); + final String mac = Script.runSimpleBashScript("ifconfig " + label + " | grep HWaddr | awk -F \" \" '{print $5}'"); return new OvsFetchInterfaceAnswer(cmd, true, "Interface " + label + " retrieved successfully", ipadd, mask, mac); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("Caught execption when fetching interface", e); return new OvsFetchInterfaceAnswer(cmd, false, "EXCEPTION:" + e.getMessage()); @@ -1429,7 +1434,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } - private Answer execute(OvsSetupBridgeCommand cmd) { + private Answer execute(final OvsSetupBridgeCommand cmd) { findOrCreateTunnelNetwork(cmd.getBridgeName()); configureTunnelNetwork(cmd.getNetworkId(), cmd.getHostId(), cmd.getBridgeName()); @@ -1437,60 +1442,60 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new Answer(cmd, true, null); } - private Answer execute(OvsDestroyBridgeCommand cmd) { + private Answer execute(final OvsDestroyBridgeCommand cmd) { destroyTunnelNetwork(cmd.getBridgeName()); s_logger.debug("OVS Bridge destroyed"); return new Answer(cmd, true, null); } - public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) { + public Answer execute(final OvsVpcPhysicalTopologyConfigCommand cmd) { - String bridge = cmd.getBridgeName(); + final String bridge = cmd.getBridgeName(); try { - Script command = new Script(_ovsTunnelPath, _timeout, s_logger); + final Script command = new Script(_ovsTunnelPath, _timeout, s_logger); command.add("configure_ovs_bridge_for_network_topology"); command.add("--bridge", bridge); command.add("--config", cmd.getVpcConfigInJson()); - String result = command.execute(); + final String result = command.execute(); if (result.equalsIgnoreCase("SUCCESS")) { return new Answer(cmd, true, result); } else { return new Answer(cmd, false, result); } - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("caught exception while updating host with latest routing polcies", e); return new Answer(cmd, false, e.getMessage()); } } - public Answer execute(OvsVpcRoutingPolicyConfigCommand cmd) { + public Answer execute(final OvsVpcRoutingPolicyConfigCommand cmd) { try { - Script command = new Script(_ovsTunnelPath, _timeout, s_logger); + final Script command = new Script(_ovsTunnelPath, _timeout, s_logger); command.add("configure_ovs_bridge_for_routing_policies"); command.add("--bridge", cmd.getBridgeName()); command.add("--config", cmd.getVpcConfigInJson()); - String result = command.execute(); + final String result = command.execute(); if (result.equalsIgnoreCase("SUCCESS")) { return new Answer(cmd, true, result); } else { return new Answer(cmd, false, result); } - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("caught exception while updating host with latest VPC topology", e); return new Answer(cmd, false, e.getMessage()); } } - private synchronized void destroyTunnelNetwork(String bridge) { + private synchronized void destroyTunnelNetwork(final String bridge) { try { findOrCreateTunnelNetwork(bridge); - Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger); + final Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger); cmd.add("destroy_ovs_bridge"); cmd.add("--bridge", bridge); - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { // TODO: Should make this error not fatal? // Can Concurrent VM shutdown/migration/reboot events can cause @@ -1499,41 +1504,41 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv throw new CloudRuntimeException("Unable to remove OVS bridge " + bridge); } return; - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("destroyTunnelNetwork failed:", e); return; } } - private synchronized boolean findOrCreateTunnelNetwork(String nwName) { + private synchronized boolean findOrCreateTunnelNetwork(final String nwName) { try { if (checkNetwork(nwName)) { return true; } // if not found, create a new one - Map otherConfig = new HashMap(); + final Map otherConfig = new HashMap(); otherConfig.put("ovs-host-setup", ""); Script.runSimpleBashScript("ovs-vsctl -- --may-exist add-br " + nwName + " -- set bridge " + nwName + " other_config:ovs-host-setup='-1'"); s_logger.debug("### KVM network for tunnels created:" + nwName); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("createTunnelNetwork failed", e); } return true; } - private synchronized boolean configureTunnelNetwork(long networkId, - long hostId, String nwName) { + private synchronized boolean configureTunnelNetwork(final long networkId, + final long hostId, final String nwName) { try { findOrCreateTunnelNetwork(nwName); - String configuredHosts = Script + final String configuredHosts = Script .runSimpleBashScript("ovs-vsctl get bridge " + nwName + " other_config:ovs-host-setup"); boolean configured = false; if (configuredHosts != null) { - String hostIdsStr[] = configuredHosts.split(","); - for (String hostIdStr : hostIdsStr) { + final String hostIdsStr[] = configuredHosts.split(","); + for (final String hostIdStr : hostIdsStr) { if (hostIdStr.equals(((Long)hostId).toString())) { configured = true; break; @@ -1541,27 +1546,27 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } if (!configured) { - Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger); + final Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger); cmd.add("setup_ovs_bridge"); cmd.add("--key", nwName); cmd.add("--cs_host_id", ((Long)hostId).toString()); cmd.add("--bridge", nwName); - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { throw new CloudRuntimeException( "Unable to pre-configure OVS bridge " + nwName + " for network ID:" + networkId); } } - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("createandConfigureTunnelNetwork failed", e); return false; } return true; } - private OvsCreateTunnelAnswer execute(OvsCreateTunnelCommand cmd) { - String bridge = cmd.getNetworkName(); + private OvsCreateTunnelAnswer execute(final OvsCreateTunnelCommand cmd) { + final String bridge = cmd.getNetworkName(); try { if (!findOrCreateTunnelNetwork(bridge)) { s_logger.debug("Error during bridge setup"); @@ -1571,7 +1576,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv configureTunnelNetwork(cmd.getNetworkId(), cmd.getFrom(), cmd.getNetworkName()); - Script command = new Script(_ovsTunnelPath, _timeout, s_logger); + final Script command = new Script(_ovsTunnelPath, _timeout, s_logger); command.add("create_tunnel"); command.add("--bridge", bridge); command.add("--remote_ip", cmd.getRemoteIp()); @@ -1579,21 +1584,21 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv command.add("--src_host", cmd.getFrom().toString()); command.add("--dst_host", cmd.getTo().toString()); - String result = command.execute(); + final String result = command.execute(); if (result != null) { return new OvsCreateTunnelAnswer(cmd, true, result, null, bridge); } else { return new OvsCreateTunnelAnswer(cmd, false, result, bridge); } - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Error during tunnel setup"); s_logger.warn("Caught execption when creating ovs tunnel", e); return new OvsCreateTunnelAnswer(cmd, false, e.getMessage(), bridge); } } - private Answer execute(OvsDestroyTunnelCommand cmd) { + private Answer execute(final OvsDestroyTunnelCommand cmd) { try { if (!findOrCreateTunnelNetwork(cmd.getBridgeName())) { s_logger.warn("Unable to find tunnel network for GRE key:" @@ -1601,26 +1606,26 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new Answer(cmd, false, "No network found"); } - Script command = new Script(_ovsTunnelPath, _timeout, s_logger); + final Script command = new Script(_ovsTunnelPath, _timeout, s_logger); command.add("destroy_tunnel"); command.add("--bridge", cmd.getBridgeName()); command.add("--iface_name", cmd.getInPortName()); - String result = command.execute(); + final String result = command.execute(); if (result == null) { return new Answer(cmd, true, result); } else { return new Answer(cmd, false, result); } - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("caught execption when destroy ovs tunnel", e); return new Answer(cmd, false, e.getMessage()); } } - private CheckNetworkAnswer execute(CheckNetworkCommand cmd) { - List phyNics = cmd.getPhysicalNetworkInfoList(); + private CheckNetworkAnswer execute(final CheckNetworkCommand cmd) { + final List phyNics = cmd.getPhysicalNetworkInfoList(); String errMsg = null; - for (PhysicalNetworkSetupInfo nic : phyNics) { + for (final PhysicalNetworkSetupInfo nic : phyNics) { if (!checkNetwork(nic.getGuestNetworkName())) { errMsg = "Can not find network: " + nic.getGuestNetworkName(); break; @@ -1640,7 +1645,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private CopyVolumeAnswer execute(CopyVolumeCommand cmd) { + private CopyVolumeAnswer execute(final CopyVolumeCommand cmd) { /** This method is only used for copying files from Primary Storage TO Secondary Storage @@ -1648,16 +1653,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv that it always sets copyToSecondary to true */ - boolean copyToSecondary = cmd.toSecondaryStorage(); + final boolean copyToSecondary = cmd.toSecondaryStorage(); String volumePath = cmd.getVolumePath(); - StorageFilerTO pool = cmd.getPool(); - String secondaryStorageUrl = cmd.getSecondaryStorageURL(); + final StorageFilerTO pool = cmd.getPool(); + final String secondaryStorageUrl = cmd.getSecondaryStorageURL(); KVMStoragePool secondaryStoragePool = null; KVMStoragePool primaryPool = null; try { try { primaryPool = _storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid()); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { if (e.getMessage().contains("not found")) { primaryPool = _storagePoolMgr.createStoragePool(cmd.getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(), cmd.getPool().getPath(), @@ -1667,12 +1672,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - String volumeName = UUID.randomUUID().toString(); + final String volumeName = UUID.randomUUID().toString(); if (copyToSecondary) { - String destVolumeName = volumeName + ".qcow2"; - KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(cmd.getVolumePath()); - String volumeDestPath = "/volumes/" + cmd.getVolumeId() + File.separator; + final String destVolumeName = volumeName + ".qcow2"; + final KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(cmd.getVolumePath()); + final String volumeDestPath = "/volumes/" + cmd.getVolumeId() + File.separator; secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl); secondaryStoragePool.createFolder(volumeDestPath); _storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid()); @@ -1682,11 +1687,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } else { volumePath = "/volumes/" + cmd.getVolumeId() + File.separator; secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumePath); - KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(cmd.getVolumePath() + ".qcow2"); + final KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(cmd.getVolumePath() + ".qcow2"); _storagePoolMgr.copyPhysicalDisk(volume, volumeName, primaryPool, 0); return new CopyVolumeAnswer(cmd, true, null, null, volumeName); } - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { return new CopyVolumeAnswer(cmd, false, e.toString(), null, null); } finally { if (secondaryStoragePool != null) { @@ -1695,52 +1700,52 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected Answer execute(DeleteStoragePoolCommand cmd) { + protected Answer execute(final DeleteStoragePoolCommand cmd) { try { _storagePoolMgr.deleteStoragePool(cmd.getPool().getType(), cmd.getPool().getUuid()); return new Answer(cmd); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { return new Answer(cmd, false, e.toString()); } } - protected FenceAnswer execute(FenceCommand cmd) { - ExecutorService executors = Executors.newSingleThreadExecutor(); - List pools = _monitor.getStoragePools(); - KVMHAChecker ha = new KVMHAChecker(pools, cmd.getHostIp()); - Future future = executors.submit(ha); + protected FenceAnswer execute(final FenceCommand cmd) { + final ExecutorService executors = Executors.newSingleThreadExecutor(); + final List pools = _monitor.getStoragePools(); + final KVMHAChecker ha = new KVMHAChecker(pools, cmd.getHostIp()); + final Future future = executors.submit(ha); try { - Boolean result = future.get(); + final Boolean result = future.get(); if (result) { return new FenceAnswer(cmd, false, "Heart is still beating..."); } else { return new FenceAnswer(cmd); } - } catch (InterruptedException e) { + } catch (final InterruptedException e) { s_logger.warn("Unable to fence", e); return new FenceAnswer(cmd, false, e.getMessage()); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { s_logger.warn("Unable to fence", e); return new FenceAnswer(cmd, false, e.getMessage()); } } - protected Answer execute(CheckOnHostCommand cmd) { - ExecutorService executors = Executors.newSingleThreadExecutor(); - List pools = _monitor.getStoragePools(); - KVMHAChecker ha = new KVMHAChecker(pools, cmd.getHost().getPrivateNetwork().getIp()); - Future future = executors.submit(ha); + protected Answer execute(final CheckOnHostCommand cmd) { + final ExecutorService executors = Executors.newSingleThreadExecutor(); + final List pools = _monitor.getStoragePools(); + final KVMHAChecker ha = new KVMHAChecker(pools, cmd.getHost().getPrivateNetwork().getIp()); + final Future future = executors.submit(ha); try { - Boolean result = future.get(); + final Boolean result = future.get(); if (result) { return new Answer(cmd, false, "Heart is still beating..."); } else { return new Answer(cmd); } - } catch (InterruptedException e) { + } catch (final InterruptedException e) { return new Answer(cmd, false, "can't get status of host:"); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { return new Answer(cmd, false, "can't get status of host:"); } @@ -1750,9 +1755,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return Storage.StorageResourceType.STORAGE_POOL; } - protected Answer execute(CreateCommand cmd) { - StorageFilerTO pool = cmd.getPool(); - DiskProfile dskch = cmd.getDiskCharacteristics(); + 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; @@ -1775,7 +1780,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } else { vol = primaryPool.createPhysicalDisk(dskch.getPath(), dskch.getProvisioningType(), dskch.getSize()); } - VolumeTO volume = + 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()); @@ -1783,16 +1788,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv volume.setIopsWriteRate(dskch.getIopsWriteRate()); volume.setCacheMode(dskch.getCacheMode()); return new CreateAnswer(cmd, volume); - } catch (CloudRuntimeException e) { + } 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 - protected KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool, String volUuid) { - int index = templateUrl.lastIndexOf("/"); - String mountpoint = templateUrl.substring(0, index); + protected 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; if (index < templateUrl.length() - 1) { templateName = templateUrl.substring(index + 1); @@ -1805,12 +1810,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /* Get template vol */ if (templateName == null) { secondaryPool.refresh(); - List disks = secondaryPool.listPhysicalDisks(); + final List disks = secondaryPool.listPhysicalDisks(); if (disks == null || disks.isEmpty()) { s_logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid()); return null; } - for (KVMPhysicalDisk disk : disks) { + for (final KVMPhysicalDisk disk : disks) { if (disk.getName().endsWith("qcow2")) { templateVol = disk; break; @@ -1826,9 +1831,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /* Copy volume to primary storage */ - KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, 0); + final KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, 0); return primaryVol; - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { s_logger.error("Failed to download template to primary storage", e); return null; } finally { @@ -1838,9 +1843,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private String getResizeScriptType(KVMStoragePool pool, KVMPhysicalDisk vol) { - StoragePoolType poolType = pool.getType(); - PhysicalDiskFormat volFormat = vol.getFormat(); + private String getResizeScriptType(final KVMStoragePool pool, final KVMPhysicalDisk vol) { + final StoragePoolType poolType = pool.getType(); + final PhysicalDiskFormat volFormat = vol.getFormat(); if (pool.getType() == StoragePoolType.CLVM && volFormat == PhysicalDiskFormat.RAW) { return "CLVM"; @@ -1856,13 +1861,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /* uses a local script now, eventually support for virStorageVolResize() will maybe work on qcow2 and lvm and we can do this in libvirt calls */ - public Answer execute(ResizeVolumeCommand cmd) { - String volid = cmd.getPath(); - long newSize = cmd.getNewSize(); - long currentSize = cmd.getCurrentSize(); - String vmInstanceName = cmd.getInstanceName(); - boolean shrinkOk = cmd.getShrinkOk(); - StorageFilerTO spool = cmd.getPool(); + public Answer execute(final ResizeVolumeCommand cmd) { + final String volid = cmd.getPath(); + final long newSize = cmd.getNewSize(); + final long currentSize = cmd.getCurrentSize(); + final String vmInstanceName = cmd.getInstanceName(); + final boolean shrinkOk = cmd.getShrinkOk(); + final StorageFilerTO spool = cmd.getPool(); final String notifyOnlyType = "NOTIFYONLY"; if ( currentSize == newSize) { @@ -1873,8 +1878,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { KVMStoragePool pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid()); - KVMPhysicalDisk vol = pool.getPhysicalDisk(volid); - String path = vol.getPath(); + final KVMPhysicalDisk vol = pool.getPhysicalDisk(volid); + final String path = vol.getPath(); String type = getResizeScriptType(pool, vol); if (pool.getType() != StoragePoolType.RBD) { @@ -1891,8 +1896,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (pool.getType() != StoragePoolType.CLVM && vol.getFormat() != PhysicalDiskFormat.QCOW2) { s_logger.debug("Volume " + path + " can be resized by libvirt. Asking libvirt to resize the volume."); try { - Connect conn = LibvirtConnection.getConnection(); - StorageVol v = conn.storageVolLookupByPath(path); + final Connect conn = LibvirtConnection.getConnection(); + final StorageVol v = conn.storageVolLookupByPath(path); int flags = 0; if (conn.getLibVirVersion() > 1001000 && vol.getFormat() == PhysicalDiskFormat.RAW && pool.getType() != StoragePoolType.RBD) { @@ -1904,7 +1909,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv v.resize(newSize, flags); type = notifyOnlyType; - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new ResizeVolumeAnswer(cmd, false, e.toString()); } } @@ -1916,7 +1921,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv resizecmd.add("-t", type); resizecmd.add("-r", String.valueOf(shrinkOk)); resizecmd.add("-v", vmInstanceName); - String result = resizecmd.execute(); + final String result = resizecmd.execute(); if (result != null) { if(type.equals(notifyOnlyType)) { @@ -1929,33 +1934,33 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /* fetch new size as seen from libvirt, don't want to assume anything */ pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid()); pool.refresh(); - long finalSize = pool.getPhysicalDisk(volid).getVirtualSize(); + final long finalSize = pool.getPhysicalDisk(volid).getVirtualSize(); s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize); return new ResizeVolumeAnswer(cmd, true, "success", finalSize); - } catch (CloudRuntimeException e) { - String error = "Failed to resize volume: " + e.getMessage(); + } catch (final CloudRuntimeException e) { + final String error = "Failed to resize volume: " + e.getMessage(); s_logger.debug(error); return new ResizeVolumeAnswer(cmd, false, error); } } - public Answer execute(DestroyCommand cmd) { - VolumeTO vol = cmd.getVolume(); + public Answer execute(final DestroyCommand cmd) { + final VolumeTO vol = cmd.getVolume(); try { - KVMStoragePool pool = _storagePoolMgr.getStoragePool(vol.getPoolType(), vol.getPoolUuid()); + final KVMStoragePool pool = _storagePoolMgr.getStoragePool(vol.getPoolType(), vol.getPoolUuid()); pool.deletePhysicalDisk(vol.getPath(), null); return new Answer(cmd, true, "Success"); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { s_logger.debug("Failed to delete volume: " + e.toString()); return new Answer(cmd, false, e.toString()); } } - private String getBroadcastUriFromBridge(String brName) { - String pif = matchPifFileInDirectory(brName); - Pattern pattern = Pattern.compile("(\\D+)(\\d+)(\\D*)(\\d*)"); - Matcher matcher = pattern.matcher(pif); + private String getBroadcastUriFromBridge(final String brName) { + final String pif = matchPifFileInDirectory(brName); + final Pattern pattern = Pattern.compile("(\\D+)(\\d+)(\\D*)(\\d*)"); + final Matcher matcher = pattern.matcher(pif); s_logger.debug("getting broadcast uri for pif " + pif + " and bridge " + brName); if(matcher.find()) { if (brName.startsWith("brvx")){ @@ -1977,14 +1982,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(PvlanSetupCommand cmd) { - String primaryPvlan = cmd.getPrimary(); - String isolatedPvlan = cmd.getIsolated(); - String op = cmd.getOp(); - String dhcpName = cmd.getDhcpName(); - String dhcpMac = cmd.getDhcpMac(); - String dhcpIp = cmd.getDhcpIp(); - String vmMac = cmd.getVmMac(); + private Answer execute(final PvlanSetupCommand cmd) { + final String primaryPvlan = cmd.getPrimary(); + final String isolatedPvlan = cmd.getIsolated(); + final String op = cmd.getOp(); + final String dhcpName = cmd.getDhcpName(); + final String dhcpMac = cmd.getDhcpMac(); + final String dhcpIp = cmd.getDhcpIp(); + final String vmMac = cmd.getVmMac(); boolean add = true; String opr = "-A"; @@ -1997,11 +2002,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv Connect conn; try { if (cmd.getType() == PvlanSetupCommand.Type.DHCP) { - Script script = new Script(_ovsPvlanDhcpHostPath, _timeout, s_logger); + final Script script = new Script(_ovsPvlanDhcpHostPath, _timeout, s_logger); if (add) { conn = LibvirtConnection.getConnectionByVmName(dhcpName); - List ifaces = getInterfaces(conn, dhcpName); - InterfaceDef guestNic = ifaces.get(0); + final List ifaces = getInterfaces(conn, dhcpName); + final InterfaceDef guestNic = ifaces.get(0); script.add(opr, "-b", _guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName, "-d", dhcpIp, "-m", dhcpMac, "-I", guestNic.getDevName()); } else { @@ -2015,7 +2020,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac); } } else if (cmd.getType() == PvlanSetupCommand.Type.VM) { - Script script = new Script(_ovsPvlanVmPath, _timeout, s_logger); + final Script script = new Script(_ovsPvlanVmPath, _timeout, s_logger); script.add(opr, "-b", _guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-v", vmMac); result = script.execute(); if (result != null) { @@ -2025,57 +2030,57 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.info("Programmed pvlan for vm with mac " + vmMac); } } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { // TODO Auto-generated catch block e.printStackTrace(); } return new Answer(cmd, true, result); } - private void VifHotPlug(Connect conn, String vmName, String broadcastUri, String macAddr) throws InternalErrorException, LibvirtException { - NicTO nicTO = new NicTO(); + private void VifHotPlug(final Connect conn, final String vmName, final String broadcastUri, final String macAddr) throws InternalErrorException, LibvirtException { + final NicTO nicTO = new NicTO(); nicTO.setMac(macAddr); nicTO.setType(TrafficType.Public); if (broadcastUri == null) { nicTO.setBroadcastType(BroadcastDomainType.Native); } else { - URI uri = BroadcastDomainType.fromString(broadcastUri); + final URI uri = BroadcastDomainType.fromString(broadcastUri); nicTO.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); nicTO.setBroadcastUri(uri); } - Domain vm = getDomain(conn, vmName); + final Domain vm = getDomain(conn, vmName); vm.attachDevice(getVifDriver(nicTO.getType()).plug(nicTO, "Other PV", "").toString()); } - private void vifHotUnPlug (Connect conn, String vmName, String macAddr) throws InternalErrorException, LibvirtException { + private void vifHotUnPlug (final Connect conn, final String vmName, final String macAddr) throws InternalErrorException, LibvirtException { Domain vm = null; vm = getDomain(conn, vmName); - List pluggedNics = getInterfaces(conn, vmName); - for (InterfaceDef pluggedNic : pluggedNics) { + final List pluggedNics = getInterfaces(conn, vmName); + for (final InterfaceDef pluggedNic : pluggedNics) { if (pluggedNic.getMacAddress().equalsIgnoreCase(macAddr)) { vm.detachDevice(pluggedNic.toString()); // We don't know which "traffic type" is associated with // each interface at this point, so inform all vif drivers - for (VifDriver vifDriver : getAllVifDrivers()) { + for (final VifDriver vifDriver : getAllVifDrivers()) { vifDriver.unplug(pluggedNic); } } } } - private PlugNicAnswer execute(PlugNicCommand cmd) { - NicTO nic = cmd.getNic(); - String vmName = cmd.getVmName(); + private PlugNicAnswer execute(final PlugNicCommand cmd) { + final NicTO nic = cmd.getNic(); + final String vmName = cmd.getVmName(); Domain vm = null; try { - Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); vm = getDomain(conn, vmName); - List pluggedNics = getInterfaces(conn, vmName); + final List pluggedNics = getInterfaces(conn, vmName); Integer nicnum = 0; - for (InterfaceDef pluggedNic : pluggedNics) { + for (final InterfaceDef pluggedNic : pluggedNics) { if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) { s_logger.debug("found existing nic for mac " + pluggedNic.getMacAddress() + " at index " + nicnum); return new PlugNicAnswer(cmd, true, "success"); @@ -2084,72 +2089,72 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } vm.attachDevice(getVifDriver(nic.getType()).plug(nic, "Other PV", "").toString()); return new PlugNicAnswer(cmd, true, "success"); - } catch (LibvirtException e) { - String msg = " Plug Nic failed due to " + e.toString(); + } catch (final LibvirtException e) { + final String msg = " Plug Nic failed due to " + e.toString(); s_logger.warn(msg, e); return new PlugNicAnswer(cmd, false, msg); - } catch (InternalErrorException e) { - String msg = " Plug Nic failed due to " + e.toString(); + } catch (final InternalErrorException e) { + final String msg = " Plug Nic failed due to " + e.toString(); s_logger.warn(msg, e); return new PlugNicAnswer(cmd, false, msg); } finally { if (vm != null) { try { vm.free(); - } catch (LibvirtException l) { + } catch (final LibvirtException l) { s_logger.trace("Ignoring libvirt error.", l); } } } } - private UnPlugNicAnswer execute(UnPlugNicCommand cmd) { + private UnPlugNicAnswer execute(final UnPlugNicCommand cmd) { Connect conn; - NicTO nic = cmd.getNic(); - String vmName = cmd.getVmName(); + final NicTO nic = cmd.getNic(); + final String vmName = cmd.getVmName(); Domain vm = null; try { conn = LibvirtConnection.getConnectionByVmName(vmName); vm = getDomain(conn, vmName); - List pluggedNics = getInterfaces(conn, vmName); - for (InterfaceDef pluggedNic : pluggedNics) { + final List pluggedNics = getInterfaces(conn, vmName); + for (final InterfaceDef pluggedNic : pluggedNics) { if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) { vm.detachDevice(pluggedNic.toString()); // We don't know which "traffic type" is associated with // each interface at this point, so inform all vif drivers - for (VifDriver vifDriver : getAllVifDrivers()) { + for (final VifDriver vifDriver : getAllVifDrivers()) { vifDriver.unplug(pluggedNic); } return new UnPlugNicAnswer(cmd, true, "success"); } } return new UnPlugNicAnswer(cmd, true, "success"); - } catch (LibvirtException e) { - String msg = " Unplug Nic failed due to " + e.toString(); + } catch (final LibvirtException e) { + final String msg = " Unplug Nic failed due to " + e.toString(); s_logger.warn(msg, e); return new UnPlugNicAnswer(cmd, false, msg); } finally { if (vm != null) { try { vm.free(); - } catch (LibvirtException l) { + } catch (final LibvirtException l) { s_logger.trace("Ignoring libvirt error.", l); } } } } - private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { + private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) { Connect conn; - NicTO nic = cmd.getNic(); - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + final NicTO nic = cmd.getNic(); + final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); try { conn = LibvirtConnection.getConnectionByVmName(routerName); - List pluggedNics = getInterfaces(conn, routerName); + final List pluggedNics = getInterfaces(conn, routerName); InterfaceDef routerNic = null; - for (InterfaceDef pluggedNic : pluggedNics) { + for (final InterfaceDef pluggedNic : pluggedNics) { if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) { routerNic = pluggedNic; break; @@ -2161,28 +2166,28 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } return new ExecutionResult(true, null); - } catch (LibvirtException e) { - String msg = "Creating guest network failed due to " + e.toString(); + } catch (final LibvirtException e) { + final String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); return new ExecutionResult(false, msg); } } - protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) { Connect conn; - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - IpAddressTO pubIP = cmd.getIpAddress(); + final IpAddressTO pubIP = cmd.getIpAddress(); try { conn = LibvirtConnection.getConnectionByVmName(routerName); Integer devNum = 0; - String pubVlan = pubIP.getBroadcastUri(); - List pluggedNics = getInterfaces(conn, routerName); + final String pubVlan = pubIP.getBroadcastUri(); + final List pluggedNics = getInterfaces(conn, routerName); - for (InterfaceDef pluggedNic : pluggedNics) { - String pluggedVlanBr = pluggedNic.getBrName(); - String pluggedVlanId = getBroadcastUriFromBridge(pluggedVlanBr); + for (final InterfaceDef pluggedNic : pluggedNics) { + final String pluggedVlanBr = pluggedNic.getBrName(); + final String pluggedVlanId = getBroadcastUriFromBridge(pluggedVlanBr); if (pubVlan.equalsIgnoreCase(Vlan.UNTAGGED) && pluggedVlanBr.equalsIgnoreCase(_publicBridgeName)) { break; } else if (pluggedVlanBr.equalsIgnoreCase(_linkLocalBridgeName)) { @@ -2200,26 +2205,26 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv pubIP.setNicDevId(devNum); return new ExecutionResult(true, "success"); - } catch (LibvirtException e) { - String msg = "Ip SNAT failure due to " + e.toString(); + } catch (final LibvirtException e) { + final String msg = "Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); return new ExecutionResult(false, msg); } } - protected ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand cmd) { Connect conn; - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); try { conn = LibvirtConnection.getConnectionByVmName(routerName); - IpAddressTO[] ips = cmd.getIpAddresses(); + final IpAddressTO[] ips = cmd.getIpAddresses(); Integer devNum = 0; - Map broadcastUriToNicNum = new HashMap(); - List pluggedNics = getInterfaces(conn, routerName); + final Map broadcastUriToNicNum = new HashMap(); + final List pluggedNics = getInterfaces(conn, routerName); - for (InterfaceDef pluggedNic : pluggedNics) { - String pluggedVlan = pluggedNic.getBrName(); + for (final InterfaceDef pluggedNic : pluggedNics) { + final String pluggedVlan = pluggedNic.getBrName(); if (pluggedVlan.equalsIgnoreCase(_linkLocalBridgeName)) { broadcastUriToNicNum.put("LinkLocal", devNum); } else if (pluggedVlan.equalsIgnoreCase(_publicBridgeName) || pluggedVlan.equalsIgnoreCase(_privBridgeName) || @@ -2231,27 +2236,27 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv devNum++; } - for (IpAddressTO ip : ips) { + for (final IpAddressTO ip : ips) { ip.setNicDevId(broadcastUriToNicNum.get(ip.getBroadcastUri())); } return new ExecutionResult(true, null); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); return new ExecutionResult(false, e.getMessage()); } } - public ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + public ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) { + final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); Connect conn; try { conn = LibvirtConnection.getConnectionByVmName(routerName); - List nics = getInterfaces(conn, routerName); - Map broadcastUriAllocatedToVM = new HashMap(); + final List nics = getInterfaces(conn, routerName); + final Map broadcastUriAllocatedToVM = new HashMap(); Integer nicPos = 0; - for (InterfaceDef nic : nics) { + for (final InterfaceDef nic : nics) { if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) { broadcastUriAllocatedToVM.put("LinkLocal", nicPos); } else { @@ -2259,15 +2264,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv nic.getBrName().equalsIgnoreCase(_guestBridgeName)) { broadcastUriAllocatedToVM.put(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString(), nicPos); } else { - String broadcastUri = getBroadcastUriFromBridge(nic.getBrName()); + final String broadcastUri = getBroadcastUriFromBridge(nic.getBrName()); broadcastUriAllocatedToVM.put(broadcastUri, nicPos); } } nicPos++; } - IpAddressTO[] ips = cmd.getIpAddresses(); + final IpAddressTO[] ips = cmd.getIpAddresses(); int nicNum = 0; - for (IpAddressTO ip : ips) { + for (final IpAddressTO ip : ips) { boolean newNic = false; if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) { /* plug a vif into router */ @@ -2282,29 +2287,29 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv ip.setNewNic(newNic); } return new ExecutionResult(true, null); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.error("ipassoccmd failed", e); return new ExecutionResult(false, e.getMessage()); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { s_logger.error("ipassoccmd failed", e); return new ExecutionResult(false, e.getMessage()); } } - protected ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) { + protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) { - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); Connect conn; try{ conn = LibvirtConnection.getConnectionByVmName(routerName); - List nics = getInterfaces(conn, routerName); - Map broadcastUriAllocatedToVM = new HashMap(); + final List nics = getInterfaces(conn, routerName); + final Map broadcastUriAllocatedToVM = new HashMap(); Integer nicPos = 0; - for (InterfaceDef nic : nics) { + for (final InterfaceDef nic : nics) { if (nic.getBrName().equalsIgnoreCase(_linkLocalBridgeName)) { broadcastUriAllocatedToVM.put("LinkLocal", nicPos); } else { @@ -2312,17 +2317,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv nic.getBrName().equalsIgnoreCase(_guestBridgeName)) { broadcastUriAllocatedToVM.put(BroadcastDomainType.Vlan.toUri(Vlan.UNTAGGED).toString(), nicPos); } else { - String broadcastUri = getBroadcastUriFromBridge(nic.getBrName()); + final String broadcastUri = getBroadcastUriFromBridge(nic.getBrName()); broadcastUriAllocatedToVM.put(broadcastUri, nicPos); } } nicPos++; } - IpAddressTO[] ips = cmd.getIpAddresses(); - int numOfIps = ips.length; + final IpAddressTO[] ips = cmd.getIpAddresses(); + final int numOfIps = ips.length; int nicNum = 0; - for (IpAddressTO ip : ips) { + for (final IpAddressTO ip : ips) { if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) { /* plug a vif into router */ @@ -2337,10 +2342,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.error("ipassoccmd failed", e); return new ExecutionResult(false, e.getMessage()); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { s_logger.error("ipassoccmd failed", e); return new ExecutionResult(false, e.getMessage()); } @@ -2349,34 +2354,34 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) { - String snapshotName = cmd.getSnapshotName(); - String snapshotPath = cmd.getSnapshotPath(); - String vmName = cmd.getVmName(); + final String snapshotName = cmd.getSnapshotName(); + final String snapshotPath = cmd.getSnapshotPath(); + final String vmName = cmd.getVmName(); try { - Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); DomainState state = null; Domain vm = null; if (vmName != null) { try { vm = getDomain(conn, cmd.getVmName()); state = vm.getInfo().state; - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } } - KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPool().getUuid()); + final KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPool().getUuid()); - KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(cmd.getVolumePath()); + final KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(cmd.getVolumePath()); if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) { - String vmUuid = vm.getUUIDString(); - Object[] args = new Object[] {snapshotName, vmUuid}; - String snapshot = SnapshotXML.format(args); + final String vmUuid = vm.getUUIDString(); + final Object[] args = new Object[] {snapshotName, vmUuid}; + final String snapshot = SnapshotXML.format(args); s_logger.debug(snapshot); if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { vm.snapshotCreateXML(snapshot); } else { - DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); + final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); snap.delete(0); } @@ -2405,16 +2410,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv */ if (primaryPool.getType() == StoragePoolType.RBD) { try { - Rados r = new Rados(primaryPool.getAuthUserName()); + final Rados r = new Rados(primaryPool.getAuthUserName()); r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort()); r.confSet("key", primaryPool.getAuthSecret()); r.confSet("client_mount_timeout", "30"); r.connect(); s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host")); - IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir()); - Rbd rbd = new Rbd(io); - RbdImage image = rbd.open(disk.getName()); + final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir()); + final Rbd rbd = new Rbd(io); + final RbdImage image = rbd.open(disk.getName()); if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { s_logger.debug("Attempting to create RBD snapshot " + disk.getName() + "@" + snapshotName); @@ -2426,7 +2431,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv rbd.close(image); r.ioCtxDestroy(io); - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("A RBD snapshot operation on " + disk.getName() + " failed. The error was: " + e.getMessage()); } } else { @@ -2439,7 +2444,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } command.add("-n", snapshotName); - String result = command.execute(); + final String result = command.execute(); if (result != null) { s_logger.debug("Failed to manage snapshot: " + result); return new ManageSnapshotAnswer(cmd, false, "Failed to manage snapshot: " + result); @@ -2447,7 +2452,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } return new ManageSnapshotAnswer(cmd, cmd.getSnapshotId(), disk.getPath() + File.separator + snapshotName, true, null); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Failed to manage snapshot: " + e.toString()); return new ManageSnapshotAnswer(cmd, false, "Failed to manage snapshot: " + e.toString()); } @@ -2455,26 +2460,26 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } protected BackupSnapshotAnswer execute(final BackupSnapshotCommand cmd) { - Long dcId = cmd.getDataCenterId(); - Long accountId = cmd.getAccountId(); - Long volumeId = cmd.getVolumeId(); - String secondaryStoragePoolUrl = cmd.getSecondaryStorageUrl(); - String snapshotName = cmd.getSnapshotName(); + final Long dcId = cmd.getDataCenterId(); + final Long accountId = cmd.getAccountId(); + final Long volumeId = cmd.getVolumeId(); + final String secondaryStoragePoolUrl = cmd.getSecondaryStorageUrl(); + final String snapshotName = cmd.getSnapshotName(); String snapshotDestPath = null; String snapshotRelPath = null; - String vmName = cmd.getVmName(); + final String vmName = cmd.getVmName(); KVMStoragePool secondaryStoragePool = null; try { - Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl); - String ssPmountPath = secondaryStoragePool.getLocalPath(); + final String ssPmountPath = secondaryStoragePool.getLocalPath(); snapshotRelPath = File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; - KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPrimaryStoragePoolNameLabel()); - KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(cmd.getVolumePath()); + final KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPrimaryStoragePoolNameLabel()); + final KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(cmd.getVolumePath()); /** * RBD snapshots can't be copied using qemu-img, so we have to use @@ -2488,24 +2493,24 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv */ if (primaryPool.getType() == StoragePoolType.RBD) { try { - Rados r = new Rados(primaryPool.getAuthUserName()); + final Rados r = new Rados(primaryPool.getAuthUserName()); r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort()); r.confSet("key", primaryPool.getAuthSecret()); r.confSet("client_mount_timeout", "30"); r.connect(); s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host")); - IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir()); - Rbd rbd = new Rbd(io); - RbdImage image = rbd.open(snapshotDisk.getName(), snapshotName); - File fh = new File(snapshotDestPath); + final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir()); + final Rbd rbd = new Rbd(io); + final RbdImage image = rbd.open(snapshotDisk.getName(), snapshotName); + final File fh = new File(snapshotDestPath); try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fh));) { - int chunkSize = 4194304; + final int chunkSize = 4194304; long offset = 0; s_logger.debug("Backuping up RBD snapshot " + snapshotName + " to " + snapshotDestPath); while (true) { - byte[] buf = new byte[chunkSize]; - int bytes = image.read(offset, buf, chunkSize); + final byte[] buf = new byte[chunkSize]; + final int bytes = image.read(offset, buf, chunkSize); if (bytes <= 0) { break; } @@ -2513,25 +2518,25 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv offset += bytes; } s_logger.debug("Completed backing up RBD snapshot " + snapshotName + " to " + snapshotDestPath + ". Bytes written: " + offset); - }catch(IOException ex) + }catch(final IOException ex) { s_logger.error("BackupSnapshotAnswer:Exception:"+ ex.getMessage()); } r.ioCtxDestroy(io); - } catch (RadosException e) { + } catch (final RadosException e) { s_logger.error("A RADOS operation failed. The error was: " + e.getMessage()); return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); - } catch (RbdException e) { + } catch (final RbdException e) { s_logger.error("A RBD operation on " + snapshotDisk.getName() + " failed. The error was: " + e.getMessage()); return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); } } else { - Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); + final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); command.add("-b", snapshotDisk.getPath()); command.add("-n", snapshotName); command.add("-p", snapshotDestPath); command.add("-t", snapshotName); - String result = command.execute(); + final String result = command.execute(); if (result != null) { s_logger.debug("Failed to backup snaptshot: " + result); return new BackupSnapshotAnswer(cmd, false, result, null, true); @@ -2545,18 +2550,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { vm = getDomain(conn, cmd.getVmName()); state = vm.getInfo().state; - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } } - KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPool().getUuid()); + final KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPool().getUuid()); if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) { - String vmUuid = vm.getUUIDString(); - Object[] args = new Object[] {snapshotName, vmUuid}; - String snapshot = SnapshotXML.format(args); + final String vmUuid = vm.getUUIDString(); + final Object[] args = new Object[] {snapshotName, vmUuid}; + final String snapshot = SnapshotXML.format(args); s_logger.debug(snapshot); - DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); + final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); snap.delete(0); /* @@ -2569,18 +2574,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vm.resume(); } } else { - Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); + final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); command.add("-d", snapshotDisk.getPath()); command.add("-n", snapshotName); - String result = command.execute(); + final String result = command.execute(); if (result != null) { s_logger.debug("Failed to backup snapshot: " + result); return new BackupSnapshotAnswer(cmd, false, "Failed to backup snapshot: " + result, null, true); } } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); } finally { if (secondaryStoragePool != null) { @@ -2594,17 +2599,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { String snapshotPath = cmd.getSnapshotUuid(); - int index = snapshotPath.lastIndexOf("/"); + final int index = snapshotPath.lastIndexOf("/"); snapshotPath = snapshotPath.substring(0, index); - KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl() + snapshotPath); - KVMPhysicalDisk snapshot = secondaryPool.getPhysicalDisk(cmd.getSnapshotName()); + final KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl() + snapshotPath); + final KVMPhysicalDisk snapshot = secondaryPool.getPhysicalDisk(cmd.getSnapshotName()); - String primaryUuid = cmd.getPrimaryStoragePoolNameLabel(); - KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), primaryUuid); - String volUuid = UUID.randomUUID().toString(); - KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool, 0); + final String primaryUuid = cmd.getPrimaryStoragePoolNameLabel(); + final KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), primaryUuid); + final String volUuid = UUID.randomUUID().toString(); + final KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool, 0); return new CreateVolumeFromSnapshotAnswer(cmd, true, "", disk.getName()); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { return new CreateVolumeFromSnapshotAnswer(cmd, false, e.toString(), null); } } @@ -2615,51 +2620,51 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) { - String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId(); - String templateInstallFolder = "template/tmpl/" + templateFolder; - String tmplName = UUID.randomUUID().toString(); - String tmplFileName = tmplName + ".qcow2"; + final String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplName = UUID.randomUUID().toString(); + final String tmplFileName = tmplName + ".qcow2"; KVMStoragePool secondaryPool = null; KVMStoragePool snapshotPool = null; try { String snapshotPath = cmd.getSnapshotUuid(); - int index = snapshotPath.lastIndexOf("/"); + final int index = snapshotPath.lastIndexOf("/"); snapshotPath = snapshotPath.substring(0, index); snapshotPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl() + snapshotPath); - KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(cmd.getSnapshotName()); + final KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(cmd.getSnapshotName()); secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl()); - String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + final String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; _storage.mkdirs(templatePath); - String tmplPath = templateInstallFolder + File.separator + tmplFileName; - Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger); + final String tmplPath = templateInstallFolder + File.separator + tmplFileName; + final Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger); command.add("-t", templatePath); command.add("-n", tmplFileName); command.add("-f", snapshot.getPath()); command.execute(); - Map params = new HashMap(); + final Map params = new HashMap(); params.put(StorageLayer.InstanceConfigKey, _storage); - Processor qcow2Processor = new QCOW2Processor(); + final Processor qcow2Processor = new QCOW2Processor(); qcow2Processor.configure("QCOW2 Processor", params); - FormatInfo info = qcow2Processor.process(templatePath, null, tmplName); + final FormatInfo info = qcow2Processor.process(templatePath, null, tmplName); - TemplateLocation loc = new TemplateLocation(_storage, templatePath); + final TemplateLocation loc = new TemplateLocation(_storage, templatePath); loc.create(1, true, tmplName); loc.addFormat(info); loc.save(); return new CreatePrivateTemplateAnswer(cmd, true, "", tmplPath, info.virtualSize, info.size, tmplName, info.format); - } catch (ConfigurationException e) { + } catch (final ConfigurationException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (IOException e) { + } catch (final IOException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); } finally { if (secondaryPool != null) { @@ -2673,27 +2678,27 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) { try { - KVMStoragePool sp = _storagePoolMgr.getStoragePool(cmd.getPooltype(), cmd.getStorageId(), true); + final KVMStoragePool sp = _storagePoolMgr.getStoragePool(cmd.getPooltype(), cmd.getStorageId(), true); return new GetStorageStatsAnswer(cmd, sp.getCapacity(), sp.getUsed()); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { return new GetStorageStatsAnswer(cmd, e.toString()); } } - protected CreatePrivateTemplateAnswer execute(CreatePrivateTemplateFromVolumeCommand cmd) { - String secondaryStorageURL = cmd.getSecondaryStorageUrl(); + protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromVolumeCommand cmd) { + final String secondaryStorageURL = cmd.getSecondaryStorageUrl(); KVMStoragePool secondaryStorage = null; KVMStoragePool primary = null; try { - String templateFolder = cmd.getAccountId() + File.separator + cmd.getTemplateId() + File.separator; - String templateInstallFolder = "/template/tmpl/" + templateFolder; + final String templateFolder = cmd.getAccountId() + File.separator + cmd.getTemplateId() + File.separator; + final String templateInstallFolder = "/template/tmpl/" + templateFolder; secondaryStorage = _storagePoolMgr.getStoragePoolByURI(secondaryStorageURL); try { primary = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPrimaryStoragePoolNameLabel()); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { if (e.getMessage().contains("not found")) { primary = _storagePoolMgr.createStoragePool(cmd.getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(), cmd.getPool().getPath(), @@ -2703,17 +2708,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); - String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateInstallFolder; + final KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); + final String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateInstallFolder; _storage.mkdirs(tmpltPath); if (primary.getType() != StoragePoolType.RBD) { - Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger); + final Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger); command.add("-f", disk.getPath()); command.add("-t", tmpltPath); command.add("-n", cmd.getUniqueName() + ".qcow2"); - String result = command.execute(); + final String result = command.execute(); if (result != null) { s_logger.debug("failed to create template: " + result); @@ -2722,65 +2727,65 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } else { s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + cmd.getUniqueName()); - QemuImgFile srcFile = + final QemuImgFile srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), primary.getSourcePort(), primary.getAuthUserName(), primary.getAuthSecret(), disk.getPath())); srcFile.setFormat(PhysicalDiskFormat.RAW); - QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + cmd.getUniqueName() + ".qcow2"); + final QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + cmd.getUniqueName() + ".qcow2"); destFile.setFormat(PhysicalDiskFormat.QCOW2); - QemuImg q = new QemuImg(0); + final QemuImg q = new QemuImg(0); try { q.convert(srcFile, destFile); - } catch (QemuImgException e) { + } catch (final QemuImgException e) { s_logger.error("Failed to create new template while converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage()); } - File templateProp = new File(tmpltPath + "/template.properties"); + final File templateProp = new File(tmpltPath + "/template.properties"); if (!templateProp.exists()) { templateProp.createNewFile(); } String templateContent = "filename=" + cmd.getUniqueName() + ".qcow2" + System.getProperty("line.separator"); - DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy"); - Date date = new Date(); + final DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy"); + final Date date = new Date(); templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator"); try(FileOutputStream templFo = new FileOutputStream(templateProp);) { templFo.write(templateContent.getBytes()); templFo.flush(); - }catch(IOException ex) + }catch(final IOException ex) { s_logger.error("CreatePrivateTemplateAnswer:Exception:"+ex.getMessage()); } } - Map params = new HashMap(); + final Map params = new HashMap(); params.put(StorageLayer.InstanceConfigKey, _storage); - Processor qcow2Processor = new QCOW2Processor(); + final Processor qcow2Processor = new QCOW2Processor(); qcow2Processor.configure("QCOW2 Processor", params); - FormatInfo info = qcow2Processor.process(tmpltPath, null, cmd.getUniqueName()); + final FormatInfo info = qcow2Processor.process(tmpltPath, null, cmd.getUniqueName()); - TemplateLocation loc = new TemplateLocation(_storage, tmpltPath); + final TemplateLocation loc = new TemplateLocation(_storage, tmpltPath); loc.create(1, true, cmd.getUniqueName()); loc.addFormat(info); loc.save(); return new CreatePrivateTemplateAnswer(cmd, true, null, templateInstallFolder + cmd.getUniqueName() + ".qcow2", info.virtualSize, info.size, cmd.getUniqueName(), ImageFormat.QCOW2); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); - } catch (IOException e) { + } catch (final IOException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); - } catch (ConfigurationException e) { + } catch (final ConfigurationException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); } finally { if (secondaryStorage != null) { @@ -2790,9 +2795,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } protected PrimaryStorageDownloadAnswer execute(final PrimaryStorageDownloadCommand cmd) { - String tmplturl = cmd.getUrl(); - int index = tmplturl.lastIndexOf("/"); - String mountpoint = tmplturl.substring(0, index); + final String tmplturl = cmd.getUrl(); + final int index = tmplturl.lastIndexOf("/"); + final String mountpoint = tmplturl.substring(0, index); String tmpltname = null; if (index < tmplturl.length() - 1) { tmpltname = tmplturl.substring(index + 1); @@ -2806,11 +2811,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /* Get template vol */ if (tmpltname == null) { secondaryPool.refresh(); - List disks = secondaryPool.listPhysicalDisks(); + final List disks = secondaryPool.listPhysicalDisks(); if (disks == null || disks.isEmpty()) { return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + secondaryPool.getUuid()); } - for (KVMPhysicalDisk disk : disks) { + for (final KVMPhysicalDisk disk : disks) { if (disk.getName().endsWith("qcow2")) { tmplVol = disk; break; @@ -2824,12 +2829,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } /* Copy volume to primary storage */ - KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPoolUuid()); + final KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPoolUuid()); - KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0); + final KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0); return new PrimaryStorageDownloadAnswer(primaryVol.getName(), primaryVol.getSize()); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { return new PrimaryStorageDownloadAnswer(e.toString()); } finally { if (secondaryPool != null) { @@ -2838,37 +2843,37 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected Answer execute(CreateStoragePoolCommand cmd) { + protected Answer execute(final CreateStoragePoolCommand cmd) { return new Answer(cmd, true, "success"); } - protected Answer execute(ModifyStoragePoolCommand cmd) { - KVMStoragePool storagepool = + protected Answer execute(final ModifyStoragePoolCommand cmd) { + final KVMStoragePool storagepool = _storagePoolMgr.createStoragePool(cmd.getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(), cmd.getPool().getPath(), cmd.getPool() .getUserInfo(), cmd.getPool().getType()); if (storagepool == null) { return new Answer(cmd, false, " Failed to create storage pool"); } - Map tInfo = new HashMap(); - ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, storagepool.getCapacity(), storagepool.getAvailable(), tInfo); + final Map tInfo = new HashMap(); + final ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, storagepool.getCapacity(), storagepool.getAvailable(), tInfo); return answer; } - private Answer execute(SecurityGroupRulesCmd cmd) { + private Answer execute(final SecurityGroupRulesCmd cmd) { String vif = null; String brname = null; try { - Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - List nics = getInterfaces(conn, cmd.getVmName()); + final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); + final List nics = getInterfaces(conn, cmd.getVmName()); vif = nics.get(0).getDevName(); brname = nics.get(0).getBrName(); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new SecurityGroupRuleAnswer(cmd, false, e.toString()); } - boolean result = + final boolean result = add_network_rules(cmd.getVmName(), Long.toString(cmd.getVmId()), cmd.getGuestIp(), cmd.getSignature(), Long.toString(cmd.getSeqNum()), cmd.getGuestMac(), cmd.stringifyRules(), vif, brname, cmd.getSecIpsString()); @@ -2882,17 +2887,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(CleanupNetworkRulesCmd cmd) { - boolean result = cleanup_rules(); + private Answer execute(final CleanupNetworkRulesCmd cmd) { + final boolean result = cleanup_rules(); return new Answer(cmd, result, ""); } - protected GetVncPortAnswer execute(GetVncPortCommand cmd) { + protected GetVncPortAnswer execute(final GetVncPortCommand cmd) { try { - Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getName()); - Integer vncPort = getVncPort(conn, cmd.getName()); + final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getName()); + final Integer vncPort = getVncPort(conn, cmd.getName()); return new GetVncPortAnswer(cmd, _privateIp, 5900 + vncPort); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new GetVncPortAnswer(cmd, e.toString()); } } @@ -2905,7 +2910,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); } - protected MaintainAnswer execute(MaintainCommand cmd) { + protected MaintainAnswer execute(final MaintainCommand cmd) { return new MaintainAnswer(cmd); } @@ -2947,54 +2952,54 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); } - private Answer execute(AttachIsoCommand cmd) { + private Answer execute(final AttachIsoCommand cmd) { try { - Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); + final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); attachOrDetachISO(conn, cmd.getVmName(), cmd.getIsoPath(), cmd.isAttach()); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new Answer(cmd, false, e.toString()); - } catch (URISyntaxException e) { + } catch (final URISyntaxException e) { return new Answer(cmd, false, e.toString()); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { return new Answer(cmd, false, e.toString()); } return new Answer(cmd); } - private AttachVolumeAnswer execute(AttachVolumeCommand cmd) { + private AttachVolumeAnswer execute(final AttachVolumeCommand cmd) { try { - Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd.getPooltype(), cmd.getPoolUuid()); - KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); + final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); + final KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd.getPooltype(), cmd.getPoolUuid()); + final KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk, cmd.getDeviceId().intValue(), cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate(), cmd.getCacheMode()); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new AttachVolumeAnswer(cmd, e.toString()); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { return new AttachVolumeAnswer(cmd, e.toString()); } return new AttachVolumeAnswer(cmd, cmd.getDeviceId(), cmd.getVolumePath()); } - private Answer execute(ReadyCommand cmd) { + private Answer execute(final ReadyCommand cmd) { return new ReadyAnswer(cmd); } - protected PowerState convertToPowerState(DomainState ps) { + protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; } - protected PowerState getVmState(Connect conn, final String vmName) { + protected PowerState getVmState(final Connect conn, final String vmName) { int retry = 3; Domain vms = null; while (retry-- > 0) { try { vms = conn.domainLookupByName(vmName); - PowerState s = convertToPowerState(vms.getInfo().state); + final PowerState s = convertToPowerState(vms.getInfo().state); return s; } catch (final LibvirtException e) { s_logger.warn("Can't get vm state " + vmName + e.getMessage() + "retry:" + retry); @@ -3011,9 +3016,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return PowerState.PowerOff; } - private Answer execute(CheckVirtualMachineCommand cmd) { + private Answer execute(final CheckVirtualMachineCommand cmd) { try { - Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); + final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); final PowerState state = getVmState(conn, cmd.getVmName()); Integer vncPort = null; if (state == PowerState.PowerOn) { @@ -3021,12 +3026,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } return new CheckVirtualMachineAnswer(cmd, state, vncPort); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new CheckVirtualMachineAnswer(cmd, e.getMessage()); } } - private Answer execute(PingTestCommand cmd) { + private Answer execute(final PingTestCommand cmd) { String result = null; final String computingHostIp = cmd.getComputingHostIp(); // TODO, split // the @@ -3061,8 +3066,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return command.execute(); } - private Answer execute(MigrateCommand cmd) { - String vmName = cmd.getVmName(); + private Answer execute(final MigrateCommand cmd) { + final String vmName = cmd.getVmName(); String result = null; @@ -3098,9 +3103,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv //run migration in thread so we can monitor it s_logger.info("Live migration of instance " + vmName + " initiated"); - ExecutorService executor = Executors.newFixedThreadPool(1); - Callable worker = new MigrateKVMAsync(dm, dconn, xmlDesc, vmName, cmd.getDestinationIp()); - Future migrateThread = executor.submit(worker); + final ExecutorService executor = Executors.newFixedThreadPool(1); + final Callable worker = new MigrateKVMAsync(dm, dconn, xmlDesc, vmName, cmd.getDestinationIp()); + final Future migrateThread = executor.submit(worker); executor.shutdown(); long sleeptime = 0; while (!executor.isTerminated()) { @@ -3109,16 +3114,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (sleeptime == 1000) { // wait 1s before attempting to set downtime on migration, since I don't know of a VIR_DOMAIN_MIGRATING state if (_migrateDowntime > 0 ) { try { - int setDowntime = dm.migrateSetMaxDowntime(_migrateDowntime); + final int setDowntime = dm.migrateSetMaxDowntime(_migrateDowntime); if (setDowntime == 0 ) { s_logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(_migrateDowntime) + "ms"); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage()); } } } - if ((sleeptime % 1000) == 0) { + if (sleeptime % 1000 == 0) { s_logger.info("Waiting for migration of " + vmName + " to complete, waited " + sleeptime + "ms"); } @@ -3127,7 +3132,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + _migratePauseAfter+ "ms to complete migration"); try { dm.suspend(); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { // pause could be racy if it attempts to pause right when vm is finished, simply warn s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage()); } @@ -3138,20 +3143,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv destDomain = migrateThread.get(10, TimeUnit.SECONDS); if (destDomain != null) { - for (DiskDef disk : disks) { + for (final DiskDef disk : disks) { cleanupDisk(disk); } } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Can't migrate domain: " + e.getMessage()); result = e.getMessage(); - } catch (InterruptedException e) { + } catch (final InterruptedException e) { s_logger.debug("Interrupted while migrating domain: " + e.getMessage()); result = e.getMessage(); - } catch (ExecutionException e) { + } catch (final ExecutionException e) { s_logger.debug("Failed to execute while migrating domain: " + e.getMessage()); result = e.getMessage(); - } catch (TimeoutException e) { + } catch (final TimeoutException e) { s_logger.debug("Timed out while migrating domain: " + e.getMessage()); result = e.getMessage(); } finally { @@ -3175,11 +3180,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (result != null) { } else { - destroy_network_rules_for_vm(conn, vmName); - for (InterfaceDef iface : ifaces) { + destroyNetworkRulesForVM(conn, vmName); + for (final InterfaceDef iface : ifaces) { // We don't know which "traffic type" is associated with // each interface at this point, so inform all vif drivers - for (VifDriver vifDriver : getAllVifDrivers()) { + for (final VifDriver vifDriver : getAllVifDrivers()) { vifDriver.unplug(iface); } } @@ -3195,7 +3200,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv String vmName = ""; String destIp = ""; - MigrateKVMAsync(Domain dm, Connect dconn, String dxml, String vmName, String destIp) { + MigrateKVMAsync(final Domain dm, final Connect dconn, final String dxml, final String vmName, final String destIp) { this.dm = dm; this.dconn = dconn; this.dxml = dxml; @@ -3207,33 +3212,33 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv public Domain call() throws LibvirtException { // set compression flag for migration if libvirt version supports it if (dconn.getLibVirVersion() < 1003000) { - return dm.migrate(dconn, (1 << 0), dxml, vmName, "tcp:" + destIp, _migrateSpeed); + return dm.migrate(dconn, 1 << 0, dxml, vmName, "tcp:" + destIp, _migrateSpeed); } else { - return dm.migrate(dconn, (1 << 0)|(1 << 11), dxml, vmName, "tcp:" + destIp, _migrateSpeed); + return dm.migrate(dconn, 1 << 0|1 << 11, dxml, vmName, "tcp:" + destIp, _migrateSpeed); } } } - private synchronized Answer execute(PrepareForMigrationCommand cmd) { + private synchronized Answer execute(final PrepareForMigrationCommand cmd) { - VirtualMachineTO vm = cmd.getVirtualMachine(); + final VirtualMachineTO vm = cmd.getVirtualMachine(); if (s_logger.isDebugEnabled()) { s_logger.debug("Preparing host for migrating " + vm); } - NicTO[] nics = vm.getNics(); + final NicTO[] nics = vm.getNics(); boolean skipDisconnect = false; try { - Connect conn = LibvirtConnection.getConnectionByVmName(vm.getName()); - for (NicTO nic : nics) { + final Connect conn = LibvirtConnection.getConnectionByVmName(vm.getName()); + for (final NicTO nic : nics) { getVifDriver(nic.getType()).plug(nic, null, ""); } /* setup disks, e.g for iso */ - DiskTO[] volumes = vm.getDisks(); - for (DiskTO volume : volumes) { + final DiskTO[] volumes = vm.getDisks(); + for (final DiskTO volume : volumes) { if (volume.getType() == Volume.Type.ISO) { getVolumePath(conn, volume); } @@ -3247,11 +3252,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv skipDisconnect = true; return new PrepareForMigrationAnswer(cmd); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new PrepareForMigrationAnswer(cmd, e.toString()); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { return new PrepareForMigrationAnswer(cmd, e.toString()); - } catch (URISyntaxException e) { + } catch (final URISyntaxException e) { return new PrepareForMigrationAnswer(cmd, e.toString()); } finally { if (!skipDisconnect) { @@ -3260,11 +3265,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(CheckHealthCommand cmd) { + private Answer execute(final CheckHealthCommand cmd) { return new CheckHealthAnswer(cmd, true); } - private Answer execute(GetHostStatsCommand cmd) { + private Answer execute(final GetHostStatsCommand cmd) { final Script cpuScript = new Script("/bin/bash", s_logger); cpuScript.add("-c"); cpuScript.add("idle=$(top -b -n 1| awk -F, '/^[%]*[Cc]pu/{$0=$4; gsub(/[^0-9.,]+/,\"\"); print }'); echo $idle"); @@ -3275,7 +3280,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.debug("Unable to get the host CPU state: " + result); return new Answer(cmd, false, result); } - double cpuUtil = (100.0D - Double.parseDouble(parser.getLine())); + final double cpuUtil = 100.0D - Double.parseDouble(parser.getLine()); long freeMem = 0; final Script memScript = new Script("/bin/bash", s_logger); @@ -3289,7 +3294,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } freeMem = Long.parseLong(Memparser.getLine()); - Script totalMem = new Script("/bin/bash", s_logger); + final Script totalMem = new Script("/bin/bash", s_logger); totalMem.add("-c"); totalMem.add("free|grep Mem:|awk '{print $2}'"); final OutputInterpreter.OneLineParser totMemparser = new OutputInterpreter.OneLineParser(); @@ -3298,16 +3303,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.debug("Unable to get the host Mem state: " + result); return new Answer(cmd, false, result); } - long totMem = Long.parseLong(totMemparser.getLine()); + final long totMem = Long.parseLong(totMemparser.getLine()); - Pair nicStats = getNicStats(_publicBridgeName); + final Pair nicStats = getNicStats(_publicBridgeName); - HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", totMem, freeMem, 0, 0); + final HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", totMem, freeMem, 0, 0); return new GetHostStatsAnswer(cmd, hostStats); } protected String networkUsage(final String privateIpAddress, final String option, final String vif) { - Script getUsage = new Script(_routerProxyPath, s_logger); + final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("netusage.sh"); getUsage.add(privateIpAddress); if (option.equals("get")) { @@ -3323,7 +3328,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser(); - String result = getUsage.execute(usageParser); + final String result = getUsage.execute(usageParser); if (result != null) { s_logger.debug("Failed to execute networkUsage:" + result); return null; @@ -3331,11 +3336,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return usageParser.getLine(); } - protected long[] getNetworkStats(String privateIP) { - String result = networkUsage(privateIP, "get", null); - long[] stats = new long[2]; + protected long[] getNetworkStats(final String privateIP) { + final String result = networkUsage(privateIP, "get", null); + final long[] stats = new long[2]; if (result != null) { - String[] splitResult = result.split(":"); + final String[] splitResult = result.split(":"); int i = 0; while (i < splitResult.length - 1) { stats[0] += Long.parseLong(splitResult[i++]); @@ -3346,7 +3351,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } protected String VPCNetworkUsage(final String privateIpAddress, final String publicIp, final String option, final String vpcCIDR) { - Script getUsage = new Script(_routerProxyPath, s_logger); + final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("vpc_netusage.sh"); getUsage.add(privateIpAddress); getUsage.add("-l", publicIp); @@ -3365,7 +3370,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser(); - String result = getUsage.execute(usageParser); + final String result = getUsage.execute(usageParser); if (result != null) { s_logger.debug("Failed to execute VPCNetworkUsage:" + result); return null; @@ -3373,11 +3378,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return usageParser.getLine(); } - protected long[] getVPCNetworkStats(String privateIP, String publicIp, String option) { - String result = VPCNetworkUsage(privateIP, publicIp, option, null); - long[] stats = new long[2]; + protected long[] getVPCNetworkStats(final String privateIP, final String publicIp, final String option) { + final String result = VPCNetworkUsage(privateIP, publicIp, option, null); + final long[] stats = new long[2]; if (result != null) { - String[] splitResult = result.split(":"); + final String[] splitResult = result.split(":"); int i = 0; while (i < splitResult.length - 1) { stats[0] += Long.parseLong(splitResult[i++]); @@ -3387,43 +3392,43 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return stats; } - private Answer execute(NetworkUsageCommand cmd) { + private Answer execute(final NetworkUsageCommand cmd) { if (cmd.isForVpc()) { if (cmd.getOption() != null && cmd.getOption().equals("create")) { - String result = VPCNetworkUsage(cmd.getPrivateIP(), cmd.getGatewayIP(), "create", cmd.getVpcCIDR()); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); + final String result = VPCNetworkUsage(cmd.getPrivateIP(), cmd.getGatewayIP(), "create", cmd.getVpcCIDR()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); return answer; } else if (cmd.getOption() != null && (cmd.getOption().equals("get") || cmd.getOption().equals("vpn"))) { - long[] stats = getVPCNetworkStats(cmd.getPrivateIP(), cmd.getGatewayIP(), cmd.getOption()); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); + final long[] stats = getVPCNetworkStats(cmd.getPrivateIP(), cmd.getGatewayIP(), cmd.getOption()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); return answer; } else { - String result = VPCNetworkUsage(cmd.getPrivateIP(), cmd.getGatewayIP(), cmd.getOption(), cmd.getVpcCIDR()); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); + final String result = VPCNetworkUsage(cmd.getPrivateIP(), cmd.getGatewayIP(), cmd.getOption(), cmd.getVpcCIDR()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); return answer; } } else { if (cmd.getOption() != null && cmd.getOption().equals("create")) { - String result = networkUsage(cmd.getPrivateIP(), "create", null); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); + final String result = networkUsage(cmd.getPrivateIP(), "create", null); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); return answer; } - long[] stats = getNetworkStats(cmd.getPrivateIP()); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); + final long[] stats = getNetworkStats(cmd.getPrivateIP()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); return answer; } } - private Answer execute(RebootCommand cmd) { + private Answer execute(final RebootCommand cmd) { try { - Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); + final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); final String result = rebootVM(conn, cmd.getVmName()); if (result == null) { Integer vncPort = null; try { vncPort = getVncPort(conn, cmd.getVmName()); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } get_rule_logs_for_vms(); @@ -3431,13 +3436,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } else { return new RebootAnswer(cmd, result, false); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new RebootAnswer(cmd, e.getMessage(), false); } } - protected Answer execute(RebootRouterCommand cmd) { - RebootAnswer answer = (RebootAnswer)execute((RebootCommand)cmd); + protected Answer execute(final RebootRouterCommand cmd) { + final RebootAnswer answer = (RebootAnswer)execute((RebootCommand)cmd); if (_virtRouterResource.connect(cmd.getPrivateIpAddress())) { networkUsage(cmd.getPrivateIpAddress(), "create", null); return answer; @@ -3446,13 +3451,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected GetVmDiskStatsAnswer execute(GetVmDiskStatsCommand cmd) { - List vmNames = cmd.getVmNames(); + protected GetVmDiskStatsAnswer execute(final GetVmDiskStatsCommand cmd) { + final List vmNames = cmd.getVmNames(); try { - HashMap> vmDiskStatsNameMap = new HashMap>(); - Connect conn = LibvirtConnection.getConnection(); - for (String vmName : vmNames) { - List statEntry = getVmDiskStat(conn, vmName); + final HashMap> vmDiskStatsNameMap = new HashMap>(); + final Connect conn = LibvirtConnection.getConnection(); + for (final String vmName : vmNames) { + final List statEntry = getVmDiskStat(conn, vmName); if (statEntry == null) { continue; } @@ -3460,19 +3465,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vmDiskStatsNameMap.put(vmName, statEntry); } return new GetVmDiskStatsAnswer(cmd, "", cmd.getHostName(), vmDiskStatsNameMap); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Can't get vm disk stats: " + e.toString()); return new GetVmDiskStatsAnswer(cmd, null, null, null); } } - protected GetVmStatsAnswer execute(GetVmStatsCommand cmd) { - List vmNames = cmd.getVmNames(); + protected GetVmStatsAnswer execute(final GetVmStatsCommand cmd) { + final List vmNames = cmd.getVmNames(); try { - HashMap vmStatsNameMap = new HashMap(); - for (String vmName : vmNames) { - Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - VmStatsEntry statEntry = getVmStat(conn, vmName); + final HashMap vmStatsNameMap = new HashMap(); + for (final String vmName : vmNames) { + final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + final VmStatsEntry statEntry = getVmStat(conn, vmName); if (statEntry == null) { continue; } @@ -3480,60 +3485,60 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vmStatsNameMap.put(vmName, statEntry); } return new GetVmStatsAnswer(cmd, vmStatsNameMap); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Can't get vm stats: " + e.toString()); return new GetVmStatsAnswer(cmd, null); } } - protected Answer execute(StopCommand cmd) { + protected Answer execute(final StopCommand cmd) { final String vmName = cmd.getVmName(); if (cmd.checkBeforeCleanup()) { try { - Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - Domain vm = conn.domainLookupByName(cmd.getVmName()); + final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + final Domain vm = conn.domainLookupByName(cmd.getVmName()); if (vm != null && vm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING) { return new StopAnswer(cmd, "vm is still running on host", false); } - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to get vm status in case of checkboforecleanup is true", e); } } try { - Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - List disks = getDisks(conn, vmName); - List ifaces = getInterfaces(conn, vmName); + final List disks = getDisks(conn, vmName); + final List ifaces = getInterfaces(conn, vmName); - destroy_network_rules_for_vm(conn, vmName); - String result = stopVM(conn, vmName); + destroyNetworkRulesForVM(conn, vmName); + final String result = stopVM(conn, vmName); if (result == null) { - for (DiskDef disk : disks) { + for (final DiskDef disk : disks) { cleanupDisk(disk); } - for (InterfaceDef iface : ifaces) { + for (final InterfaceDef iface : ifaces) { // We don't know which "traffic type" is associated with // each interface at this point, so inform all vif drivers - for (VifDriver vifDriver : getAllVifDrivers()) { + for (final VifDriver vifDriver : getAllVifDrivers()) { vifDriver.unplug(iface); } } } return new StopAnswer(cmd, result, true); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { return new StopAnswer(cmd, e.getMessage(), false); } } - protected Answer execute(ModifySshKeysCommand cmd) { - File sshKeysDir = new File(SSHKEYSPATH); + protected Answer execute(final ModifySshKeysCommand cmd) { + final File sshKeysDir = new File(SSHKEYSPATH); String result = null; if (!sshKeysDir.exists()) { // Change permissions for the 700 - Script script = new Script("mkdir", _timeout, s_logger); + final Script script = new Script("mkdir", _timeout, s_logger); script.add("-m", "700"); script.add(SSHKEYSPATH); script.execute(); @@ -3543,11 +3548,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - File pubKeyFile = new File(SSHPUBKEYPATH); + final File pubKeyFile = new File(SSHPUBKEYPATH); if (!pubKeyFile.exists()) { try { pubKeyFile.createNewFile(); - } catch (IOException e) { + } catch (final IOException e) { result = "Failed to create file: " + e.toString(); s_logger.debug(result); } @@ -3556,40 +3561,40 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (pubKeyFile.exists()) { try (FileOutputStream pubkStream = new FileOutputStream(pubKeyFile)) { pubkStream.write(cmd.getPubKey().getBytes()); - } catch (FileNotFoundException e) { + } catch (final FileNotFoundException e) { result = "File" + SSHPUBKEYPATH + "is not found:" + e.toString(); s_logger.debug(result); - } catch (IOException e) { + } catch (final IOException e) { result = "Write file " + SSHPUBKEYPATH + ":" + e.toString(); s_logger.debug(result); } } - File prvKeyFile = new File(SSHPRVKEYPATH); + final File prvKeyFile = new File(SSHPRVKEYPATH); if (!prvKeyFile.exists()) { try { prvKeyFile.createNewFile(); - } catch (IOException e) { + } catch (final IOException e) { result = "Failed to create file: " + e.toString(); s_logger.debug(result); } } if (prvKeyFile.exists()) { - String prvKey = cmd.getPrvKey(); + final String prvKey = cmd.getPrvKey(); try (FileOutputStream prvKStream = new FileOutputStream(prvKeyFile);){ if ( prvKStream != null) { prvKStream.write(prvKey.getBytes()); } - } catch (FileNotFoundException e) { + } catch (final FileNotFoundException e) { result = "File" + SSHPRVKEYPATH + "is not found:" + e.toString(); s_logger.debug(result); - } catch (IOException e) { + } catch (final IOException e) { result = "Write file " + SSHPRVKEYPATH + ":" + e.toString(); s_logger.debug(result); } - Script script = new Script("chmod", _timeout, s_logger); + final Script script = new Script("chmod", _timeout, s_logger); script.add("600", SSHPRVKEYPATH); script.execute(); } @@ -3601,7 +3606,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected void handleVmStartFailure(Connect conn, String vmName, LibvirtVMDef vm) { + protected void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVMDef vm) { if (vm != null && vm.getDevices() != null) { cleanupVMNetworks(conn, vm.getDevices().getInterfaces()); } @@ -3612,12 +3617,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv uuid = UUID.randomUUID().toString(); } else { try { - UUID uuid2 = UUID.fromString(uuid); - String uuid3 = uuid2.toString(); + final UUID uuid2 = UUID.fromString(uuid); + final String uuid3 = uuid2.toString(); if (!uuid3.equals(uuid)) { uuid = UUID.randomUUID().toString(); } - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { uuid = UUID.randomUUID().toString(); } } @@ -3625,25 +3630,25 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } private void getOsVersion() { - String version = Script.runSimpleBashScript("cat /etc/redhat-release | awk '{print $7}'"); + final String version = Script.runSimpleBashScript("cat /etc/redhat-release | awk '{print $7}'"); if (version != null) { - String[] versions = version.split("\\."); + final String[] versions = version.split("\\."); if (versions.length == 2) { - String major = versions[0]; - String minor = versions[1]; + final String major = versions[0]; + final String minor = versions[1]; try { - Integer m = Integer.parseInt(major); - Integer min = Integer.parseInt(minor); + final Integer m = Integer.parseInt(major); + final Integer min = Integer.parseInt(minor); hostOsVersion = new Pair<>(m, min); - } catch(NumberFormatException e) { + } catch(final NumberFormatException e) { } } } } - protected LibvirtVMDef createVMFromSpec(VirtualMachineTO vmTO) { - LibvirtVMDef vm = new LibvirtVMDef(); + protected LibvirtVMDef createVMFromSpec(final VirtualMachineTO vmTO) { + final LibvirtVMDef vm = new LibvirtVMDef(); vm.setDomainName(vmTO.getName()); String uuid = vmTO.getUuid(); uuid = getUuid(uuid); @@ -3651,7 +3656,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vm.setDomDescription(vmTO.getOs()); vm.setPlatformEmulator(vmTO.getPlatformEmulator()); - GuestDef guest = new GuestDef(); + final GuestDef guest = new GuestDef(); if (HypervisorType.LXC == _hypervisorType && VirtualMachine.Type.User == vmTO.getType()) { // LXC domain is only valid for user VMs. Use KVM for system VMs. @@ -3670,7 +3675,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vm.addComp(guest); - GuestResourceDef grd = new GuestResourceDef(); + final GuestResourceDef grd = new GuestResourceDef(); if (vmTO.getMinRam() != vmTO.getMaxRam() && !_noMemBalloon) { grd.setMemBalloning(true); @@ -3679,11 +3684,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } else { grd.setMemorySize(vmTO.getMaxRam() / 1024); } - int vcpus = vmTO.getCpus(); + final int vcpus = vmTO.getCpus(); grd.setVcpuNum(vcpus); vm.addComp(grd); - CpuModeDef cmd = new CpuModeDef(); + final CpuModeDef cmd = new CpuModeDef(); cmd.setMode(_guestCpuMode); cmd.setModel(_guestCpuModel); if (vmTO.getType() == VirtualMachine.Type.User) { @@ -3691,16 +3696,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } // multi cores per socket, for larger core configs if (vcpus % 6 == 0) { - int sockets = vcpus / 6; + final int sockets = vcpus / 6; cmd.setTopology(6, sockets); } else if (vcpus % 4 == 0) { - int sockets = vcpus / 4; + final int sockets = vcpus / 4; cmd.setTopology(4, sockets); } vm.addComp(cmd); if (_hypervisorLibvirtVersion >= 9000) { - CpuTuneDef ctd = new CpuTuneDef(); + final CpuTuneDef ctd = new CpuTuneDef(); /** A 4.0.X/4.1.X management server doesn't send the correct JSON command for getMinSpeed, it only sends a 'speed' field. @@ -3719,7 +3724,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vm.addComp(ctd); } - FeaturesDef features = new FeaturesDef(); + final FeaturesDef features = new FeaturesDef(); features.addFeatures("pae"); features.addFeatures("apic"); features.addFeatures("acpi"); @@ -3733,48 +3738,48 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv */ vm.addComp(features); - TermPolicy term = new TermPolicy(); + final TermPolicy term = new TermPolicy(); term.setCrashPolicy("destroy"); term.setPowerOffPolicy("destroy"); term.setRebootPolicy("restart"); vm.addComp(term); - ClockDef clock = new ClockDef(); + final ClockDef clock = new ClockDef(); if (vmTO.getOs().startsWith("Windows")) { clock.setClockOffset(ClockDef.ClockOffset.LOCALTIME); clock.setTimer("rtc", "catchup", null); } else if (vmTO.getType() != VirtualMachine.Type.User || isGuestPVEnabled(vmTO.getOs())) { - if (_hypervisorLibvirtVersion >= (9 * 1000 + 10)) { + if (_hypervisorLibvirtVersion >= 9 * 1000 + 10) { clock.setTimer("kvmclock", null, null, _noKvmClock); } } vm.addComp(clock); - DevicesDef devices = new DevicesDef(); + final DevicesDef devices = new DevicesDef(); devices.setEmulatorPath(_hypervisorPath); devices.setGuestType(guest.getGuestType()); - SerialDef serial = new SerialDef("pty", null, (short)0); + final SerialDef serial = new SerialDef("pty", null, (short)0); devices.addDevice(serial); if (vmTO.getType() != VirtualMachine.Type.User) { - VirtioSerialDef vserial = new VirtioSerialDef(vmTO.getName(), null); + final VirtioSerialDef vserial = new VirtioSerialDef(vmTO.getName(), null); devices.addDevice(vserial); } - VideoDef videoCard = new VideoDef(_videoHw, _videoRam); + final VideoDef videoCard = new VideoDef(_videoHw, _videoRam); devices.addDevice(videoCard); - ConsoleDef console = new ConsoleDef("pty", null, null, (short)0); + final ConsoleDef console = new ConsoleDef("pty", null, null, (short)0); devices.addDevice(console); //add the VNC port passwd here, get the passwd from the vmInstance. - String passwd = vmTO.getVncPassword(); - GraphicDef grap = new GraphicDef("vnc", (short)0, true, vmTO.getVncAddr(), passwd, null); + final String passwd = vmTO.getVncPassword(); + final GraphicDef grap = new GraphicDef("vnc", (short)0, true, vmTO.getVncAddr(), passwd, null); devices.addDevice(grap); - InputDef input = new InputDef("tablet", "usb"); + final InputDef input = new InputDef("tablet", "usb"); devices.addDevice(input); vm.addComp(devices); @@ -3782,15 +3787,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return vm; } - protected void createVifs(VirtualMachineTO vmSpec, LibvirtVMDef vm) throws InternalErrorException, LibvirtException { - NicTO[] nics = vmSpec.getNics(); - Map params = vmSpec.getDetails(); + protected void createVifs(final VirtualMachineTO vmSpec, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException { + final NicTO[] nics = vmSpec.getNics(); + final Map params = vmSpec.getDetails(); String nicAdapter = ""; if (params != null && params.get("nicAdapter") != null && !params.get("nicAdapter").isEmpty()) { nicAdapter = params.get("nicAdapter"); } for (int i = 0; i < nics.length; i++) { - for (NicTO nic : vmSpec.getNics()) { + for (final NicTO nic : vmSpec.getNics()) { if (nic.getDeviceId() == i) { createVif(vm, nic, nicAdapter); } @@ -3798,18 +3803,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected StartAnswer execute(StartCommand cmd) { - VirtualMachineTO vmSpec = cmd.getVirtualMachine(); + protected StartAnswer execute(final StartCommand cmd) { + final VirtualMachineTO vmSpec = cmd.getVirtualMachine(); vmSpec.setVncAddr(cmd.getHostIp()); - String vmName = vmSpec.getName(); + final String vmName = vmSpec.getName(); LibvirtVMDef vm = null; DomainState state = DomainState.VIR_DOMAIN_SHUTOFF; Connect conn = null; try { - NicTO[] nics = vmSpec.getNics(); + final NicTO[] nics = vmSpec.getNics(); - for (NicTO nic : nics) { + for (final NicTO nic : nics) { if (vmSpec.getType() != VirtualMachine.Type.User) { nic.setPxeDisable(true); } @@ -3830,17 +3835,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.debug("starting " + vmName + ": " + vm.toString()); startVM(conn, vmName, vm.toString()); - for (NicTO nic : nics) { - if (nic.isSecurityGroupEnabled() || (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString()))) { + for (final NicTO nic : nics) { + if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { if (vmSpec.getType() != VirtualMachine.Type.User) { default_network_rules_for_systemvm(conn, vmName); break; } else { - List nicSecIps = nic.getNicSecIps(); + final List nicSecIps = nic.getNicSecIps(); String secIpsStr; - StringBuilder sb = new StringBuilder(); + final StringBuilder sb = new StringBuilder(); if (nicSecIps != null) { - for (String ip : nicSecIps) { + for (final String ip : nicSecIps) { sb.append(ip).append(":"); } secIpsStr = sb.toString(); @@ -3856,7 +3861,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (vmSpec.getType() != VirtualMachine.Type.User) { //wait and try passCmdLine for 5 minutes at most for CLOUDSTACK-2823 String controlIp = null; - for (NicTO nic : nics) { + for (final NicTO nic : nics) { if (nic.getType() == TrafficType.Control) { controlIp = nic.getIp(); break; @@ -3865,7 +3870,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv for (int count = 0; count < 30; count++) { passCmdLine(vmName, vmSpec.getBootArgs()); //check router is up? - boolean result = _virtRouterResource.connect(controlIp, 1, 5000); + final boolean result = _virtRouterResource.connect(controlIp, 1, 5000); if (result) { break; } @@ -3874,19 +3879,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv state = DomainState.VIR_DOMAIN_RUNNING; return new StartAnswer(cmd); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.warn("LibvirtException ", e); if (conn != null) { handleVmStartFailure(conn, vmName, vm); } return new StartAnswer(cmd, e.getMessage()); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { s_logger.warn("InternalErrorException ", e); if (conn != null) { handleVmStartFailure(conn, vmName, vm); } return new StartAnswer(cmd, e.getMessage()); - } catch (URISyntaxException e) { + } catch (final URISyntaxException e) { s_logger.warn("URISyntaxException ", e); if (conn != null) { handleVmStartFailure(conn, vmName, vm); @@ -3899,47 +3904,47 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private String getVolumePath(Connect conn, DiskTO volume) throws LibvirtException, URISyntaxException { - DataTO data = volume.getData(); - DataStoreTO store = data.getDataStore(); + private String getVolumePath(final Connect conn, final DiskTO volume) throws LibvirtException, URISyntaxException { + final DataTO data = volume.getData(); + final DataStoreTO store = data.getDataStore(); if (volume.getType() == Volume.Type.ISO && data.getPath() != null) { - NfsTO nfsStore = (NfsTO)store; - String isoPath = nfsStore.getUrl() + File.separator + data.getPath(); - int index = isoPath.lastIndexOf("/"); - String path = isoPath.substring(0, index); - String name = isoPath.substring(index + 1); - KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(path); - KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name); + final NfsTO nfsStore = (NfsTO)store; + final String isoPath = nfsStore.getUrl() + File.separator + data.getPath(); + final int index = isoPath.lastIndexOf("/"); + final String path = isoPath.substring(0, index); + final String name = isoPath.substring(index + 1); + final KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(path); + final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name); return isoVol.getPath(); } else { return data.getPath(); } } - protected void createVbd(Connect conn, VirtualMachineTO vmSpec, String vmName, LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException { - List disks = Arrays.asList(vmSpec.getDisks()); + protected void createVbd(final Connect conn, final VirtualMachineTO vmSpec, final String vmName, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException { + final List disks = Arrays.asList(vmSpec.getDisks()); Collections.sort(disks, new Comparator() { @Override - public int compare(DiskTO arg0, DiskTO arg1) { + public int compare(final DiskTO arg0, final DiskTO arg1) { return arg0.getDiskSeq() > arg1.getDiskSeq() ? 1 : -1; } }); - for (DiskTO volume : disks) { + for (final DiskTO volume : disks) { KVMPhysicalDisk physicalDisk = null; KVMStoragePool pool = null; - DataTO data = volume.getData(); + final DataTO data = volume.getData(); if (volume.getType() == Volume.Type.ISO && data.getPath() != null) { - NfsTO nfsStore = (NfsTO)data.getDataStore(); - String volPath = nfsStore.getUrl() + File.separator + data.getPath(); - int index = volPath.lastIndexOf("/"); - String volDir = volPath.substring(0, index); - String volName = volPath.substring(index + 1); - KVMStoragePool secondaryStorage = _storagePoolMgr.getStoragePoolByURI(volDir); + final NfsTO nfsStore = (NfsTO)data.getDataStore(); + final String volPath = nfsStore.getUrl() + File.separator + data.getPath(); + final int index = volPath.lastIndexOf("/"); + final String volDir = volPath.substring(0, index); + final String volName = volPath.substring(index + 1); + final KVMStoragePool secondaryStorage = _storagePoolMgr.getStoragePoolByURI(volDir); physicalDisk = secondaryStorage.getPhysicalDisk(volName); } else if (volume.getType() != Volume.Type.ISO) { - PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore(); + final PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore(); physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath()); pool = physicalDisk.getPool(); } @@ -3951,11 +3956,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv // if params contains a rootDiskController key, use its value (this is what other HVs are doing) DiskDef.diskBus diskBusType = null; - Map params = vmSpec.getDetails(); + final Map params = vmSpec.getDetails(); if (params != null && params.get("rootDiskController") != null && !params.get("rootDiskController").isEmpty()) { - String rootDiskController = params.get("rootDiskController"); + final String rootDiskController = params.get("rootDiskController"); s_logger.debug("Passed custom disk bus " + rootDiskController); - for (DiskDef.diskBus bus : DiskDef.diskBus.values()) { + for (final DiskDef.diskBus bus : DiskDef.diskBus.values()) { if (bus.toString().equalsIgnoreCase(rootDiskController)) { s_logger.debug("Found matching enum for disk bus " + rootDiskController); diskBusType = bus; @@ -3967,7 +3972,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (diskBusType == null) { diskBusType = getGuestDiskModel(vmSpec.getPlatformEmulator()); } - DiskDef disk = new DiskDef(); + final DiskDef disk = new DiskDef(); if (volume.getType() == Volume.Type.ISO) { if (volPath == null) { /* Add iso as placeholder */ @@ -3976,7 +3981,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv disk.defISODisk(volPath); } } else { - int devId = volume.getDiskSeq().intValue(); + final int devId = volume.getDiskSeq().intValue(); if (pool.getType() == StoragePoolType.RBD) { /* @@ -3987,9 +3992,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv disk.defNetworkBasedDisk(physicalDisk.getPath().replace("rbd:", ""), pool.getSourceHost(), pool.getSourcePort(), pool.getAuthUserName(), pool.getUuid(), devId, diskBusType, diskProtocol.RBD, DiskDef.diskFmtType.RAW); } else if (pool.getType() == StoragePoolType.Gluster) { - String mountpoint = pool.getLocalPath(); - String path = physicalDisk.getPath(); - String glusterVolume = pool.getSourceDir().replace("/", ""); + final String mountpoint = pool.getLocalPath(); + final String path = physicalDisk.getPath(); + final String glusterVolume = pool.getSourceDir().replace("/", ""); disk.defNetworkBasedDisk(glusterVolume + path.replace(mountpoint, ""), pool.getSourceHost(), pool.getSourcePort(), null, null, devId, diskBusType, diskProtocol.GLUSTER, DiskDef.diskFmtType.QCOW2); } else if (pool.getType() == StoragePoolType.CLVM || physicalDisk.getFormat() == PhysicalDiskFormat.RAW) { @@ -4006,24 +4011,29 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } if (data instanceof VolumeObjectTO) { - VolumeObjectTO volumeObjectTO = (VolumeObjectTO)data; - if ((volumeObjectTO.getBytesReadRate() != null) && (volumeObjectTO.getBytesReadRate() > 0)) + final VolumeObjectTO volumeObjectTO = (VolumeObjectTO)data; + if (volumeObjectTO.getBytesReadRate() != null && volumeObjectTO.getBytesReadRate() > 0) { disk.setBytesReadRate(volumeObjectTO.getBytesReadRate()); - if ((volumeObjectTO.getBytesWriteRate() != null) && (volumeObjectTO.getBytesWriteRate() > 0)) + } + if (volumeObjectTO.getBytesWriteRate() != null && volumeObjectTO.getBytesWriteRate() > 0) { disk.setBytesWriteRate(volumeObjectTO.getBytesWriteRate()); - if ((volumeObjectTO.getIopsReadRate() != null) && (volumeObjectTO.getIopsReadRate() > 0)) + } + if (volumeObjectTO.getIopsReadRate() != null && volumeObjectTO.getIopsReadRate() > 0) { disk.setIopsReadRate(volumeObjectTO.getIopsReadRate()); - if ((volumeObjectTO.getIopsWriteRate() != null) && (volumeObjectTO.getIopsWriteRate() > 0)) + } + if (volumeObjectTO.getIopsWriteRate() != null && volumeObjectTO.getIopsWriteRate() > 0) { disk.setIopsWriteRate(volumeObjectTO.getIopsWriteRate()); - if (volumeObjectTO.getCacheMode() != null) + } + if (volumeObjectTO.getCacheMode() != null) { disk.setCacheMode(DiskDef.diskCacheMode.valueOf(volumeObjectTO.getCacheMode().toString().toUpperCase())); + } } vm.getDevices().addDevice(disk); } if (vmSpec.getType() != VirtualMachine.Type.User) { if (_sysvmISOPath != null) { - DiskDef iso = new DiskDef(); + final DiskDef iso = new DiskDef(); iso.defISODisk(_sysvmISOPath); vm.getDevices().addDevice(iso); } @@ -4031,22 +4041,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv // For LXC, find and add the root filesystem, rbd data disks if (HypervisorType.LXC.toString().toLowerCase().equals(vm.getHvsType())) { - for (DiskTO volume : disks) { - DataTO data = volume.getData(); - PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore(); + for (final DiskTO volume : disks) { + final DataTO data = volume.getData(); + final PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore(); if (volume.getType() == Volume.Type.ROOT) { - KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath()); - FilesystemDef rootFs = new FilesystemDef(physicalDisk.getPath(), "/"); + final KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath()); + final FilesystemDef rootFs = new FilesystemDef(physicalDisk.getPath(), "/"); vm.getDevices().addDevice(rootFs); } else if (volume.getType() == Volume.Type.DATADISK) { - KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath()); - KVMStoragePool pool = physicalDisk.getPool(); + final KVMPhysicalDisk physicalDisk = _storagePoolMgr.getPhysicalDisk(store.getPoolType(), store.getUuid(), data.getPath()); + final KVMStoragePool pool = physicalDisk.getPool(); if(StoragePoolType.RBD.equals(pool.getType())) { - int devId = volume.getDiskSeq().intValue(); - String device = mapRbdDevice(physicalDisk); + final int devId = volume.getDiskSeq().intValue(); + final String device = mapRbdDevice(physicalDisk); if (device != null) { s_logger.debug("RBD device on host is: " + device); - DiskDef diskdef = new DiskDef(); + final DiskDef diskdef = new DiskDef(); diskdef.defBlockBasedDisk(device, devId, DiskDef.diskBus.VIRTIO); diskdef.setQemuDriver(false); vm.getDevices().addDevice(diskdef); @@ -4060,14 +4070,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } - private void createVif(LibvirtVMDef vm, NicTO nic, String nicAdapter) throws InternalErrorException, LibvirtException { + private void createVif(final LibvirtVMDef vm, final NicTO nic, final String nicAdapter) throws InternalErrorException, LibvirtException { vm.getDevices().addDevice(getVifDriver(nic.getType()).plug(nic, vm.getPlatformEmulator().toString(), nicAdapter).toString()); } - protected CheckSshAnswer execute(CheckSshCommand cmd) { - String vmName = cmd.getName(); - String privateIp = cmd.getIp(); - int cmdPort = cmd.getPort(); + protected CheckSshAnswer execute(final CheckSshCommand cmd) { + final String vmName = cmd.getName(); + final String privateIp = cmd.getIp(); + final int cmdPort = cmd.getPort(); if (s_logger.isDebugEnabled()) { s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); @@ -4084,8 +4094,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new CheckSshAnswer(cmd); } - public boolean cleanupDisk(DiskDef disk) { - String path = disk.getDiskPath(); + public boolean cleanupDisk(final DiskDef disk) { + final String path = disk.getDiskPath(); if (path == null) { s_logger.debug("Unable to clean up disk with null path (perhaps empty cdrom drive):" + disk); @@ -4104,30 +4114,30 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _storagePoolMgr; } - protected synchronized String attachOrDetachISO(Connect conn, String vmName, String isoPath, boolean isAttach) throws LibvirtException, URISyntaxException, + protected synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach) throws LibvirtException, URISyntaxException, InternalErrorException { String isoXml = null; if (isoPath != null && isAttach) { - int index = isoPath.lastIndexOf("/"); - String path = isoPath.substring(0, index); - String name = isoPath.substring(index + 1); - KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(path); - KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name); + final int index = isoPath.lastIndexOf("/"); + final String path = isoPath.substring(0, index); + final String name = isoPath.substring(index + 1); + final KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(path); + final KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name); isoPath = isoVol.getPath(); - DiskDef iso = new DiskDef(); + final DiskDef iso = new DiskDef(); iso.defISODisk(isoPath); isoXml = iso.toString(); } else { - DiskDef iso = new DiskDef(); + final DiskDef iso = new DiskDef(); iso.defISODisk(null); isoXml = iso.toString(); } - List disks = getDisks(conn, vmName); - String result = attachOrDetachDevice(conn, true, vmName, isoXml); + final List disks = getDisks(conn, vmName); + final String result = attachOrDetachDevice(conn, true, vmName, isoXml); if (result == null && !isAttach) { - for (DiskDef disk : disks) { + for (final DiskDef disk : disks) { if (disk.getDeviceType() == DiskDef.deviceType.CDROM) { cleanupDisk(disk); } @@ -4137,23 +4147,23 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return result; } - protected synchronized String attachOrDetachDisk(Connect conn, - boolean attach, String vmName, KVMPhysicalDisk attachingDisk, - int devId, Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate, String cacheMode) throws LibvirtException, InternalErrorException { + protected synchronized String attachOrDetachDisk(final Connect conn, + final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, + final int devId, final Long bytesReadRate, final Long bytesWriteRate, final Long iopsReadRate, final Long iopsWriteRate, final String cacheMode) throws LibvirtException, InternalErrorException { List disks = null; Domain dm = null; DiskDef diskdef = null; - KVMStoragePool attachingPool = attachingDisk.getPool(); + final KVMStoragePool attachingPool = attachingDisk.getPool(); try { if (!attach) { dm = conn.domainLookupByName(vmName); - LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); - String xml = dm.getXMLDesc(0); + final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + final String xml = dm.getXMLDesc(0); parser.parseDomainXML(xml); disks = parser.getDisks(); - for (DiskDef disk : disks) { - String file = disk.getDiskPath(); + for (final DiskDef disk : disks) { + final String file = disk.getDiskPath(); if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) { diskdef = disk; break; @@ -4175,21 +4185,25 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) { diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, DiskDef.diskBus.VIRTIO); } - if ((bytesReadRate != null) && (bytesReadRate > 0)) + if (bytesReadRate != null && bytesReadRate > 0) { diskdef.setBytesReadRate(bytesReadRate); - if ((bytesWriteRate != null) && (bytesWriteRate > 0)) + } + if (bytesWriteRate != null && bytesWriteRate > 0) { diskdef.setBytesWriteRate(bytesWriteRate); - if ((iopsReadRate != null) && (iopsReadRate > 0)) + } + if (iopsReadRate != null && iopsReadRate > 0) { diskdef.setIopsReadRate(iopsReadRate); - if ((iopsWriteRate != null) && (iopsWriteRate > 0)) + } + if (iopsWriteRate != null && iopsWriteRate > 0) { diskdef.setIopsWriteRate(iopsWriteRate); + } if (cacheMode != null) { diskdef.setCacheMode(DiskDef.diskCacheMode.valueOf(cacheMode.toUpperCase())); } } - String xml = diskdef.toString(); + final String xml = diskdef.toString(); return attachOrDetachDevice(conn, attach, vmName, xml); } finally { if (dm != null) { @@ -4198,7 +4212,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected synchronized String attachOrDetachDevice(Connect conn, boolean attach, String vmName, String xml) throws LibvirtException, InternalErrorException { + protected synchronized String attachOrDetachDevice(final Connect conn, final boolean attach, final String vmName, final String xml) throws LibvirtException, InternalErrorException { Domain dm = null; try { dm = conn.domainLookupByName(vmName); @@ -4209,7 +4223,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.debug("Detaching device: " + xml); dm.detachDevice(xml); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { if (attach) { s_logger.warn("Failed to attach device to " + vmName + ": " + e.getMessage()); } else { @@ -4220,7 +4234,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { try { dm.free(); - } catch (LibvirtException l) { + } catch (final LibvirtException l) { s_logger.trace("Ignoring libvirt error.", l); } } @@ -4230,12 +4244,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } @Override - public PingCommand getCurrentStatus(long id) { + public PingCommand getCurrentStatus(final long id) { if (!_canBridgeFirewall) { return new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id, this.getHostVmStateReport()); } else { - HashMap> nwGrpStates = syncNetworkGroups(id); + final HashMap> nwGrpStates = syncNetworkGroups(id); return new PingRoutingWithNwGroupsCommand(getType(), id, this.getHostVmStateReport(), nwGrpStates); } } @@ -4247,8 +4261,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private Map getVersionStrings() { final Script command = new Script(_versionstringpath, _timeout, s_logger); - KeyValueInterpreter kvi = new KeyValueInterpreter(); - String result = command.execute(kvi); + final KeyValueInterpreter kvi = new KeyValueInterpreter(); + final String result = command.execute(kvi); if (result == null) { return kvi.getKeyValues(); } else { @@ -4276,8 +4290,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv StartupStorageCommand sscmd = null; try { - KVMStoragePool localStoragePool = _storagePoolMgr.createStoragePool(_localStorageUUID, "localhost", -1, _localStoragePath, "", StoragePoolType.Filesystem); - com.cloud.agent.api.StoragePoolInfo pi = + final KVMStoragePool localStoragePool = _storagePoolMgr.createStoragePool(_localStorageUUID, "localhost", -1, _localStoragePath, "", StoragePoolType.Filesystem); + final com.cloud.agent.api.StoragePoolInfo pi = new com.cloud.agent.api.StoragePoolInfo(localStoragePool.getUuid(), cmd.getPrivateIpAddress(), _localStoragePath, _localStoragePath, StoragePoolType.Filesystem, localStoragePool.getCapacity(), localStoragePool.getAvailable()); @@ -4286,7 +4300,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv sscmd.setGuid(pi.getUuid()); sscmd.setDataCenter(_dcId); sscmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { s_logger.debug("Unable to initialize local storage pool: " + e); } @@ -4301,30 +4315,30 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { final String textToFind = "InitiatorName="; - Script iScsiAdmCmd = new Script(true, "grep", 0, s_logger); + final Script iScsiAdmCmd = new Script(true, "grep", 0, s_logger); iScsiAdmCmd.add(textToFind); iScsiAdmCmd.add("/etc/iscsi/initiatorname.iscsi"); - OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); + final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - String result = iScsiAdmCmd.execute(parser); + final String result = iScsiAdmCmd.execute(parser); if (result != null) { return null; } - String textFound = parser.getLine().trim(); + final String textFound = parser.getLine().trim(); return textFound.substring(textToFind.length()); } - catch (Exception ex) { + catch (final Exception ex) { return null; } } - protected List getAllVmNames(Connect conn) { - ArrayList la = new ArrayList(); + protected List getAllVmNames(final Connect conn) { + final ArrayList la = new ArrayList(); try { final String names[] = conn.listDefinedDomains(); for (int i = 0; i < names.length; i++) { @@ -4373,7 +4387,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vmStates.putAll(getHostVmStateReport(conn)); conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString()); vmStates.putAll(getHostVmStateReport(conn)); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Failed to get connection: " + e.getMessage()); } } @@ -4382,7 +4396,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString()); vmStates.putAll(getHostVmStateReport(conn)); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Failed to get connection: " + e.getMessage()); } } @@ -4390,7 +4404,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return vmStates; } - private HashMap getHostVmStateReport(Connect conn) { + private HashMap getHostVmStateReport(final Connect conn) { final HashMap vmStates = new HashMap(); String[] vms = null; @@ -4414,19 +4428,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { dm = conn.domainLookupByID(ids[i]); - DomainState ps = dm.getInfo().state; + final DomainState ps = dm.getInfo().state; final PowerState state = convertToPowerState(ps); s_logger.trace("VM " + dm.getName() + ": powerstate = " + ps + "; vm state=" + state.toString()); - String vmName = dm.getName(); + final String vmName = dm.getName(); // TODO : for XS/KVM (host-based resource), we require to remove // VM completely from host, for some reason, KVM seems to still keep // Stopped VM around, to work-around that, reporting only powered-on VM // - if (state == PowerState.PowerOn) + if (state == PowerState.PowerOn) { vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName())); + } } catch (final LibvirtException e) { s_logger.warn("Unable to get vms", e); } finally { @@ -4434,7 +4449,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { dm.free(); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } } @@ -4445,17 +4460,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv dm = conn.domainLookupByName(vms[i]); - DomainState ps = dm.getInfo().state; + final DomainState ps = dm.getInfo().state; final PowerState state = convertToPowerState(ps); - String vmName = dm.getName(); + final String vmName = dm.getName(); s_logger.trace("VM " + vmName + ": powerstate = " + ps + "; vm state=" + state.toString()); // TODO : for XS/KVM (host-based resource), we require to remove // VM completely from host, for some reason, KVM seems to still keep // Stopped VM around, to work-around that, reporting only powered-on VM // - if (state == PowerState.PowerOn) + if (state == PowerState.PowerOn) { vmStates.put(vmName, new HostVmStateReportEntry(state, conn.getHostName())); + } } catch (final LibvirtException e) { s_logger.warn("Unable to get vms", e); } finally { @@ -4463,7 +4479,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { dm.free(); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } } @@ -4487,10 +4503,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv cpuSockets = hosts.sockets; cpus = hosts.cpus; ram = hosts.memory * 1024L; - LibvirtCapXMLParser parser = new LibvirtCapXMLParser(); + final LibvirtCapXMLParser parser = new LibvirtCapXMLParser(); parser.parseCapabilitiesXML(conn.getCapabilities()); - ArrayList oss = parser.getGuestOsType(); - for (String s : oss) { + final ArrayList oss = parser.getGuestOsType(); + for (final String s : oss) { /* * Even host supports guest os type more than hvm, we only * report hvm to management server @@ -4499,7 +4515,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv cap = "hvm"; } } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } @@ -4533,23 +4549,23 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected String rebootVM(Connect conn, String vmName) { + protected String rebootVM(final Connect conn, final String vmName) { Domain dm = null; String msg = null; try { dm = conn.domainLookupByName(vmName); String vmDef = dm.getXMLDesc(0); - LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); parser.parseDomainXML(vmDef); - for (InterfaceDef nic : parser.getInterfaces()) { - if ((nic.getNetType() == guestNetType.BRIDGE) && (nic.getBrName().startsWith("cloudVirBr"))) { + for (final InterfaceDef nic : parser.getInterfaces()) { + if (nic.getNetType() == guestNetType.BRIDGE && nic.getBrName().startsWith("cloudVirBr")) { try { - int vnetId = Integer.parseInt(nic.getBrName().replaceFirst("cloudVirBr", "")); - String pifName = getPif(_guestBridgeName); - String newBrName = "br" + pifName + "-" + vnetId; + final int vnetId = Integer.parseInt(nic.getBrName().replaceFirst("cloudVirBr", "")); + final String pifName = getPif(_guestBridgeName); + final String newBrName = "br" + pifName + "-" + vnetId; vmDef = vmDef.replaceAll("'" + nic.getBrName() + "'", "'" + newBrName + "'"); s_logger.debug("VM bridge name is changed from " + nic.getBrName() + " to " + newBrName); - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { continue; } } @@ -4558,10 +4574,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv msg = stopVM(conn, vmName); msg = startVM(conn, vmName, vmDef); return null; - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.warn("Failed to create vm", e); msg = e.getMessage(); - } catch (InternalErrorException e) { + } catch (final InternalErrorException e) { s_logger.warn("Failed to create vm", e); msg = e.getMessage(); } finally { @@ -4569,7 +4585,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { dm.free(); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } } @@ -4577,7 +4593,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return msg; } - protected String stopVM(Connect conn, String vmName) { + public String stopVM(final Connect conn, final String vmName) { DomainState state = null; Domain dm = null; @@ -4597,14 +4613,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv dm = conn.domainLookupByName(vmName); state = dm.getInfo().state; break; - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Failed to get vm status:" + e.getMessage()); } finally { try { if (dm != null) { dm.free(); } - } catch (LibvirtException l) { + } catch (final LibvirtException l) { s_logger.trace("Ignoring libvirt error.", l); } } @@ -4627,11 +4643,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return null; } - protected String stopVM(Connect conn, String vmName, boolean force) { + protected String stopVM(final Connect conn, final String vmName, final boolean force) { Domain dm = null; try { dm = conn.domainLookupByName(vmName); - int persist = dm.isPersistent(); + final int persist = dm.isPersistent(); if (force) { if (dm.isActive() == 1) { dm.destroy(); @@ -4648,12 +4664,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /* Wait for the domain gets into shutoff state. When it does the dm object will no longer work, so we need to catch it. */ try { - while (dm.isActive() == 1 && (retry >= 0)) { + while (dm.isActive() == 1 && retry >= 0) { Thread.sleep(2000); retry--; } - } catch (LibvirtException e) { - String error = e.toString(); + } catch (final LibvirtException e) { + final String error = e.toString(); if (error.contains("Domain not found")) { s_logger.debug("successfully shut down vm " + vmName); } else { @@ -4669,14 +4685,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { if (e.getMessage().contains("Domain not found")) { s_logger.debug("VM " + vmName + " doesn't exist, no need to stop it"); return null; } s_logger.debug("Failed to stop VM :" + vmName + " :", e); return e.getMessage(); - } catch (InterruptedException ie) { + } catch (final InterruptedException ie) { s_logger.debug("Interrupted sleep"); return ie.getMessage(); } finally { @@ -4684,7 +4700,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { dm.free(); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } } @@ -4692,12 +4708,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return null; } - protected Integer getVncPort(Connect conn, String vmName) throws LibvirtException { - LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + protected Integer getVncPort(final Connect conn, final String vmName) throws LibvirtException { + final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); Domain dm = null; try { dm = conn.domainLookupByName(vmName); - String xmlDesc = dm.getXMLDesc(0); + final String xmlDesc = dm.getXMLDesc(0); parser.parseDomainXML(xmlDesc); return parser.getVncPort(); } finally { @@ -4705,47 +4721,47 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { dm.free(); } - } catch (LibvirtException l) { + } catch (final LibvirtException l) { s_logger.trace("Ignoring libvirt error.", l); } } } - private boolean IsHVMEnabled(Connect conn) { - LibvirtCapXMLParser parser = new LibvirtCapXMLParser(); + private boolean IsHVMEnabled(final Connect conn) { + final LibvirtCapXMLParser parser = new LibvirtCapXMLParser(); try { parser.parseCapabilitiesXML(conn.getCapabilities()); - ArrayList osTypes = parser.getGuestOsType(); - for (String o : osTypes) { + final ArrayList osTypes = parser.getGuestOsType(); + for (final String o : osTypes) { if (o.equalsIgnoreCase("hvm")) { return true; } } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } return false; } - private String getHypervisorPath(Connect conn) { - LibvirtCapXMLParser parser = new LibvirtCapXMLParser(); + private String getHypervisorPath(final Connect conn) { + final LibvirtCapXMLParser parser = new LibvirtCapXMLParser(); try { parser.parseCapabilitiesXML(conn.getCapabilities()); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug(e.getMessage()); } return parser.getEmulator(); } - private String getGuestType(Connect conn, String vmName) { - LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + private String getGuestType(final Connect conn, final String vmName) { + final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); Domain dm = null; try { dm = conn.domainLookupByName(vmName); - String xmlDesc = dm.getXMLDesc(0); + final String xmlDesc = dm.getXMLDesc(0); parser.parseDomainXML(xmlDesc); return parser.getDescription(); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); return null; } finally { @@ -4753,13 +4769,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { dm.free(); } - } catch (LibvirtException l) { + } catch (final LibvirtException l) { s_logger.trace("Ignoring libvirt error.", l); } } } - boolean isGuestPVEnabled(String guestOSName) { + boolean isGuestPVEnabled(final String guestOSName) { if (guestOSName == null) { return false; } @@ -4783,7 +4799,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private DiskDef.diskBus getGuestDiskModel(String platformEmulator) { + private DiskDef.diskBus getGuestDiskModel(final String platformEmulator) { if (isGuestPVEnabled(platformEmulator)) { return DiskDef.diskBus.VIRTIO; } else { @@ -4791,29 +4807,29 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private void cleanupVMNetworks(Connect conn, List nics) { + private void cleanupVMNetworks(final Connect conn, final List nics) { if (nics != null) { - for (InterfaceDef nic : nics) { - for (VifDriver vifDriver : getAllVifDrivers()) { + for (final InterfaceDef nic : nics) { + for (final VifDriver vifDriver : getAllVifDrivers()) { vifDriver.unplug(nic); } } } } - public Domain getDomain(Connect conn, String vmName) throws LibvirtException { + public Domain getDomain(final Connect conn, final String vmName) throws LibvirtException { return conn.domainLookupByName(vmName); } - protected List getInterfaces(Connect conn, String vmName) { - LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + public List getInterfaces(final Connect conn, final String vmName) { + final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); Domain dm = null; try { dm = conn.domainLookupByName(vmName); parser.parseDomainXML(dm.getXMLDesc(0)); return parser.getInterfaces(); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Failed to get dom xml: " + e.toString()); return new ArrayList(); } finally { @@ -4821,21 +4837,21 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { dm.free(); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } } } - public List getDisks(Connect conn, String vmName) { - LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + public List getDisks(final Connect conn, final String vmName) { + final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); Domain dm = null; try { dm = conn.domainLookupByName(vmName); parser.parseDomainXML(dm.getXMLDesc(0)); return parser.getDisks(); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.debug("Failed to get dom xml: " + e.toString()); return new ArrayList(); } finally { @@ -4843,39 +4859,40 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dm != null) { dm.free(); } - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } } } - private String executeBashScript(String script) { - Script command = new Script("/bin/bash", _timeout, s_logger); + private String executeBashScript(final String script) { + final Script command = new Script("/bin/bash", _timeout, s_logger); command.add("-c"); command.add(script); return command.execute(); } - private List getVmDiskStat(Connect conn, String vmName) throws LibvirtException { + private List getVmDiskStat(final Connect conn, final String vmName) throws LibvirtException { Domain dm = null; try { dm = getDomain(conn, vmName); - List stats = new ArrayList(); + final List stats = new ArrayList(); - List disks = getDisks(conn, vmName); + final List disks = getDisks(conn, vmName); - for (DiskDef disk : disks) { - if (disk.getDeviceType() != deviceType.DISK) + for (final DiskDef disk : disks) { + if (disk.getDeviceType() != deviceType.DISK) { break; - DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel()); - String path = disk.getDiskPath(); // for example, path = /mnt/pool_uuid/disk_path/ + } + final DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel()); + final String path = disk.getDiskPath(); // for example, path = /mnt/pool_uuid/disk_path/ String diskPath = null; if (path != null) { - String[] token = path.split("/"); + final String[] token = path.split("/"); if (token.length > 3) { diskPath = token[3]; - VmDiskStatsEntry stat = new VmDiskStatsEntry(vmName, diskPath, blockStats.wr_req, blockStats.rd_req, blockStats.wr_bytes, blockStats.rd_bytes); + final VmDiskStatsEntry stat = new VmDiskStatsEntry(vmName, diskPath, blockStats.wr_req, blockStats.rd_req, blockStats.wr_bytes, blockStats.rd_bytes); stats.add(stat); } } @@ -4900,20 +4917,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv Calendar _timestamp; } - VmStatsEntry getVmStat(Connect conn, String vmName) throws LibvirtException { + VmStatsEntry getVmStat(final Connect conn, final String vmName) throws LibvirtException { Domain dm = null; try { dm = getDomain(conn, vmName); - DomainInfo info = dm.getInfo(); + final DomainInfo info = dm.getInfo(); - VmStatsEntry stats = new VmStatsEntry(); + final VmStatsEntry stats = new VmStatsEntry(); stats.setNumCPUs(info.nrVirtCpu); stats.setEntityType("vm"); /* get cpu utilization */ VmStats oldStats = null; - Calendar now = Calendar.getInstance(); + final Calendar now = Calendar.getInstance(); oldStats = _vmStats.get(vmName); @@ -4922,7 +4939,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv elapsedTime = now.getTimeInMillis() - oldStats._timestamp.getTimeInMillis(); double utilization = (info.cpuTime - oldStats._usedTime) / ((double)elapsedTime * 1000000); - NodeInfo node = conn.nodeInfo(); + final NodeInfo node = conn.nodeInfo(); utilization = utilization / node.cpus; if (utilization > 0) { stats.setCPUUtilization(utilization * 100); @@ -4931,32 +4948,34 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /* get network stats */ - List vifs = getInterfaces(conn, vmName); + final List vifs = getInterfaces(conn, vmName); long rx = 0; long tx = 0; - for (InterfaceDef vif : vifs) { - DomainInterfaceStats ifStats = dm.interfaceStats(vif.getDevName()); + for (final InterfaceDef vif : vifs) { + final DomainInterfaceStats ifStats = dm.interfaceStats(vif.getDevName()); rx += ifStats.rx_bytes; tx += ifStats.tx_bytes; } if (oldStats != null) { - double deltarx = rx - oldStats._rx; - if (deltarx > 0) + final double deltarx = rx - oldStats._rx; + if (deltarx > 0) { stats.setNetworkReadKBs(deltarx / 1024); - double deltatx = tx - oldStats._tx; - if (deltatx > 0) + } + final double deltatx = tx - oldStats._tx; + if (deltatx > 0) { stats.setNetworkWriteKBs(deltatx / 1024); + } } /* get disk stats */ - List disks = getDisks(conn, vmName); + final List disks = getDisks(conn, vmName); long io_rd = 0; long io_wr = 0; long bytes_rd = 0; long bytes_wr = 0; - for (DiskDef disk : disks) { - DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel()); + for (final DiskDef disk : disks) { + final DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel()); io_rd += blockStats.rd_req; io_wr += blockStats.wr_req; bytes_rd += blockStats.rd_bytes; @@ -4964,22 +4983,26 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } if (oldStats != null) { - long deltaiord = io_rd - oldStats._ioRead; - if (deltaiord > 0) + final long deltaiord = io_rd - oldStats._ioRead; + if (deltaiord > 0) { stats.setDiskReadIOs(deltaiord); - long deltaiowr = io_wr - oldStats._ioWrote; - if (deltaiowr > 0) + } + final long deltaiowr = io_wr - oldStats._ioWrote; + if (deltaiowr > 0) { stats.setDiskWriteIOs(deltaiowr); - double deltabytesrd = bytes_rd - oldStats._bytesRead; - if (deltabytesrd > 0) + } + final double deltabytesrd = bytes_rd - oldStats._bytesRead; + if (deltabytesrd > 0) { stats.setDiskReadKBs(deltabytesrd / 1024); - double deltabyteswr = bytes_wr - oldStats._bytesWrote; - if (deltabyteswr > 0) + } + final double deltabyteswr = bytes_wr - oldStats._bytesWrote; + if (deltabyteswr > 0) { stats.setDiskWriteKBs(deltabyteswr / 1024); + } } /* save to Hashmap */ - VmStats newStat = new VmStats(); + final VmStats newStat = new VmStats(); newStat._usedTime = info.cpuTime; newStat._rx = rx; newStat._tx = tx; @@ -4997,55 +5020,55 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private boolean can_bridge_firewall(String prvNic) { - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + private boolean can_bridge_firewall(final String prvNic) { + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("can_bridge_firewall"); cmd.add(prvNic); - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { return false; } return true; } - protected boolean destroy_network_rules_for_vm(Connect conn, String vmName) { + public boolean destroyNetworkRulesForVM(final Connect conn, final String vmName) { if (!_canBridgeFirewall) { return false; } String vif = null; - List intfs = getInterfaces(conn, vmName); + final List intfs = getInterfaces(conn, vmName); if (intfs.size() > 0) { - InterfaceDef intf = intfs.get(0); + final InterfaceDef intf = intfs.get(0); vif = intf.getDevName(); } - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("destroy_network_rules_for_vm"); cmd.add("--vmname", vmName); if (vif != null) { cmd.add("--vif", vif); } - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { return false; } return true; } - protected boolean default_network_rules(Connect conn, String vmName, NicTO nic, Long vmId, String secIpStr) { + protected boolean default_network_rules(final Connect conn, final String vmName, final NicTO nic, final Long vmId, final String secIpStr) { if (!_canBridgeFirewall) { return false; } - List intfs = getInterfaces(conn, vmName); + final List intfs = getInterfaces(conn, vmName); if (intfs.size() == 0 || intfs.size() < nic.getDeviceId()) { return false; } - InterfaceDef intf = intfs.get(nic.getDeviceId()); - String brname = intf.getBrName(); - String vif = intf.getDevName(); + final InterfaceDef intf = intfs.get(nic.getDeviceId()); + final String brname = intf.getBrName(); + final String vif = intf.getDevName(); - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("default_network_rules"); cmd.add("--vmname", vmName); cmd.add("--vmid", vmId.toString()); @@ -5056,28 +5079,28 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv cmd.add("--vif", vif); cmd.add("--brname", brname); cmd.add("--nicsecips", secIpStr); - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { return false; } return true; } - protected boolean post_default_network_rules(Connect conn, String vmName, NicTO nic, Long vmId, InetAddress dhcpServerIp, String hostIp, String hostMacAddr) { + protected boolean post_default_network_rules(final Connect conn, final String vmName, final NicTO nic, final Long vmId, final InetAddress dhcpServerIp, final String hostIp, final String hostMacAddr) { if (!_canBridgeFirewall) { return false; } - List intfs = getInterfaces(conn, vmName); + final List intfs = getInterfaces(conn, vmName); if (intfs.size() < nic.getDeviceId()) { return false; } - InterfaceDef intf = intfs.get(nic.getDeviceId()); - String brname = intf.getBrName(); - String vif = intf.getDevName(); + final InterfaceDef intf = intfs.get(nic.getDeviceId()); + final String brname = intf.getBrName(); + final String vif = intf.getDevName(); - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("post_default_network_rules"); cmd.add("--vmname", vmName); cmd.add("--vmid", vmId.toString()); @@ -5085,42 +5108,43 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv cmd.add("--vmmac", nic.getMac()); cmd.add("--vif", vif); cmd.add("--brname", brname); - if (dhcpServerIp != null) + if (dhcpServerIp != null) { cmd.add("--dhcpSvr", dhcpServerIp.getHostAddress()); + } cmd.add("--hostIp", hostIp); cmd.add("--hostMacAddr", hostMacAddr); - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { return false; } return true; } - protected boolean default_network_rules_for_systemvm(Connect conn, String vmName) { + protected boolean default_network_rules_for_systemvm(final Connect conn, final String vmName) { if (!_canBridgeFirewall) { return false; } - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("default_network_rules_systemvm"); cmd.add("--vmname", vmName); cmd.add("--localbrname", _linkLocalBridgeName); - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { return false; } return true; } - private boolean add_network_rules(String vmName, String vmId, String guestIP, String sig, String seq, String mac, String rules, String vif, String brname, - String secIps) { + private boolean add_network_rules(final String vmName, final String vmId, final String guestIP, final String sig, final String seq, final String mac, final String rules, final String vif, final String brname, + final String secIps) { if (!_canBridgeFirewall) { return false; } - String newRules = rules.replace(" ", ";"); - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + final String newRules = rules.replace(" ", ";"); + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("add_network_rules"); cmd.add("--vmname", vmName); cmd.add("--vmid", vmId); @@ -5134,26 +5158,26 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (newRules != null && !newRules.isEmpty()) { cmd.add("--rules", newRules); } - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { return false; } return true; } - private boolean network_rules_vmSecondaryIp(Connect conn, String vmName, String secIp, String action) { + private boolean network_rules_vmSecondaryIp(final Connect conn, final String vmName, final String secIp, final String action) { if (!_canBridgeFirewall) { return false; } - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("network_rules_vmSecondaryIp"); cmd.add("--vmname", vmName); cmd.add("--nicsecips", secIp); cmd.add("--action", action); - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { return false; } @@ -5164,9 +5188,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (!_canBridgeFirewall) { return false; } - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("cleanup_rules"); - String result = cmd.execute(); + final String result = cmd.execute(); if (result != null) { return false; } @@ -5174,30 +5198,30 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } private String get_rule_logs_for_vms() { - Script cmd = new Script(_securityGroupPath, _timeout, s_logger); + final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("get_rule_logs_for_vms"); - OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - String result = cmd.execute(parser); + final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); + final String result = cmd.execute(parser); if (result == null) { return parser.getLine(); } return null; } - private HashMap> syncNetworkGroups(long id) { - HashMap> states = new HashMap>(); + private HashMap> syncNetworkGroups(final long id) { + final HashMap> states = new HashMap>(); - String result = get_rule_logs_for_vms(); + final String result = get_rule_logs_for_vms(); s_logger.trace("syncNetworkGroups: id=" + id + " got: " + result); - String[] rulelogs = result != null ? result.split(";") : new String[0]; - for (String rulesforvm : rulelogs) { - String[] log = rulesforvm.split(","); + final String[] rulelogs = result != null ? result.split(";") : new String[0]; + for (final String rulesforvm : rulelogs) { + final String[] log = rulesforvm.split(","); if (log.length != 6) { continue; } try { states.put(log[0], new Pair(Long.parseLong(log[1]), Long.parseLong(log[5]))); - } catch (NumberFormatException nfe) { + } catch (final NumberFormatException nfe) { states.put(log[0], new Pair(-1L, -1L)); } } @@ -5206,7 +5230,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /* online snapshot supported by enhanced qemu-kvm */ private boolean isSnapshotSupported() { - String result = executeBashScript("qemu-img --help|grep convert"); + final String result = executeBashScript("qemu-img --help|grep convert"); if (result != null) { return false; } else { @@ -5214,40 +5238,40 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - static Pair getNicStats(String nicName) { + static Pair getNicStats(final String nicName) { return new Pair(readDouble(nicName, "rx_bytes"), readDouble(nicName, "tx_bytes")); } - static double readDouble(String nicName, String fileName) { + static double readDouble(final String nicName, final String fileName) { final String path = "/sys/class/net/" + nicName + "/statistics/" + fileName; try { return Double.parseDouble(FileUtils.readFileToString(new File(path))); - } catch (IOException ioe) { + } catch (final IOException ioe) { s_logger.warn("Failed to read the " + fileName + " for " + nicName + " from " + path, ioe); return 0.0; } } - private Answer execute(NetworkRulesSystemVmCommand cmd) { + private Answer execute(final NetworkRulesSystemVmCommand cmd) { boolean success = false; Connect conn; try { conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); success = default_network_rules_for_systemvm(conn, cmd.getVmName()); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } return new Answer(cmd, success, ""); } - private Answer execute(NetworkRulesVmSecondaryIpCommand cmd) { + private Answer execute(final NetworkRulesVmSecondaryIpCommand cmd) { boolean success = false; Connect conn; try { conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); success = network_rules_vmSecondaryIp(conn, cmd.getVmName(), cmd.getVmSecIp(), cmd.getAction()); - } catch (LibvirtException e) { + } catch (final LibvirtException e) { // TODO Auto-generated catch block e.printStackTrace(); } @@ -5255,21 +5279,21 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new Answer(cmd, success, ""); } - private String prettyVersion(long version) { - long major = version / 1000000; - long minor = version % 1000000 / 1000; - long release = version % 1000000 % 1000; + private String prettyVersion(final long version) { + final long major = version / 1000000; + final long minor = version % 1000000 / 1000; + final long release = version % 1000000 % 1000; return major + "." + minor + "." + release; } @Override - public void setName(String name) { + public void setName(final String name) { // TODO Auto-generated method stub } @Override - public void setConfigParams(Map params) { + public void setConfigParams(final Map params) { // TODO Auto-generated method stub } @@ -5287,7 +5311,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } @Override - public void setRunLevel(int level) { + public void setRunLevel(final int level) { // TODO Auto-generated method stub } @@ -5307,10 +5331,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - public String mapRbdDevice(KVMPhysicalDisk disk){ - KVMStoragePool pool = disk.getPool(); + public String mapRbdDevice(final KVMPhysicalDisk disk){ + final KVMStoragePool pool = disk.getPool(); //Check if rbd image is already mapped - String[] splitPoolImage = disk.getPath().split("/"); + final String[] splitPoolImage = disk.getPath().split("/"); String device = Script.runSimpleBashScript("rbd showmapped | grep \""+splitPoolImage[0]+"[ ]*"+splitPoolImage[1]+"\" | grep -o \"[^ ]*[ ]*$\""); if(device == null) { //If not mapped, map and return mapped device 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 new file mode 100644 index 00000000000..fc039b8d163 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java @@ -0,0 +1,72 @@ +// +// 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 java.util.Hashtable; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.StopCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.RequestWrapper; +import com.cloud.resource.ServerResource; + +public class LibvirtRequestWrapper extends RequestWrapper { + + private static LibvirtRequestWrapper instance; + + static { + instance = new LibvirtRequestWrapper(); + } + + private LibvirtRequestWrapper() { + init(); + } + + @SuppressWarnings("rawtypes") + private void init() { + // LibvirtComputingResource commands + final Hashtable, CommandWrapper> linbvirtCommands = new Hashtable, CommandWrapper>(); + + linbvirtCommands.put(StopCommand.class, new LibvirtStopCommandWrapper()); + resources.put(LibvirtComputingResource.class, linbvirtCommands); + } + + public static LibvirtRequestWrapper getInstance() { + return instance; + } + + @SuppressWarnings({"rawtypes" }) + @Override + public Answer execute(final Command command, final ServerResource serverResource) { + final Class resourceClass = serverResource.getClass(); + + final Hashtable, CommandWrapper> resourceCommands = retrieveResource(command, resourceClass); + + CommandWrapper commandWrapper = retrieveCommands(command.getClass(), resourceCommands); + + while (commandWrapper == null) { + //Could not find the command in the given resource, will traverse the family tree. + commandWrapper = retryWhenAllFails(command, resourceClass, resourceCommands); + } + + return commandWrapper.execute(command, serverResource); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java new file mode 100644 index 00000000000..3e6c6b4adfa --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java @@ -0,0 +1,86 @@ +// +// 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 java.util.List; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainInfo.DomainState; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.StopCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtConnection; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; +import com.cloud.hypervisor.kvm.resource.VifDriver; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtStopCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtStopCommandWrapper.class); + + @Override + public Answer execute(final StopCommand command, final LibvirtComputingResource citrixResourceBase) { + final String vmName = command.getVmName(); + + if (command.checkBeforeCleanup()) { + try { + final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + final Domain vm = conn.domainLookupByName(command.getVmName()); + if (vm != null && vm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING) { + return new StopAnswer(command, "vm is still running on host", false); + } + } catch (final Exception e) { + s_logger.debug("Failed to get vm status in case of checkboforecleanup is true", e); + } + } + + try { + final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + + final List disks = citrixResourceBase.getDisks(conn, vmName); + final List ifaces = citrixResourceBase.getInterfaces(conn, vmName); + + citrixResourceBase.destroyNetworkRulesForVM(conn, vmName); + final String result = citrixResourceBase.stopVM(conn, vmName); + if (result == null) { + for (final DiskDef disk : disks) { + citrixResourceBase.cleanupDisk(disk); + } + for (final InterfaceDef iface : ifaces) { + // We don't know which "traffic type" is associated with + // each interface at this point, so inform all vif drivers + for (final VifDriver vifDriver : citrixResourceBase.getAllVifDrivers()) { + vifDriver.unplug(iface); + } + } + } + + return new StopAnswer(command, result, true); + } catch (final LibvirtException e) { + return new StopAnswer(command, e.getMessage(), false); + } + } +} \ No newline at end of file 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 b82796fa616..881ebc522b1 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 @@ -38,6 +38,7 @@ import org.apache.commons.lang.SystemUtils; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; import org.libvirt.Connect; import org.libvirt.Domain; import org.libvirt.DomainBlockStats; @@ -46,22 +47,29 @@ import org.libvirt.DomainInterfaceStats; import org.libvirt.LibvirtException; import org.libvirt.NodeInfo; import org.mockito.Matchers; +import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; +import org.powermock.modules.junit4.PowerMockRunner; import org.w3c.dom.Document; import org.xml.sax.SAXException; +import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; +import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine; +@RunWith(PowerMockRunner.class) public class LibvirtComputingResourceTest { + @Mock + private LibvirtComputingResource libvirtComputingResource; + String _hyperVisorType = "kvm"; Random _random = new Random(); @@ -71,28 +79,28 @@ public class LibvirtComputingResourceTest { The overcommit feature has not been merged in there and thus only 'speed' is set. - */ + */ @Test public void testCreateVMFromSpecLegacy() { - int id = _random.nextInt(65534); - String name = "test-instance-1"; + final int id = _random.nextInt(65534); + final String name = "test-instance-1"; - int cpus = _random.nextInt(2) + 1; - int speed = 1024; - int minRam = 256 * 1024; - int maxRam = 512 * 1024; + final int cpus = _random.nextInt(2) + 1; + final int speed = 1024; + final int minRam = 256 * 1024; + final int maxRam = 512 * 1024; - String os = "Ubuntu"; + final String os = "Ubuntu"; - String vncAddr = ""; - String vncPassword = "mySuperSecretPassword"; + final String vncAddr = ""; + final String vncPassword = "mySuperSecretPassword"; - LibvirtComputingResource lcr = new LibvirtComputingResource(); - VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); + final LibvirtComputingResource lcr = new LibvirtComputingResource(); + final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, speed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); to.setVncAddr(vncAddr); to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); - LibvirtVMDef vm = lcr.createVMFromSpec(to); + final LibvirtVMDef vm = lcr.createVMFromSpec(to); vm.setHvsType(_hyperVisorType); verifyVm(to, vm); @@ -100,29 +108,29 @@ public class LibvirtComputingResourceTest { /** This test verifies that CPU topology is properly set for hex-core - */ + */ @Test public void testCreateVMFromSpecWithTopology6() { - int id = _random.nextInt(65534); - String name = "test-instance-1"; + final int id = _random.nextInt(65534); + final String name = "test-instance-1"; - int cpus = 12; - int minSpeed = 1024; - int maxSpeed = 2048; - int minRam = 256 * 1024; - int maxRam = 512 * 1024; + final int cpus = 12; + final int minSpeed = 1024; + final int maxSpeed = 2048; + final int minRam = 256 * 1024; + final int maxRam = 512 * 1024; - String os = "Ubuntu"; + final String os = "Ubuntu"; - String vncAddr = ""; - String vncPassword = "mySuperSecretPassword"; + final String vncAddr = ""; + final String vncPassword = "mySuperSecretPassword"; - LibvirtComputingResource lcr = new LibvirtComputingResource(); - VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); + final LibvirtComputingResource lcr = new LibvirtComputingResource(); + final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); to.setVncAddr(vncAddr); to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); - LibvirtVMDef vm = lcr.createVMFromSpec(to); + final LibvirtVMDef vm = lcr.createVMFromSpec(to); vm.setHvsType(_hyperVisorType); verifyVm(to, vm); @@ -130,29 +138,29 @@ public class LibvirtComputingResourceTest { /** This test verifies that CPU topology is properly set for quad-core - */ + */ @Test public void testCreateVMFromSpecWithTopology4() { - int id = _random.nextInt(65534); - String name = "test-instance-1"; + final int id = _random.nextInt(65534); + final String name = "test-instance-1"; - int cpus = 8; - int minSpeed = 1024; - int maxSpeed = 2048; - int minRam = 256 * 1024; - int maxRam = 512 * 1024; + final int cpus = 8; + final int minSpeed = 1024; + final int maxSpeed = 2048; + final int minRam = 256 * 1024; + final int maxRam = 512 * 1024; - String os = "Ubuntu"; + final String os = "Ubuntu"; - String vncAddr = ""; - String vncPassword = "mySuperSecretPassword"; + final String vncAddr = ""; + final String vncPassword = "mySuperSecretPassword"; - LibvirtComputingResource lcr = new LibvirtComputingResource(); - VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); + final LibvirtComputingResource lcr = new LibvirtComputingResource(); + final VirtualMachineTO to = new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); to.setVncAddr(vncAddr); to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); - LibvirtVMDef vm = lcr.createVMFromSpec(to); + final LibvirtVMDef vm = lcr.createVMFromSpec(to); vm.setHvsType(_hyperVisorType); verifyVm(to, vm); @@ -164,37 +172,37 @@ public class LibvirtComputingResourceTest { It tests if the Agent can handle a vmSpec with overcommit data like minSpeed and maxSpeed in there - */ + */ @Test public void testCreateVMFromSpec() { - int id = _random.nextInt(65534); - String name = "test-instance-1"; + final int id = _random.nextInt(65534); + final String name = "test-instance-1"; - int cpus = _random.nextInt(2) + 1; - int minSpeed = 1024; - int maxSpeed = 2048; - int minRam = 256 * 1024; - int maxRam = 512 * 1024; + final int cpus = _random.nextInt(2) + 1; + final int minSpeed = 1024; + final int maxSpeed = 2048; + final int minRam = 256 * 1024; + final int maxRam = 512 * 1024; - String os = "Ubuntu"; + final String os = "Ubuntu"; - String vncAddr = ""; - String vncPassword = "mySuperSecretPassword"; + final String vncAddr = ""; + final String vncPassword = "mySuperSecretPassword"; - LibvirtComputingResource lcr = new LibvirtComputingResource(); - VirtualMachineTO to = - new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); + final LibvirtComputingResource lcr = new LibvirtComputingResource(); + final VirtualMachineTO to = + new VirtualMachineTO(id, name, VirtualMachine.Type.User, cpus, minSpeed, maxSpeed, minRam, maxRam, BootloaderType.HVM, os, false, false, vncPassword); to.setVncAddr(vncAddr); to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); - LibvirtVMDef vm = lcr.createVMFromSpec(to); + final LibvirtVMDef vm = lcr.createVMFromSpec(to); vm.setHvsType(_hyperVisorType); verifyVm(to, vm); } - private void verifyVm(VirtualMachineTO to, LibvirtVMDef vm) { - Document domainDoc = parse(vm.toString()); + private void verifyVm(final VirtualMachineTO to, final LibvirtVMDef vm) { + final Document domainDoc = parse(vm.toString()); assertXpath(domainDoc, "/domain/@type", vm.getHvsType()); assertXpath(domainDoc, "/domain/name/text()", to.getName()); assertXpath(domainDoc, "/domain/uuid/text()", to.getUuid()); @@ -246,7 +254,7 @@ public class LibvirtComputingResourceTest { try { Assert.assertNotNull(XPathFactory.newInstance().newXPath() .evaluate(xPathExpr, doc, XPathConstants.NODE)); - } catch (XPathExpressionException e) { + } catch (final XPathExpressionException e) { Assert.fail(e.getMessage()); } } @@ -256,7 +264,7 @@ public class LibvirtComputingResourceTest { try { Assert.assertEquals(expected, XPathFactory.newInstance().newXPath() .evaluate(xPathExpr, doc)); - } catch (XPathExpressionException e) { + } catch (final XPathExpressionException e) { Assert.fail("Could not evaluate xpath" + xPathExpr + ":" + e.getMessage()); } @@ -267,18 +275,18 @@ public class LibvirtComputingResourceTest { //this test is only working on linux because of the loopback interface name //also the tested code seems to work only on linux Assume.assumeTrue(SystemUtils.IS_OS_LINUX); - Pair stats = LibvirtComputingResource.getNicStats("lo"); + final Pair stats = LibvirtComputingResource.getNicStats("lo"); assertNotNull(stats); } @Test public void testUUID() { String uuid = "1"; - LibvirtComputingResource lcr = new LibvirtComputingResource(); + final LibvirtComputingResource lcr = new LibvirtComputingResource(); uuid = lcr.getUuid(uuid); Assert.assertTrue(!uuid.equals("1")); - String oldUuid = UUID.randomUUID().toString(); + final String oldUuid = UUID.randomUUID().toString(); uuid = oldUuid; uuid = lcr.getUuid(uuid); Assert.assertTrue(uuid.equals(oldUuid)); @@ -288,12 +296,12 @@ public class LibvirtComputingResourceTest { @Test public void testGetVmStat() throws LibvirtException { - Connect connect = Mockito.mock(Connect.class); - Domain domain = Mockito.mock(Domain.class); - DomainInfo domainInfo = new DomainInfo(); + final Connect connect = Mockito.mock(Connect.class); + final Domain domain = Mockito.mock(Domain.class); + final DomainInfo domainInfo = new DomainInfo(); Mockito.when(domain.getInfo()).thenReturn(domainInfo); Mockito.when(connect.domainLookupByName(VMNAME)).thenReturn(domain); - NodeInfo nodeInfo = new NodeInfo(); + final NodeInfo nodeInfo = new NodeInfo(); nodeInfo.cpus = 8; nodeInfo.memory = 8 * 1024 * 1024; nodeInfo.sockets = 2; @@ -301,24 +309,24 @@ public class LibvirtComputingResourceTest { nodeInfo.model = "Foo processor"; Mockito.when(connect.nodeInfo()).thenReturn(nodeInfo); // this is testing the interface stats, returns an increasing number of sent and received bytes - Mockito.when(domain.interfaceStats(Matchers.anyString())).thenAnswer(new Answer() { + Mockito.when(domain.interfaceStats(Matchers.anyString())).thenAnswer(new org.mockito.stubbing.Answer() { // increment with less than a KB, so this should be less than 1 KB final static int increment = 1000; int rxBytes = 1000; int txBytes = 1000; @Override - public DomainInterfaceStats answer(InvocationOnMock invocation) throws Throwable { - DomainInterfaceStats domainInterfaceStats = new DomainInterfaceStats(); - domainInterfaceStats.rx_bytes = (rxBytes += increment); - domainInterfaceStats.tx_bytes = (txBytes += increment); + public DomainInterfaceStats answer(final InvocationOnMock invocation) throws Throwable { + final DomainInterfaceStats domainInterfaceStats = new DomainInterfaceStats(); + domainInterfaceStats.rx_bytes = rxBytes += increment; + domainInterfaceStats.tx_bytes = txBytes += increment; return domainInterfaceStats; } }); - Mockito.when(domain.blockStats(Matchers.anyString())).thenAnswer(new Answer() { + Mockito.when(domain.blockStats(Matchers.anyString())).thenAnswer(new org.mockito.stubbing.Answer() { // a little less than a KB final static int increment = 1000; @@ -326,32 +334,32 @@ public class LibvirtComputingResourceTest { int wrBytes = 1024; @Override - public DomainBlockStats answer(InvocationOnMock invocation) throws Throwable { - DomainBlockStats domainBlockStats = new DomainBlockStats(); + public DomainBlockStats answer(final InvocationOnMock invocation) throws Throwable { + final DomainBlockStats domainBlockStats = new DomainBlockStats(); - domainBlockStats.rd_bytes = (rdBytes += increment); - domainBlockStats.wr_bytes = (wrBytes += increment); + domainBlockStats.rd_bytes = rdBytes += increment; + domainBlockStats.wr_bytes = wrBytes += increment; return domainBlockStats; } }); - LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource() { + final LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource() { @Override - protected List getInterfaces(Connect conn, String vmName) { - InterfaceDef interfaceDef = new InterfaceDef(); + public List getInterfaces(final Connect conn, final String vmName) { + final InterfaceDef interfaceDef = new InterfaceDef(); return Arrays.asList(interfaceDef); } @Override - public List getDisks(Connect conn, String vmName) { - DiskDef diskDef = new DiskDef(); + public List getDisks(final Connect conn, final String vmName) { + final DiskDef diskDef = new DiskDef(); return Arrays.asList(diskDef); } }; libvirtComputingResource.getVmStat(connect, VMNAME); - VmStatsEntry vmStat = libvirtComputingResource.getVmStat(connect, VMNAME); + final VmStatsEntry vmStat = libvirtComputingResource.getVmStat(connect, VMNAME); // network traffic as generated by the logic above, must be greater than zero Assert.assertTrue(vmStat.getNetworkReadKBs() > 0); Assert.assertTrue(vmStat.getNetworkWriteKBs() > 0); @@ -363,7 +371,24 @@ public class LibvirtComputingResourceTest { @Test public void getCpuSpeed() { Assume.assumeTrue(SystemUtils.IS_OS_LINUX); - NodeInfo nodeInfo = Mockito.mock(NodeInfo.class); + final NodeInfo nodeInfo = Mockito.mock(NodeInfo.class); LibvirtComputingResource.getCpuSpeed(nodeInfo); } -} + + /* + * New Tests + */ + + @Test(expected = UnsatisfiedLinkError.class) + public void testStopCommand() { + // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need + // a better way to mock stuff! + final String vmName = "Test"; + final StopCommand stopCommand = new StopCommand(vmName, false, false); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + wrapper.execute(stopCommand, libvirtComputingResource); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java index 4537b2a4cfe..02f377428a2 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java @@ -107,12 +107,7 @@ public class CitrixRequestWrapper extends RequestWrapper { instance = new CitrixRequestWrapper(); } - @SuppressWarnings("rawtypes") - private final Hashtable, Hashtable, CommandWrapper>> resources; - - @SuppressWarnings("rawtypes") private CitrixRequestWrapper() { - resources = new Hashtable, Hashtable, CommandWrapper>>(); init(); } @@ -232,73 +227,4 @@ public class CitrixRequestWrapper extends RequestWrapper { return commandWrapper.execute(command, serverResource); } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected Hashtable, CommandWrapper> retrieveResource(final Command command, final Class resourceClass) { - Class keepResourceClass = resourceClass; - Hashtable, CommandWrapper> resource = resources.get(keepResourceClass); - while (resource == null) { - try { - final Class keepResourceClass2 = (Class) keepResourceClass.getSuperclass(); - resource = resources.get(keepResourceClass2); - - keepResourceClass = keepResourceClass2; - } catch (final ClassCastException e) { - throw new NullPointerException("No key found for '" + command.getClass() + "' in the Map!"); - } - } - return resource; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected CommandWrapper retrieveCommands(final Class commandClass, - final Hashtable, CommandWrapper> resourceCommands) { - - Class keepCommandClass = commandClass; - CommandWrapper commandWrapper = resourceCommands.get(keepCommandClass); - while (commandWrapper == null) { - try { - final Class commandClass2 = (Class) keepCommandClass.getSuperclass(); - - if (commandClass2 == null) { - throw new NullPointerException("All the COMMAND hierarchy tree has been visited but no compliant key has been found for '" + commandClass +"'."); - } - - commandWrapper = resourceCommands.get(commandClass2); - - keepCommandClass = commandClass2; - } catch (final NullPointerException e) { - // Will now traverse all the resource hierarchy. Returning null is not a problem. - // It is all being nicely checked and in case we do not have a resource, an Unsupported answer will be thrown by the base class. - return null; - } - } - return commandWrapper; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected CommandWrapper retryWhenAllFails(final Command command, final Class resourceClass, - final Hashtable, CommandWrapper> resourceCommands) { - - Class keepResourceClass = resourceClass; - CommandWrapper commandWrapper = resourceCommands.get(command.getClass()); - while (commandWrapper == null) { - //Could not find the command in the given resource, will traverse the family tree. - try { - final Class resourceClass2 = (Class) keepResourceClass.getSuperclass(); - - if (resourceClass2 == null) { - throw new NullPointerException("All the SERVER-RESOURCE hierarchy tree has been visited but no compliant key has been found for '" + command.getClass() +"'."); - } - - final Hashtable, CommandWrapper> resourceCommands2 = retrieveResource(command, (Class) keepResourceClass.getSuperclass()); - keepResourceClass = resourceClass2; - - commandWrapper = retrieveCommands(command.getClass(), resourceCommands2); - } catch (final NullPointerException e) { - throw e; - } - } - return commandWrapper; - } } \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java index 060d3b5d13f..28fc3708d61 100644 --- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java @@ -42,7 +42,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import com.cloud.agent.api.Answer; @@ -136,7 +135,6 @@ import com.xensource.xenapi.Types.BadServerResponse; import com.xensource.xenapi.Types.XenAPIException; @RunWith(PowerMockRunner.class) -@PrepareForTest({ Connection.class, Host.Record.class }) public class CitrixRequestWrapperTest { @Mock @@ -279,7 +277,7 @@ public class CitrixRequestWrapperTest { } @Test - public void testStopCommandCommand() { + public void testStopCommand() { final StopCommand stopCommand = new StopCommand("Test", false, false); final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); From 7086d64387fd0fb6381e4dbb63d46361d619b948 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 22 Apr 2015 14:53:28 +0200 Subject: [PATCH 02/36] Refactoring the LibvirtComputingResource - Adding LibvirtGetVmStatsCommandWrapper - 3 unit tests Refactored the LibvirtConnectiobn by surrounding it with an wrapper. - Make it easier to cover the static/native calls - Added better coverage to StopCommand tests --- .../spring-kvm-compute-context.xml | 3 + .../resource/LibvirtComputingResource.java | 15 ++- .../wrapper/LibvirtConnectionWrapper.java | 33 ++++++ .../LibvirtGetVmStatsCommandWrapper.java | 63 +++++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../wrapper/LibvirtStopCommandWrapper.java | 21 ++-- .../LibvirtComputingResourceTest.java | 106 +++++++++++++++++- 7 files changed, 227 insertions(+), 16 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java diff --git a/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml b/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml index ce596f22bbf..de6853e3b9d 100644 --- a/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml +++ b/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml @@ -31,4 +31,7 @@ + + 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 892e9063688..5969df35573 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 @@ -59,6 +59,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.ejb.Local; +import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; @@ -230,6 +231,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VirtioSerialDef; +import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; import com.cloud.hypervisor.kvm.storage.KVMStoragePool; @@ -332,6 +334,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver"; protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver"; + @Inject + private LibvirtConnectionWrapper libvirtConnectionWrapper; + @Override public ExecutionResult executeInVR(final String routerIp, final String script, final String args) { return executeInVR(routerIp, script, args, _timeout / 1000); @@ -393,6 +398,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ExecutionResult(true, null); } + public LibvirtConnectionWrapper getLibvirtConnectionWrapper() { + return libvirtConnectionWrapper; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -915,7 +924,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } s_logger.debug("Found pif: " + _pifs.get("private") + " on " + _privBridgeName + ", pif: " + _pifs.get("public") + " on " + _publicBridgeName); - _canBridgeFirewall = can_bridge_firewall(_pifs.get("public")); + _canBridgeFirewall = canBridgeFirewall(_pifs.get("public")); _localGateway = Script.runSimpleBashScript("ip route |grep default|awk '{print $3}'"); if (_localGateway == null) { @@ -4917,7 +4926,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv Calendar _timestamp; } - VmStatsEntry getVmStat(final Connect conn, final String vmName) throws LibvirtException { + public VmStatsEntry getVmStat(final Connect conn, final String vmName) throws LibvirtException { Domain dm = null; try { dm = getDomain(conn, vmName); @@ -5020,7 +5029,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private boolean can_bridge_firewall(final String prvNic) { + private boolean canBridgeFirewall(final String prvNic) { final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("can_bridge_firewall"); cmd.add(prvNic); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java new file mode 100644 index 00000000000..40643c13b20 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java @@ -0,0 +1,33 @@ +// 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.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.hypervisor.kvm.resource.LibvirtConnection; + +/** + * This class is used to wrapp the calls to LibvirtConnection and ease the burden of the unit tests. + * Please do not instantiate this class directly, but inject it using the {@code @Inject} annotation. + */ +public class LibvirtConnectionWrapper { + + public Connect getConnectionByName(final String vmName) throws LibvirtException { + return LibvirtConnection.getConnectionByVmName(vmName); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java new file mode 100644 index 00000000000..d894243fa8a --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java @@ -0,0 +1,63 @@ +// +// 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 java.util.HashMap; +import java.util.List; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVmStatsAnswer; +import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.VmStatsEntry; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtGetVmStatsCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtGetVmStatsCommandWrapper.class); + + @Override + public Answer execute(final GetVmStatsCommand command, final LibvirtComputingResource libvirtComputingResource) { + final List vmNames = command.getVmNames(); + try { + final HashMap vmStatsNameMap = new HashMap(); + for (final String vmName : vmNames) { + + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByName(vmName); + final VmStatsEntry statEntry = libvirtComputingResource.getVmStat(conn, vmName); + if (statEntry == null) { + continue; + } + + vmStatsNameMap.put(vmName, statEntry); + } + return new GetVmStatsAnswer(command, vmStatsNameMap); + } catch (final LibvirtException e) { + s_logger.debug("Can't get vm stats: " + e.toString()); + return new GetVmStatsAnswer(command, null); + } + } +} \ 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 fc039b8d163..26dc305e68d 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 @@ -22,6 +22,7 @@ import java.util.Hashtable; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.StopCommand; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.resource.CommandWrapper; @@ -46,6 +47,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { final Hashtable, CommandWrapper> linbvirtCommands = new Hashtable, CommandWrapper>(); linbvirtCommands.put(StopCommand.class, new LibvirtStopCommandWrapper()); + linbvirtCommands.put(GetVmStatsCommand.class, new LibvirtGetVmStatsCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java index 3e6c6b4adfa..c5d6a5bd56e 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java @@ -31,7 +31,6 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; -import com.cloud.hypervisor.kvm.resource.LibvirtConnection; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; import com.cloud.hypervisor.kvm.resource.VifDriver; @@ -42,12 +41,14 @@ public final class LibvirtStopCommandWrapper extends CommandWrapper disks = citrixResourceBase.getDisks(conn, vmName); - final List ifaces = citrixResourceBase.getInterfaces(conn, vmName); + final List disks = libvirtComputingResource.getDisks(conn, vmName); + final List ifaces = libvirtComputingResource.getInterfaces(conn, vmName); - citrixResourceBase.destroyNetworkRulesForVM(conn, vmName); - final String result = citrixResourceBase.stopVM(conn, vmName); + libvirtComputingResource.destroyNetworkRulesForVM(conn, vmName); + final String result = libvirtComputingResource.stopVM(conn, vmName); if (result == null) { for (final DiskDef disk : disks) { - citrixResourceBase.cleanupDisk(disk); + libvirtComputingResource.cleanupDisk(disk); } for (final InterfaceDef iface : ifaces) { // We don't know which "traffic type" is associated with // each interface at this point, so inform all vif drivers - for (final VifDriver vifDriver : citrixResourceBase.getAllVifDrivers()) { + for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) { vifDriver.unplug(iface); } } 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 881ebc522b1..0d8c3f509f0 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 @@ -20,9 +20,15 @@ package com.cloud.hypervisor.kvm.resource; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; @@ -54,11 +60,14 @@ import org.powermock.modules.junit4.PowerMockRunner; import org.w3c.dom.Document; import org.xml.sax.SAXException; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; +import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; @@ -379,16 +388,107 @@ public class LibvirtComputingResourceTest { * New Tests */ - @Test(expected = UnsatisfiedLinkError.class) - public void testStopCommand() { + @Test + public void testStopCommandNoCheck() { // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need // a better way to mock stuff! + + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final String vmName = "Test"; final StopCommand stopCommand = new StopCommand(vmName, false, false); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); assertNotNull(wrapper); - wrapper.execute(stopCommand, libvirtComputingResource); + final Answer answer = wrapper.execute(stopCommand, libvirtComputingResource); + + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testStopCommandCheck() { + // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need + // a better way to mock stuff! + + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Domain domain = Mockito.mock(Domain.class); + + final String vmName = "Test"; + final StopCommand stopCommand = new StopCommand(vmName, false, true); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByName(vmName)).thenReturn(conn); + when(conn.domainLookupByName(stopCommand.getVmName())).thenReturn(domain); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(stopCommand, libvirtComputingResource); + + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(2)).getConnectionByName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testGetVmStatsCommand() { + // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need + // a better way to mock stuff! + + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; + final List vms = new ArrayList(); + vms.add(vmName); + + final GetVmStatsCommand stopCommand = new GetVmStatsCommand(vms, uuid, "hostname"); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(stopCommand, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } } } \ No newline at end of file From 51093afcf11ef37b3d54c5430b955e87e17d2be2 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 22 Apr 2015 15:05:59 +0200 Subject: [PATCH 03/36] Refactoring the LibvirtComputingResource - Adding LibvirtGetVmDiskStatsCommandWrapper - 1 unit test Added getConnection() to LibvirtConnectionWrapper --- .../resource/LibvirtComputingResource.java | 96 +------------------ .../wrapper/LibvirtConnectionWrapper.java | 6 +- .../LibvirtGetVmDiskStatsCommandWrapper.java | 62 ++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 37 +++++++ 5 files changed, 108 insertions(+), 95 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java 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 5969df35573..82ea791333d 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 @@ -117,10 +117,6 @@ import com.cloud.agent.api.GetHostStatsAnswer; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; -import com.cloud.agent.api.GetVmDiskStatsAnswer; -import com.cloud.agent.api.GetVmDiskStatsCommand; -import com.cloud.agent.api.GetVmStatsAnswer; -import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.GetVncPortAnswer; import com.cloud.agent.api.GetVncPortCommand; import com.cloud.agent.api.HostStatsEntry; @@ -169,8 +165,6 @@ import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupStorageCommand; -import com.cloud.agent.api.StopAnswer; -import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.UnPlugNicAnswer; import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; @@ -1304,11 +1298,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof GetVmStatsCommand) { - return execute((GetVmStatsCommand)cmd); - } else if (cmd instanceof GetVmDiskStatsCommand) { - return execute((GetVmDiskStatsCommand)cmd); - } else if (cmd instanceof RebootRouterCommand) { + if (cmd instanceof RebootRouterCommand) { return execute((RebootRouterCommand)cmd); } else if (cmd instanceof RebootCommand) { return execute((RebootCommand)cmd); @@ -3460,88 +3450,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected GetVmDiskStatsAnswer execute(final GetVmDiskStatsCommand cmd) { - final List vmNames = cmd.getVmNames(); - try { - final HashMap> vmDiskStatsNameMap = new HashMap>(); - final Connect conn = LibvirtConnection.getConnection(); - for (final String vmName : vmNames) { - final List statEntry = getVmDiskStat(conn, vmName); - if (statEntry == null) { - continue; - } - - vmDiskStatsNameMap.put(vmName, statEntry); - } - return new GetVmDiskStatsAnswer(cmd, "", cmd.getHostName(), vmDiskStatsNameMap); - } catch (final LibvirtException e) { - s_logger.debug("Can't get vm disk stats: " + e.toString()); - return new GetVmDiskStatsAnswer(cmd, null, null, null); - } - } - - protected GetVmStatsAnswer execute(final GetVmStatsCommand cmd) { - final List vmNames = cmd.getVmNames(); - try { - final HashMap vmStatsNameMap = new HashMap(); - for (final String vmName : vmNames) { - final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - final VmStatsEntry statEntry = getVmStat(conn, vmName); - if (statEntry == null) { - continue; - } - - vmStatsNameMap.put(vmName, statEntry); - } - return new GetVmStatsAnswer(cmd, vmStatsNameMap); - } catch (final LibvirtException e) { - s_logger.debug("Can't get vm stats: " + e.toString()); - return new GetVmStatsAnswer(cmd, null); - } - } - - protected Answer execute(final StopCommand cmd) { - final String vmName = cmd.getVmName(); - - if (cmd.checkBeforeCleanup()) { - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - final Domain vm = conn.domainLookupByName(cmd.getVmName()); - if (vm != null && vm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING) { - return new StopAnswer(cmd, "vm is still running on host", false); - } - } catch (final Exception e) { - s_logger.debug("Failed to get vm status in case of checkboforecleanup is true", e); - } - } - - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - - final List disks = getDisks(conn, vmName); - final List ifaces = getInterfaces(conn, vmName); - - destroyNetworkRulesForVM(conn, vmName); - final String result = stopVM(conn, vmName); - if (result == null) { - for (final DiskDef disk : disks) { - cleanupDisk(disk); - } - for (final InterfaceDef iface : ifaces) { - // We don't know which "traffic type" is associated with - // each interface at this point, so inform all vif drivers - for (final VifDriver vifDriver : getAllVifDrivers()) { - vifDriver.unplug(iface); - } - } - } - - return new StopAnswer(cmd, result, true); - } catch (final LibvirtException e) { - return new StopAnswer(cmd, e.getMessage(), false); - } - } - protected Answer execute(final ModifySshKeysCommand cmd) { final File sshKeysDir = new File(SSHKEYSPATH); String result = null; @@ -4881,7 +4789,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return command.execute(); } - private List getVmDiskStat(final Connect conn, final String vmName) throws LibvirtException { + public List getVmDiskStat(final Connect conn, final String vmName) throws LibvirtException { Domain dm = null; try { dm = getDomain(conn, vmName); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java index 40643c13b20..0a6b966d61a 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java @@ -22,7 +22,7 @@ import org.libvirt.LibvirtException; import com.cloud.hypervisor.kvm.resource.LibvirtConnection; /** - * This class is used to wrapp the calls to LibvirtConnection and ease the burden of the unit tests. + * This class is used to wrap the calls to LibvirtConnection and ease the burden of the unit tests. * Please do not instantiate this class directly, but inject it using the {@code @Inject} annotation. */ public class LibvirtConnectionWrapper { @@ -30,4 +30,8 @@ public class LibvirtConnectionWrapper { public Connect getConnectionByName(final String vmName) throws LibvirtException { return LibvirtConnection.getConnectionByVmName(vmName); } + + public Connect getConnection() throws LibvirtException { + return LibvirtConnection.getConnection(); + } } \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java new file mode 100644 index 00000000000..32ff7dfc9e2 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java @@ -0,0 +1,62 @@ +// +// 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 java.util.HashMap; +import java.util.List; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVmDiskStatsAnswer; +import com.cloud.agent.api.GetVmDiskStatsCommand; +import com.cloud.agent.api.VmDiskStatsEntry; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtGetVmDiskStatsCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtGetVmDiskStatsCommandWrapper.class); + + @Override + public Answer execute(final GetVmDiskStatsCommand command, final LibvirtComputingResource libvirtComputingResource) { + final List vmNames = command.getVmNames(); + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + try { + final HashMap> vmDiskStatsNameMap = new HashMap>(); + final Connect conn = libvirtConnectionWrapper.getConnection(); + for (final String vmName : vmNames) { + final List statEntry = libvirtComputingResource.getVmDiskStat(conn, vmName); + if (statEntry == null) { + continue; + } + + vmDiskStatsNameMap.put(vmName, statEntry); + } + return new GetVmDiskStatsAnswer(command, "", command.getHostName(), vmDiskStatsNameMap); + } catch (final LibvirtException e) { + s_logger.debug("Can't get vm disk stats: " + e.toString()); + return new GetVmDiskStatsAnswer(command, null, null, null); + } + } +} \ 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 26dc305e68d..c74a09797fe 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 @@ -22,6 +22,7 @@ import java.util.Hashtable; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.StopCommand; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; @@ -48,6 +49,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(StopCommand.class, new LibvirtStopCommandWrapper()); linbvirtCommands.put(GetVmStatsCommand.class, new LibvirtGetVmStatsCommandWrapper()); + linbvirtCommands.put(GetVmDiskStatsCommand.class, new LibvirtGetVmDiskStatsCommandWrapper()); 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 0d8c3f509f0..cd1255631ce 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 @@ -61,6 +61,7 @@ import org.w3c.dom.Document; import org.xml.sax.SAXException; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.VmStatsEntry; @@ -491,4 +492,40 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testGetVmDiskStatsCommand() { + // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need + // a better way to mock stuff! + + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; + final List vms = new ArrayList(); + vms.add(vmName); + + final GetVmDiskStatsCommand stopCommand = new GetVmDiskStatsCommand(vms, uuid, "hostname"); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnection()).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(stopCommand, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnection(); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From 7a90c018fbba0419c55c245aa1cb3488472d2a62 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 22 Apr 2015 16:06:43 +0200 Subject: [PATCH 04/36] Refactoring the LibvirtComputingResource - Adding LibvirtRebootCommandWrapper and LibVirtRebootRouterCommandWrapper - 2 unit tests added - KVM hypervisor with 10.5% coverage --- .../resource/LibvirtComputingResource.java | 55 ++-------- .../wrapper/LibvirtConnectionWrapper.java | 2 +- .../LibvirtGetVmStatsCommandWrapper.java | 2 +- .../wrapper/LibvirtRebootCommandWrapper.java | 59 ++++++++++ .../LibvirtRebootRouterCommandWrapper.java | 47 ++++++++ .../wrapper/LibvirtRequestWrapper.java | 4 + .../wrapper/LibvirtStopCommandWrapper.java | 4 +- .../LibvirtComputingResourceTest.java | 102 +++++++++++++++--- 8 files changed, 211 insertions(+), 64 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java 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 82ea791333d..a559e9965c7 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 @@ -154,9 +154,6 @@ import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.ReadyCommand; -import com.cloud.agent.api.RebootAnswer; -import com.cloud.agent.api.RebootCommand; -import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SetupGuestNetworkCommand; @@ -396,6 +393,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return libvirtConnectionWrapper; } + public VirtualRoutingResource getVirtRouterResource() { + return _virtRouterResource; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1298,11 +1299,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof RebootRouterCommand) { - return execute((RebootRouterCommand)cmd); - } else if (cmd instanceof RebootCommand) { - return execute((RebootCommand)cmd); - } else if (cmd instanceof GetHostStatsCommand) { + if (cmd instanceof GetHostStatsCommand) { return execute((GetHostStatsCommand)cmd); } else if (cmd instanceof CheckStateCommand) { return executeRequest(cmd); @@ -3310,7 +3307,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new GetHostStatsAnswer(cmd, hostStats); } - protected String networkUsage(final String privateIpAddress, final String option, final String vif) { + public String networkUsage(final String privateIpAddress, final String option, final String vif) { final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("netusage.sh"); getUsage.add(privateIpAddress); @@ -3418,38 +3415,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(final RebootCommand cmd) { - - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - final String result = rebootVM(conn, cmd.getVmName()); - if (result == null) { - Integer vncPort = null; - try { - vncPort = getVncPort(conn, cmd.getVmName()); - } catch (final LibvirtException e) { - s_logger.trace("Ignoring libvirt error.", e); - } - get_rule_logs_for_vms(); - return new RebootAnswer(cmd, null, vncPort); - } else { - return new RebootAnswer(cmd, result, false); - } - } catch (final LibvirtException e) { - return new RebootAnswer(cmd, e.getMessage(), false); - } - } - - protected Answer execute(final RebootRouterCommand cmd) { - final RebootAnswer answer = (RebootAnswer)execute((RebootCommand)cmd); - if (_virtRouterResource.connect(cmd.getPrivateIpAddress())) { - networkUsage(cmd.getPrivateIpAddress(), "create", null); - return answer; - } else { - return new Answer(cmd, false, "Failed to connect to virtual router " + cmd.getVmName()); - } - } - protected Answer execute(final ModifySshKeysCommand cmd) { final File sshKeysDir = new File(SSHKEYSPATH); String result = null; @@ -4466,7 +4431,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected String rebootVM(final Connect conn, final String vmName) { + public String rebootVM(final Connect conn, final String vmName) { Domain dm = null; String msg = null; try { @@ -4625,7 +4590,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return null; } - protected Integer getVncPort(final Connect conn, final String vmName) throws LibvirtException { + public Integer getVncPort(final Connect conn, final String vmName) throws LibvirtException { final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); Domain dm = null; try { @@ -5114,7 +5079,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - private String get_rule_logs_for_vms() { + public String getRuleLogsForVms() { final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("get_rule_logs_for_vms"); final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); @@ -5128,7 +5093,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private HashMap> syncNetworkGroups(final long id) { final HashMap> states = new HashMap>(); - final String result = get_rule_logs_for_vms(); + final String result = getRuleLogsForVms(); s_logger.trace("syncNetworkGroups: id=" + id + " got: " + result); final String[] rulelogs = result != null ? result.split(";") : new String[0]; for (final String rulesforvm : rulelogs) { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java index 0a6b966d61a..e6743ace118 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java @@ -27,7 +27,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtConnection; */ public class LibvirtConnectionWrapper { - public Connect getConnectionByName(final String vmName) throws LibvirtException { + public Connect getConnectionByVmName(final String vmName) throws LibvirtException { return LibvirtConnection.getConnectionByVmName(vmName); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java index d894243fa8a..e0649dae837 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java @@ -46,7 +46,7 @@ public final class LibvirtGetVmStatsCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtRebootCommandWrapper.class); + + @Override + public Answer execute(final RebootCommand command, final LibvirtComputingResource libvirtComputingResource) { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + try { + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(command.getVmName()); + final String result = libvirtComputingResource.rebootVM(conn, command.getVmName()); + if (result == null) { + Integer vncPort = null; + try { + vncPort = libvirtComputingResource.getVncPort(conn, command.getVmName()); + } catch (final LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); + } + libvirtComputingResource.getRuleLogsForVms(); + return new RebootAnswer(command, null, vncPort); + } else { + return new RebootAnswer(command, result, false); + } + } catch (final LibvirtException e) { + return new RebootAnswer(command, e.getMessage(), false); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java new file mode 100644 index 00000000000..671b8c800c4 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootRouterCommandWrapper.java @@ -0,0 +1,47 @@ +// +// 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.RebootCommand; +import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtRebootRouterCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final RebootRouterCommand command, final LibvirtComputingResource libvirtComputingResource) { + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + + final RebootCommand rebootCommand = new RebootCommand(command.getVmName()); + final Answer answer = wrapper.execute(rebootCommand, libvirtComputingResource); + + final VirtualRoutingResource virtualRouterResource = libvirtComputingResource.getVirtRouterResource(); + if (virtualRouterResource.connect(command.getPrivateIpAddress())) { + libvirtComputingResource.networkUsage(command.getPrivateIpAddress(), "create", null); + + return answer; + } else { + return new Answer(command, false, "Failed to connect to virtual router " + command.getVmName()); + } + } +} \ 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 c74a09797fe..c2c3d8b5d28 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 @@ -24,6 +24,8 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.resource.CommandWrapper; @@ -50,6 +52,8 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(StopCommand.class, new LibvirtStopCommandWrapper()); linbvirtCommands.put(GetVmStatsCommand.class, new LibvirtGetVmStatsCommandWrapper()); linbvirtCommands.put(GetVmDiskStatsCommand.class, new LibvirtGetVmDiskStatsCommandWrapper()); + linbvirtCommands.put(RebootRouterCommand.class, new LibvirtRebootRouterCommandWrapper()); + linbvirtCommands.put(RebootCommand.class, new LibvirtRebootCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java index c5d6a5bd56e..280c7f1e7de 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java @@ -48,7 +48,7 @@ public final class LibvirtStopCommandWrapper extends CommandWrapper disks = libvirtComputingResource.getDisks(conn, vmName); final List ifaces = libvirtComputingResource.getInterfaces(conn, vmName); 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 cd1255631ce..8457e23b768 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 @@ -19,6 +19,7 @@ package com.cloud.hypervisor.kvm.resource; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -63,9 +64,12 @@ import org.xml.sax.SAXException; import com.cloud.agent.api.Answer; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; @@ -398,11 +402,11 @@ public class LibvirtComputingResourceTest { final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); final String vmName = "Test"; - final StopCommand stopCommand = new StopCommand(vmName, false, false); + final StopCommand command = new StopCommand(vmName, false, false); when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); try { - when(libvirtConnectionWrapper.getConnectionByName(vmName)).thenReturn(conn); + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -410,13 +414,13 @@ public class LibvirtComputingResourceTest { final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); assertNotNull(wrapper); - final Answer answer = wrapper.execute(stopCommand, libvirtComputingResource); + final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByName(vmName); + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -432,12 +436,12 @@ public class LibvirtComputingResourceTest { final Domain domain = Mockito.mock(Domain.class); final String vmName = "Test"; - final StopCommand stopCommand = new StopCommand(vmName, false, true); + final StopCommand command = new StopCommand(vmName, false, true); when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); try { - when(libvirtConnectionWrapper.getConnectionByName(vmName)).thenReturn(conn); - when(conn.domainLookupByName(stopCommand.getVmName())).thenReturn(domain); + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(conn.domainLookupByName(command.getVmName())).thenReturn(domain); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -445,13 +449,13 @@ public class LibvirtComputingResourceTest { final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); assertNotNull(wrapper); - final Answer answer = wrapper.execute(stopCommand, libvirtComputingResource); + final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(2)).getConnectionByName(vmName); + verify(libvirtConnectionWrapper, times(2)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -470,11 +474,11 @@ public class LibvirtComputingResourceTest { final List vms = new ArrayList(); vms.add(vmName); - final GetVmStatsCommand stopCommand = new GetVmStatsCommand(vms, uuid, "hostname"); + final GetVmStatsCommand command = new GetVmStatsCommand(vms, uuid, "hostname"); when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); try { - when(libvirtConnectionWrapper.getConnectionByName(vmName)).thenReturn(conn); + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -482,12 +486,12 @@ public class LibvirtComputingResourceTest { final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); assertNotNull(wrapper); - final Answer answer = wrapper.execute(stopCommand, libvirtComputingResource); + final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByName(vmName); + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -506,7 +510,7 @@ public class LibvirtComputingResourceTest { final List vms = new ArrayList(); vms.add(vmName); - final GetVmDiskStatsCommand stopCommand = new GetVmDiskStatsCommand(vms, uuid, "hostname"); + final GetVmDiskStatsCommand command = new GetVmDiskStatsCommand(vms, uuid, "hostname"); when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); try { @@ -518,7 +522,7 @@ public class LibvirtComputingResourceTest { final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); assertNotNull(wrapper); - final Answer answer = wrapper.execute(stopCommand, libvirtComputingResource); + final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); @@ -528,4 +532,72 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testRebootCommand() { + // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need + // a better way to mock stuff! + + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final RebootCommand command = new RebootCommand(vmName); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testRebootRouterCommand() { + // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need + // a better way to mock stuff! + + final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class); + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final RebootRouterCommand command = new RebootRouterCommand(vmName, "192.168.0.10"); + + when(libvirtComputingResource.getVirtRouterResource()).thenReturn(routingResource); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getVirtRouterResource(); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From 6e568125fc282a3d0984f59fa0755b087e29cf7f Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 23 Apr 2015 10:30:13 +0200 Subject: [PATCH 05/36] Refactoring the LibvirtComputingResource - Adding LibvirtGetHosStatsCommandWrapper - 1 unit test added - KVM hypervisor with 10.5% coverage Tests are a bit limited on this one becuause of the current implementation. Would clean it up later in a separate branch --- .../resource/LibvirtComputingResource.java | 55 ++----------- .../LibvirtGetHostStatsCommandWrapper.java | 80 +++++++++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 3 + .../LibvirtComputingResourceTest.java | 34 ++++---- 4 files changed, 104 insertions(+), 68 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java 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 a559e9965c7..5d8fc3a7f6c 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 @@ -113,13 +113,10 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.FenceAnswer; import com.cloud.agent.api.FenceCommand; -import com.cloud.agent.api.GetHostStatsAnswer; -import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVncPortAnswer; import com.cloud.agent.api.GetVncPortCommand; -import com.cloud.agent.api.HostStatsEntry; import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.MaintainAnswer; import com.cloud.agent.api.MaintainCommand; @@ -397,6 +394,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _virtRouterResource; } + public String getPublicBridgeName() { + return _publicBridgeName; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1299,9 +1300,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof GetHostStatsCommand) { - return execute((GetHostStatsCommand)cmd); - } else if (cmd instanceof CheckStateCommand) { + if (cmd instanceof CheckStateCommand) { return executeRequest(cmd); } else if (cmd instanceof CheckHealthCommand) { return execute((CheckHealthCommand)cmd); @@ -3265,48 +3264,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new CheckHealthAnswer(cmd, true); } - private Answer execute(final GetHostStatsCommand cmd) { - final Script cpuScript = new Script("/bin/bash", s_logger); - cpuScript.add("-c"); - cpuScript.add("idle=$(top -b -n 1| awk -F, '/^[%]*[Cc]pu/{$0=$4; gsub(/[^0-9.,]+/,\"\"); print }'); echo $idle"); - - final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - String result = cpuScript.execute(parser); - if (result != null) { - s_logger.debug("Unable to get the host CPU state: " + result); - return new Answer(cmd, false, result); - } - final double cpuUtil = 100.0D - Double.parseDouble(parser.getLine()); - - long freeMem = 0; - final Script memScript = new Script("/bin/bash", s_logger); - memScript.add("-c"); - memScript.add("freeMem=$(free|grep cache:|awk '{print $4}');echo $freeMem"); - final OutputInterpreter.OneLineParser Memparser = new OutputInterpreter.OneLineParser(); - result = memScript.execute(Memparser); - if (result != null) { - s_logger.debug("Unable to get the host Mem state: " + result); - return new Answer(cmd, false, result); - } - freeMem = Long.parseLong(Memparser.getLine()); - - final Script totalMem = new Script("/bin/bash", s_logger); - totalMem.add("-c"); - totalMem.add("free|grep Mem:|awk '{print $2}'"); - final OutputInterpreter.OneLineParser totMemparser = new OutputInterpreter.OneLineParser(); - result = totalMem.execute(totMemparser); - if (result != null) { - s_logger.debug("Unable to get the host Mem state: " + result); - return new Answer(cmd, false, result); - } - final long totMem = Long.parseLong(totMemparser.getLine()); - - final Pair nicStats = getNicStats(_publicBridgeName); - - final HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", totMem, freeMem, 0, 0); - return new GetHostStatsAnswer(cmd, hostStats); - } - public String networkUsage(final String privateIpAddress, final String option, final String vif) { final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("netusage.sh"); @@ -5120,7 +5077,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - static Pair getNicStats(final String nicName) { + public Pair getNicStats(final String nicName) { return new Pair(readDouble(nicName, "rx_bytes"), readDouble(nicName, "tx_bytes")); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java new file mode 100644 index 00000000000..ba9ba188dad --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java @@ -0,0 +1,80 @@ +// +// 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.GetHostStatsAnswer; +import com.cloud.agent.api.GetHostStatsCommand; +import com.cloud.agent.api.HostStatsEntry; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.Pair; +import com.cloud.utils.script.OutputInterpreter; +import com.cloud.utils.script.Script; + +public final class LibvirtGetHostStatsCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtGetHostStatsCommandWrapper.class); + + @Override + public Answer execute(final GetHostStatsCommand command, final LibvirtComputingResource libvirtComputingResource) { + final Script cpuScript = new Script("/bin/bash", s_logger); + cpuScript.add("-c"); + cpuScript.add("idle=$(top -b -n 1| awk -F, '/^[%]*[Cc]pu/{$0=$4; gsub(/[^0-9.,]+/,\"\"); print }'); echo $idle"); + + final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); + String result = cpuScript.execute(parser); + if (result != null) { + s_logger.debug("Unable to get the host CPU state: " + result); + return new Answer(command, false, result); + } + final double cpuUtil = 100.0D - Double.parseDouble(parser.getLine()); + + long freeMem = 0; + final Script memScript = new Script("/bin/bash", s_logger); + memScript.add("-c"); + memScript.add("freeMem=$(free|grep cache:|awk '{print $4}');echo $freeMem"); + final OutputInterpreter.OneLineParser Memparser = new OutputInterpreter.OneLineParser(); + result = memScript.execute(Memparser); + if (result != null) { + s_logger.debug("Unable to get the host Mem state: " + result); + return new Answer(command, false, result); + } + freeMem = Long.parseLong(Memparser.getLine()); + + final Script totalMem = new Script("/bin/bash", s_logger); + totalMem.add("-c"); + totalMem.add("free|grep Mem:|awk '{print $2}'"); + final OutputInterpreter.OneLineParser totMemparser = new OutputInterpreter.OneLineParser(); + result = totalMem.execute(totMemparser); + if (result != null) { + s_logger.debug("Unable to get the host Mem state: " + result); + return new Answer(command, false, result); + } + final long totMem = Long.parseLong(totMemparser.getLine()); + + final Pair nicStats = libvirtComputingResource.getNicStats(libvirtComputingResource.getPublicBridgeName()); + + final HostStatsEntry hostStats = new HostStatsEntry(command.getHostId(), cpuUtil, nicStats.first() / 1024, nicStats.second() / 1024, "host", totMem, freeMem, 0, 0); + return new GetHostStatsAnswer(command, hostStats); + } +} \ 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 c2c3d8b5d28..e76a4eb4680 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 @@ -22,6 +22,7 @@ import java.util.Hashtable; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.RebootCommand; @@ -54,6 +55,8 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(GetVmDiskStatsCommand.class, new LibvirtGetVmDiskStatsCommandWrapper()); linbvirtCommands.put(RebootRouterCommand.class, new LibvirtRebootRouterCommandWrapper()); linbvirtCommands.put(RebootCommand.class, new LibvirtRebootCommandWrapper()); + linbvirtCommands.put(GetHostStatsCommand.class, new LibvirtGetHostStatsCommandWrapper()); + 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 8457e23b768..85f2c74c0f9 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 @@ -62,6 +62,7 @@ import org.w3c.dom.Document; import org.xml.sax.SAXException; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.RebootCommand; @@ -289,7 +290,8 @@ public class LibvirtComputingResourceTest { //this test is only working on linux because of the loopback interface name //also the tested code seems to work only on linux Assume.assumeTrue(SystemUtils.IS_OS_LINUX); - final Pair stats = LibvirtComputingResource.getNicStats("lo"); + final LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource(); + final Pair stats = libvirtComputingResource.getNicStats("lo"); assertNotNull(stats); } @@ -395,9 +397,6 @@ public class LibvirtComputingResourceTest { @Test public void testStopCommandNoCheck() { - // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need - // a better way to mock stuff! - final Connect conn = Mockito.mock(Connect.class); final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); @@ -428,9 +427,6 @@ public class LibvirtComputingResourceTest { @Test public void testStopCommandCheck() { - // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need - // a better way to mock stuff! - final Connect conn = Mockito.mock(Connect.class); final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); final Domain domain = Mockito.mock(Domain.class); @@ -463,9 +459,6 @@ public class LibvirtComputingResourceTest { @Test public void testGetVmStatsCommand() { - // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need - // a better way to mock stuff! - final Connect conn = Mockito.mock(Connect.class); final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); @@ -499,9 +492,6 @@ public class LibvirtComputingResourceTest { @Test public void testGetVmDiskStatsCommand() { - // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need - // a better way to mock stuff! - final Connect conn = Mockito.mock(Connect.class); final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); @@ -535,9 +525,6 @@ public class LibvirtComputingResourceTest { @Test public void testRebootCommand() { - // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need - // a better way to mock stuff! - final Connect conn = Mockito.mock(Connect.class); final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); @@ -567,9 +554,6 @@ public class LibvirtComputingResourceTest { @Test public void testRebootRouterCommand() { - // We cannot do much here due to the Native libraries and Static methods used by the LibvirtConnection we need - // a better way to mock stuff! - final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class); final Connect conn = Mockito.mock(Connect.class); final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); @@ -600,4 +584,16 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test(expected = NumberFormatException.class) + public void testGetHostStatsCommand() { + final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; + final GetHostStatsCommand command = new GetHostStatsCommand(uuid, "summer", 1l); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } } \ No newline at end of file From 54f68f519fc3baefe435f9b37f028ff2cca9106f Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 23 Apr 2015 10:45:57 +0200 Subject: [PATCH 06/36] Removing the CheckStateCommand form the IF statement on LibvirtComputingResource - It's not used and if so would cause an infinite loop. --- .../hypervisor/kvm/resource/LibvirtComputingResource.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 5d8fc3a7f6c..b90b28b86fc 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 @@ -100,7 +100,6 @@ import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CheckStateCommand; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; @@ -1300,9 +1299,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof CheckStateCommand) { - return executeRequest(cmd); - } else if (cmd instanceof CheckHealthCommand) { + if (cmd instanceof CheckHealthCommand) { return execute((CheckHealthCommand)cmd); } else if (cmd instanceof PrepareForMigrationCommand) { return execute((PrepareForMigrationCommand)cmd); From d730efb86681b2206b82cbacc828e77e1204367b Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 23 Apr 2015 11:36:38 +0200 Subject: [PATCH 07/36] Refactoring the LibvirtComputingResource - Adding LibvirtCheckHealthCommandWrapper and LibvirtPrepareForMigrationCommandWrapper - 2 unit tests added - KVM hypervisor plugin with 10.8% coverage --- .../resource/LibvirtComputingResource.java | 68 ++------------ .../LibvirtCheckHealthCommandWrapper.java | 34 +++++++ ...virtPrepareForMigrationCommandWrapper.java | 89 +++++++++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 4 + .../LibvirtComputingResourceTest.java | 72 +++++++++++++++ 5 files changed, 206 insertions(+), 61 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckHealthCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java 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 b90b28b86fc..69f291e2bc2 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 @@ -95,8 +95,6 @@ import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.CheckHealthAnswer; -import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; @@ -145,8 +143,6 @@ import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PlugNicAnswer; import com.cloud.agent.api.PlugNicCommand; -import com.cloud.agent.api.PrepareForMigrationAnswer; -import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.ReadyCommand; @@ -397,6 +393,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _publicBridgeName; } + public KVMStoragePoolManager getStoragePoolMgr() { + return _storagePoolMgr; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1044,7 +1044,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return vifDriver; } - protected VifDriver getVifDriver(final TrafficType trafficType) { + public VifDriver getVifDriver(final TrafficType trafficType) { VifDriver vifDriver = _trafficTypeVifDrivers.get(trafficType); if (vifDriver == null) { @@ -1299,11 +1299,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof CheckHealthCommand) { - return execute((CheckHealthCommand)cmd); - } else if (cmd instanceof PrepareForMigrationCommand) { - return execute((PrepareForMigrationCommand)cmd); - } else if (cmd instanceof MigrateCommand) { + if (cmd instanceof MigrateCommand) { return execute((MigrateCommand)cmd); } else if (cmd instanceof PingTestCommand) { return execute((PingTestCommand)cmd); @@ -3211,56 +3207,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private synchronized Answer execute(final PrepareForMigrationCommand cmd) { - - final VirtualMachineTO vm = cmd.getVirtualMachine(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Preparing host for migrating " + vm); - } - - final NicTO[] nics = vm.getNics(); - - boolean skipDisconnect = false; - - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(vm.getName()); - for (final NicTO nic : nics) { - getVifDriver(nic.getType()).plug(nic, null, ""); - } - - /* setup disks, e.g for iso */ - final DiskTO[] volumes = vm.getDisks(); - for (final DiskTO volume : volumes) { - if (volume.getType() == Volume.Type.ISO) { - getVolumePath(conn, volume); - } - } - - if (!_storagePoolMgr.connectPhysicalDisksViaVmSpec(vm)) { - skipDisconnect = true; - return new PrepareForMigrationAnswer(cmd, "failed to connect physical disks to host"); - } - - skipDisconnect = true; - - return new PrepareForMigrationAnswer(cmd); - } catch (final LibvirtException e) { - return new PrepareForMigrationAnswer(cmd, e.toString()); - } catch (final InternalErrorException e) { - return new PrepareForMigrationAnswer(cmd, e.toString()); - } catch (final URISyntaxException e) { - return new PrepareForMigrationAnswer(cmd, e.toString()); - } finally { - if (!skipDisconnect) { - _storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vm); - } - } - } - - private Answer execute(final CheckHealthCommand cmd) { - return new CheckHealthAnswer(cmd, true); - } - public String networkUsage(final String privateIpAddress, final String option, final String vif) { final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("netusage.sh"); @@ -3740,7 +3686,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private String getVolumePath(final Connect conn, final DiskTO volume) throws LibvirtException, URISyntaxException { + public String getVolumePath(final Connect conn, final DiskTO volume) throws LibvirtException, URISyntaxException { final DataTO data = volume.getData(); final DataStoreTO store = data.getDataStore(); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckHealthCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckHealthCommandWrapper.java new file mode 100644 index 00000000000..c89d031ccd7 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckHealthCommandWrapper.java @@ -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.CheckHealthAnswer; +import com.cloud.agent.api.CheckHealthCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtCheckHealthCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CheckHealthCommand command, final LibvirtComputingResource libvirtComputingResource) { + return new CheckHealthAnswer(command, true); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java new file mode 100644 index 00000000000..921d5b8cf64 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java @@ -0,0 +1,89 @@ +// +// 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 java.net.URISyntaxException; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.PrepareForMigrationAnswer; +import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.exception.InternalErrorException; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.storage.Volume; + +public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtPrepareForMigrationCommandWrapper.class); + + @Override + public Answer execute(final PrepareForMigrationCommand command, final LibvirtComputingResource libvirtComputingResource) { + final VirtualMachineTO vm = command.getVirtualMachine(); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Preparing host for migrating " + vm); + } + + final NicTO[] nics = vm.getNics(); + + boolean skipDisconnect = false; + + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(vm.getName()); + for (final NicTO nic : nics) { + libvirtComputingResource.getVifDriver(nic.getType()).plug(nic, null, ""); + } + + /* setup disks, e.g for iso */ + final DiskTO[] volumes = vm.getDisks(); + for (final DiskTO volume : volumes) { + if (volume.getType() == Volume.Type.ISO) { + libvirtComputingResource.getVolumePath(conn, volume); + } + } + + skipDisconnect = true; + + if (!libvirtComputingResource.getStoragePoolMgr().connectPhysicalDisksViaVmSpec(vm)) { + return new PrepareForMigrationAnswer(command, "failed to connect physical disks to host"); + } + + return new PrepareForMigrationAnswer(command); + } catch (final LibvirtException e) { + return new PrepareForMigrationAnswer(command, e.toString()); + } catch (final InternalErrorException e) { + return new PrepareForMigrationAnswer(command, e.toString()); + } catch (final URISyntaxException e) { + return new PrepareForMigrationAnswer(command, e.toString()); + } finally { + if (!skipDisconnect) { + libvirtComputingResource.getStoragePoolMgr().disconnectPhysicalDisksViaVmSpec(vm); + } + } + } +} \ 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 e76a4eb4680..d8ca27fd280 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 @@ -21,10 +21,12 @@ package com.cloud.hypervisor.kvm.resource.wrapper; import java.util.Hashtable; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; @@ -56,6 +58,8 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(RebootRouterCommand.class, new LibvirtRebootRouterCommandWrapper()); linbvirtCommands.put(RebootCommand.class, new LibvirtRebootCommandWrapper()); linbvirtCommands.put(GetHostStatsCommand.class, new LibvirtGetHostStatsCommandWrapper()); + linbvirtCommands.put(CheckHealthCommand.class, new LibvirtCheckHealthCommandWrapper()); + linbvirtCommands.put(PrepareForMigrationCommand.class, new LibvirtPrepareForMigrationCommandWrapper()); 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 85f2c74c0f9..9b4b4213d33 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 @@ -62,19 +62,26 @@ import org.w3c.dom.Document; import org.xml.sax.SAXException; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.VmStatsEntry; +import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; +import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; +import com.cloud.network.Networks.TrafficType; +import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine; @@ -587,6 +594,9 @@ public class LibvirtComputingResourceTest { @Test(expected = NumberFormatException.class) public void testGetHostStatsCommand() { + // A bit difficult top test due to the logger being passed and the parser itself relying on the connection. + // Have to spend some more time afterwards in order to refactor the wrapper itself. + final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; final GetHostStatsCommand command = new GetHostStatsCommand(uuid, "summer", 1l); @@ -596,4 +606,66 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertFalse(answer.getResult()); } + + @Test + public void testCheckHealthCommand() { + // A bit difficult top test due to the logger being passed and the parser itself relying on the connection. + // Have to spend some more time afterwards in order to refactor the wrapper itself. + + final CheckHealthCommand command = new CheckHealthCommand(); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + } + + @Test + public void testPrepareForMigrationCommand() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); + final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); + final NicTO nicTO = Mockito.mock(NicTO.class); + final DiskTO diskTO = Mockito.mock(DiskTO.class); + final VifDriver vifDriver = Mockito.mock(VifDriver.class); + + final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(vm.getNics()).thenReturn(new NicTO[]{nicTO}); + when(vm.getDisks()).thenReturn(new DiskTO[]{diskTO}); + + when(nicTO.getType()).thenReturn(TrafficType.Guest); + when(diskTO.getType()).thenReturn(Volume.Type.ISO); + + when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver); + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(vm, times(1)).getNics(); + verify(vm, times(1)).getDisks(); + verify(diskTO, times(1)).getType(); + } } \ No newline at end of file From 28e55462f15bdd8699e97b668c4ffc01735a533d Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 23 Apr 2015 13:31:58 +0200 Subject: [PATCH 08/36] Refactoring the LibvirtComputingResource - Adding LibvirtMigrateCommandWrapper - 1 unit tests added - KVM hypervisor plugin with 10.9% coverage --- .../resource/LibvirtComputingResource.java | 185 ++---------------- .../kvm/resource/MigrateKVMAsync.java | 38 ++++ .../wrapper/LibvirtMigrateCommandWrapper.java | 183 +++++++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 75 +++++++ 5 files changed, 319 insertions(+), 164 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java 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 69f291e2bc2..893f82dc40a 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 @@ -47,14 +47,11 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.UUID; -import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -119,8 +116,6 @@ 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.MigrateAnswer; -import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolAnswer; import com.cloud.agent.api.ModifyStoragePoolCommand; @@ -298,9 +293,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private String _dcId; private String _pod; private String _clusterId; - private int _migrateSpeed; - private int _migrateDowntime; - private int _migratePauseAfter; private long _hvVersion; private long _kernelVersion; @@ -397,6 +389,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _storagePoolMgr; } + public String getPrivateIp() { + return _privateIp; + } + + public int getMigrateDowntime() { + return _migrateDowntime; + } + + public int getMigratePauseAfter() { + return _migratePauseAfter; + } + + public int getMigrateSpeed() { + return _migrateSpeed; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -459,6 +467,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected String _videoHw; protected int _videoRam; protected Pair hostOsVersion; + protected int _migrateSpeed; + protected int _migrateDowntime; + protected int _migratePauseAfter; + private final Map _pifs = new HashMap(); private final Map _vmStats = new ConcurrentHashMap(); @@ -1299,9 +1311,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof MigrateCommand) { - return execute((MigrateCommand)cmd); - } else if (cmd instanceof PingTestCommand) { + if (cmd instanceof PingTestCommand) { return execute((PingTestCommand)cmd); } else if (cmd instanceof CheckVirtualMachineCommand) { return execute((CheckVirtualMachineCommand)cmd); @@ -3054,159 +3064,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return command.execute(); } - private Answer execute(final MigrateCommand cmd) { - final String vmName = cmd.getVmName(); - - String result = null; - - List ifaces = null; - List disks = null; - - Domain dm = null; - Connect dconn = null; - Domain destDomain = null; - Connect conn = null; - String xmlDesc = null; - try { - conn = LibvirtConnection.getConnectionByVmName(vmName); - ifaces = getInterfaces(conn, vmName); - disks = getDisks(conn, vmName); - dm = conn.domainLookupByName(vmName); - /* - We replace the private IP address with the address of the destination host. - This is because the VNC listens on the private IP address of the hypervisor, - but that address is ofcourse different on the target host. - - MigrateCommand.getDestinationIp() returns the private IP address of the target - hypervisor. So it's safe to use. - - The Domain.migrate method from libvirt supports passing a different XML - description for the instance to be used on the target host. - - This is supported by libvirt-java from version 0.50.0 - */ - xmlDesc = dm.getXMLDesc(0).replace(_privateIp, cmd.getDestinationIp()); - - dconn = new Connect("qemu+tcp://" + cmd.getDestinationIp() + "/system"); - - //run migration in thread so we can monitor it - s_logger.info("Live migration of instance " + vmName + " initiated"); - final ExecutorService executor = Executors.newFixedThreadPool(1); - final Callable worker = new MigrateKVMAsync(dm, dconn, xmlDesc, vmName, cmd.getDestinationIp()); - final Future migrateThread = executor.submit(worker); - executor.shutdown(); - long sleeptime = 0; - while (!executor.isTerminated()) { - Thread.sleep(100); - sleeptime += 100; - if (sleeptime == 1000) { // wait 1s before attempting to set downtime on migration, since I don't know of a VIR_DOMAIN_MIGRATING state - if (_migrateDowntime > 0 ) { - try { - final int setDowntime = dm.migrateSetMaxDowntime(_migrateDowntime); - if (setDowntime == 0 ) { - s_logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(_migrateDowntime) + "ms"); - } - } catch (final LibvirtException e) { - s_logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage()); - } - } - } - if (sleeptime % 1000 == 0) { - s_logger.info("Waiting for migration of " + vmName + " to complete, waited " + sleeptime + "ms"); - } - - // pause vm if we meet the vm.migrate.pauseafter threshold and not already paused - if (_migratePauseAfter > 0 && sleeptime > _migratePauseAfter && dm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING ) { - s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + _migratePauseAfter+ "ms to complete migration"); - try { - dm.suspend(); - } catch (final LibvirtException e) { - // pause could be racy if it attempts to pause right when vm is finished, simply warn - s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage()); - } - } - } - s_logger.info("Migration thread for " + vmName + " is done"); - - destDomain = migrateThread.get(10, TimeUnit.SECONDS); - - if (destDomain != null) { - for (final DiskDef disk : disks) { - cleanupDisk(disk); - } - } - } catch (final LibvirtException e) { - s_logger.debug("Can't migrate domain: " + e.getMessage()); - result = e.getMessage(); - } catch (final InterruptedException e) { - s_logger.debug("Interrupted while migrating domain: " + e.getMessage()); - result = e.getMessage(); - } catch (final ExecutionException e) { - s_logger.debug("Failed to execute while migrating domain: " + e.getMessage()); - result = e.getMessage(); - } catch (final TimeoutException e) { - s_logger.debug("Timed out while migrating domain: " + e.getMessage()); - result = e.getMessage(); - } finally { - try { - if (dm != null) { - if (dm.isPersistent() == 1) { - dm.undefine(); - } - dm.free(); - } - if (dconn != null) { - dconn.close(); - } - if (destDomain != null) { - destDomain.free(); - } - } catch (final LibvirtException e) { - s_logger.trace("Ignoring libvirt error.", e); - } - } - - if (result != null) { - } else { - destroyNetworkRulesForVM(conn, vmName); - for (final InterfaceDef iface : ifaces) { - // We don't know which "traffic type" is associated with - // each interface at this point, so inform all vif drivers - for (final VifDriver vifDriver : getAllVifDrivers()) { - vifDriver.unplug(iface); - } - } - } - - return new MigrateAnswer(cmd, result == null, result, null); - } - - private class MigrateKVMAsync implements Callable { - Domain dm = null; - Connect dconn = null; - String dxml = ""; - String vmName = ""; - String destIp = ""; - - MigrateKVMAsync(final Domain dm, final Connect dconn, final String dxml, final String vmName, final String destIp) { - this.dm = dm; - this.dconn = dconn; - this.dxml = dxml; - this.vmName = vmName; - this.destIp = destIp; - } - - @Override - public Domain call() throws LibvirtException { - // set compression flag for migration if libvirt version supports it - if (dconn.getLibVirVersion() < 1003000) { - return dm.migrate(dconn, 1 << 0, dxml, vmName, "tcp:" + destIp, _migrateSpeed); - } else { - return dm.migrate(dconn, 1 << 0|1 << 11, dxml, vmName, "tcp:" + destIp, _migrateSpeed); - } - } - } - public String networkUsage(final String privateIpAddress, final String option, final String vif) { final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("netusage.sh"); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java new file mode 100644 index 00000000000..fdec032ed5b --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/MigrateKVMAsync.java @@ -0,0 +1,38 @@ +package com.cloud.hypervisor.kvm.resource; + +import java.util.concurrent.Callable; + +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.LibvirtException; + +public class MigrateKVMAsync implements Callable { + + private final LibvirtComputingResource libvirtComputingResource; + + private Domain dm = null; + private Connect dconn = null; + private String dxml = ""; + private String vmName = ""; + private String destIp = ""; + + public MigrateKVMAsync(final LibvirtComputingResource libvirtComputingResource, final Domain dm, final Connect dconn, final String dxml, final String vmName, final String destIp) { + this.libvirtComputingResource = libvirtComputingResource; + + this.dm = dm; + this.dconn = dconn; + this.dxml = dxml; + this.vmName = vmName; + this.destIp = destIp; + } + + @Override + public Domain call() throws LibvirtException { + // set compression flag for migration if libvirt version supports it + if (dconn.getLibVirVersion() < 1003000) { + return dm.migrate(dconn, 1 << 0, dxml, vmName, "tcp:" + destIp, libvirtComputingResource.getMigrateSpeed()); + } else { + return dm.migrate(dconn, 1 << 0|1 << 11, dxml, vmName, "tcp:" + destIp, libvirtComputingResource.getMigrateSpeed()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java new file mode 100644 index 00000000000..d3637e62e3c --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateCommandWrapper.java @@ -0,0 +1,183 @@ +// +// 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 java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainInfo.DomainState; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.MigrateAnswer; +import com.cloud.agent.api.MigrateCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; +import com.cloud.hypervisor.kvm.resource.MigrateKVMAsync; +import com.cloud.hypervisor.kvm.resource.VifDriver; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtMigrateCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtMigrateCommandWrapper.class); + + @Override + public Answer execute(final MigrateCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String vmName = command.getVmName(); + + String result = null; + + List ifaces = null; + List disks = null; + + Domain dm = null; + Connect dconn = null; + Domain destDomain = null; + Connect conn = null; + String xmlDesc = null; + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + conn = libvirtConnectionWrapper.getConnectionByVmName(vmName); + ifaces = libvirtComputingResource.getInterfaces(conn, vmName); + disks = libvirtComputingResource.getDisks(conn, vmName); + dm = conn.domainLookupByName(vmName); + /* + We replace the private IP address with the address of the destination host. + This is because the VNC listens on the private IP address of the hypervisor, + but that address is ofcourse different on the target host. + + MigrateCommand.getDestinationIp() returns the private IP address of the target + hypervisor. So it's safe to use. + + The Domain.migrate method from libvirt supports passing a different XML + description for the instance to be used on the target host. + + This is supported by libvirt-java from version 0.50.0 + */ + xmlDesc = dm.getXMLDesc(0).replace(libvirtComputingResource.getPrivateIp(), command.getDestinationIp()); + + dconn = new Connect("qemu+tcp://" + command.getDestinationIp() + "/system"); + + //run migration in thread so we can monitor it + s_logger.info("Live migration of instance " + vmName + " initiated"); + final ExecutorService executor = Executors.newFixedThreadPool(1); + final Callable worker = new MigrateKVMAsync(libvirtComputingResource, dm, dconn, xmlDesc, vmName, command.getDestinationIp()); + final Future migrateThread = executor.submit(worker); + executor.shutdown(); + long sleeptime = 0; + while (!executor.isTerminated()) { + Thread.sleep(100); + sleeptime += 100; + if (sleeptime == 1000) { // wait 1s before attempting to set downtime on migration, since I don't know of a VIR_DOMAIN_MIGRATING state + final int migrateDowntime = libvirtComputingResource.getMigrateDowntime(); + if (migrateDowntime > 0 ) { + try { + final int setDowntime = dm.migrateSetMaxDowntime(migrateDowntime); + if (setDowntime == 0 ) { + s_logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(migrateDowntime) + "ms"); + } + } catch (final LibvirtException e) { + s_logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage()); + } + } + } + if (sleeptime % 1000 == 0) { + s_logger.info("Waiting for migration of " + vmName + " to complete, waited " + sleeptime + "ms"); + } + + // pause vm if we meet the vm.migrate.pauseafter threshold and not already paused + final int migratePauseAfter = libvirtComputingResource.getMigratePauseAfter(); + if (migratePauseAfter > 0 && sleeptime > migratePauseAfter && dm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING ) { + s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + migratePauseAfter+ "ms to complete migration"); + try { + dm.suspend(); + } catch (final LibvirtException e) { + // pause could be racy if it attempts to pause right when vm is finished, simply warn + s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage()); + } + } + } + s_logger.info("Migration thread for " + vmName + " is done"); + + destDomain = migrateThread.get(10, TimeUnit.SECONDS); + + if (destDomain != null) { + for (final DiskDef disk : disks) { + libvirtComputingResource.cleanupDisk(disk); + } + } + } catch (final LibvirtException e) { + s_logger.debug("Can't migrate domain: " + e.getMessage()); + result = e.getMessage(); + } catch (final InterruptedException e) { + s_logger.debug("Interrupted while migrating domain: " + e.getMessage()); + result = e.getMessage(); + } catch (final ExecutionException e) { + s_logger.debug("Failed to execute while migrating domain: " + e.getMessage()); + result = e.getMessage(); + } catch (final TimeoutException e) { + s_logger.debug("Timed out while migrating domain: " + e.getMessage()); + result = e.getMessage(); + } finally { + try { + if (dm != null) { + if (dm.isPersistent() == 1) { + dm.undefine(); + } + dm.free(); + } + if (dconn != null) { + dconn.close(); + } + if (destDomain != null) { + destDomain.free(); + } + } catch (final LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); + } + } + + if (result != null) { + } else { + libvirtComputingResource.destroyNetworkRulesForVM(conn, vmName); + for (final InterfaceDef iface : ifaces) { + // We don't know which "traffic type" is associated with + // each interface at this point, so inform all vif drivers + final List allVifDrivers = libvirtComputingResource.getAllVifDrivers(); + for (final VifDriver vifDriver : allVifDrivers) { + vifDriver.unplug(iface); + } + } + } + + return new MigrateAnswer(command, result == null, result, null); + } +} \ 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 d8ca27fd280..ee444b8e88f 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 @@ -26,6 +26,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; @@ -60,6 +61,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(GetHostStatsCommand.class, new LibvirtGetHostStatsCommandWrapper()); linbvirtCommands.put(CheckHealthCommand.class, new LibvirtCheckHealthCommandWrapper()); linbvirtCommands.put(PrepareForMigrationCommand.class, new LibvirtPrepareForMigrationCommandWrapper()); + linbvirtCommands.put(MigrateCommand.class, new LibvirtMigrateCommandWrapper()); 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 9b4b4213d33..4aa249e7f0a 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 @@ -23,6 +23,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -66,6 +67,7 @@ import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; @@ -668,4 +670,77 @@ public class LibvirtComputingResourceTest { verify(vm, times(1)).getDisks(); verify(diskTO, times(1)).getType(); } + + @Test(expected = UnsatisfiedLinkError.class) + public void testMigrateCommand() { + // The Connect constructor used inside the LibvirtMigrateCommandWrapper has a call to native methods, which + // makes difficult to test it now. + // Will keep it expecting the UnsatisfiedLinkError and fix later. + + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final String destIp = "10.1.1.100"; + final boolean isWindows = false; + final VirtualMachineTO vmTO = Mockito.mock(VirtualMachineTO.class); + final boolean executeInSequence = false; + + final MigrateCommand command = new MigrateCommand(vmName, destIp, isWindows, vmTO, executeInSequence ); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); + final List ifaces = new ArrayList(); + ifaces.add(interfaceDef); + + when(libvirtComputingResource.getInterfaces(conn, vmName)).thenReturn(ifaces); + + final DiskDef diskDef = Mockito.mock(DiskDef.class); + final List disks = new ArrayList(); + disks.add(diskDef); + + when(libvirtComputingResource.getDisks(conn, vmName)).thenReturn(disks); + final Domain dm = Mockito.mock(Domain.class); + try { + when(conn.domainLookupByName(vmName)).thenReturn(dm); + + when(libvirtComputingResource.getPrivateIp()).thenReturn("192.168.1.10"); + when(dm.getXMLDesc(0)).thenReturn("host_domain"); + when(dm.isPersistent()).thenReturn(1); + doNothing().when(dm).undefine(); + + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final Exception e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + verify(libvirtComputingResource, times(1)).getInterfaces(conn, vmName); + verify(libvirtComputingResource, times(1)).getDisks(conn, vmName); + try { + verify(conn, times(1)).domainLookupByName(vmName); + verify(dm, times(1)).getXMLDesc(0); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From be1e5176156d9b7eb78e53c703b48d679ad52f56 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 23 Apr 2015 13:57:13 +0200 Subject: [PATCH 09/36] Refactoring the LibvirtComputingResource - Adding LibvirtPingTestCommandWrapper - 3 unit tests added - KVM hypervisor plugin with 11.2% coverage --- .../resource/LibvirtComputingResource.java | 44 ++----------- .../LibvirtPingTestCommandWrapper.java | 65 +++++++++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 39 +++++++++-- 4 files changed, 107 insertions(+), 43 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPingTestCommandWrapper.java 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 893f82dc40a..1c7aa241411 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 @@ -135,7 +135,6 @@ import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; -import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PlugNicAnswer; import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PvlanSetupCommand; @@ -405,6 +404,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _migrateSpeed; } + public String getPingTestPath() { + return _pingTestPath; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1311,9 +1314,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof PingTestCommand) { - return execute((PingTestCommand)cmd); - } else if (cmd instanceof CheckVirtualMachineCommand) { + if (cmd instanceof CheckVirtualMachineCommand) { return execute((CheckVirtualMachineCommand)cmd); } else if (cmd instanceof ReadyCommand) { return execute((ReadyCommand)cmd); @@ -3029,41 +3030,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(final PingTestCommand cmd) { - String result = null; - final String computingHostIp = cmd.getComputingHostIp(); // TODO, split - // the - // command - // into 2 - // types - - if (computingHostIp != null) { - result = doPingTest(computingHostIp); - } else if (cmd.getRouterIp() != null && cmd.getPrivateIp() != null) { - result = doPingTest(cmd.getRouterIp(), cmd.getPrivateIp()); - } else { - return new Answer(cmd, false, "routerip and private ip is null"); - } - - if (result != null) { - return new Answer(cmd, false, result); - } - return new Answer(cmd); - } - - private String doPingTest(final String computingHostIp) { - final Script command = new Script(_pingTestPath, 10000, s_logger); - command.add("-h", computingHostIp); - return command.execute(); - } - - private String doPingTest(final String domRIp, final String vmIp) { - final Script command = new Script(_pingTestPath, 10000, s_logger); - command.add("-i", domRIp); - command.add("-p", vmIp); - return command.execute(); - } - public String networkUsage(final String privateIpAddress, final String option, final String vif) { final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("netusage.sh"); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPingTestCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPingTestCommandWrapper.java new file mode 100644 index 00000000000..3ef9e2c73ce --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPingTestCommandWrapper.java @@ -0,0 +1,65 @@ +// +// 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.PingTestCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.script.Script; + +public final class LibvirtPingTestCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtPingTestCommandWrapper.class); + + @Override + public Answer execute(final PingTestCommand command, final LibvirtComputingResource libvirtComputingResource) { + String result = null; + final String computingHostIp = command.getComputingHostIp(); // TODO, split the command into 2 types + + if (computingHostIp != null) { + result = doPingTest(libvirtComputingResource, computingHostIp); + } else if (command.getRouterIp() != null && command.getPrivateIp() != null) { + result = doPingTest(libvirtComputingResource, command.getRouterIp(), command.getPrivateIp()); + } else { + return new Answer(command, false, "routerip and private ip is null"); + } + + if (result != null) { + return new Answer(command, false, result); + } + return new Answer(command); + } + + protected String doPingTest(final LibvirtComputingResource libvirtComputingResource, final String computingHostIp) { + final Script command = new Script(libvirtComputingResource.getPingTestPath(), 10000, s_logger); + command.add("-h", computingHostIp); + return command.execute(); + } + + protected String doPingTest(final LibvirtComputingResource libvirtComputingResource, final String domRIp, final String vmIp) { + final Script command = new Script(libvirtComputingResource.getPingTestPath(), 10000, s_logger); + command.add("-i", domRIp); + command.add("-p", vmIp); + return command.execute(); + } +} \ 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 ee444b8e88f..aeac43c5d72 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 @@ -27,6 +27,7 @@ import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; @@ -62,6 +63,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CheckHealthCommand.class, new LibvirtCheckHealthCommandWrapper()); linbvirtCommands.put(PrepareForMigrationCommand.class, new LibvirtPrepareForMigrationCommandWrapper()); linbvirtCommands.put(MigrateCommand.class, new LibvirtMigrateCommandWrapper()); + linbvirtCommands.put(PingTestCommand.class, new LibvirtPingTestCommandWrapper()); 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 4aa249e7f0a..50c8ca68a6d 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 @@ -68,6 +68,7 @@ import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; @@ -596,7 +597,7 @@ public class LibvirtComputingResourceTest { @Test(expected = NumberFormatException.class) public void testGetHostStatsCommand() { - // A bit difficult top test due to the logger being passed and the parser itself relying on the connection. + // A bit difficult to test due to the logger being passed and the parser itself relying on the connection. // Have to spend some more time afterwards in order to refactor the wrapper itself. final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; @@ -611,9 +612,6 @@ public class LibvirtComputingResourceTest { @Test public void testCheckHealthCommand() { - // A bit difficult top test due to the logger being passed and the parser itself relying on the connection. - // Have to spend some more time afterwards in order to refactor the wrapper itself. - final CheckHealthCommand command = new CheckHealthCommand(); final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); @@ -743,4 +741,37 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testPingTestHostIpCommand() { + final PingTestCommand command = new PingTestCommand("172.1.10.10"); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } + + @Test + public void testPingTestPvtIpCommand() { + final PingTestCommand command = new PingTestCommand("169.17.1.10", "192.168.10.10"); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } + + @Test + public void testPingOnlyOneIpCommand() { + final PingTestCommand command = new PingTestCommand("169.17.1.10", null); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } } \ No newline at end of file From 4d216f1a6382c42cf94a947aa5432f4d18782811 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 23 Apr 2015 14:24:53 +0200 Subject: [PATCH 10/36] Refactoring the LibvirtComputingResource - Adding LibvirtAttachIsoCommandWrapper, LibvirtAttachIsoCommandWrapper and LibvirtAttachIsoCommandWrapper - 7 unit tests added - KVM hypervisor plugin with 11.5% coverage --- .../resource/LibvirtComputingResource.java | 53 +---- .../LibvirtAttachIsoCommandWrapper.java | 52 +++++ ...virtCheckVirtualMachineCommandWrapper.java | 51 +++++ .../wrapper/LibvirtReadyCommandWrapper.java | 34 +++ .../wrapper/LibvirtRequestWrapper.java | 6 + .../LibvirtComputingResourceTest.java | 196 ++++++++++++++++++ 6 files changed, 343 insertions(+), 49 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java 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 1c7aa241411..0fb20ee79ac 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 @@ -87,7 +87,6 @@ import com.ceph.rbd.Rbd; import com.ceph.rbd.RbdException; import com.ceph.rbd.RbdImage; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.BackupSnapshotAnswer; @@ -95,8 +94,6 @@ import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CheckVirtualMachineAnswer; -import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; @@ -138,8 +135,6 @@ import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PlugNicAnswer; import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PvlanSetupCommand; -import com.cloud.agent.api.ReadyAnswer; -import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SetupGuestNetworkCommand; @@ -1314,13 +1309,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof CheckVirtualMachineCommand) { - return execute((CheckVirtualMachineCommand)cmd); - } else if (cmd instanceof ReadyCommand) { - return execute((ReadyCommand)cmd); - } else if (cmd instanceof AttachIsoCommand) { - return execute((AttachIsoCommand)cmd); - } else if (cmd instanceof AttachVolumeCommand) { + if (cmd instanceof AttachVolumeCommand) { return execute((AttachVolumeCommand)cmd); } else if (cmd instanceof CheckConsoleProxyLoadCommand) { return execute((CheckConsoleProxyLoadCommand)cmd); @@ -2951,21 +2940,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); } - private Answer execute(final AttachIsoCommand cmd) { - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - attachOrDetachISO(conn, cmd.getVmName(), cmd.getIsoPath(), cmd.isAttach()); - } catch (final LibvirtException e) { - return new Answer(cmd, false, e.toString()); - } catch (final URISyntaxException e) { - return new Answer(cmd, false, e.toString()); - } catch (final InternalErrorException e) { - return new Answer(cmd, false, e.toString()); - } - - return new Answer(cmd); - } - private AttachVolumeAnswer execute(final AttachVolumeCommand cmd) { try { final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); @@ -2983,16 +2957,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new AttachVolumeAnswer(cmd, cmd.getDeviceId(), cmd.getVolumePath()); } - private Answer execute(final ReadyCommand cmd) { - return new ReadyAnswer(cmd); - } - protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; } - protected PowerState getVmState(final Connect conn, final String vmName) { + public PowerState getVmState(final Connect conn, final String vmName) { int retry = 3; Domain vms = null; while (retry-- > 0) { @@ -3015,21 +2985,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return PowerState.PowerOff; } - private Answer execute(final CheckVirtualMachineCommand cmd) { - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - final PowerState state = getVmState(conn, cmd.getVmName()); - Integer vncPort = null; - if (state == PowerState.PowerOn) { - vncPort = getVncPort(conn, cmd.getVmName()); - } - - return new CheckVirtualMachineAnswer(cmd, state, vncPort); - } catch (final LibvirtException e) { - return new CheckVirtualMachineAnswer(cmd, e.getMessage()); - } - } - public String networkUsage(final String privateIpAddress, final String option, final String vif) { final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("netusage.sh"); @@ -3719,7 +3674,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _storagePoolMgr; } - protected synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach) throws LibvirtException, URISyntaxException, + public synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach) throws LibvirtException, URISyntaxException, InternalErrorException { String isoXml = null; if (isoPath != null && isAttach) { @@ -4948,4 +4903,4 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } return device; } -} +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java new file mode 100644 index 00000000000..4380b666494 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java @@ -0,0 +1,52 @@ +// +// 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 java.net.URISyntaxException; + +import org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachIsoCommand; +import com.cloud.exception.InternalErrorException; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtAttachIsoCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final AttachIsoCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(command.getVmName()); + libvirtComputingResource.attachOrDetachISO(conn, command.getVmName(), command.getIsoPath(), command.isAttach()); + } catch (final LibvirtException e) { + return new Answer(command, false, e.toString()); + } catch (final URISyntaxException e) { + return new Answer(command, false, e.toString()); + } catch (final InternalErrorException e) { + return new Answer(command, false, e.toString()); + } + + return new Answer(command); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java new file mode 100644 index 00000000000..3ad3300b95b --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckVirtualMachineCommandWrapper.java @@ -0,0 +1,51 @@ +// +// 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.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckVirtualMachineAnswer; +import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.vm.VirtualMachine.PowerState; + +public final class LibvirtCheckVirtualMachineCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CheckVirtualMachineCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(command.getVmName()); + final PowerState state = libvirtComputingResource.getVmState(conn, command.getVmName()); + Integer vncPort = null; + if (state == PowerState.PowerOn) { + vncPort = libvirtComputingResource.getVncPort(conn, command.getVmName()); + } + + return new CheckVirtualMachineAnswer(command, state, vncPort); + } catch (final LibvirtException e) { + return new CheckVirtualMachineAnswer(command, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java new file mode 100644 index 00000000000..7fce9096595 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtReadyCommandWrapper.java @@ -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.ReadyAnswer; +import com.cloud.agent.api.ReadyCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtReadyCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final ReadyCommand command, final LibvirtComputingResource libvirtComputingResource) { + return new ReadyAnswer(command); + } +} \ 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 aeac43c5d72..ff0a8a56a89 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 @@ -21,7 +21,9 @@ package com.cloud.hypervisor.kvm.resource.wrapper; import java.util.Hashtable; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.CheckHealthCommand; +import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; @@ -29,6 +31,7 @@ import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; @@ -64,6 +67,9 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(PrepareForMigrationCommand.class, new LibvirtPrepareForMigrationCommandWrapper()); linbvirtCommands.put(MigrateCommand.class, new LibvirtMigrateCommandWrapper()); linbvirtCommands.put(PingTestCommand.class, new LibvirtPingTestCommandWrapper()); + linbvirtCommands.put(CheckVirtualMachineCommand.class, new LibvirtCheckVirtualMachineCommandWrapper()); + linbvirtCommands.put(ReadyCommand.class, new LibvirtReadyCommandWrapper()); + linbvirtCommands.put(AttachIsoCommand.class, new LibvirtAttachIsoCommandWrapper()); 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 50c8ca68a6d..f122a2a0442 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 @@ -30,6 +30,7 @@ import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -63,13 +64,16 @@ import org.w3c.dom.Document; import org.xml.sax.SAXException; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.CheckHealthCommand; +import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; @@ -78,6 +82,7 @@ import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; +import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; @@ -88,6 +93,7 @@ import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.PowerState; @RunWith(PowerMockRunner.class) public class LibvirtComputingResourceTest { @@ -774,4 +780,194 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertFalse(answer.getResult()); } + + @Test + public void testCheckVirtualMachineCommand() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final CheckVirtualMachineCommand command = new CheckVirtualMachineCommand(vmName); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(libvirtComputingResource.getVmState(conn, command.getVmName())).thenReturn(PowerState.PowerOn); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testExceptionCheckVirtualMachineCommand() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final CheckVirtualMachineCommand command = new CheckVirtualMachineCommand(vmName); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(libvirtComputingResource.getVmState(conn, command.getVmName())).thenReturn(PowerState.PowerOn); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testReadyCommand() { + final ReadyCommand command = new ReadyCommand(1l); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + } + + @Test + public void testAttachIsoCommand() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testAttachIsoCommandLibvirtException() { + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testAttachIsoCommandURISyntaxException() { + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(URISyntaxException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testAttachIsoCommandInternalErrorException() { + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(InternalErrorException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From 40886b337c953378b93c03c899f801bb24e3aff6 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 23 Apr 2015 14:44:13 +0200 Subject: [PATCH 11/36] Refactoring the LibvirtComputingResource - Adding LibvirtAttachVolumeCommandWrapper - 3 unit tests added - KVM hypervisor plugin with 11.7% coverage --- .../resource/LibvirtComputingResource.java | 25 +--- .../LibvirtAttachVolumeCommandWrapper.java | 58 ++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 139 ++++++++++++++++++ 4 files changed, 201 insertions(+), 23 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachVolumeCommandWrapper.java 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 0fb20ee79ac..95b2faffe41 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 @@ -87,8 +87,6 @@ import com.ceph.rbd.Rbd; import com.ceph.rbd.RbdException; import com.ceph.rbd.RbdImage; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.AttachVolumeAnswer; -import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.CheckNetworkAnswer; @@ -1309,9 +1307,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof AttachVolumeCommand) { - return execute((AttachVolumeCommand)cmd); - } else if (cmd instanceof CheckConsoleProxyLoadCommand) { + if (cmd instanceof CheckConsoleProxyLoadCommand) { return execute((CheckConsoleProxyLoadCommand)cmd); } else if (cmd instanceof WatchConsoleProxyLoadCommand) { return execute((WatchConsoleProxyLoadCommand)cmd); @@ -2940,23 +2936,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); } - private AttachVolumeAnswer execute(final AttachVolumeCommand cmd) { - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - final KVMStoragePool primary = _storagePoolMgr.getStoragePool(cmd.getPooltype(), cmd.getPoolUuid()); - final KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); - attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk, - cmd.getDeviceId().intValue(), cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate(), - cmd.getCacheMode()); - } catch (final LibvirtException e) { - return new AttachVolumeAnswer(cmd, e.toString()); - } catch (final InternalErrorException e) { - return new AttachVolumeAnswer(cmd, e.toString()); - } - - return new AttachVolumeAnswer(cmd, cmd.getDeviceId(), cmd.getVolumePath()); - } - protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; @@ -3707,7 +3686,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return result; } - protected synchronized String attachOrDetachDisk(final Connect conn, + public synchronized String attachOrDetachDisk(final Connect conn, final boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final int devId, final Long bytesReadRate, final Long bytesWriteRate, final Long iopsReadRate, final Long iopsWriteRate, final String cacheMode) throws LibvirtException, InternalErrorException { List disks = null; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachVolumeCommandWrapper.java new file mode 100644 index 00000000000..861bccc28c4 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachVolumeCommandWrapper.java @@ -0,0 +1,58 @@ +// +// 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.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachVolumeAnswer; +import com.cloud.agent.api.AttachVolumeCommand; +import com.cloud.exception.InternalErrorException; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; +import com.cloud.hypervisor.kvm.storage.KVMStoragePool; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtAttachVolumeCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final AttachVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(command.getVmName()); + + final KVMStoragePool primary = libvirtComputingResource.getStoragePoolMgr().getStoragePool(command.getPooltype(), command.getPoolUuid()); + final KVMPhysicalDisk disk = primary.getPhysicalDisk(command.getVolumePath()); + + libvirtComputingResource.attachOrDetachDisk(conn, command.getAttach(), command.getVmName(), disk, + command.getDeviceId().intValue(), command.getBytesReadRate(), command.getBytesWriteRate(), command.getIopsReadRate(), command.getIopsWriteRate(), + command.getCacheMode()); + + } catch (final LibvirtException e) { + return new AttachVolumeAnswer(command, e.toString()); + } catch (final InternalErrorException e) { + return new AttachVolumeAnswer(command, e.toString()); + } + + return new AttachVolumeAnswer(command, command.getDeviceId(), command.getVolumePath()); + } +} \ 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 ff0a8a56a89..601db130615 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 @@ -22,6 +22,7 @@ import java.util.Hashtable; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; +import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; @@ -70,6 +71,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CheckVirtualMachineCommand.class, new LibvirtCheckVirtualMachineCommandWrapper()); linbvirtCommands.put(ReadyCommand.class, new LibvirtReadyCommandWrapper()); linbvirtCommands.put(AttachIsoCommand.class, new LibvirtAttachIsoCommandWrapper()); + linbvirtCommands.put(AttachVolumeCommand.class, new LibvirtAttachVolumeCommandWrapper()); 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 f122a2a0442..e274485d920 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 @@ -65,6 +65,7 @@ import org.xml.sax.SAXException; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; +import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.GetHostStatsCommand; @@ -87,8 +88,11 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; +import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; +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.Volume; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; @@ -970,4 +974,139 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testAttachVolumeCommand() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final boolean attach = true; + final boolean managed = true; + final String vmName = "Test"; + final StoragePoolType poolType = StoragePoolType.ISO; + final String volumePath = "/path"; + final String volumeName = "volume"; + final Long volumeSize = 200l; + final Long deviceId = 1l; + final String chainInfo = "none"; + final AttachVolumeCommand command = new AttachVolumeCommand(attach, managed, vmName, poolType, volumePath, volumeName, volumeSize, deviceId, chainInfo); + + final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager); + when(poolManager.getStoragePool(command.getPooltype(), command.getPoolUuid())).thenReturn(primary); + when(primary.getPhysicalDisk(command.getVolumePath())).thenReturn(disk); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testAttachVolumeCommandLibvirtException() { + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final boolean attach = true; + final boolean managed = true; + final String vmName = "Test"; + final StoragePoolType poolType = StoragePoolType.ISO; + final String volumePath = "/path"; + final String volumeName = "volume"; + final Long volumeSize = 200l; + final Long deviceId = 1l; + final String chainInfo = "none"; + final AttachVolumeCommand command = new AttachVolumeCommand(attach, managed, vmName, poolType, volumePath, volumeName, volumeSize, deviceId, chainInfo); + + final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager); + when(poolManager.getStoragePool(command.getPooltype(), command.getPoolUuid())).thenReturn(primary); + when(primary.getPhysicalDisk(command.getVolumePath())).thenReturn(disk); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testAttachVolumeCommandInternalErrorException() { + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final boolean attach = true; + final boolean managed = true; + final String vmName = "Test"; + final StoragePoolType poolType = StoragePoolType.ISO; + final String volumePath = "/path"; + final String volumeName = "volume"; + final Long volumeSize = 200l; + final Long deviceId = 1l; + final String chainInfo = "none"; + final AttachVolumeCommand command = new AttachVolumeCommand(attach, managed, vmName, poolType, volumePath, volumeName, volumeSize, deviceId, chainInfo); + + final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(InternalErrorException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager); + when(poolManager.getStoragePool(command.getPooltype(), command.getPoolUuid())).thenReturn(primary); + when(primary.getPhysicalDisk(command.getVolumePath())).thenReturn(disk); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From 08a9523dcdd5b4d736c4ef29b9ea93daa2b6e400 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 23 Apr 2015 14:46:09 +0200 Subject: [PATCH 12/36] Fixing assertion on the tests that are execting exceptions --- .../hypervisor/kvm/resource/LibvirtComputingResourceTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 e274485d920..75ce22131f0 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 @@ -1055,7 +1055,7 @@ public class LibvirtComputingResourceTest { assertNotNull(wrapper); final Answer answer = wrapper.execute(command, libvirtComputingResource); - assertTrue(answer.getResult()); + assertFalse(answer.getResult()); verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { @@ -1100,7 +1100,7 @@ public class LibvirtComputingResourceTest { assertNotNull(wrapper); final Answer answer = wrapper.execute(command, libvirtComputingResource); - assertTrue(answer.getResult()); + assertFalse(answer.getResult()); verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { From 7319a12600a7823aef8167348ee66a74a43ede8b Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 24 Apr 2015 11:49:00 +0200 Subject: [PATCH 13/36] Refactoring the LibvirtComputingResource - Adding LibvirtCheckConsoleProxyLoadCommandWrapper, LibvirtConsoleProxyLoadCommandWrapper, LibvirtWatchConsoleProxyLoadCommandWrapperand CitrixConsoleProxyLoadCommandWrapper - 2 unit tests added - KVM hypervisor plugin with 12% coverage Refactored the CommandWrapper interface in order to remove the esecuteProxyLoadScan, which is now implemented bu subclasses. --- .../com/cloud/resource/CommandWrapper.java | 65 --------------- .../resource/LibvirtComputingResource.java | 59 +------------ ...rtCheckConsoleProxyLoadCommandWrapper.java | 41 +++++++++ ...LibvirtConsoleProxyLoadCommandWrapper.java | 78 +++++++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 4 + ...rtWatchConsoleProxyLoadCommandWrapper.java | 41 +++++++++ .../LibvirtComputingResourceTest.java | 35 ++++++++ ...ixCheckConsoleProxyLoadCommandWrapper.java | 17 ++-- .../CitrixConsoleProxyLoadCommandWrapper.java | 83 +++++++++++++++++++ ...ixWatchConsoleProxyLoadCommandWrapper.java | 17 ++-- 10 files changed, 303 insertions(+), 137 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckConsoleProxyLoadCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConsoleProxyLoadCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtWatchConsoleProxyLoadCommandWrapper.java create mode 100644 plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixConsoleProxyLoadCommandWrapper.java diff --git a/core/src/com/cloud/resource/CommandWrapper.java b/core/src/com/cloud/resource/CommandWrapper.java index 48c105f5575..f68e92a2327 100644 --- a/core/src/com/cloud/resource/CommandWrapper.java +++ b/core/src/com/cloud/resource/CommandWrapper.java @@ -19,81 +19,16 @@ package com.cloud.resource; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; -import java.nio.charset.Charset; - -import org.apache.log4j.Logger; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; public abstract class CommandWrapper { - private static final Logger s_logger = Logger.getLogger(CommandWrapper.class); - /** * @param T is the command to be used. * @param R is the resource base to be used. * @return A and the Answer from the command. */ public abstract A execute(T command, R serverResource); - - /** - * Common method so we added it here. - * - * @param cmd - * @param proxyVmId - * @param proxyVmName - * @param proxyManagementIp - * @param cmdPort - * @return - */ - protected Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { - String result = null; - - final StringBuffer sb = new StringBuffer(); - sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus"); - - boolean success = true; - try { - final URL url = new URL(sb.toString()); - final URLConnection conn = url.openConnection(); - - // setting TIMEOUTs to avoid possible waiting until death situations - conn.setConnectTimeout(5000); - conn.setReadTimeout(5000); - - final InputStream is = conn.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.defaultCharset())); - final StringBuilder sb2 = new StringBuilder(); - String line = null; - try { - while ((line = reader.readLine()) != null) { - sb2.append(line + "\n"); - } - result = sb2.toString(); - } catch (final IOException e) { - success = false; - } finally { - try { - is.close(); - } catch (final IOException e) { - s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp); - success = false; - } - } - } catch (final IOException e) { - s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp); - success = false; - } - - return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); - } } \ No newline at end of file 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 95b2faffe41..07cb4ddeedf 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 @@ -23,14 +23,10 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.Reader; import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; @@ -148,9 +144,6 @@ import com.cloud.agent.api.VmDiskStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; -import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; -import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; -import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.NetworkElementCommand; @@ -1307,11 +1300,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof CheckConsoleProxyLoadCommand) { - return execute((CheckConsoleProxyLoadCommand)cmd); - } else if (cmd instanceof WatchConsoleProxyLoadCommand) { - return execute((WatchConsoleProxyLoadCommand)cmd); - } else if (cmd instanceof GetVncPortCommand) { + if (cmd instanceof GetVncPortCommand) { return execute((GetVncPortCommand)cmd); } else if (cmd instanceof ModifySshKeysCommand) { return execute((ModifySshKeysCommand)cmd); @@ -2886,56 +2875,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected Answer execute(final CheckConsoleProxyLoadCommand cmd) { - return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); - } - - protected Answer execute(final WatchConsoleProxyLoadCommand cmd) { - return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); - } - protected MaintainAnswer execute(final MaintainCommand cmd) { return new MaintainAnswer(cmd); } - private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { - String result = null; - - final StringBuffer sb = new StringBuffer(); - sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus"); - - boolean success = true; - try { - final URL url = new URL(sb.toString()); - final URLConnection conn = url.openConnection(); - - final InputStream is = conn.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - final StringBuilder sb2 = new StringBuilder(); - String line = null; - try { - while ((line = reader.readLine()) != null) { - sb2.append(line + "\n"); - } - result = sb2.toString(); - } catch (final IOException e) { - success = false; - } finally { - try { - is.close(); - } catch (final IOException e) { - s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp); - success = false; - } - } - } catch (final IOException e) { - s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp); - success = false; - } - - return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); - } - protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckConsoleProxyLoadCommandWrapper.java new file mode 100644 index 00000000000..1267984069d --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckConsoleProxyLoadCommandWrapper.java @@ -0,0 +1,41 @@ +// +// 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.Command; +import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.ServerResource; + +public class LibvirtCheckConsoleProxyLoadCommandWrapper extends LibvirtConsoleProxyLoadCommandWrapper { + + @Override + public Answer execute(final Command command, final ServerResource serverResource) { + final CheckConsoleProxyLoadCommand cmd = (CheckConsoleProxyLoadCommand) command; + + final long proxyVmId = cmd.getProxyVmId(); + final String proxyVmName = cmd.getProxyVmName(); + final String proxyManagementIp = cmd.getProxyManagementIp(); + final int proxyCmdPort = cmd.getProxyCmdPort(); + + return executeProxyLoadScan(cmd, proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConsoleProxyLoadCommandWrapper.java new file mode 100644 index 00000000000..125a295eb90 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConsoleProxyLoadCommandWrapper.java @@ -0,0 +1,78 @@ +// +// 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 java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ServerResource; + +public abstract class LibvirtConsoleProxyLoadCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtConsoleProxyLoadCommandWrapper.class); + + public Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { + String result = null; + + final StringBuffer sb = new StringBuffer(); + sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus"); + + boolean success = true; + try { + final URL url = new URL(sb.toString()); + final URLConnection conn = url.openConnection(); + + final InputStream is = conn.getInputStream(); + final BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + final StringBuilder sb2 = new StringBuilder(); + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb2.append(line + "\n"); + } + result = sb2.toString(); + } catch (final IOException e) { + success = false; + } finally { + try { + is.close(); + } catch (final IOException e) { + s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp); + success = false; + } + } + } catch (final IOException e) { + s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp); + success = false; + } + + return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); + } +} \ 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 601db130615..72d3a874c6b 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 @@ -36,6 +36,8 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; 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.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.resource.CommandWrapper; import com.cloud.resource.RequestWrapper; @@ -72,6 +74,8 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(ReadyCommand.class, new LibvirtReadyCommandWrapper()); linbvirtCommands.put(AttachIsoCommand.class, new LibvirtAttachIsoCommandWrapper()); linbvirtCommands.put(AttachVolumeCommand.class, new LibvirtAttachVolumeCommandWrapper()); + linbvirtCommands.put(WatchConsoleProxyLoadCommand.class, new LibvirtWatchConsoleProxyLoadCommandWrapper()); + linbvirtCommands.put(CheckConsoleProxyLoadCommand.class, new LibvirtCheckConsoleProxyLoadCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtWatchConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtWatchConsoleProxyLoadCommandWrapper.java new file mode 100644 index 00000000000..62fff110714 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtWatchConsoleProxyLoadCommandWrapper.java @@ -0,0 +1,41 @@ +// +// 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.Command; +import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.ServerResource; + +public class LibvirtWatchConsoleProxyLoadCommandWrapper extends LibvirtConsoleProxyLoadCommandWrapper { + + @Override + public Answer execute(final Command command, final ServerResource serverResource) { + final WatchConsoleProxyLoadCommand cmd = (WatchConsoleProxyLoadCommand) command; + + final long proxyVmId = cmd.getProxyVmId(); + final String proxyVmName = cmd.getProxyVmName(); + final String proxyManagementIp = cmd.getProxyManagementIp(); + final int proxyCmdPort = cmd.getProxyCmdPort(); + + return executeProxyLoadScan(cmd, proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort); + } +} \ No newline at end of file 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 75ce22131f0..8f56ee052e6 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 @@ -79,6 +79,8 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; 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.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; @@ -1109,4 +1111,37 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testWatchConsoleProxyLoadCommand() { + final int interval = 0; + final long proxyVmId = 0l; + final String proxyVmName = "host"; + final String proxyManagementIp = "169.172.15.16"; + final int proxyCmdPort = 0; + + final WatchConsoleProxyLoadCommand command = new WatchConsoleProxyLoadCommand(interval, proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } + + @Test + public void testCheckConsoleProxyLoadCommand() { + final long proxyVmId = 0l; + final String proxyVmName = "host"; + final String proxyManagementIp = "169.172.15.16"; + final int proxyCmdPort = 0; + + final CheckConsoleProxyLoadCommand command = new CheckConsoleProxyLoadCommand(proxyVmId, proxyVmName, proxyManagementIp, proxyCmdPort); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } } \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckConsoleProxyLoadCommandWrapper.java index bdf7c319a59..08d36b3d995 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckConsoleProxyLoadCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckConsoleProxyLoadCommandWrapper.java @@ -20,18 +20,21 @@ package com.cloud.hypervisor.xenserver.resource.wrapper; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; -import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ServerResource; -public final class CitrixCheckConsoleProxyLoadCommandWrapper extends CommandWrapper { +public final class CitrixCheckConsoleProxyLoadCommandWrapper extends CitrixConsoleProxyLoadCommandWrapper { @Override - public Answer execute(final CheckConsoleProxyLoadCommand command, final CitrixResourceBase citrixResourceBase) { - final long proxyVmId = command.getProxyVmId(); - final String proxyVmName = command.getProxyVmName(); - final String proxyManagementIp = command.getProxyManagementIp(); - final int cmdPort = command.getProxyCmdPort(); + public Answer execute(final Command command, final ServerResource serverResource) { + final CheckConsoleProxyLoadCommand cmd = (CheckConsoleProxyLoadCommand) command; + + final long proxyVmId = cmd.getProxyVmId(); + final String proxyVmName = cmd.getProxyVmName(); + final String proxyManagementIp = cmd.getProxyManagementIp(); + final int cmdPort = cmd.getProxyCmdPort(); return executeProxyLoadScan(command, proxyVmId, proxyVmName, proxyManagementIp, cmdPort); } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixConsoleProxyLoadCommandWrapper.java new file mode 100644 index 00000000000..4e71b0e1237 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixConsoleProxyLoadCommandWrapper.java @@ -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.xenserver.resource.wrapper; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ServerResource; + +public abstract class CitrixConsoleProxyLoadCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixConsoleProxyLoadCommandWrapper.class); + + protected Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { + String result = null; + + final StringBuffer sb = new StringBuffer(); + sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus"); + + boolean success = true; + try { + final URL url = new URL(sb.toString()); + final URLConnection conn = url.openConnection(); + + // setting TIMEOUTs to avoid possible waiting until death situations + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + + final InputStream is = conn.getInputStream(); + final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.defaultCharset())); + final StringBuilder sb2 = new StringBuilder(); + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb2.append(line + "\n"); + } + result = sb2.toString(); + } catch (final IOException e) { + success = false; + } finally { + try { + is.close(); + } catch (final IOException e) { + s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp); + success = false; + } + } + } catch (final IOException e) { + s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp); + success = false; + } + + return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixWatchConsoleProxyLoadCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixWatchConsoleProxyLoadCommandWrapper.java index 4ee961402f9..f188c20a30d 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixWatchConsoleProxyLoadCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixWatchConsoleProxyLoadCommandWrapper.java @@ -20,18 +20,21 @@ package com.cloud.hypervisor.xenserver.resource.wrapper; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; -import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ServerResource; -public final class CitrixWatchConsoleProxyLoadCommandWrapper extends CommandWrapper { +public final class CitrixWatchConsoleProxyLoadCommandWrapper extends CitrixConsoleProxyLoadCommandWrapper { @Override - public Answer execute(final WatchConsoleProxyLoadCommand command, final CitrixResourceBase citrixResourceBase) { - final long proxyVmId = command.getProxyVmId(); - final String proxyVmName = command.getProxyVmName(); - final String proxyManagementIp = command.getProxyManagementIp(); - final int cmdPort = command.getProxyCmdPort(); + public Answer execute(final Command command, final ServerResource serverResource) { + final WatchConsoleProxyLoadCommand cmd = (WatchConsoleProxyLoadCommand) command; + + final long proxyVmId = cmd.getProxyVmId(); + final String proxyVmName = cmd.getProxyVmName(); + final String proxyManagementIp = cmd.getProxyManagementIp(); + final int cmdPort = cmd.getProxyCmdPort(); return executeProxyLoadScan(command, proxyVmId, proxyVmName, proxyManagementIp, cmdPort); } From f14c7c207494c1c01d73713f6a2c4ab5452d07e9 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 24 Apr 2015 13:17:58 +0200 Subject: [PATCH 14/36] Refactoring the LibvirtComputingResource - Adding LibvirtGetVncPortCommandWrapper - 2 unit tests added - KVM hypervisor plugin with 12.1% coverage --- .../resource/LibvirtComputingResource.java | 16 +----- .../LibvirtGetVncPortCommandWrapper.java | 45 +++++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 57 +++++++++++++++++++ 4 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java 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 07cb4ddeedf..788a3e4bde8 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 @@ -100,8 +100,6 @@ import com.cloud.agent.api.FenceAnswer; import com.cloud.agent.api.FenceCommand; import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; -import com.cloud.agent.api.GetVncPortAnswer; -import com.cloud.agent.api.GetVncPortCommand; import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.MaintainAnswer; import com.cloud.agent.api.MaintainCommand; @@ -1300,9 +1298,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof GetVncPortCommand) { - return execute((GetVncPortCommand)cmd); - } else if (cmd instanceof ModifySshKeysCommand) { + if (cmd instanceof ModifySshKeysCommand) { return execute((ModifySshKeysCommand)cmd); } else if (cmd instanceof MaintainCommand) { return execute((MaintainCommand)cmd); @@ -2865,16 +2861,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new Answer(cmd, result, ""); } - protected GetVncPortAnswer execute(final GetVncPortCommand cmd) { - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getName()); - final Integer vncPort = getVncPort(conn, cmd.getName()); - return new GetVncPortAnswer(cmd, _privateIp, 5900 + vncPort); - } catch (final LibvirtException e) { - return new GetVncPortAnswer(cmd, e.toString()); - } - } - protected MaintainAnswer execute(final MaintainCommand cmd) { return new MaintainAnswer(cmd); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java new file mode 100644 index 00000000000..9b76374d4c3 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java @@ -0,0 +1,45 @@ +// +// 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.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVncPortAnswer; +import com.cloud.agent.api.GetVncPortCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtGetVncPortCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final GetVncPortCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(command.getName()); + final Integer vncPort = libvirtComputingResource.getVncPort(conn, command.getName()); + return new GetVncPortAnswer(command, libvirtComputingResource.getPrivateIp(), 5900 + vncPort); + } catch (final LibvirtException e) { + return new GetVncPortAnswer(command, 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 72d3a874c6b..daa5a0ca39f 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 @@ -29,6 +29,7 @@ import com.cloud.agent.api.Command; 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.MigrateCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; @@ -76,6 +77,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(AttachVolumeCommand.class, new LibvirtAttachVolumeCommandWrapper()); linbvirtCommands.put(WatchConsoleProxyLoadCommand.class, new LibvirtWatchConsoleProxyLoadCommandWrapper()); linbvirtCommands.put(CheckConsoleProxyLoadCommand.class, new LibvirtCheckConsoleProxyLoadCommandWrapper()); + linbvirtCommands.put(GetVncPortCommand.class, new LibvirtGetVncPortCommandWrapper()); 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 8f56ee052e6..09a9e369687 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 @@ -71,6 +71,7 @@ import com.cloud.agent.api.CheckVirtualMachineCommand; 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.MigrateCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; @@ -1144,4 +1145,60 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertFalse(answer.getResult()); } + + @Test + public void testGetVncPortCommand() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final GetVncPortCommand command = new GetVncPortCommand(1l, "host"); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testGetVncPortCommandLibvirtException() { + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final GetVncPortCommand command = new GetVncPortCommand(1l, "host"); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From 6f757c6bf062d75c726f12dac49548dad9104cd0 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 29 Apr 2015 15:24:18 +0200 Subject: [PATCH 15/36] Refactoring the LibvirtComputingResource - Adding LibvirtModifySshKeysCommandWrapper - 1 unit test added - KVM hypervisor plugin with 12.3% coverage --- .../resource/LibvirtComputingResource.java | 210 ++++++------------ .../LibvirtModifySshKeysCommandWrapper.java | 112 ++++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 16 ++ 4 files changed, 201 insertions(+), 139 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java 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 788a3e4bde8..62c71489229 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 @@ -105,7 +105,6 @@ 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.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolAnswer; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkRulesSystemVmCommand; @@ -279,19 +278,82 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private long _hvVersion; private long _kernelVersion; + private int _timeout; + private KVMHAMonitor _monitor; - private static final String SSHKEYSPATH = "/root/.ssh"; - private static final String SSHPRVKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.cloud"; - private static final String SSHPUBKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.pub.cloud"; + public static final String SSHKEYSPATH = "/root/.ssh"; + public static final String SSHPRVKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.cloud"; + public static final String SSHPUBKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.pub.cloud"; + private String _mountPoint = "/mnt"; StorageLayer _storage; private KVMStoragePoolManager _storagePoolMgr; private VifDriver _defaultVifDriver; private Map _trafficTypeVifDrivers; + protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver"; protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver"; + protected HypervisorType _hypervisorType; + protected String _hypervisorURI; + protected long _hypervisorLibvirtVersion; + protected long _hypervisorQemuVersion; + protected String _hypervisorPath; + protected String _networkDirectSourceMode; + protected String _networkDirectDevice; + protected String _sysvmISOPath; + protected String _privNwName; + protected String _privBridgeName; + protected String _linkLocalBridgeName; + protected String _publicBridgeName; + protected String _guestBridgeName; + protected String _privateIp; + protected String _pool; + protected String _localGateway; + private boolean _canBridgeFirewall; + protected String _localStoragePath; + protected String _localStorageUUID; + protected boolean _noMemBalloon = false; + protected String _guestCpuMode; + protected String _guestCpuModel; + protected boolean _noKvmClock; + protected String _videoHw; + protected int _videoRam; + protected Pair hostOsVersion; + protected int _migrateSpeed; + protected int _migrateDowntime; + protected int _migratePauseAfter; + + private final Map _pifs = new HashMap(); + private final Map _vmStats = new ConcurrentHashMap(); + + protected static final MessageFormat SnapshotXML = new MessageFormat(" " + " {0}" + " " + + " {1}" + " " + " "); + + protected static final HashMap s_powerStatesTable; + static { + s_powerStatesTable = new HashMap(); + s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTOFF, PowerState.PowerOff); + s_powerStatesTable.put(DomainState.VIR_DOMAIN_PAUSED, PowerState.PowerOn); + s_powerStatesTable.put(DomainState.VIR_DOMAIN_RUNNING, PowerState.PowerOn); + s_powerStatesTable.put(DomainState.VIR_DOMAIN_BLOCKED, PowerState.PowerOn); + s_powerStatesTable.put(DomainState.VIR_DOMAIN_NOSTATE, PowerState.PowerUnknown); + s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTDOWN, PowerState.PowerOff); + } + + protected List _vmsKilled = new ArrayList(); + + private VirtualRoutingResource _virtRouterResource; + + private String _pingTestPath; + + private int _dom0MinMem; + + protected boolean _disconnected = true; + protected int _cmdsTimeout; + protected int _stopTimeout; + @Inject private LibvirtConnectionWrapper libvirtConnectionWrapper; @@ -392,6 +454,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _pingTestPath; } + public int getTimeout() { + return _timeout; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -424,66 +490,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return null; } - protected static final MessageFormat SnapshotXML = new MessageFormat(" " + " {0}" + " " - + " {1}" + " " + " "); - - protected HypervisorType _hypervisorType; - protected String _hypervisorURI; - protected long _hypervisorLibvirtVersion; - protected long _hypervisorQemuVersion; - protected String _hypervisorPath; - protected String _networkDirectSourceMode; - protected String _networkDirectDevice; - protected String _sysvmISOPath; - protected String _privNwName; - protected String _privBridgeName; - protected String _linkLocalBridgeName; - protected String _publicBridgeName; - protected String _guestBridgeName; - protected String _privateIp; - protected String _pool; - protected String _localGateway; - private boolean _canBridgeFirewall; - protected String _localStoragePath; - protected String _localStorageUUID; - protected boolean _noMemBalloon = false; - protected String _guestCpuMode; - protected String _guestCpuModel; protected List _cpuFeatures; - protected boolean _noKvmClock; - protected String _videoHw; - protected int _videoRam; - protected Pair hostOsVersion; - protected int _migrateSpeed; - protected int _migrateDowntime; - protected int _migratePauseAfter; - - private final Map _pifs = new HashMap(); - private final Map _vmStats = new ConcurrentHashMap(); - - protected boolean _disconnected = true; - protected int _timeout; - protected int _cmdsTimeout; - protected int _stopTimeout; - - protected static final HashMap s_powerStatesTable; - static { - s_powerStatesTable = new HashMap(); - s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTOFF, PowerState.PowerOff); - s_powerStatesTable.put(DomainState.VIR_DOMAIN_PAUSED, PowerState.PowerOn); - s_powerStatesTable.put(DomainState.VIR_DOMAIN_RUNNING, PowerState.PowerOn); - s_powerStatesTable.put(DomainState.VIR_DOMAIN_BLOCKED, PowerState.PowerOn); - s_powerStatesTable.put(DomainState.VIR_DOMAIN_NOSTATE, PowerState.PowerUnknown); - s_powerStatesTable.put(DomainState.VIR_DOMAIN_SHUTDOWN, PowerState.PowerOff); - } - - protected List _vmsKilled = new ArrayList(); - - private VirtualRoutingResource _virtRouterResource; - - private String _pingTestPath; - - private int _dom0MinMem; protected enum BridgeType { NATIVE, OPENVSWITCH @@ -1298,9 +1305,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof ModifySshKeysCommand) { - return execute((ModifySshKeysCommand)cmd); - } else if (cmd instanceof MaintainCommand) { + if (cmd instanceof MaintainCommand) { return execute((MaintainCommand)cmd); } else if (cmd instanceof CreateCommand) { return execute((CreateCommand)cmd); @@ -3001,79 +3006,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected Answer execute(final ModifySshKeysCommand cmd) { - final File sshKeysDir = new File(SSHKEYSPATH); - String result = null; - if (!sshKeysDir.exists()) { - // Change permissions for the 700 - final Script script = new Script("mkdir", _timeout, s_logger); - script.add("-m", "700"); - script.add(SSHKEYSPATH); - script.execute(); - - if (!sshKeysDir.exists()) { - s_logger.debug("failed to create directory " + SSHKEYSPATH); - } - } - - final File pubKeyFile = new File(SSHPUBKEYPATH); - if (!pubKeyFile.exists()) { - try { - pubKeyFile.createNewFile(); - } catch (final IOException e) { - result = "Failed to create file: " + e.toString(); - s_logger.debug(result); - } - } - - if (pubKeyFile.exists()) { - try (FileOutputStream pubkStream = new FileOutputStream(pubKeyFile)) { - pubkStream.write(cmd.getPubKey().getBytes()); - } catch (final FileNotFoundException e) { - result = "File" + SSHPUBKEYPATH + "is not found:" - + e.toString(); - s_logger.debug(result); - } catch (final IOException e) { - result = "Write file " + SSHPUBKEYPATH + ":" + e.toString(); - s_logger.debug(result); - } - } - - final File prvKeyFile = new File(SSHPRVKEYPATH); - if (!prvKeyFile.exists()) { - try { - prvKeyFile.createNewFile(); - } catch (final IOException e) { - result = "Failed to create file: " + e.toString(); - s_logger.debug(result); - } - } - - if (prvKeyFile.exists()) { - final String prvKey = cmd.getPrvKey(); - try (FileOutputStream prvKStream = new FileOutputStream(prvKeyFile);){ - if ( prvKStream != null) { - prvKStream.write(prvKey.getBytes()); - } - } catch (final FileNotFoundException e) { - result = "File" + SSHPRVKEYPATH + "is not found:" + e.toString(); - s_logger.debug(result); - } catch (final IOException e) { - result = "Write file " + SSHPRVKEYPATH + ":" + e.toString(); - s_logger.debug(result); - } - final Script script = new Script("chmod", _timeout, s_logger); - script.add("600", SSHPRVKEYPATH); - script.execute(); - } - - if (result != null) { - return new Answer(cmd, false, result); - } else { - return new Answer(cmd, true, null); - } - } - protected void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVMDef vm) { if (vm != null && vm.getDevices() != null) { cleanupVMNetworks(conn, vm.getDevices().getInterfaces()); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java new file mode 100644 index 00000000000..d5943c5f034 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java @@ -0,0 +1,112 @@ +// +// 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 java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ModifySshKeysCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.script.Script; + +public final class LibvirtModifySshKeysCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtModifySshKeysCommandWrapper.class); + + @Override + public Answer execute(final ModifySshKeysCommand command, final LibvirtComputingResource libvirtComputingResource) { + final File sshKeysDir = new File(LibvirtComputingResource.SSHKEYSPATH); + String result = null; + if (!sshKeysDir.exists()) { + // Change permissions for the 700 + final Script script = new Script("mkdir", libvirtComputingResource.getTimeout(), s_logger); + script.add("-m", "700"); + script.add(LibvirtComputingResource.SSHKEYSPATH); + script.execute(); + + if (!sshKeysDir.exists()) { + s_logger.debug("failed to create directory " + LibvirtComputingResource.SSHKEYSPATH); + } + } + + final File pubKeyFile = new File(LibvirtComputingResource.SSHPUBKEYPATH); + if (!pubKeyFile.exists()) { + try { + pubKeyFile.createNewFile(); + } catch (final IOException e) { + result = "Failed to create file: " + e.toString(); + s_logger.debug(result); + } + } + + if (pubKeyFile.exists()) { + try (FileOutputStream pubkStream = new FileOutputStream(pubKeyFile)) { + pubkStream.write(command.getPubKey().getBytes()); + } catch (final FileNotFoundException e) { + result = "File" + LibvirtComputingResource.SSHPUBKEYPATH + "is not found:" + + e.toString(); + s_logger.debug(result); + } catch (final IOException e) { + result = "Write file " + LibvirtComputingResource.SSHPUBKEYPATH + ":" + e.toString(); + s_logger.debug(result); + } + } + + final File prvKeyFile = new File(LibvirtComputingResource.SSHPRVKEYPATH); + if (!prvKeyFile.exists()) { + try { + prvKeyFile.createNewFile(); + } catch (final IOException e) { + result = "Failed to create file: " + e.toString(); + s_logger.debug(result); + } + } + + if (prvKeyFile.exists()) { + final String prvKey = command.getPrvKey(); + try (FileOutputStream prvKStream = new FileOutputStream(prvKeyFile);){ + if ( prvKStream != null) { + prvKStream.write(prvKey.getBytes()); + } + } catch (final FileNotFoundException e) { + result = "File" + LibvirtComputingResource.SSHPRVKEYPATH + "is not found:" + e.toString(); + s_logger.debug(result); + } catch (final IOException e) { + result = "Write file " + LibvirtComputingResource.SSHPRVKEYPATH + ":" + e.toString(); + s_logger.debug(result); + } + final Script script = new Script("chmod", libvirtComputingResource.getTimeout(), s_logger); + script.add("600", LibvirtComputingResource.SSHPRVKEYPATH); + script.execute(); + } + + if (result != null) { + return new Answer(command, false, result); + } else { + return new Answer(command, true, null); + } + } +} \ 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 daa5a0ca39f..c5001c47386 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 @@ -31,6 +31,7 @@ import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.GetVncPortCommand; import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; @@ -78,6 +79,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(WatchConsoleProxyLoadCommand.class, new LibvirtWatchConsoleProxyLoadCommandWrapper()); linbvirtCommands.put(CheckConsoleProxyLoadCommand.class, new LibvirtCheckConsoleProxyLoadCommandWrapper()); linbvirtCommands.put(GetVncPortCommand.class, new LibvirtGetVncPortCommandWrapper()); + linbvirtCommands.put(ModifySshKeysCommand.class, new LibvirtModifySshKeysCommandWrapper()); 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 09a9e369687..a2b3b7fc4ee 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 @@ -73,6 +73,7 @@ import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.GetVncPortCommand; import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; @@ -1201,4 +1202,19 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testModifySshKeysCommand() { + final ModifySshKeysCommand command = new ModifySshKeysCommand("", ""); + + when(libvirtComputingResource.getTimeout()).thenReturn(0); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getTimeout(); + } } \ No newline at end of file From cb4670279f764e1747f6eaaf1e39b1516cce6a5d Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 29 Apr 2015 16:05:44 +0200 Subject: [PATCH 16/36] Refactoring the LibvirtComputingResource - Adding LibvirtCreateCommandWrapper and LibvirtMaintainCommandWrapper - 4 unit tests added - KVM hypervisor plugin with 12.7% coverage --- .../resource/LibvirtComputingResource.java | 12 +-- .../wrapper/LibvirtCreateCommandWrapper.java | 83 ++++++++++++++ .../LibvirtMaintainCommandWrapper.java | 34 ++++++ .../wrapper/LibvirtRequestWrapper.java | 4 + .../LibvirtComputingResourceTest.java | 102 ++++++++++++++++++ 5 files changed, 225 insertions(+), 10 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMaintainCommandWrapper.java 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 62c71489229..3c959ef70b8 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 @@ -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; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java new file mode 100644 index 00000000000..f169e720c52 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateCommandWrapper.java @@ -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 { + + 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); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMaintainCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMaintainCommandWrapper.java new file mode 100644 index 00000000000..c1aba38ffe4 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMaintainCommandWrapper.java @@ -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 { + + @Override + public Answer execute(final MaintainCommand command, final LibvirtComputingResource libvirtComputingResource) { + return new MaintainAnswer(command); + } +} \ 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 c5001c47386..bced7f88d8a 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 @@ -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); } 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 a2b3b7fc4ee..22fa80863e4 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 @@ -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()); + } } \ No newline at end of file From 4472cade2f1c079d96ed738d32c0e046f76c832e Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 29 Apr 2015 17:19:57 +0200 Subject: [PATCH 17/36] Refactoring the LibvirtComputingResource - Adding LibvirtDestroyCommandWrapper - 2 unit tests added - KVM hypervisor plugin with 12.9% coverage --- .../resource/LibvirtComputingResource.java | 62 +------------------ .../wrapper/LibvirtDestroyCommandWrapper.java | 50 +++++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 59 ++++++++++++++++++ 4 files changed, 112 insertions(+), 61 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDestroyCommandWrapper.java 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 From 8268d353a2a5ffb032017687f7df82c4a6871812 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 30 Apr 2015 14:53:17 +0200 Subject: [PATCH 18/36] Refactoring the LibvirtComputingResource - Adding LibvirtPrimaryStorageDownloadCommandWrapper - 4 unit tests added - KVM hypervisor plugin with 13.3% coverage --- .../resource/LibvirtComputingResource.java | 55 +----- ...tPrimaryStorageDownloadCommandWrapper.java | 88 ++++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 157 +++++++++++++++++- 4 files changed, 247 insertions(+), 55 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrimaryStorageDownloadCommandWrapper.java 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 4abc04880f6..8e9cbc1d121 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 @@ -146,8 +146,6 @@ 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.CreatePrivateTemplateAnswer; -import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; -import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; @@ -1298,9 +1296,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof PrimaryStorageDownloadCommand) { - return execute((PrimaryStorageDownloadCommand)cmd); - } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) { + if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) { return execute((CreatePrivateTemplateFromVolumeCommand)cmd); } else if (cmd instanceof GetStorageStatsCommand) { return execute((GetStorageStatsCommand)cmd); @@ -2704,55 +2700,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected PrimaryStorageDownloadAnswer execute(final PrimaryStorageDownloadCommand cmd) { - final String tmplturl = cmd.getUrl(); - final int index = tmplturl.lastIndexOf("/"); - final String mountpoint = tmplturl.substring(0, index); - String tmpltname = null; - if (index < tmplturl.length() - 1) { - tmpltname = tmplturl.substring(index + 1); - } - - KVMPhysicalDisk tmplVol = null; - KVMStoragePool secondaryPool = null; - try { - secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint); - - /* Get template vol */ - if (tmpltname == null) { - secondaryPool.refresh(); - final List disks = secondaryPool.listPhysicalDisks(); - if (disks == null || disks.isEmpty()) { - return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + secondaryPool.getUuid()); - } - for (final KVMPhysicalDisk disk : disks) { - if (disk.getName().endsWith("qcow2")) { - tmplVol = disk; - break; - } - } - if (tmplVol == null) { - return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid()); - } - } else { - tmplVol = secondaryPool.getPhysicalDisk(tmpltname); - } - - /* Copy volume to primary storage */ - final KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPoolUuid()); - - final KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0); - - return new PrimaryStorageDownloadAnswer(primaryVol.getName(), primaryVol.getSize()); - } catch (final CloudRuntimeException e) { - return new PrimaryStorageDownloadAnswer(e.toString()); - } finally { - if (secondaryPool != null) { - _storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid()); - } - } - } - protected Answer execute(final CreateStoragePoolCommand cmd) { return new Answer(cmd, true, "success"); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrimaryStorageDownloadCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrimaryStorageDownloadCommandWrapper.java new file mode 100644 index 00000000000..391ab2787ba --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrimaryStorageDownloadCommandWrapper.java @@ -0,0 +1,88 @@ +// +// 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 java.util.List; +import java.util.UUID; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +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.utils.exception.CloudRuntimeException; + +public final class LibvirtPrimaryStorageDownloadCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final PrimaryStorageDownloadCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String tmplturl = command.getUrl(); + final int index = tmplturl.lastIndexOf("/"); + final String mountpoint = tmplturl.substring(0, index); + String tmpltname = null; + + if (index < tmplturl.length() - 1) { + tmpltname = tmplturl.substring(index + 1); + } + + KVMPhysicalDisk tmplVol = null; + KVMStoragePool secondaryPool = null; + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + try { + secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint); + + /* Get template vol */ + if (tmpltname == null) { + secondaryPool.refresh(); + final List disks = secondaryPool.listPhysicalDisks(); + if (disks == null || disks.isEmpty()) { + return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + secondaryPool.getUuid()); + } + for (final KVMPhysicalDisk disk : disks) { + if (disk.getName().endsWith("qcow2")) { + tmplVol = disk; + break; + } + } + if (tmplVol == null) { + return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid()); + } + } else { + tmplVol = secondaryPool.getPhysicalDisk(tmpltname); + } + + /* Copy volume to primary storage */ + final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid()); + + final KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0); + + return new PrimaryStorageDownloadAnswer(primaryVol.getName(), primaryVol.getSize()); + } catch (final CloudRuntimeException e) { + return new PrimaryStorageDownloadAnswer(e.toString()); + } finally { + if (secondaryPool != null) { + storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid()); + } + } + } +} \ 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 eb8d569e234..7c9b443c91d 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 @@ -43,6 +43,7 @@ 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.storage.PrimaryStorageDownloadCommand; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.resource.CommandWrapper; import com.cloud.resource.RequestWrapper; @@ -86,6 +87,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(MaintainCommand.class, new LibvirtMaintainCommandWrapper()); linbvirtCommands.put(CreateCommand.class, new LibvirtCreateCommandWrapper()); linbvirtCommands.put(DestroyCommand.class, new LibvirtDestroyCommandWrapper()); + linbvirtCommands.put(PrimaryStorageDownloadCommand.class, new LibvirtPrimaryStorageDownloadCommandWrapper()); 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 0865fb59e8b..946d87139bc 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 @@ -86,6 +86,7 @@ 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.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; @@ -101,6 +102,7 @@ import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; 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.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; @@ -1378,4 +1380,157 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); verify(poolManager, times(1)).getStoragePool(vol.getPoolType(), vol.getPoolUuid()); } -} \ No newline at end of file + + @Test(expected = NullPointerException.class) + public void testPrimaryStorageDownloadCommandNOTemplateDisk() { + final StoragePool pool = Mockito.mock(StoragePool.class); + + final List disks = new ArrayList(); + + final String name = "Test"; + final String url = "http://template/"; + final ImageFormat format = ImageFormat.QCOW2; + final long accountId = 1l; + final int wait = 0; + final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class); + final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class); + + final KVMPhysicalDisk disk = new KVMPhysicalDisk("/path", "disk.qcow2", primaryPool); + disks.add(disk); + + final int index = url.lastIndexOf("/"); + final String mountpoint = url.substring(0, index); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool); + when(secondaryPool.listPhysicalDisks()).thenReturn(disks); + when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool); + when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + } + + @Test + public void testPrimaryStorageDownloadCommandNOTemplateNODisk() { + final StoragePool pool = Mockito.mock(StoragePool.class); + + final List disks = new ArrayList(); + + final String name = "Test"; + final String url = "http://template/"; + final ImageFormat format = ImageFormat.QCOW2; + final long accountId = 1l; + final int wait = 0; + final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class); + final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class); + + final int index = url.lastIndexOf("/"); + final String mountpoint = url.substring(0, index); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool); + when(secondaryPool.listPhysicalDisks()).thenReturn(disks); + when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool); + when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + } + + @Test + public void testPrimaryStorageDownloadCommandNOTemplateNOQcow2() { + final StoragePool pool = Mockito.mock(StoragePool.class); + + final List disks = new ArrayList(); + final List spiedDisks = Mockito.spy(disks); + + final String name = "Test"; + final String url = "http://template/"; + final ImageFormat format = ImageFormat.QCOW2; + final long accountId = 1l; + final int wait = 0; + final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class); + final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class); + + final int index = url.lastIndexOf("/"); + final String mountpoint = url.substring(0, index); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool); + when(secondaryPool.listPhysicalDisks()).thenReturn(spiedDisks); + when(spiedDisks.isEmpty()).thenReturn(false); + + when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool); + when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + } + + @Test(expected = NullPointerException.class) + public void testPrimaryStorageDownloadCommandTemplateNoDisk() { + final StoragePool pool = Mockito.mock(StoragePool.class); + + final String name = "Test"; + final String url = "http://template/template.qcow2"; + final ImageFormat format = ImageFormat.VHD; + final long accountId = 1l; + final int wait = 0; + final PrimaryStorageDownloadCommand command = new PrimaryStorageDownloadCommand(name, url, format, accountId, pool, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk tmplVol = Mockito.mock(KVMPhysicalDisk.class); + final KVMPhysicalDisk primaryVol = Mockito.mock(KVMPhysicalDisk.class); + + final int index = url.lastIndexOf("/"); + final String mountpoint = url.substring(0, index); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePoolByURI(mountpoint)).thenReturn(secondaryPool); + when(secondaryPool.getPhysicalDisk("template.qcow2")).thenReturn(tmplVol); + when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPoolUuid())).thenReturn(primaryPool); + when(storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, 0)).thenReturn(primaryVol); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), command.getPoolUuid()); + } +} From 0d860af659da24b509910e5edbce95d58c6fe569 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Thu, 30 Apr 2015 21:33:19 +0200 Subject: [PATCH 19/36] Refactoring the LibvirtComputingResource - Adding LibvirtDeleteStoragePoolCommandWrapper, LibvirtGetStorageStatsCommandWrapper and LibvirtUpgradeSnapshotCommandWrapper - 7 unit tests added - KVM hypervisor plugin with 13.6% coverage --- .../resource/LibvirtComputingResource.java | 33 ---- ...ibvirtDeleteStoragePoolCommandWrapper.java | 43 +++++ .../LibvirtGetStorageStatsCommandWrapper.java | 43 +++++ .../wrapper/LibvirtRequestWrapper.java | 6 + .../LibvirtUpgradeSnapshotCommandWrapper.java | 33 ++++ .../LibvirtComputingResourceTest.java | 177 +++++++++++++++++- 6 files changed, 301 insertions(+), 34 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteStoragePoolCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetStorageStatsCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpgradeSnapshotCommandWrapper.java 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 8e9cbc1d121..f72fecf756c 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 @@ -95,11 +95,8 @@ import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.FenceAnswer; 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.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; @@ -134,7 +131,6 @@ import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.UnPlugNicAnswer; import com.cloud.agent.api.UnPlugNicCommand; -import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.VmDiskStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; @@ -1298,8 +1294,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) { return execute((CreatePrivateTemplateFromVolumeCommand)cmd); - } else if (cmd instanceof GetStorageStatsCommand) { - return execute((GetStorageStatsCommand)cmd); } else if (cmd instanceof ManageSnapshotCommand) { return execute((ManageSnapshotCommand)cmd); } else if (cmd instanceof BackupSnapshotCommand) { @@ -1308,16 +1302,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((CreateVolumeFromSnapshotCommand)cmd); } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { return execute((CreatePrivateTemplateFromSnapshotCommand)cmd); - } else if (cmd instanceof UpgradeSnapshotCommand) { - return execute((UpgradeSnapshotCommand)cmd); } else if (cmd instanceof CreateStoragePoolCommand) { return execute((CreateStoragePoolCommand)cmd); } else if (cmd instanceof ModifyStoragePoolCommand) { return execute((ModifyStoragePoolCommand)cmd); } else if (cmd instanceof SecurityGroupRulesCmd) { return execute((SecurityGroupRulesCmd)cmd); - } else if (cmd instanceof DeleteStoragePoolCommand) { - return execute((DeleteStoragePoolCommand)cmd); } else if (cmd instanceof FenceCommand) { return execute((FenceCommand)cmd); } else if (cmd instanceof StartCommand) { @@ -1657,15 +1647,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected Answer execute(final DeleteStoragePoolCommand cmd) { - try { - _storagePoolMgr.deleteStoragePool(cmd.getPool().getType(), cmd.getPool().getUuid()); - return new Answer(cmd); - } catch (final CloudRuntimeException e) { - return new Answer(cmd, false, e.toString()); - } - } - protected FenceAnswer execute(final FenceCommand cmd) { final ExecutorService executors = Executors.newSingleThreadExecutor(); final List pools = _monitor.getStoragePools(); @@ -2520,11 +2501,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected Answer execute(final UpgradeSnapshotCommand cmd) { - - return new Answer(cmd, true, "success"); - } - protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) { final String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId(); final String templateInstallFolder = "template/tmpl/" + templateFolder; @@ -2582,15 +2558,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) { - try { - final KVMStoragePool sp = _storagePoolMgr.getStoragePool(cmd.getPooltype(), cmd.getStorageId(), true); - return new GetStorageStatsAnswer(cmd, sp.getCapacity(), sp.getUsed()); - } catch (final CloudRuntimeException e) { - return new GetStorageStatsAnswer(cmd, e.toString()); - } - } - protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromVolumeCommand cmd) { final String secondaryStorageURL = cmd.getSecondaryStorageUrl(); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteStoragePoolCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteStoragePoolCommandWrapper.java new file mode 100644 index 00000000000..9b0b245f80d --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtDeleteStoragePoolCommandWrapper.java @@ -0,0 +1,43 @@ +// +// 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.DeleteStoragePoolCommand; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.exception.CloudRuntimeException; + +public final class LibvirtDeleteStoragePoolCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final DeleteStoragePoolCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + StorageFilerTO pool = command.getPool(); + KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + storagePoolMgr.deleteStoragePool(pool.getType(), pool.getUuid()); + return new Answer(command); + } catch (final CloudRuntimeException e) { + 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/LibvirtGetStorageStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetStorageStatsCommandWrapper.java new file mode 100644 index 00000000000..98deae2c382 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetStorageStatsCommandWrapper.java @@ -0,0 +1,43 @@ +// +// 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.GetStorageStatsAnswer; +import com.cloud.agent.api.GetStorageStatsCommand; +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 LibvirtGetStorageStatsCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final GetStorageStatsCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + final KVMStoragePool sp = storagePoolMgr.getStoragePool(command.getPooltype(), command.getStorageId(), true); + return new GetStorageStatsAnswer(command, sp.getCapacity(), sp.getUsed()); + } catch (final CloudRuntimeException e) { + return new GetStorageStatsAnswer(command, 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 7c9b443c91d..04aa2ea518d 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 @@ -26,7 +26,9 @@ import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; +import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.GetHostStatsCommand; +import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.GetVncPortCommand; @@ -39,6 +41,7 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.storage.CreateCommand; @@ -88,6 +91,9 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CreateCommand.class, new LibvirtCreateCommandWrapper()); linbvirtCommands.put(DestroyCommand.class, new LibvirtDestroyCommandWrapper()); linbvirtCommands.put(PrimaryStorageDownloadCommand.class, new LibvirtPrimaryStorageDownloadCommandWrapper()); + linbvirtCommands.put(GetStorageStatsCommand.class, new LibvirtGetStorageStatsCommandWrapper()); + linbvirtCommands.put(UpgradeSnapshotCommand.class, new LibvirtUpgradeSnapshotCommandWrapper()); + linbvirtCommands.put(DeleteStoragePoolCommand.class, new LibvirtDeleteStoragePoolCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpgradeSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpgradeSnapshotCommandWrapper.java new file mode 100644 index 00000000000..0f0fb9a73dc --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUpgradeSnapshotCommandWrapper.java @@ -0,0 +1,33 @@ +// +// 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.UpgradeSnapshotCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtUpgradeSnapshotCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final UpgradeSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) { + return new Answer(command, true, "success"); + } +} \ No newline at end of file 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 946d87139bc..2432c98c39a 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 @@ -68,7 +68,9 @@ import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.GetHostStatsCommand; +import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.GetVncPortCommand; @@ -81,12 +83,14 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.UpgradeSnapshotCommand; 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.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; @@ -557,6 +561,40 @@ public class LibvirtComputingResourceTest { } } + @SuppressWarnings("unchecked") + @Test + public void testGetVmDiskStatsCommandException() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; + final List vms = new ArrayList(); + vms.add(vmName); + + final GetVmDiskStatsCommand command = new GetVmDiskStatsCommand(vms, uuid, "hostname"); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnection()).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnection(); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + @Test public void testRebootCommand() { final Connect conn = Mockito.mock(Connect.class); @@ -619,6 +657,39 @@ public class LibvirtComputingResourceTest { } } + @Test + public void testRebootRouterCommandConnect() { + final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class); + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String vmName = "Test"; + final RebootRouterCommand command = new RebootRouterCommand(vmName, "192.168.0.10"); + + when(libvirtComputingResource.getVirtRouterResource()).thenReturn(routingResource); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(routingResource.connect(command.getPrivateIpAddress())).thenReturn(true); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getVirtRouterResource(); + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + @Test(expected = NumberFormatException.class) public void testGetHostStatsCommand() { // A bit difficult to test due to the logger being passed and the parser itself relying on the connection. @@ -1533,4 +1604,108 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), command.getPoolUuid()); } -} + + @Test + public void testGetStorageStatsCommand() { + final DataStoreTO store = Mockito.mock(DataStoreTO.class); + final GetStorageStatsCommand command = new GetStorageStatsCommand(store ); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePool(command.getPooltype(), command.getStorageId(), true)).thenReturn(secondaryPool); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePool(command.getPooltype(), command.getStorageId(), true); + } + + @SuppressWarnings("unchecked") + @Test + public void testGetStorageStatsCommandException() { + final DataStoreTO store = Mockito.mock(DataStoreTO.class); + final GetStorageStatsCommand command = new GetStorageStatsCommand(store ); + + when(libvirtComputingResource.getStoragePoolMgr()).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(); + } + + @Test + public void testUpgradeSnapshotCommand() { + final StoragePool pool = null; + final String secondaryStoragePoolURL = null; + final Long dcId = null; + final Long accountId = null; + final Long volumeId = null; + final Long templateId = null; + final Long tmpltAccountId = null; + final String volumePath = null; + final String snapshotUuid = null; + final String snapshotName = null; + final String version = null; + + final UpgradeSnapshotCommand command = new UpgradeSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, templateId, tmpltAccountId, volumePath, snapshotUuid, snapshotName, version); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + } + + @Test + public void testDeleteStoragePoolCommand() { + final StoragePool storagePool = Mockito.mock(StoragePool.class); + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + + final DeleteStoragePoolCommand command = new DeleteStoragePoolCommand(storagePool); + + final StorageFilerTO pool = command.getPool(); + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.deleteStoragePool(pool.getType(), pool.getUuid())).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).deleteStoragePool(pool.getType(), pool.getUuid()); + } + + @SuppressWarnings("unchecked") + @Test + public void testDeleteStoragePoolCommandException() { + final StoragePool storagePool = Mockito.mock(StoragePool.class); + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + + final DeleteStoragePoolCommand command = new DeleteStoragePoolCommand(storagePool); + + final StorageFilerTO pool = command.getPool(); + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.deleteStoragePool(pool.getType(), pool.getUuid())).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(storagePoolMgr, times(1)).deleteStoragePool(pool.getType(), pool.getUuid()); + } +} \ No newline at end of file From 4887ce72544c3a9b9f507a916ec0c3a22e6b25f5 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 1 May 2015 12:04:16 +0200 Subject: [PATCH 20/36] Refactoring the LibvirtComputingResource - Adding LibvirtOvsDestroyBridgeCommandWrapper, LibvirtOvsSetupBridgeCommandWrapper - 4 unit tests added - KVM hypervisor plugin with 13.9% coverage More tests added to cover LibvirtPrepareForMigrationCommandWrapper - Coverage of this wrapper broght from 37% to 90.6% - 4 new tests added --- .../resource/LibvirtComputingResource.java | 55 +--- ...LibvirtOvsDestroyBridgeCommandWrapper.java | 43 +++ .../LibvirtOvsSetupBridgeCommandWrapper.java | 47 +++ ...virtPrepareForMigrationCommandWrapper.java | 6 +- .../wrapper/LibvirtRequestWrapper.java | 4 + .../LibvirtComputingResourceTest.java | 287 ++++++++++++++++++ 6 files changed, 400 insertions(+), 42 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyBridgeCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsSetupBridgeCommandWrapper.java 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 f72fecf756c..cc73e65768e 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 @@ -108,11 +108,9 @@ import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.OvsCreateTunnelAnswer; import com.cloud.agent.api.OvsCreateTunnelCommand; -import com.cloud.agent.api.OvsDestroyBridgeCommand; import com.cloud.agent.api.OvsDestroyTunnelCommand; import com.cloud.agent.api.OvsFetchInterfaceAnswer; import com.cloud.agent.api.OvsFetchInterfaceCommand; -import com.cloud.agent.api.OvsSetupBridgeCommand; import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; import com.cloud.agent.api.PingCommand; @@ -1342,10 +1340,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((CheckOnHostCommand)cmd); } else if (cmd instanceof OvsFetchInterfaceCommand) { return execute((OvsFetchInterfaceCommand)cmd); - } else if (cmd instanceof OvsSetupBridgeCommand) { - return execute((OvsSetupBridgeCommand)cmd); - } else if (cmd instanceof OvsDestroyBridgeCommand) { - return execute((OvsDestroyBridgeCommand)cmd); } else if (cmd instanceof OvsCreateTunnelCommand) { return execute((OvsCreateTunnelCommand)cmd); } else if (cmd instanceof OvsDestroyTunnelCommand) { @@ -1381,20 +1375,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } - private Answer execute(final OvsSetupBridgeCommand cmd) { - findOrCreateTunnelNetwork(cmd.getBridgeName()); - configureTunnelNetwork(cmd.getNetworkId(), cmd.getHostId(), - cmd.getBridgeName()); - s_logger.debug("OVS Bridge configured"); - return new Answer(cmd, true, null); - } - - private Answer execute(final OvsDestroyBridgeCommand cmd) { - destroyTunnelNetwork(cmd.getBridgeName()); - s_logger.debug("OVS Bridge destroyed"); - return new Answer(cmd, true, null); - } - public Answer execute(final OvsVpcPhysicalTopologyConfigCommand cmd) { final String bridge = cmd.getBridgeName(); @@ -1436,28 +1416,23 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private synchronized void destroyTunnelNetwork(final String bridge) { - try { - findOrCreateTunnelNetwork(bridge); - final Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger); - cmd.add("destroy_ovs_bridge"); - cmd.add("--bridge", bridge); - final String result = cmd.execute(); - if (result != null) { - // TODO: Should make this error not fatal? - // Can Concurrent VM shutdown/migration/reboot events can cause - // this method - // to be executed on a bridge which has already been removed? - throw new CloudRuntimeException("Unable to remove OVS bridge " + bridge); - } - return; - } catch (final Exception e) { - s_logger.warn("destroyTunnelNetwork failed:", e); - return; + public synchronized boolean destroyTunnelNetwork(final String bridge) { + findOrCreateTunnelNetwork(bridge); + + final Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger); + cmd.add("destroy_ovs_bridge"); + cmd.add("--bridge", bridge); + + final String result = cmd.execute(); + + if (result != null) { + s_logger.debug("OVS Bridge could not be destroyed due to error ==> " + result); + return false; } + return true; } - private synchronized boolean findOrCreateTunnelNetwork(final String nwName) { + public synchronized boolean findOrCreateTunnelNetwork(final String nwName) { try { if (checkNetwork(nwName)) { return true; @@ -1475,7 +1450,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - private synchronized boolean configureTunnelNetwork(final long networkId, + public synchronized boolean configureTunnelNetwork(final long networkId, final long hostId, final String nwName) { try { findOrCreateTunnelNetwork(nwName); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyBridgeCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyBridgeCommandWrapper.java new file mode 100644 index 00000000000..ab2b9c40c40 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyBridgeCommandWrapper.java @@ -0,0 +1,43 @@ +// +// 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.OvsDestroyBridgeCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtOvsDestroyBridgeCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsDestroyBridgeCommandWrapper.class); + + @Override + public Answer execute(final OvsDestroyBridgeCommand command, final LibvirtComputingResource libvirtComputingResource) { + final boolean result = libvirtComputingResource.destroyTunnelNetwork(command.getBridgeName()); + + if (!result) { + s_logger.debug("Error trying to destroy OVS Bridge!"); + } + + return new Answer(command, result, null); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsSetupBridgeCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsSetupBridgeCommandWrapper.java new file mode 100644 index 00000000000..4c979a7be43 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsSetupBridgeCommandWrapper.java @@ -0,0 +1,47 @@ +// +// 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.OvsSetupBridgeCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtOvsSetupBridgeCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsSetupBridgeCommandWrapper.class); + + @Override + public Answer execute(final OvsSetupBridgeCommand command, final LibvirtComputingResource libvirtComputingResource) { + final boolean findResult = libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName()); + final boolean configResult = libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(), + command.getBridgeName()); + + final boolean finalResult = findResult && configResult; + + if (!finalResult) { + s_logger.debug("::FAILURE:: OVS Bridge was NOT configured properly!"); + } + + return new Answer(command, finalResult, null); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java index 921d5b8cf64..108b0d2f3d7 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java @@ -33,6 +33,7 @@ import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; import com.cloud.resource.CommandWrapper; import com.cloud.storage.Volume; @@ -51,6 +52,7 @@ public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapp boolean skipDisconnect = false; + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); try { final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); @@ -69,7 +71,7 @@ public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapp skipDisconnect = true; - if (!libvirtComputingResource.getStoragePoolMgr().connectPhysicalDisksViaVmSpec(vm)) { + if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vm)) { return new PrepareForMigrationAnswer(command, "failed to connect physical disks to host"); } @@ -82,7 +84,7 @@ public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapp return new PrepareForMigrationAnswer(command, e.toString()); } finally { if (!skipDisconnect) { - libvirtComputingResource.getStoragePoolMgr().disconnectPhysicalDisksViaVmSpec(vm); + storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vm); } } } 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 04aa2ea518d..05dbe2d1606 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 @@ -35,6 +35,8 @@ 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.OvsDestroyBridgeCommand; +import com.cloud.agent.api.OvsSetupBridgeCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; @@ -94,6 +96,8 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(GetStorageStatsCommand.class, new LibvirtGetStorageStatsCommandWrapper()); linbvirtCommands.put(UpgradeSnapshotCommand.class, new LibvirtUpgradeSnapshotCommandWrapper()); linbvirtCommands.put(DeleteStoragePoolCommand.class, new LibvirtDeleteStoragePoolCommandWrapper()); + linbvirtCommands.put(OvsSetupBridgeCommand.class, new LibvirtOvsSetupBridgeCommandWrapper()); + linbvirtCommands.put(OvsDestroyBridgeCommand.class, new LibvirtOvsDestroyBridgeCommandWrapper()); 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 2432c98c39a..b8046f5f2a3 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 @@ -77,6 +77,8 @@ 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.OvsDestroyBridgeCommand; +import com.cloud.agent.api.OvsSetupBridgeCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; @@ -764,6 +766,203 @@ public class LibvirtComputingResourceTest { verify(diskTO, times(1)).getType(); } + @Test + public void testPrepareForMigrationCommandMigration() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); + final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); + final NicTO nicTO = Mockito.mock(NicTO.class); + final DiskTO diskTO = Mockito.mock(DiskTO.class); + final VifDriver vifDriver = Mockito.mock(VifDriver.class); + + final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(vm.getNics()).thenReturn(new NicTO[]{nicTO}); + when(vm.getDisks()).thenReturn(new DiskTO[]{diskTO}); + + when(nicTO.getType()).thenReturn(TrafficType.Guest); + when(diskTO.getType()).thenReturn(Volume.Type.ISO); + + when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver); + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager); + when(storagePoolManager.connectPhysicalDisksViaVmSpec(vm)).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(vm, times(1)).getNics(); + verify(vm, times(1)).getDisks(); + verify(diskTO, times(1)).getType(); + } + + @SuppressWarnings("unchecked") + @Test + public void testPrepareForMigrationCommandLibvirtException() { + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); + final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); + final NicTO nicTO = Mockito.mock(NicTO.class); + final VifDriver vifDriver = Mockito.mock(VifDriver.class); + + final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(vm.getNics()).thenReturn(new NicTO[]{nicTO}); + when(nicTO.getType()).thenReturn(TrafficType.Guest); + + when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver); + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(vm, times(1)).getNics(); + } + + @SuppressWarnings("unchecked") + @Test + public void testPrepareForMigrationCommandURISyntaxException() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); + final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); + final NicTO nicTO = Mockito.mock(NicTO.class); + final DiskTO volume = Mockito.mock(DiskTO.class); + final VifDriver vifDriver = Mockito.mock(VifDriver.class); + + final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(vm.getNics()).thenReturn(new NicTO[]{nicTO}); + when(vm.getDisks()).thenReturn(new DiskTO[]{volume}); + + when(nicTO.getType()).thenReturn(TrafficType.Guest); + when(volume.getType()).thenReturn(Volume.Type.ISO); + + when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenReturn(vifDriver); + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager); + try { + when(libvirtComputingResource.getVolumePath(conn, volume)).thenThrow(URISyntaxException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(vm, times(1)).getNics(); + verify(vm, times(1)).getDisks(); + verify(volume, times(1)).getType(); + } + + @SuppressWarnings("unchecked") + @Test + public void testPrepareForMigrationCommandInternalErrorException() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); + final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); + final NicTO nicTO = Mockito.mock(NicTO.class); + final DiskTO volume = Mockito.mock(DiskTO.class); + + final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(vm.getNics()).thenReturn(new NicTO[]{nicTO}); + when(nicTO.getType()).thenReturn(TrafficType.Guest); + + when(libvirtComputingResource.getVifDriver(nicTO.getType())).thenThrow(InternalErrorException.class); + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolManager); + try { + when(libvirtComputingResource.getVolumePath(conn, volume)).thenReturn("/path"); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(vm, times(1)).getNics(); + } + @Test(expected = UnsatisfiedLinkError.class) public void testMigrateCommand() { // The Connect constructor used inside the LibvirtMigrateCommandWrapper has a call to native methods, which @@ -1708,4 +1907,92 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); verify(storagePoolMgr, times(1)).deleteStoragePool(pool.getType(), pool.getUuid()); } + + @Test + public void testOvsSetupBridgeCommand() { + final String name = "Test"; + final Long hostId = 1l; + final Long networkId = 1l; + + final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true); + when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(), + command.getBridgeName())).thenReturn(true); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName()); + verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(), + command.getBridgeName()); + } + + @Test + public void testOvsSetupBridgeCommandFailure() { + final String name = "Test"; + final Long hostId = 1l; + final Long networkId = 1l; + + final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true); + when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(), + command.getBridgeName())).thenReturn(false); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName()); + verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(), + command.getBridgeName()); + } + + @Test + public void testOvsDestroyBridgeCommand() { + final String name = "Test"; + final Long hostId = 1l; + final Long networkId = 1l; + + final OvsDestroyBridgeCommand command = new OvsDestroyBridgeCommand(networkId, name, hostId); + + when(libvirtComputingResource.destroyTunnelNetwork(command.getBridgeName())).thenReturn(true); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).destroyTunnelNetwork(command.getBridgeName()); + } + + @Test + public void testOvsDestroyBridgeCommandFailure() { + final String name = "Test"; + final Long hostId = 1l; + final Long networkId = 1l; + + final OvsDestroyBridgeCommand command = new OvsDestroyBridgeCommand(networkId, name, hostId); + + when(libvirtComputingResource.destroyTunnelNetwork(command.getBridgeName())).thenReturn(false); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).destroyTunnelNetwork(command.getBridgeName()); + } } \ No newline at end of file From 5499eecd33d93c88ed9c0b4828deb0d11ac0a66e Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 1 May 2015 14:43:30 +0200 Subject: [PATCH 21/36] Refactoring the LibvirtComputingResource - Adding 7 new command wrappers - 10 unit tests added - KVM hypervisor plugin with 14.8% coverage --- .../resource/LibvirtComputingResource.java | 128 +---------- ...virtCleanupNetworkRulesCommandWrapper.java | 34 +++ ...ibvirtCreateStoragePoolCommandWrapper.java | 33 +++ ...ibvirtModifyStoragePoolCommandWrapper.java | 51 +++++ ...tworkRulesVmSecondaryIpCommandWrapper.java | 49 ++++ ...ibvirtOvsFetchInterfaceCommandWrapper.java | 53 +++++ ...cPhysicalTopologyConfigCommandWrapper.java | 53 +++++ ...sVpcRoutingPolicyConfigCommandWrapper.java | 53 +++++ .../wrapper/LibvirtRequestWrapper.java | 14 ++ .../LibvirtComputingResourceTest.java | 212 ++++++++++++++++++ 10 files changed, 558 insertions(+), 122 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCleanupNetworkRulesCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateStoragePoolCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyStoragePoolCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesVmSecondaryIpCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsFetchInterfaceCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.java 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 cc73e65768e..75c9663e35f 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 @@ -88,11 +88,9 @@ import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; -import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.FenceAnswer; @@ -100,19 +98,12 @@ import com.cloud.agent.api.FenceCommand; import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.ModifyStoragePoolAnswer; -import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkRulesSystemVmCommand; -import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.OvsCreateTunnelAnswer; import com.cloud.agent.api.OvsCreateTunnelCommand; import com.cloud.agent.api.OvsDestroyTunnelCommand; -import com.cloud.agent.api.OvsFetchInterfaceAnswer; -import com.cloud.agent.api.OvsFetchInterfaceCommand; -import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; -import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; @@ -202,7 +193,6 @@ import com.cloud.storage.template.Processor; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; import com.cloud.storage.template.TemplateLocation; -import com.cloud.storage.template.TemplateProp; import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -443,6 +433,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _timeout; } + public String getOvsTunnelPath() { + return _ovsTunnelPath; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1300,10 +1294,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((CreateVolumeFromSnapshotCommand)cmd); } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { return execute((CreatePrivateTemplateFromSnapshotCommand)cmd); - } else if (cmd instanceof CreateStoragePoolCommand) { - return execute((CreateStoragePoolCommand)cmd); - } else if (cmd instanceof ModifyStoragePoolCommand) { - return execute((ModifyStoragePoolCommand)cmd); } else if (cmd instanceof SecurityGroupRulesCmd) { return execute((SecurityGroupRulesCmd)cmd); } else if (cmd instanceof FenceCommand) { @@ -1322,32 +1312,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((NetworkUsageCommand)cmd); } else if (cmd instanceof NetworkRulesSystemVmCommand) { return execute((NetworkRulesSystemVmCommand)cmd); - } else if (cmd instanceof CleanupNetworkRulesCmd) { - return execute((CleanupNetworkRulesCmd)cmd); } else if (cmd instanceof CopyVolumeCommand) { return execute((CopyVolumeCommand)cmd); } else if (cmd instanceof ResizeVolumeCommand) { return execute((ResizeVolumeCommand)cmd); } else if (cmd instanceof CheckNetworkCommand) { return execute((CheckNetworkCommand)cmd); - } else if (cmd instanceof NetworkRulesVmSecondaryIpCommand) { - return execute((NetworkRulesVmSecondaryIpCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else if (cmd instanceof PvlanSetupCommand) { return execute((PvlanSetupCommand)cmd); } else if (cmd instanceof CheckOnHostCommand) { return execute((CheckOnHostCommand)cmd); - } else if (cmd instanceof OvsFetchInterfaceCommand) { - return execute((OvsFetchInterfaceCommand)cmd); } else if (cmd instanceof OvsCreateTunnelCommand) { return execute((OvsCreateTunnelCommand)cmd); } else if (cmd instanceof OvsDestroyTunnelCommand) { return execute((OvsDestroyTunnelCommand)cmd); - } else if (cmd instanceof OvsVpcPhysicalTopologyConfigCommand) { - return execute((OvsVpcPhysicalTopologyConfigCommand) cmd); - } else if (cmd instanceof OvsVpcRoutingPolicyConfigCommand) { - return execute((OvsVpcRoutingPolicyConfigCommand) cmd); } else { s_logger.warn("Unsupported command "); return Answer.createUnsupportedCommandAnswer(cmd); @@ -1357,65 +1337,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private OvsFetchInterfaceAnswer execute(final OvsFetchInterfaceCommand cmd) { - final String label = cmd.getLabel(); - s_logger.debug("Will look for network with name-label:" + label); - try { - final String ipadd = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'"); - final String mask = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f4"); - final String mac = Script.runSimpleBashScript("ifconfig " + label + " | grep HWaddr | awk -F \" \" '{print $5}'"); - return new OvsFetchInterfaceAnswer(cmd, true, "Interface " + label - + " retrieved successfully", ipadd, mask, mac); - - } catch (final Exception e) { - s_logger.warn("Caught execption when fetching interface", e); - return new OvsFetchInterfaceAnswer(cmd, false, "EXCEPTION:" - + e.getMessage()); - } - - } - - public Answer execute(final OvsVpcPhysicalTopologyConfigCommand cmd) { - - final String bridge = cmd.getBridgeName(); - try { - final Script command = new Script(_ovsTunnelPath, _timeout, s_logger); - command.add("configure_ovs_bridge_for_network_topology"); - command.add("--bridge", bridge); - command.add("--config", cmd.getVpcConfigInJson()); - - final String result = command.execute(); - if (result.equalsIgnoreCase("SUCCESS")) { - return new Answer(cmd, true, result); - } else { - return new Answer(cmd, false, result); - } - } catch (final Exception e) { - s_logger.warn("caught exception while updating host with latest routing polcies", e); - return new Answer(cmd, false, e.getMessage()); - } - } - - public Answer execute(final OvsVpcRoutingPolicyConfigCommand cmd) { - - try { - final Script command = new Script(_ovsTunnelPath, _timeout, s_logger); - command.add("configure_ovs_bridge_for_routing_policies"); - command.add("--bridge", cmd.getBridgeName()); - command.add("--config", cmd.getVpcConfigInJson()); - - final String result = command.execute(); - if (result.equalsIgnoreCase("SUCCESS")) { - return new Answer(cmd, true, result); - } else { - return new Answer(cmd, false, result); - } - } catch (final Exception e) { - s_logger.warn("caught exception while updating host with latest VPC topology", e); - return new Answer(cmd, false, e.getMessage()); - } - } - public synchronized boolean destroyTunnelNetwork(final String bridge) { findOrCreateTunnelNetwork(bridge); @@ -2642,24 +2563,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected Answer execute(final CreateStoragePoolCommand cmd) { - return new Answer(cmd, true, "success"); - } - - protected Answer execute(final ModifyStoragePoolCommand cmd) { - final KVMStoragePool storagepool = - _storagePoolMgr.createStoragePool(cmd.getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(), cmd.getPool().getPath(), cmd.getPool() - .getUserInfo(), cmd.getPool().getType()); - if (storagepool == null) { - return new Answer(cmd, false, " Failed to create storage pool"); - } - - final Map tInfo = new HashMap(); - final ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, storagepool.getCapacity(), storagepool.getAvailable(), tInfo); - - return answer; - } - private Answer execute(final SecurityGroupRulesCmd cmd) { String vif = null; String brname = null; @@ -2686,11 +2589,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(final CleanupNetworkRulesCmd cmd) { - final boolean result = cleanup_rules(); - return new Answer(cmd, result, ""); - } - protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; @@ -4386,7 +4284,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - private boolean network_rules_vmSecondaryIp(final Connect conn, final String vmName, final String secIp, final String action) { + public boolean configureNetworkRulesVMSecondaryIP(final Connect conn, final String vmName, final String secIp, final String action) { if (!_canBridgeFirewall) { return false; @@ -4405,7 +4303,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - private boolean cleanup_rules() { + public boolean cleanupRules() { if (!_canBridgeFirewall) { return false; } @@ -4486,20 +4384,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new Answer(cmd, success, ""); } - private Answer execute(final NetworkRulesVmSecondaryIpCommand cmd) { - boolean success = false; - Connect conn; - try { - conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - success = network_rules_vmSecondaryIp(conn, cmd.getVmName(), cmd.getVmSecIp(), cmd.getAction()); - } catch (final LibvirtException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return new Answer(cmd, success, ""); - } - private String prettyVersion(final long version) { final long major = version / 1000000; final long minor = version % 1000000 / 1000; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCleanupNetworkRulesCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCleanupNetworkRulesCommandWrapper.java new file mode 100644 index 00000000000..59c353b594c --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCleanupNetworkRulesCommandWrapper.java @@ -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.CleanupNetworkRulesCmd; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtCleanupNetworkRulesCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CleanupNetworkRulesCmd command, final LibvirtComputingResource libvirtComputingResource) { + final boolean result = libvirtComputingResource.cleanupRules(); + return new Answer(command, result, ""); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateStoragePoolCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateStoragePoolCommandWrapper.java new file mode 100644 index 00000000000..e233b4fcd91 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateStoragePoolCommandWrapper.java @@ -0,0 +1,33 @@ +// +// 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.CreateStoragePoolCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtCreateStoragePoolCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CreateStoragePoolCommand command, final LibvirtComputingResource libvirtComputingResource) { + return new Answer(command, true, "success"); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyStoragePoolCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyStoragePoolCommandWrapper.java new file mode 100644 index 00000000000..34d12bad4dd --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifyStoragePoolCommandWrapper.java @@ -0,0 +1,51 @@ +// +// 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 java.util.HashMap; +import java.util.Map; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ModifyStoragePoolAnswer; +import com.cloud.agent.api.ModifyStoragePoolCommand; +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.storage.template.TemplateProp; + +public final class LibvirtModifyStoragePoolCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final ModifyStoragePoolCommand command, final LibvirtComputingResource libvirtComputingResource) { + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + final KVMStoragePool storagepool = + storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool() + .getUserInfo(), command.getPool().getType()); + if (storagepool == null) { + return new Answer(command, false, " Failed to create storage pool"); + } + + final Map tInfo = new HashMap(); + final ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(command, storagepool.getCapacity(), storagepool.getAvailable(), tInfo); + + return answer; + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesVmSecondaryIpCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesVmSecondaryIpCommandWrapper.java new file mode 100644 index 00000000000..6f153450890 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesVmSecondaryIpCommandWrapper.java @@ -0,0 +1,49 @@ +// +// 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 org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtNetworkRulesVmSecondaryIpCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.class); + + @Override + public Answer execute(final NetworkRulesVmSecondaryIpCommand command, final LibvirtComputingResource libvirtComputingResource) { + boolean result = false; + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(command.getVmName()); + result = libvirtComputingResource.configureNetworkRulesVMSecondaryIP(conn, command.getVmName(), command.getVmSecIp(), command.getAction()); + } catch (final LibvirtException e) { + s_logger.debug("Could not configure VM secondary IP! => " + e.getLocalizedMessage()); + } + + return new Answer(command, result, ""); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsFetchInterfaceCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsFetchInterfaceCommandWrapper.java new file mode 100644 index 00000000000..e7d0b7e9536 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsFetchInterfaceCommandWrapper.java @@ -0,0 +1,53 @@ +// +// 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.OvsFetchInterfaceAnswer; +import com.cloud.agent.api.OvsFetchInterfaceCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.script.Script; + +public final class LibvirtOvsFetchInterfaceCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsFetchInterfaceCommandWrapper.class); + + @Override + public Answer execute(final OvsFetchInterfaceCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String label = command.getLabel(); + + s_logger.debug("Will look for network with name-label:" + label); + try { + final String ipadd = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'"); + final String mask = Script.runSimpleBashScript("ifconfig " + label + " | grep 'inet addr:' | cut -d: -f4"); + final String mac = Script.runSimpleBashScript("ifconfig " + label + " | grep HWaddr | awk -F \" \" '{print $5}'"); + return new OvsFetchInterfaceAnswer(command, true, "Interface " + label + + " retrieved successfully", ipadd, mask, mac); + + } catch (final Exception e) { + s_logger.warn("Caught execption when fetching interface", e); + return new OvsFetchInterfaceAnswer(command, false, "EXCEPTION:" + + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.java new file mode 100644 index 00000000000..d1e86516d0e --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.java @@ -0,0 +1,53 @@ +// +// 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.OvsVpcPhysicalTopologyConfigCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.script.Script; + +public final class LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper.class); + + @Override + public Answer execute(final OvsVpcPhysicalTopologyConfigCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + final Script scriptCommand = new Script(libvirtComputingResource.getOvsTunnelPath(), libvirtComputingResource.getTimeout(), s_logger); + scriptCommand.add("configure_ovs_bridge_for_network_topology"); + scriptCommand.add("--bridge", command.getBridgeName()); + scriptCommand.add("--config", command.getVpcConfigInJson()); + + final String result = scriptCommand.execute(); + if (result.equalsIgnoreCase("SUCCESS")) { + return new Answer(command, true, result); + } else { + return new Answer(command, false, result); + } + } catch (final Exception e) { + s_logger.warn("caught exception while updating host with latest routing polcies", e); + return new Answer(command, false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.java new file mode 100644 index 00000000000..36762ed0a4a --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.java @@ -0,0 +1,53 @@ +// +// 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.OvsVpcRoutingPolicyConfigCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.script.Script; + +public final class LibvirtOvsVpcRoutingPolicyConfigCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.class); + + @Override + public Answer execute(final OvsVpcRoutingPolicyConfigCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + final Script scriptCommand = new Script(libvirtComputingResource.getOvsTunnelPath(), libvirtComputingResource.getTimeout(), s_logger); + scriptCommand.add("configure_ovs_bridge_for_routing_policies"); + scriptCommand.add("--bridge", command.getBridgeName()); + scriptCommand.add("--config", command.getVpcConfigInJson()); + + final String result = scriptCommand.execute(); + if (result.equalsIgnoreCase("SUCCESS")) { + return new Answer(command, true, result); + } else { + return new Answer(command, false, result); + } + } catch (final Exception e) { + s_logger.warn("caught exception while updating host with latest VPC topology", e); + return new Answer(command, false, e.getMessage()); + } + } +} \ 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 05dbe2d1606..87b4ec24d35 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 @@ -25,7 +25,9 @@ import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsCommand; @@ -35,8 +37,13 @@ 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.ModifyStoragePoolCommand; +import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; import com.cloud.agent.api.OvsDestroyBridgeCommand; +import com.cloud.agent.api.OvsFetchInterfaceCommand; import com.cloud.agent.api.OvsSetupBridgeCommand; +import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; +import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; @@ -98,6 +105,13 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(DeleteStoragePoolCommand.class, new LibvirtDeleteStoragePoolCommandWrapper()); linbvirtCommands.put(OvsSetupBridgeCommand.class, new LibvirtOvsSetupBridgeCommandWrapper()); linbvirtCommands.put(OvsDestroyBridgeCommand.class, new LibvirtOvsDestroyBridgeCommandWrapper()); + linbvirtCommands.put(OvsFetchInterfaceCommand.class, new LibvirtOvsFetchInterfaceCommandWrapper()); + linbvirtCommands.put(OvsVpcPhysicalTopologyConfigCommand.class, new LibvirtOvsVpcPhysicalTopologyConfigCommandWrapper()); + linbvirtCommands.put(OvsVpcRoutingPolicyConfigCommand.class, new LibvirtOvsVpcRoutingPolicyConfigCommandWrapper()); + linbvirtCommands.put(CreateStoragePoolCommand.class, new LibvirtCreateStoragePoolCommandWrapper()); + linbvirtCommands.put(ModifyStoragePoolCommand.class, new LibvirtModifyStoragePoolCommandWrapper()); + linbvirtCommands.put(CleanupNetworkRulesCmd.class, new LibvirtCleanupNetworkRulesCommandWrapper()); + linbvirtCommands.put(NetworkRulesVmSecondaryIpCommand.class, new LibvirtNetworkRulesVmSecondaryIpCommandWrapper()); 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 b8046f5f2a3..8fd1ecfd66e 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 @@ -68,6 +68,8 @@ import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.CleanupNetworkRulesCmd; +import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsCommand; @@ -77,8 +79,17 @@ 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.ModifyStoragePoolCommand; +import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; import com.cloud.agent.api.OvsDestroyBridgeCommand; +import com.cloud.agent.api.OvsFetchInterfaceCommand; import com.cloud.agent.api.OvsSetupBridgeCommand; +import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; +import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Host; +import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Tier; +import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Vm; +import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; +import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Acl; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; @@ -1995,4 +2006,205 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).destroyTunnelNetwork(command.getBridgeName()); } + + @Test + public void testOvsFetchInterfaceCommand() { + final String label = "eth0"; + + final OvsFetchInterfaceCommand command = new OvsFetchInterfaceCommand(label); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + } + + @Test + public void testOvsVpcPhysicalTopologyConfigCommand() { + final Host[] hosts = null; + final Tier[] tiers = null; + final Vm[] vms = null; + final String cidr = null; + + final OvsVpcPhysicalTopologyConfigCommand command = new OvsVpcPhysicalTopologyConfigCommand(hosts, tiers, vms, cidr); + + when(libvirtComputingResource.getOvsTunnelPath()).thenReturn("/path"); + when(libvirtComputingResource.getTimeout()).thenReturn(0); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getOvsTunnelPath(); + verify(libvirtComputingResource, times(1)).getTimeout(); + } + + @Test + public void testOvsVpcRoutingPolicyConfigCommand() { + final String id = null; + final String cidr = null; + final Acl[] acls = null; + final com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Tier[] tiers = null; + + final OvsVpcRoutingPolicyConfigCommand command = new OvsVpcRoutingPolicyConfigCommand(id, cidr, acls, tiers); + + when(libvirtComputingResource.getOvsTunnelPath()).thenReturn("/path"); + when(libvirtComputingResource.getTimeout()).thenReturn(0); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getOvsTunnelPath(); + verify(libvirtComputingResource, times(1)).getTimeout(); + } + + @Test + public void testCreateStoragePoolCommand() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final CreateStoragePoolCommand command = new CreateStoragePoolCommand(true, pool); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + } + + @Test + public void testModifyStoragePoolCommand() { + final StoragePool pool = Mockito.mock(StoragePool.class);; + final ModifyStoragePoolCommand command = new ModifyStoragePoolCommand(true, pool); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool kvmStoragePool = Mockito.mock(KVMStoragePool.class); + + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool() + .getUserInfo(), command.getPool().getType())).thenReturn(kvmStoragePool); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool() + .getUserInfo(), command.getPool().getType()); + } + + @Test + public void testModifyStoragePoolCommandFailure() { + final StoragePool pool = Mockito.mock(StoragePool.class);; + final ModifyStoragePoolCommand command = new ModifyStoragePoolCommand(true, pool); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool() + .getUserInfo(), command.getPool().getType())).thenReturn(null); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), command.getPool() + .getUserInfo(), command.getPool().getType()); + } + + @Test + public void testCleanupNetworkRulesCmd() { + final CleanupNetworkRulesCmd command = new CleanupNetworkRulesCmd(1); + + when(libvirtComputingResource.cleanupRules()).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).cleanupRules(); + } + + @Test + public void testNetworkRulesVmSecondaryIpCommand() { + final String vmName = "Test"; + final String vmMac = "00:00:00:00"; + final String secondaryIp = "172.168.25.25"; + final boolean action = true; + + final NetworkRulesVmSecondaryIpCommand command = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, action ); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + when(libvirtComputingResource.configureNetworkRulesVMSecondaryIP(conn, command.getVmName(), command.getVmSecIp(), command.getAction())).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + verify(libvirtComputingResource, times(1)).configureNetworkRulesVMSecondaryIP(conn, command.getVmName(), command.getVmSecIp(), command.getAction()); + } + + @SuppressWarnings("unchecked") + @Test + public void testNetworkRulesVmSecondaryIpCommandFailure() { + final String vmName = "Test"; + final String vmMac = "00:00:00:00"; + final String secondaryIp = "172.168.25.25"; + final boolean action = true; + + final NetworkRulesVmSecondaryIpCommand command = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, action ); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + } } \ No newline at end of file From 6748a73b82bb7d1d45fdde1cbcc02f78b8f7b330 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 1 May 2015 16:17:09 +0200 Subject: [PATCH 22/36] Refactoring the LibvirtComputingResource - Adding 4 new command wrappers - 12 unit tests added - KVM hypervisor plugin with 15.5% coverage --- .../resource/LibvirtComputingResource.java | 108 +----- .../LibvirtCheckNetworkCommandWrapper.java | 57 +++ .../LibvirtCheckSshCommandWrapper.java | 56 +++ ...irtNetworkRulesSystemVmCommandWrapper.java | 49 +++ ...LibvirtOvsDestroyTunnelCommandWrapper.java | 58 +++ .../wrapper/LibvirtRequestWrapper.java | 8 + .../LibvirtComputingResourceTest.java | 337 +++++++++++++++++- 7 files changed, 573 insertions(+), 100 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckNetworkCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckSshCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesSystemVmCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyTunnelCommandWrapper.java 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 75c9663e35f..9c1a6b42570 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 @@ -85,8 +85,6 @@ import com.ceph.rbd.RbdImage; import com.cloud.agent.api.Answer; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.CheckNetworkAnswer; -import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; @@ -98,12 +96,10 @@ import com.cloud.agent.api.FenceCommand; import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.OvsCreateTunnelAnswer; import com.cloud.agent.api.OvsCreateTunnelCommand; -import com.cloud.agent.api.OvsDestroyTunnelCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; @@ -122,8 +118,6 @@ import com.cloud.agent.api.UnPlugNicAnswer; import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.VmDiskStatsEntry; import com.cloud.agent.api.VmStatsEntry; -import com.cloud.agent.api.check.CheckSshAnswer; -import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.NetworkElementCommand; @@ -178,7 +172,6 @@ import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetworkSetupInfo; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; import com.cloud.storage.JavaStorageLayer; @@ -1161,7 +1154,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return ""; } - private boolean checkNetwork(final String networkName) { + public boolean checkNetwork(final String networkName) { if (networkName == null) { return true; } @@ -1306,18 +1299,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((UnPlugNicCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest((NetworkElementCommand)cmd); - } else if (cmd instanceof CheckSshCommand) { - return execute((CheckSshCommand)cmd); } else if (cmd instanceof NetworkUsageCommand) { return execute((NetworkUsageCommand)cmd); - } else if (cmd instanceof NetworkRulesSystemVmCommand) { - return execute((NetworkRulesSystemVmCommand)cmd); } else if (cmd instanceof CopyVolumeCommand) { return execute((CopyVolumeCommand)cmd); } else if (cmd instanceof ResizeVolumeCommand) { return execute((ResizeVolumeCommand)cmd); - } else if (cmd instanceof CheckNetworkCommand) { - return execute((CheckNetworkCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else if (cmd instanceof PvlanSetupCommand) { @@ -1326,8 +1313,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((CheckOnHostCommand)cmd); } else if (cmd instanceof OvsCreateTunnelCommand) { return execute((OvsCreateTunnelCommand)cmd); - } else if (cmd instanceof OvsDestroyTunnelCommand) { - return execute((OvsDestroyTunnelCommand)cmd); } else { s_logger.warn("Unsupported command "); return Answer.createUnsupportedCommandAnswer(cmd); @@ -1367,6 +1352,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.debug("### KVM network for tunnels created:" + nwName); } catch (final Exception e) { s_logger.warn("createTunnelNetwork failed", e); + return false; } return true; } @@ -1374,7 +1360,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv public synchronized boolean configureTunnelNetwork(final long networkId, final long hostId, final String nwName) { try { - findOrCreateTunnelNetwork(nwName); + final boolean findResult = findOrCreateTunnelNetwork(nwName); + if (!findResult) { + s_logger.warn("LibvirtComputingResource.findOrCreateTunnelNetwork() failed! Cannot proceed creating the tunnel."); + return false; + } final String configuredHosts = Script .runSimpleBashScript("ovs-vsctl get bridge " + nwName + " other_config:ovs-host-setup"); @@ -1441,53 +1431,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(final OvsDestroyTunnelCommand cmd) { - try { - if (!findOrCreateTunnelNetwork(cmd.getBridgeName())) { - s_logger.warn("Unable to find tunnel network for GRE key:" - + cmd.getBridgeName()); - return new Answer(cmd, false, "No network found"); - } - - final Script command = new Script(_ovsTunnelPath, _timeout, s_logger); - command.add("destroy_tunnel"); - command.add("--bridge", cmd.getBridgeName()); - command.add("--iface_name", cmd.getInPortName()); - final String result = command.execute(); - if (result == null) { - return new Answer(cmd, true, result); - } else { - return new Answer(cmd, false, result); - } - } catch (final Exception e) { - s_logger.warn("caught execption when destroy ovs tunnel", e); - return new Answer(cmd, false, e.getMessage()); - } - } - - private CheckNetworkAnswer execute(final CheckNetworkCommand cmd) { - final List phyNics = cmd.getPhysicalNetworkInfoList(); - String errMsg = null; - for (final PhysicalNetworkSetupInfo nic : phyNics) { - if (!checkNetwork(nic.getGuestNetworkName())) { - errMsg = "Can not find network: " + nic.getGuestNetworkName(); - break; - } else if (!checkNetwork(nic.getPrivateNetworkName())) { - errMsg = "Can not find network: " + nic.getPrivateNetworkName(); - break; - } else if (!checkNetwork(nic.getPublicNetworkName())) { - errMsg = "Can not find network: " + nic.getPublicNetworkName(); - break; - } - } - - if (errMsg != null) { - return new CheckNetworkAnswer(cmd, false, errMsg); - } else { - return new CheckNetworkAnswer(cmd, true, null); - } - } - private CopyVolumeAnswer execute(final CopyVolumeCommand cmd) { /** This method is only used for copying files from Primary Storage TO Secondary Storage @@ -2957,7 +2900,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv for (final NicTO nic : nics) { if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { if (vmSpec.getType() != VirtualMachine.Type.User) { - default_network_rules_for_systemvm(conn, vmName); + configureDefaultNetworkRulesForSystemVm(conn, vmName); break; } else { final List nicSecIps = nic.getNicSecIps(); @@ -3193,26 +3136,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vm.getDevices().addDevice(getVifDriver(nic.getType()).plug(nic, vm.getPlatformEmulator().toString(), nicAdapter).toString()); } - protected CheckSshAnswer execute(final CheckSshCommand cmd) { - final String vmName = cmd.getName(); - final String privateIp = cmd.getIp(); - final int cmdPort = cmd.getPort(); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); - } - - if (!_virtRouterResource.connect(privateIp, cmdPort)) { - return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + " because of a connection failure"); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Ping command port succeeded for vm " + vmName); - } - - return new CheckSshAnswer(cmd); - } - public boolean cleanupDisk(final DiskDef disk) { final String path = disk.getDiskPath(); @@ -4240,7 +4163,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - protected boolean default_network_rules_for_systemvm(final Connect conn, final String vmName) { + public boolean configureDefaultNetworkRulesForSystemVm(final Connect conn, final String vmName) { if (!_canBridgeFirewall) { return false; } @@ -4371,19 +4294,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(final NetworkRulesSystemVmCommand cmd) { - boolean success = false; - Connect conn; - try { - conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - success = default_network_rules_for_systemvm(conn, cmd.getVmName()); - } catch (final LibvirtException e) { - s_logger.trace("Ignoring libvirt error.", e); - } - - return new Answer(cmd, success, ""); - } - private String prettyVersion(final long version) { final long major = version / 1000000; final long minor = version % 1000000 / 1000; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckNetworkCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckNetworkCommandWrapper.java new file mode 100644 index 00000000000..4cf012d6cd6 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckNetworkCommandWrapper.java @@ -0,0 +1,57 @@ +// +// 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 java.util.List; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckNetworkAnswer; +import com.cloud.agent.api.CheckNetworkCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.network.PhysicalNetworkSetupInfo; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtCheckNetworkCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CheckNetworkCommand command, final LibvirtComputingResource libvirtComputingResource) { + final List phyNics = command.getPhysicalNetworkInfoList(); + String errMsg = null; + + for (final PhysicalNetworkSetupInfo nic : phyNics) { + if (!libvirtComputingResource.checkNetwork(nic.getGuestNetworkName())) { + errMsg = "Can not find network: " + nic.getGuestNetworkName(); + break; + } else if (!libvirtComputingResource.checkNetwork(nic.getPrivateNetworkName())) { + errMsg = "Can not find network: " + nic.getPrivateNetworkName(); + break; + } else if (!libvirtComputingResource.checkNetwork(nic.getPublicNetworkName())) { + errMsg = "Can not find network: " + nic.getPublicNetworkName(); + break; + } + } + + if (errMsg != null) { + return new CheckNetworkAnswer(command, false, errMsg); + } else { + return new CheckNetworkAnswer(command, true, null); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckSshCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckSshCommandWrapper.java new file mode 100644 index 00000000000..d258d6d41d3 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckSshCommandWrapper.java @@ -0,0 +1,56 @@ +// +// 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.check.CheckSshAnswer; +import com.cloud.agent.api.check.CheckSshCommand; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtCheckSshCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.class); + + @Override + public Answer execute(final CheckSshCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String vmName = command.getName(); + final String privateIp = command.getIp(); + final int cmdPort = command.getPort(); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); + } + + final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource(); + if (!virtRouterResource.connect(privateIp, cmdPort)) { + return new CheckSshAnswer(command, "Can not ping System vm " + vmName + " because of a connection failure"); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Ping command port succeeded for vm " + vmName); + } + + return new CheckSshAnswer(command); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesSystemVmCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesSystemVmCommandWrapper.java new file mode 100644 index 00000000000..b8ef8a8ac2f --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkRulesSystemVmCommandWrapper.java @@ -0,0 +1,49 @@ +// +// 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 org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.NetworkRulesSystemVmCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtNetworkRulesSystemVmCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsVpcRoutingPolicyConfigCommandWrapper.class); + + @Override + public Answer execute(final NetworkRulesSystemVmCommand command, final LibvirtComputingResource libvirtComputingResource) { + boolean success = false; + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(command.getVmName()); + success = libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, command.getVmName()); + } catch (final LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); + } + + return new Answer(command, success, ""); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyTunnelCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyTunnelCommandWrapper.java new file mode 100644 index 00000000000..ca694f81797 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsDestroyTunnelCommandWrapper.java @@ -0,0 +1,58 @@ +// +// 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.OvsDestroyTunnelCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.script.Script; + +public final class LibvirtOvsDestroyTunnelCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsDestroyTunnelCommandWrapper.class); + + @Override + public Answer execute(final OvsDestroyTunnelCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + if (!libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())) { + s_logger.warn("Unable to find tunnel network for GRE key:" + + command.getBridgeName()); + return new Answer(command, false, "No network found"); + } + + final Script scriptCommand = new Script(libvirtComputingResource.getOvsTunnelPath(), libvirtComputingResource.getTimeout(), s_logger); + scriptCommand.add("destroy_tunnel"); + scriptCommand.add("--bridge", command.getBridgeName()); + scriptCommand.add("--iface_name", command.getInPortName()); + final String result = scriptCommand.execute(); + if (result == null) { + return new Answer(command, true, result); + } else { + return new Answer(command, false, result); + } + } catch (final Exception e) { + s_logger.warn("caught execption when destroy ovs tunnel", e); + return new Answer(command, false, e.getMessage()); + } + } +} \ 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 87b4ec24d35..ca7a7d2638c 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 @@ -24,6 +24,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; +import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; @@ -38,8 +39,10 @@ import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; +import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; import com.cloud.agent.api.OvsDestroyBridgeCommand; +import com.cloud.agent.api.OvsDestroyTunnelCommand; import com.cloud.agent.api.OvsFetchInterfaceCommand; import com.cloud.agent.api.OvsSetupBridgeCommand; import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; @@ -51,6 +54,7 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; +import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.storage.CreateCommand; @@ -112,6 +116,10 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(ModifyStoragePoolCommand.class, new LibvirtModifyStoragePoolCommandWrapper()); linbvirtCommands.put(CleanupNetworkRulesCmd.class, new LibvirtCleanupNetworkRulesCommandWrapper()); linbvirtCommands.put(NetworkRulesVmSecondaryIpCommand.class, new LibvirtNetworkRulesVmSecondaryIpCommandWrapper()); + linbvirtCommands.put(NetworkRulesSystemVmCommand.class, new LibvirtNetworkRulesSystemVmCommandWrapper()); + linbvirtCommands.put(CheckSshCommand.class, new LibvirtCheckSshCommandWrapper()); + linbvirtCommands.put(CheckNetworkCommand.class, new LibvirtCheckNetworkCommandWrapper()); + linbvirtCommands.put(OvsDestroyTunnelCommand.class, new LibvirtOvsDestroyTunnelCommandWrapper()); 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 8fd1ecfd66e..1551f98e4d5 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 @@ -67,6 +67,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; +import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.CreateStoragePoolCommand; @@ -80,8 +81,10 @@ import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; +import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; import com.cloud.agent.api.OvsDestroyBridgeCommand; +import com.cloud.agent.api.OvsDestroyTunnelCommand; import com.cloud.agent.api.OvsFetchInterfaceCommand; import com.cloud.agent.api.OvsSetupBridgeCommand; import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; @@ -98,6 +101,7 @@ import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; +import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.storage.CreateCommand; @@ -119,6 +123,7 @@ import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; import com.cloud.hypervisor.kvm.storage.KVMStoragePool; import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkSetupInfo; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePool; @@ -129,6 +134,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; +import com.cloud.vm.VirtualMachine.Type; @RunWith(PowerMockRunner.class) public class LibvirtComputingResourceTest { @@ -1944,7 +1950,7 @@ public class LibvirtComputingResourceTest { } @Test - public void testOvsSetupBridgeCommandFailure() { + public void testOvsSetupBridgeCommandFailure1() { final String name = "Test"; final Long hostId = 1l; final Long networkId = 1l; @@ -1967,6 +1973,30 @@ public class LibvirtComputingResourceTest { command.getBridgeName()); } + @Test + public void testOvsSetupBridgeCommandFailure2() { + final String name = "Test"; + final Long hostId = 1l; + final Long networkId = 1l; + + final OvsSetupBridgeCommand command = new OvsSetupBridgeCommand(name, hostId, networkId); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(false); + when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getHostId(), + command.getBridgeName())).thenReturn(true); + + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName()); + verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getHostId(), + command.getBridgeName()); + } + @Test public void testOvsDestroyBridgeCommand() { final String name = "Test"; @@ -2043,6 +2073,27 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getTimeout(); } + @SuppressWarnings("unchecked") + @Test + public void testOvsVpcPhysicalTopologyConfigCommandFailure() { + final Host[] hosts = null; + final Tier[] tiers = null; + final Vm[] vms = null; + final String cidr = null; + + final OvsVpcPhysicalTopologyConfigCommand command = new OvsVpcPhysicalTopologyConfigCommand(hosts, tiers, vms, cidr); + + when(libvirtComputingResource.getOvsTunnelPath()).thenThrow(Exception.class); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getOvsTunnelPath(); + } + @Test public void testOvsVpcRoutingPolicyConfigCommand() { final String id = null; @@ -2066,6 +2117,27 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getTimeout(); } + @SuppressWarnings("unchecked") + @Test + public void testOvsVpcRoutingPolicyConfigCommandFailure() { + final String id = null; + final String cidr = null; + final Acl[] acls = null; + final com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Tier[] tiers = null; + + final OvsVpcRoutingPolicyConfigCommand command = new OvsVpcRoutingPolicyConfigCommand(id, cidr, acls, tiers); + + when(libvirtComputingResource.getOvsTunnelPath()).thenThrow(Exception.class); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getOvsTunnelPath(); + } + @Test public void testCreateStoragePoolCommand() { final StoragePool pool = Mockito.mock(StoragePool.class); @@ -2207,4 +2279,267 @@ public class LibvirtComputingResourceTest { } verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); } + + @Test + public void testNetworkRulesSystemVmCommand() { + final String vmName = "Test"; + final Type type = Type.SecondaryStorageVm; + + final NetworkRulesSystemVmCommand command = new NetworkRulesSystemVmCommand(vmName, type); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + when(libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, command.getVmName())).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + verify(libvirtComputingResource, times(1)).configureDefaultNetworkRulesForSystemVm(conn, command.getVmName()); + } + + @SuppressWarnings("unchecked") + @Test + public void testNetworkRulesSystemVmCommandFailure() { + final String vmName = "Test"; + final Type type = Type.SecondaryStorageVm; + + final NetworkRulesSystemVmCommand command = new NetworkRulesSystemVmCommand(vmName, type); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + } + + @Test + public void testCheckSshCommand() { + final String instanceName = "Test"; + final String ip = "172.16.16.16"; + final int port = 22; + + final CheckSshCommand command = new CheckSshCommand(instanceName, ip, port); + + final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class); + + final String privateIp = command.getIp(); + final int cmdPort = command.getPort(); + + when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource); + when(virtRouterResource.connect(privateIp, cmdPort)).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getVirtRouterResource(); + verify(virtRouterResource, times(1)).connect(privateIp, cmdPort); + } + + @Test + public void testCheckSshCommandFailure() { + final String instanceName = "Test"; + final String ip = "172.16.16.16"; + final int port = 22; + + final CheckSshCommand command = new CheckSshCommand(instanceName, ip, port); + + final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class); + + final String privateIp = command.getIp(); + final int cmdPort = command.getPort(); + + when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource); + when(virtRouterResource.connect(privateIp, cmdPort)).thenReturn(false); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getVirtRouterResource(); + verify(virtRouterResource, times(1)).connect(privateIp, cmdPort); + } + + @Test + public void testCheckNetworkCommand() { + final List networkInfoList = new ArrayList(); + + final PhysicalNetworkSetupInfo nic = Mockito.mock(PhysicalNetworkSetupInfo.class); + networkInfoList.add(nic); + + final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList); + + when(libvirtComputingResource.checkNetwork(nic.getGuestNetworkName())).thenReturn(true); + when(libvirtComputingResource.checkNetwork(nic.getPrivateNetworkName())).thenReturn(true); + when(libvirtComputingResource.checkNetwork(nic.getPublicNetworkName())).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(3)).checkNetwork(nic.getGuestNetworkName()); + verify(libvirtComputingResource, times(3)).checkNetwork(nic.getPrivateNetworkName()); + verify(libvirtComputingResource, times(3)).checkNetwork(nic.getPublicNetworkName()); + } + + @Test + public void testCheckNetworkCommandFail1() { + final List networkInfoList = new ArrayList(); + + final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class); + networkInfoList.add(networkSetupInfo); + + final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList); + + when(libvirtComputingResource.checkNetwork(networkSetupInfo.getGuestNetworkName())).thenReturn(false); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getGuestNetworkName()); + } + + @Test + public void testCheckNetworkCommandFail2() { + final List networkInfoList = new ArrayList(); + + final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class); + networkInfoList.add(networkSetupInfo); + + final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList); + + when(libvirtComputingResource.checkNetwork(networkSetupInfo.getGuestNetworkName())).thenReturn(true); + when(libvirtComputingResource.checkNetwork(networkSetupInfo.getPrivateNetworkName())).thenReturn(false); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getGuestNetworkName()); + verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getPrivateNetworkName()); + } + + @Test + public void testCheckNetworkCommandFail3() { + final List networkInfoList = new ArrayList(); + + final PhysicalNetworkSetupInfo networkSetupInfo = Mockito.mock(PhysicalNetworkSetupInfo.class); + networkInfoList.add(networkSetupInfo); + + final CheckNetworkCommand command = new CheckNetworkCommand(networkInfoList); + + when(libvirtComputingResource.checkNetwork(networkSetupInfo.getGuestNetworkName())).thenReturn(true); + when(libvirtComputingResource.checkNetwork(networkSetupInfo.getPrivateNetworkName())).thenReturn(true); + when(libvirtComputingResource.checkNetwork(networkSetupInfo.getPublicNetworkName())).thenReturn(false); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getGuestNetworkName()); + verify(libvirtComputingResource, times(1)).checkNetwork(networkSetupInfo.getPrivateNetworkName()); + } + + @Test + public void testOvsDestroyTunnelCommand() { + final String networkName = "Test"; + final Long networkId = 1l; + final String inPortName = "eth"; + + final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName()); + } + + @Test + public void testOvsDestroyTunnelCommandFailure1() { + final String networkName = "Test"; + final Long networkId = 1l; + final String inPortName = "eth"; + + final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenReturn(false); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName()); + } + + @SuppressWarnings("unchecked") + @Test + public void testOvsDestroyTunnelCommandFailure2() { + final String networkName = "Test"; + final Long networkId = 1l; + final String inPortName = "eth"; + + final OvsDestroyTunnelCommand command = new OvsDestroyTunnelCommand(networkId, networkName, inPortName); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(command.getBridgeName())).thenThrow(Exception.class); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName()); + } } \ No newline at end of file From 3c8b217262e08053fd59329f7466b65b150a18c2 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 1 May 2015 19:17:30 +0200 Subject: [PATCH 23/36] Refactoring the LibvirtComputingResource - Adding LibvirtCheckOnHostCommandWrapper and LibvirtOvsCreateTunnelCommandWrapper - 4 unit tests added - KVM hypervisor plugin with 16.2% coverage --- .../resource/LibvirtComputingResource.java | 89 +------------- .../LibvirtCheckOnHostCommandWrapper.java | 64 ++++++++++ .../LibvirtOvsCreateTunnelCommandWrapper.java | 68 +++++++++++ .../wrapper/LibvirtRequestWrapper.java | 4 + .../LibvirtComputingResourceTest.java | 112 ++++++++++++++++++ 5 files changed, 252 insertions(+), 85 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckOnHostCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java 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 9c1a6b42570..6d13ce61c72 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 @@ -85,7 +85,6 @@ import com.ceph.rbd.RbdImage; import com.cloud.agent.api.Answer; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; @@ -98,8 +97,6 @@ import com.cloud.agent.api.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; -import com.cloud.agent.api.OvsCreateTunnelAnswer; -import com.cloud.agent.api.OvsCreateTunnelCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; @@ -430,6 +427,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _ovsTunnelPath; } + public KVMHAMonitor getMonitor() { + return _monitor; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1309,10 +1310,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else if (cmd instanceof PvlanSetupCommand) { return execute((PvlanSetupCommand)cmd); - } else if (cmd instanceof CheckOnHostCommand) { - return execute((CheckOnHostCommand)cmd); - } else if (cmd instanceof OvsCreateTunnelCommand) { - return execute((OvsCreateTunnelCommand)cmd); } else { s_logger.warn("Unsupported command "); return Answer.createUnsupportedCommandAnswer(cmd); @@ -1398,39 +1395,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - private OvsCreateTunnelAnswer execute(final OvsCreateTunnelCommand cmd) { - final String bridge = cmd.getNetworkName(); - try { - if (!findOrCreateTunnelNetwork(bridge)) { - s_logger.debug("Error during bridge setup"); - return new OvsCreateTunnelAnswer(cmd, false, - "Cannot create network", bridge); - } - - configureTunnelNetwork(cmd.getNetworkId(), cmd.getFrom(), - cmd.getNetworkName()); - final Script command = new Script(_ovsTunnelPath, _timeout, s_logger); - command.add("create_tunnel"); - command.add("--bridge", bridge); - command.add("--remote_ip", cmd.getRemoteIp()); - command.add("--key", cmd.getKey().toString()); - command.add("--src_host", cmd.getFrom().toString()); - command.add("--dst_host", cmd.getTo().toString()); - - final String result = command.execute(); - if (result != null) { - return new OvsCreateTunnelAnswer(cmd, true, result, null, - bridge); - } else { - return new OvsCreateTunnelAnswer(cmd, false, result, bridge); - } - } catch (final Exception e) { - s_logger.debug("Error during tunnel setup"); - s_logger.warn("Caught execption when creating ovs tunnel", e); - return new OvsCreateTunnelAnswer(cmd, false, e.getMessage(), bridge); - } - } - private CopyVolumeAnswer execute(final CopyVolumeCommand cmd) { /** This method is only used for copying files from Primary Storage TO Secondary Storage @@ -1508,26 +1472,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } - protected Answer execute(final CheckOnHostCommand cmd) { - final ExecutorService executors = Executors.newSingleThreadExecutor(); - final List pools = _monitor.getStoragePools(); - final KVMHAChecker ha = new KVMHAChecker(pools, cmd.getHost().getPrivateNetwork().getIp()); - final Future future = executors.submit(ha); - try { - final Boolean result = future.get(); - if (result) { - return new Answer(cmd, false, "Heart is still beating..."); - } else { - return new Answer(cmd); - } - } catch (final InterruptedException e) { - return new Answer(cmd, false, "can't get status of host:"); - } catch (final ExecutionException e) { - return new Answer(cmd, false, "can't get status of host:"); - } - - } - protected Storage.StorageResourceType getStorageResourceType() { return Storage.StorageResourceType.STORAGE_POOL; } @@ -3795,28 +3739,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return parser.getEmulator(); } - private String getGuestType(final Connect conn, final String vmName) { - final LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); - Domain dm = null; - try { - dm = conn.domainLookupByName(vmName); - final String xmlDesc = dm.getXMLDesc(0); - parser.parseDomainXML(xmlDesc); - return parser.getDescription(); - } catch (final LibvirtException e) { - s_logger.trace("Ignoring libvirt error.", e); - return null; - } finally { - try { - if (dm != null) { - dm.free(); - } - } catch (final LibvirtException l) { - s_logger.trace("Ignoring libvirt error.", l); - } - } - } - boolean isGuestPVEnabled(final String guestOSName) { if (guestOSName == null) { return false; @@ -4304,13 +4226,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv @Override public void setName(final String name) { // TODO Auto-generated method stub - } @Override public void setConfigParams(final Map params) { // TODO Auto-generated method stub - } @Override @@ -4328,7 +4248,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv @Override public void setRunLevel(final int level) { // TODO Auto-generated method stub - } public HypervisorType getHypervisorType(){ diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckOnHostCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckOnHostCommandWrapper.java new file mode 100644 index 00000000000..5e5602351a3 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCheckOnHostCommandWrapper.java @@ -0,0 +1,64 @@ +// +// 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 java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckOnHostCommand; +import com.cloud.agent.api.to.HostTO; +import com.cloud.agent.api.to.NetworkTO; +import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool; +import com.cloud.hypervisor.kvm.resource.KVMHAChecker; +import com.cloud.hypervisor.kvm.resource.KVMHAMonitor; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtCheckOnHostCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CheckOnHostCommand command, final LibvirtComputingResource libvirtComputingResource) { + final ExecutorService executors = Executors.newSingleThreadExecutor(); + final KVMHAMonitor monitor = libvirtComputingResource.getMonitor(); + + final List pools = monitor.getStoragePools(); + HostTO host = command.getHost(); + NetworkTO privateNetwork = host.getPrivateNetwork(); + final KVMHAChecker ha = new KVMHAChecker(pools, privateNetwork.getIp()); + + final Future future = executors.submit(ha); + try { + final Boolean result = future.get(); + if (result) { + return new Answer(command, false, "Heart is still beating..."); + } else { + return new Answer(command); + } + } catch (final InterruptedException e) { + return new Answer(command, false, "can't get status of host:"); + } catch (final ExecutionException e) { + return new Answer(command, false, "can't get status of host:"); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java new file mode 100644 index 00000000000..3a620577d12 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtOvsCreateTunnelCommandWrapper.java @@ -0,0 +1,68 @@ +// +// 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.OvsCreateTunnelAnswer; +import com.cloud.agent.api.OvsCreateTunnelCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.script.Script; + +public final class LibvirtOvsCreateTunnelCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtOvsCreateTunnelCommandWrapper.class); + + @Override + public Answer execute(final OvsCreateTunnelCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String bridge = command.getNetworkName(); + try { + if (!libvirtComputingResource.findOrCreateTunnelNetwork(bridge)) { + s_logger.debug("Error during bridge setup"); + return new OvsCreateTunnelAnswer(command, false, + "Cannot create network", bridge); + } + + libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(), + command.getNetworkName()); + + final Script scriptCommand = new Script(libvirtComputingResource.getOvsTunnelPath(), libvirtComputingResource.getTimeout(), s_logger); + scriptCommand.add("create_tunnel"); + scriptCommand.add("--bridge", bridge); + scriptCommand.add("--remote_ip", command.getRemoteIp()); + scriptCommand.add("--key", command.getKey().toString()); + scriptCommand.add("--src_host", command.getFrom().toString()); + scriptCommand.add("--dst_host", command.getTo().toString()); + + final String result = scriptCommand.execute(); + if (result != null) { + return new OvsCreateTunnelAnswer(command, true, result, null, + bridge); + } else { + return new OvsCreateTunnelAnswer(command, false, result, bridge); + } + } catch (final Exception e) { + s_logger.warn("Caught execption when creating ovs tunnel", e); + return new OvsCreateTunnelAnswer(command, false, e.getMessage(), bridge); + } + } +} \ 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 ca7a7d2638c..af2f544e094 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 @@ -25,6 +25,7 @@ import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkCommand; +import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; @@ -41,6 +42,7 @@ import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; +import com.cloud.agent.api.OvsCreateTunnelCommand; import com.cloud.agent.api.OvsDestroyBridgeCommand; import com.cloud.agent.api.OvsDestroyTunnelCommand; import com.cloud.agent.api.OvsFetchInterfaceCommand; @@ -120,6 +122,8 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CheckSshCommand.class, new LibvirtCheckSshCommandWrapper()); linbvirtCommands.put(CheckNetworkCommand.class, new LibvirtCheckNetworkCommandWrapper()); linbvirtCommands.put(OvsDestroyTunnelCommand.class, new LibvirtOvsDestroyTunnelCommandWrapper()); + linbvirtCommands.put(CheckOnHostCommand.class, new LibvirtCheckOnHostCommandWrapper()); + linbvirtCommands.put(OvsCreateTunnelCommand.class, new LibvirtOvsCreateTunnelCommandWrapper()); 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 1551f98e4d5..f01ad7a76dc 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 @@ -68,6 +68,7 @@ import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkCommand; +import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.CreateStoragePoolCommand; @@ -83,6 +84,7 @@ import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; +import com.cloud.agent.api.OvsCreateTunnelCommand; import com.cloud.agent.api.OvsDestroyBridgeCommand; import com.cloud.agent.api.OvsDestroyTunnelCommand; import com.cloud.agent.api.OvsFetchInterfaceCommand; @@ -2542,4 +2544,114 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(command.getBridgeName()); } + + @Test + public void testCheckOnHostCommand() { + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);; + + final CheckOnHostCommand command = new CheckOnHostCommand(host); + + final KVMHAMonitor monitor = Mockito.mock(KVMHAMonitor.class); + + when(libvirtComputingResource.getMonitor()).thenReturn(monitor); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getMonitor(); + } + + @Test + public void testOvsCreateTunnelCommand() { + final String remoteIp = "172.16.16.16"; + final Integer key = 1; + final Long from = 1l; + final Long to = 2l; + final long networkId = 1l; + final String fromIp = "172.15.15.15"; + final String networkName = "eth"; + final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861"; + + final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid); + + final String bridge = command.getNetworkName(); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(true); + when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(), + command.getNetworkName())).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge); + verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(), + command.getNetworkName()); + } + + @Test + public void testOvsCreateTunnelCommandFailure1() { + final String remoteIp = "172.16.16.16"; + final Integer key = 1; + final Long from = 1l; + final Long to = 2l; + final long networkId = 1l; + final String fromIp = "172.15.15.15"; + final String networkName = "eth"; + final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861"; + + final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid); + + final String bridge = command.getNetworkName(); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(false); + when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(), + command.getNetworkName())).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge); + verify(libvirtComputingResource, times(0)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(), + command.getNetworkName()); + } + + @SuppressWarnings("unchecked") + @Test + public void testOvsCreateTunnelCommandFailure2() { + final String remoteIp = "172.16.16.16"; + final Integer key = 1; + final Long from = 1l; + final Long to = 2l; + final long networkId = 1l; + final String fromIp = "172.15.15.15"; + final String networkName = "eth"; + final String networkUuid = "8edb1156-a851-4914-afc6-468ee52ac861"; + + final OvsCreateTunnelCommand command = new OvsCreateTunnelCommand(remoteIp, key, from, to, networkId, fromIp, networkName, networkUuid); + + final String bridge = command.getNetworkName(); + + when(libvirtComputingResource.findOrCreateTunnelNetwork(bridge)).thenReturn(true); + when(libvirtComputingResource.configureTunnelNetwork(command.getNetworkId(), command.getFrom(), + command.getNetworkName())).thenThrow(Exception.class); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).findOrCreateTunnelNetwork(bridge); + verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(), + command.getNetworkName()); + } } \ No newline at end of file From ff7ae9ca0c9714dca684f3972eacae56254b76fd Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Sat, 2 May 2015 09:37:59 +0200 Subject: [PATCH 24/36] Refactoring the LibvirtComputingResource - Adding LibvirtCreateVolumeFromSnapshotCommandWrapper, LibvirtFenceCommandWrapper and LibvirtSecurityGroupRulesCommandWrapper - 6 unit tests added - KVM hypervisor plugin with 17.2% coverage --- .../com/cloud/agent/api/SnapshotCommand.java | 8 +- .../resource/LibvirtComputingResource.java | 86 +---- ...reateVolumeFromSnapshotCommandWrapper.java | 68 ++++ .../wrapper/LibvirtFenceCommandWrapper.java | 67 ++++ .../wrapper/LibvirtRequestWrapper.java | 6 + ...bvirtSecurityGroupRulesCommandWrapper.java | 67 ++++ .../LibvirtComputingResourceTest.java | 296 +++++++++++++++++- 7 files changed, 498 insertions(+), 100 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVolumeFromSnapshotCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtFenceCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSecurityGroupRulesCommandWrapper.java diff --git a/core/src/com/cloud/agent/api/SnapshotCommand.java b/core/src/com/cloud/agent/api/SnapshotCommand.java index a4975e68fe7..cf4eeb5da58 100644 --- a/core/src/com/cloud/agent/api/SnapshotCommand.java +++ b/core/src/com/cloud/agent/api/SnapshotCommand.java @@ -53,9 +53,9 @@ public class SnapshotCommand extends Command { * is the value of that field If you have better ideas on how to * get it, you are welcome. */ - public SnapshotCommand(StoragePool pool, String secondaryStorageUrl, String snapshotUuid, String snapshotName, Long dcId, Long accountId, Long volumeId) { - // this.primaryStoragePoolNameLabel = pool.getUuid(); - //this.primaryPool = new StorageFilerTO(pool); + public SnapshotCommand(final StoragePool pool, final String secondaryStorageUrl, final String snapshotUuid, final String snapshotName, final Long dcId, final Long accountId, final Long volumeId) { + primaryStoragePoolNameLabel = pool.getUuid(); + primaryPool = new StorageFilerTO(pool); this.snapshotUuid = snapshotUuid; this.secondaryStorageUrl = secondaryStorageUrl; this.dcId = dcId; @@ -112,7 +112,7 @@ public class SnapshotCommand extends Command { return volumePath; } - public void setVolumePath(String path) { + public void setVolumePath(final String path) { volumePath = path; } 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 6d13ce61c72..6f24b31b716 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 @@ -44,10 +44,6 @@ import java.util.Properties; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -88,10 +84,6 @@ import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; -import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; -import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.FenceAnswer; -import com.cloud.agent.api.FenceCommand; import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; @@ -103,8 +95,6 @@ import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PlugNicAnswer; import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PvlanSetupCommand; -import com.cloud.agent.api.SecurityGroupRuleAnswer; -import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -138,7 +128,6 @@ import com.cloud.dc.Vlan; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ClockDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.ConsoleDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.CpuModeDef; @@ -1284,14 +1273,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((ManageSnapshotCommand)cmd); } else if (cmd instanceof BackupSnapshotCommand) { return execute((BackupSnapshotCommand)cmd); - } else if (cmd instanceof CreateVolumeFromSnapshotCommand) { - return execute((CreateVolumeFromSnapshotCommand)cmd); } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { return execute((CreatePrivateTemplateFromSnapshotCommand)cmd); - } else if (cmd instanceof SecurityGroupRulesCmd) { - return execute((SecurityGroupRulesCmd)cmd); - } else if (cmd instanceof FenceCommand) { - return execute((FenceCommand)cmd); } else if (cmd instanceof StartCommand) { return execute((StartCommand)cmd); } else if (cmd instanceof PlugNicCommand) { @@ -1450,28 +1433,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected FenceAnswer execute(final FenceCommand cmd) { - final ExecutorService executors = Executors.newSingleThreadExecutor(); - final List pools = _monitor.getStoragePools(); - final KVMHAChecker ha = new KVMHAChecker(pools, cmd.getHostIp()); - final Future future = executors.submit(ha); - try { - final Boolean result = future.get(); - if (result) { - return new FenceAnswer(cmd, false, "Heart is still beating..."); - } else { - return new FenceAnswer(cmd); - } - } catch (final InterruptedException e) { - s_logger.warn("Unable to fence", e); - return new FenceAnswer(cmd, false, e.getMessage()); - } catch (final ExecutionException e) { - s_logger.warn("Unable to fence", e); - return new FenceAnswer(cmd, false, e.getMessage()); - } - - } - protected Storage.StorageResourceType getStorageResourceType() { return Storage.StorageResourceType.STORAGE_POOL; } @@ -2265,25 +2226,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new BackupSnapshotAnswer(cmd, true, null, snapshotRelPath + File.separator + snapshotName, true); } - protected CreateVolumeFromSnapshotAnswer execute(final CreateVolumeFromSnapshotCommand cmd) { - try { - - String snapshotPath = cmd.getSnapshotUuid(); - final int index = snapshotPath.lastIndexOf("/"); - snapshotPath = snapshotPath.substring(0, index); - final KVMStoragePool secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl() + snapshotPath); - final KVMPhysicalDisk snapshot = secondaryPool.getPhysicalDisk(cmd.getSnapshotName()); - - final String primaryUuid = cmd.getPrimaryStoragePoolNameLabel(); - final KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), primaryUuid); - final String volUuid = UUID.randomUUID().toString(); - final KVMPhysicalDisk disk = _storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool, 0); - return new CreateVolumeFromSnapshotAnswer(cmd, true, "", disk.getName()); - } catch (final CloudRuntimeException e) { - return new CreateVolumeFromSnapshotAnswer(cmd, false, e.toString(), null); - } - } - protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) { final String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId(); final String templateInstallFolder = "template/tmpl/" + templateFolder; @@ -2450,32 +2392,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(final SecurityGroupRulesCmd cmd) { - String vif = null; - String brname = null; - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - final List nics = getInterfaces(conn, cmd.getVmName()); - vif = nics.get(0).getDevName(); - brname = nics.get(0).getBrName(); - } catch (final LibvirtException e) { - return new SecurityGroupRuleAnswer(cmd, false, e.toString()); - } - - final boolean result = - add_network_rules(cmd.getVmName(), Long.toString(cmd.getVmId()), cmd.getGuestIp(), cmd.getSignature(), Long.toString(cmd.getSeqNum()), cmd.getGuestMac(), - cmd.stringifyRules(), vif, brname, cmd.getSecIpsString()); - - if (!result) { - s_logger.warn("Failed to program network rules for vm " + cmd.getVmName()); - return new SecurityGroupRuleAnswer(cmd, false, "programming network rules failed"); - } else { - s_logger.debug("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ",ingress numrules=" + cmd.getIngressRuleSet().length + - ",egress numrules=" + cmd.getEgressRuleSet().length); - return new SecurityGroupRuleAnswer(cmd); - } - } - protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; @@ -4101,7 +4017,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - private boolean add_network_rules(final String vmName, final String vmId, final String guestIP, final String sig, final String seq, final String mac, final String rules, final String vif, final String brname, + public boolean addNetworkRules(final String vmName, final String vmId, final String guestIP, final String sig, final String seq, final String mac, final String rules, final String vif, final String brname, final String secIps) { if (!_canBridgeFirewall) { return false; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVolumeFromSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVolumeFromSnapshotCommandWrapper.java new file mode 100644 index 00000000000..b30c3f8777d --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreateVolumeFromSnapshotCommandWrapper.java @@ -0,0 +1,68 @@ +// +// 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 java.util.UUID; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; +import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; +import com.cloud.agent.api.to.StorageFilerTO; +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.utils.exception.CloudRuntimeException; + +public final class LibvirtCreateVolumeFromSnapshotCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CreateVolumeFromSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) { + try { + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + final KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + final KVMPhysicalDisk snapshot = secondaryPool.getPhysicalDisk(command.getSnapshotName()); + + final String primaryUuid = command.getPrimaryStoragePoolNameLabel(); + + final StorageFilerTO pool = command.getPool(); + final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getType(), primaryUuid); + + final String volUuid = UUID.randomUUID().toString(); + final KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool, 0); + + if (disk == null) { + throw new NullPointerException("Disk was not successfully copied to the new storage."); + } + + return new CreateVolumeFromSnapshotAnswer(command, true, "", disk.getName()); + } catch (final CloudRuntimeException e) { + return new CreateVolumeFromSnapshotAnswer(command, false, e.toString(), null); + } catch (final Exception e) { + return new CreateVolumeFromSnapshotAnswer(command, false, e.toString(), null); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtFenceCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtFenceCommandWrapper.java new file mode 100644 index 00000000000..53e3845db71 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtFenceCommandWrapper.java @@ -0,0 +1,67 @@ +// +// 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 java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.FenceAnswer; +import com.cloud.agent.api.FenceCommand; +import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool; +import com.cloud.hypervisor.kvm.resource.KVMHAChecker; +import com.cloud.hypervisor.kvm.resource.KVMHAMonitor; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtFenceCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtFenceCommandWrapper.class); + + @Override + public Answer execute(final FenceCommand command, final LibvirtComputingResource libvirtComputingResource) { + final ExecutorService executors = Executors.newSingleThreadExecutor(); + final KVMHAMonitor monitor = libvirtComputingResource.getMonitor(); + + final List pools = monitor.getStoragePools(); + final KVMHAChecker ha = new KVMHAChecker(pools, command.getHostIp()); + + final Future future = executors.submit(ha); + try { + final Boolean result = future.get(); + if (result) { + return new FenceAnswer(command, false, "Heart is still beating..."); + } else { + return new FenceAnswer(command); + } + } catch (final InterruptedException e) { + s_logger.warn("Unable to fence", e); + return new FenceAnswer(command, false, e.getMessage()); + } catch (final ExecutionException e) { + s_logger.warn("Unable to fence", e); + return new FenceAnswer(command, false, e.getMessage()); + } + } +} \ 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 af2f544e094..23248c4a6d2 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 @@ -30,7 +30,9 @@ import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; +import com.cloud.agent.api.FenceCommand; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; @@ -54,6 +56,7 @@ import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.check.CheckSshCommand; @@ -124,6 +127,9 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(OvsDestroyTunnelCommand.class, new LibvirtOvsDestroyTunnelCommandWrapper()); linbvirtCommands.put(CheckOnHostCommand.class, new LibvirtCheckOnHostCommandWrapper()); linbvirtCommands.put(OvsCreateTunnelCommand.class, new LibvirtOvsCreateTunnelCommandWrapper()); + linbvirtCommands.put(CreateVolumeFromSnapshotCommand.class, new LibvirtCreateVolumeFromSnapshotCommandWrapper()); + linbvirtCommands.put(FenceCommand.class, new LibvirtFenceCommandWrapper()); + linbvirtCommands.put(SecurityGroupRulesCmd.class, new LibvirtSecurityGroupRulesCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSecurityGroupRulesCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSecurityGroupRulesCommandWrapper.java new file mode 100644 index 00000000000..5bdafe7b2d8 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSecurityGroupRulesCommandWrapper.java @@ -0,0 +1,67 @@ +// +// 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 java.util.List; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtSecurityGroupRulesCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtSecurityGroupRulesCommandWrapper.class); + + @Override + public Answer execute(final SecurityGroupRulesCmd command, final LibvirtComputingResource libvirtComputingResource) { + String vif = null; + String brname = null; + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(command.getVmName()); + final List nics = libvirtComputingResource.getInterfaces(conn, command.getVmName()); + + vif = nics.get(0).getDevName(); + brname = nics.get(0).getBrName(); + } catch (final LibvirtException e) { + return new SecurityGroupRuleAnswer(command, false, e.toString()); + } + + final boolean result = libvirtComputingResource.addNetworkRules(command.getVmName(), Long.toString(command.getVmId()), command.getGuestIp(), command.getSignature(), + Long.toString(command.getSeqNum()), command.getGuestMac(), command.stringifyRules(), vif, brname, command.getSecIpsString()); + + if (!result) { + s_logger.warn("Failed to program network rules for vm " + command.getVmName()); + return new SecurityGroupRuleAnswer(command, false, "programming network rules failed"); + } else { + s_logger.debug("Programmed network rules for vm " + command.getVmName() + " guestIp=" + command.getGuestIp() + ",ingress numrules=" + + command.getIngressRuleSet().length + ",egress numrules=" + command.getEgressRuleSet().length); + return new SecurityGroupRuleAnswer(command); + } + } +} \ No newline at end of file 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 f01ad7a76dc..15ba52b251d 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 @@ -72,7 +72,9 @@ import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; +import com.cloud.agent.api.FenceCommand; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVmDiskStatsCommand; @@ -100,6 +102,8 @@ import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; @@ -117,6 +121,7 @@ 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.KVMHABase.NfsStoragePool; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; @@ -1863,17 +1868,17 @@ public class LibvirtComputingResourceTest { @Test public void testUpgradeSnapshotCommand() { - final StoragePool pool = null; - final String secondaryStoragePoolURL = null; - final Long dcId = null; - final Long accountId = null; - final Long volumeId = null; - final Long templateId = null; - final Long tmpltAccountId = null; - final String volumePath = null; - final String snapshotUuid = null; - final String snapshotName = null; - final String version = null; + final StoragePool pool = Mockito.mock(StoragePool.class);; + final String secondaryStoragePoolURL = "url"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final Long templateId = 1l; + final Long tmpltAccountId = 1l; + final String volumePath = "/opt/path"; + final String snapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/"; + final String snapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/"; + final String version = "1"; final UpgradeSnapshotCommand command = new UpgradeSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, templateId, tmpltAccountId, volumePath, snapshotUuid, snapshotName, version); @@ -2654,4 +2659,273 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).configureTunnelNetwork(command.getNetworkId(), command.getFrom(), command.getNetworkName()); } + + @Test + public void testCreateVolumeFromSnapshotCommand() { + // This tests asserts to False because there will be a NPE due to UUID static method calls. + + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "/opt/storage/"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/"; + final String backedUpSnapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac862/"; + final int wait = 0; + + final CreateVolumeFromSnapshotCommand command = new CreateVolumeFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + final String primaryUuid = command.getPrimaryStoragePoolNameLabel(); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(secondaryPool); + when(secondaryPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(storagePoolMgr.getStoragePool(command.getPool().getType(), primaryUuid)).thenReturn(primaryPool); + + //when(storagePoolMgr.copyPhysicalDisk(snapshot, volUuid, primaryPool, 0)).thenReturn(disk); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(secondaryPool, times(1)).getPhysicalDisk(command.getSnapshotName()); + verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), primaryUuid); + //verify(storagePoolMgr, times(1)).copyPhysicalDisk(snapshot, volUuid, primaryPool, 0); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreateVolumeFromSnapshotCommandCloudException() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "/opt/storage/"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "uuid:/8edb1156-a851-4914-afc6-468ee52ac861/"; + final String backedUpSnapshotName = "uuid:/8edb1156-a851-4914-afc6-468ee52ac862/"; + final int wait = 0; + + final CreateVolumeFromSnapshotCommand command = new CreateVolumeFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + final String primaryUuid = command.getPrimaryStoragePoolNameLabel(); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(secondaryPool); + when(secondaryPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(storagePoolMgr.getStoragePool(command.getPool().getType(), primaryUuid)).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(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(secondaryPool, times(1)).getPhysicalDisk(command.getSnapshotName()); + verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), primaryUuid); + } + + @Test + public void testFenceCommand() { + final VirtualMachine vm = Mockito.mock(VirtualMachine.class);; + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + + final FenceCommand command = new FenceCommand(vm, host); + + final KVMHAMonitor monitor = Mockito.mock(KVMHAMonitor.class); + + final NfsStoragePool storagePool = Mockito.mock(NfsStoragePool.class); + final List pools = new ArrayList(); + pools.add(storagePool); + + when(libvirtComputingResource.getMonitor()).thenReturn(monitor); + when(monitor.getStoragePools()).thenReturn(pools); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getMonitor(); + verify(monitor, times(1)).getStoragePools(); + } + + @Test + public void testSecurityGroupRulesCmdFalse() { + final String guestIp = "172.16.16.16"; + final String guestMac = "00:00:00:00"; + final String vmName = "Test"; + final Long vmId = 1l; + final String signature = "signature"; + final Long seqNum = 1l; + final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)}; + final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)}; + + final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + + final List nics = new ArrayList(); + final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); + nics.add(interfaceDef); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(ingressRuleSet[0].getProto()).thenReturn("tcp"); + when(ingressRuleSet[0].getStartPort()).thenReturn(22); + when(ingressRuleSet[0].getEndPort()).thenReturn(22); + when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(new String[]{"0.0.0.0/0"}); + + when(egressRuleSet[0].getProto()).thenReturn("tcp"); + when(egressRuleSet[0].getStartPort()).thenReturn(22); + when(egressRuleSet[0].getEndPort()).thenReturn(22); + when(egressRuleSet[0].getAllowedCidrs()).thenReturn(new String[]{"0.0.0.0/0"}); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testSecurityGroupRulesCmdTrue() { + final String guestIp = "172.16.16.16"; + final String guestMac = "00:00:00:00"; + final String vmName = "Test"; + final Long vmId = 1l; + final String signature = "signature"; + final Long seqNum = 1l; + final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)}; + final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)}; + + final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + + final List nics = new ArrayList(); + final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); + nics.add(interfaceDef); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(interfaceDef.getDevName()).thenReturn("eth0"); + when(interfaceDef.getBrName()).thenReturn("br0"); + + final String vif = nics.get(0).getDevName(); + final String brname = nics.get(0).getBrName(); + + when(ingressRuleSet[0].getProto()).thenReturn("tcp"); + when(ingressRuleSet[0].getStartPort()).thenReturn(22); + when(ingressRuleSet[0].getEndPort()).thenReturn(22); + when(ingressRuleSet[0].getAllowedCidrs()).thenReturn(new String[]{"0.0.0.0/0"}); + + when(egressRuleSet[0].getProto()).thenReturn("tcp"); + when(egressRuleSet[0].getStartPort()).thenReturn(22); + when(egressRuleSet[0].getEndPort()).thenReturn(22); + when(egressRuleSet[0].getAllowedCidrs()).thenReturn(new String[]{"0.0.0.0/0"}); + + when(libvirtComputingResource.addNetworkRules(command.getVmName(), Long.toString(command.getVmId()), command.getGuestIp(), command.getSignature(), + Long.toString(command.getSeqNum()), command.getGuestMac(), command.stringifyRules(), vif, brname, command.getSecIpsString())).thenReturn(true); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testSecurityGroupRulesCmdException() { + final String guestIp = "172.16.16.16"; + final String guestMac = "00:00:00:00"; + final String vmName = "Test"; + final Long vmId = 1l; + final String signature = "signature"; + final Long seqNum = 1l; + final IpPortAndProto[] ingressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)}; + final IpPortAndProto[] egressRuleSet = new IpPortAndProto[]{Mockito.mock(IpPortAndProto.class)}; + + final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + + final List nics = new ArrayList(); + final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); + nics.add(interfaceDef); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From 52d9f0c20624e74dd2852038cd3912e1756d11e3 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Tue, 5 May 2015 10:39:50 +0200 Subject: [PATCH 25/36] Refactoring the LibvirtComputingResource - Adding LibvirtNetworkUsageCommandWrapper, LibvirtPlugNicCommandWrapper and LibvirtUnPlugNicCommandWrapper - 9 unit tests added - KVM hypervisor plugin with 18.3% coverage --- .../resource/LibvirtComputingResource.java | 120 +---- .../LibvirtNetworkUsageCommandWrapper.java | 57 +++ .../wrapper/LibvirtPlugNicCommandWrapper.java | 85 ++++ .../wrapper/LibvirtRequestWrapper.java | 6 + .../LibvirtUnPlugNicCommandWrapper.java | 80 +++ .../LibvirtComputingResourceTest.java | 481 ++++++++++++++++++ 6 files changed, 713 insertions(+), 116 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkUsageCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java 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 6f24b31b716..3c40c908071 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 @@ -87,13 +87,9 @@ import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.NetworkUsageAnswer; -import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; -import com.cloud.agent.api.PlugNicAnswer; -import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; @@ -101,8 +97,6 @@ import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupStorageCommand; -import com.cloud.agent.api.UnPlugNicAnswer; -import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.VmDiskStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.routing.IpAssocCommand; @@ -1277,14 +1271,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((CreatePrivateTemplateFromSnapshotCommand)cmd); } else if (cmd instanceof StartCommand) { return execute((StartCommand)cmd); - } else if (cmd instanceof PlugNicCommand) { - return execute((PlugNicCommand)cmd); - } else if (cmd instanceof UnPlugNicCommand) { - return execute((UnPlugNicCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest((NetworkElementCommand)cmd); - } else if (cmd instanceof NetworkUsageCommand) { - return execute((NetworkUsageCommand)cmd); } else if (cmd instanceof CopyVolumeCommand) { return execute((CopyVolumeCommand)cmd); } else if (cmd instanceof ResizeVolumeCommand) { @@ -1702,79 +1690,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private PlugNicAnswer execute(final PlugNicCommand cmd) { - final NicTO nic = cmd.getNic(); - final String vmName = cmd.getVmName(); - Domain vm = null; - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - vm = getDomain(conn, vmName); - final List pluggedNics = getInterfaces(conn, vmName); - Integer nicnum = 0; - for (final InterfaceDef pluggedNic : pluggedNics) { - if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) { - s_logger.debug("found existing nic for mac " + pluggedNic.getMacAddress() + " at index " + nicnum); - return new PlugNicAnswer(cmd, true, "success"); - } - nicnum++; - } - vm.attachDevice(getVifDriver(nic.getType()).plug(nic, "Other PV", "").toString()); - return new PlugNicAnswer(cmd, true, "success"); - } catch (final LibvirtException e) { - final String msg = " Plug Nic failed due to " + e.toString(); - s_logger.warn(msg, e); - return new PlugNicAnswer(cmd, false, msg); - } catch (final InternalErrorException e) { - final String msg = " Plug Nic failed due to " + e.toString(); - s_logger.warn(msg, e); - return new PlugNicAnswer(cmd, false, msg); - } finally { - if (vm != null) { - try { - vm.free(); - } catch (final LibvirtException l) { - s_logger.trace("Ignoring libvirt error.", l); - } - } - } - } - - private UnPlugNicAnswer execute(final UnPlugNicCommand cmd) { - Connect conn; - final NicTO nic = cmd.getNic(); - final String vmName = cmd.getVmName(); - Domain vm = null; - try { - conn = LibvirtConnection.getConnectionByVmName(vmName); - vm = getDomain(conn, vmName); - final List pluggedNics = getInterfaces(conn, vmName); - for (final InterfaceDef pluggedNic : pluggedNics) { - if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) { - vm.detachDevice(pluggedNic.toString()); - // We don't know which "traffic type" is associated with - // each interface at this point, so inform all vif drivers - for (final VifDriver vifDriver : getAllVifDrivers()) { - vifDriver.unplug(pluggedNic); - } - return new UnPlugNicAnswer(cmd, true, "success"); - } - } - return new UnPlugNicAnswer(cmd, true, "success"); - } catch (final LibvirtException e) { - final String msg = " Unplug Nic failed due to " + e.toString(); - s_logger.warn(msg, e); - return new UnPlugNicAnswer(cmd, false, msg); - } finally { - if (vm != null) { - try { - vm.free(); - } catch (final LibvirtException l) { - s_logger.trace("Ignoring libvirt error.", l); - } - } - } - } - private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) { Connect conn; final NicTO nic = cmd.getNic(); @@ -2445,7 +2360,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return usageParser.getLine(); } - protected long[] getNetworkStats(final String privateIP) { + public long[] getNetworkStats(final String privateIP) { final String result = networkUsage(privateIP, "get", null); final long[] stats = new long[2]; if (result != null) { @@ -2459,7 +2374,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return stats; } - protected String VPCNetworkUsage(final String privateIpAddress, final String publicIp, final String option, final String vpcCIDR) { + public String configureVPCNetworkUsage(final String privateIpAddress, final String publicIp, final String option, final String vpcCIDR) { final Script getUsage = new Script(_routerProxyPath, s_logger); getUsage.add("vpc_netusage.sh"); getUsage.add(privateIpAddress); @@ -2487,8 +2402,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return usageParser.getLine(); } - protected long[] getVPCNetworkStats(final String privateIP, final String publicIp, final String option) { - final String result = VPCNetworkUsage(privateIP, publicIp, option, null); + public long[] getVPCNetworkStats(final String privateIP, final String publicIp, final String option) { + final String result = configureVPCNetworkUsage(privateIP, publicIp, option, null); final long[] stats = new long[2]; if (result != null) { final String[] splitResult = result.split(":"); @@ -2501,33 +2416,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return stats; } - private Answer execute(final NetworkUsageCommand cmd) { - if (cmd.isForVpc()) { - if (cmd.getOption() != null && cmd.getOption().equals("create")) { - final String result = VPCNetworkUsage(cmd.getPrivateIP(), cmd.getGatewayIP(), "create", cmd.getVpcCIDR()); - final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); - return answer; - } else if (cmd.getOption() != null && (cmd.getOption().equals("get") || cmd.getOption().equals("vpn"))) { - final long[] stats = getVPCNetworkStats(cmd.getPrivateIP(), cmd.getGatewayIP(), cmd.getOption()); - final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); - return answer; - } else { - final String result = VPCNetworkUsage(cmd.getPrivateIP(), cmd.getGatewayIP(), cmd.getOption(), cmd.getVpcCIDR()); - final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); - return answer; - } - } else { - if (cmd.getOption() != null && cmd.getOption().equals("create")) { - final String result = networkUsage(cmd.getPrivateIP(), "create", null); - final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); - return answer; - } - final long[] stats = getNetworkStats(cmd.getPrivateIP()); - final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); - return answer; - } - } - protected void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVMDef vm) { if (vm != null && vm.getDevices() != null) { cleanupVMNetworks(conn, vm.getDevices().getInterfaces()); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkUsageCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkUsageCommandWrapper.java new file mode 100644 index 00000000000..3ac21825bee --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkUsageCommandWrapper.java @@ -0,0 +1,57 @@ +// +// 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.NetworkUsageAnswer; +import com.cloud.agent.api.NetworkUsageCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtNetworkUsageCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final NetworkUsageCommand command, final LibvirtComputingResource libvirtComputingResource) { + if (command.isForVpc()) { + if (command.getOption() != null && command.getOption().equals("create")) { + final String result = libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, result, 0L, 0L); + return answer; + } else if (command.getOption() != null && (command.getOption().equals("get") || command.getOption().equals("vpn"))) { + final long[] stats = libvirtComputingResource.getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, "", stats[0], stats[1]); + return answer; + } else { + final String result = libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, result, 0L, 0L); + return answer; + } + } else { + if (command.getOption() != null && command.getOption().equals("create")) { + final String result = libvirtComputingResource.networkUsage(command.getPrivateIP(), "create", null); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, result, 0L, 0L); + return answer; + } + final long [] stats = libvirtComputingResource.getNetworkStats(command.getPrivateIP()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, "", stats[0], stats[1]); + return answer; + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java new file mode 100644 index 00000000000..7e6f642964a --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java @@ -0,0 +1,85 @@ +// +// 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 java.util.List; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.PlugNicAnswer; +import com.cloud.agent.api.PlugNicCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.exception.InternalErrorException; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; +import com.cloud.hypervisor.kvm.resource.VifDriver; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtPlugNicCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtPlugNicCommandWrapper.class); + + @Override + public Answer execute(final PlugNicCommand command, final LibvirtComputingResource libvirtComputingResource) { + final NicTO nic = command.getNic(); + final String vmName = command.getVmName(); + Domain vm = null; + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(vmName); + vm = libvirtComputingResource.getDomain(conn, vmName); + + final List pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName); + Integer nicnum = 0; + for (final InterfaceDef pluggedNic : pluggedNics) { + if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) { + s_logger.debug("found existing nic for mac " + pluggedNic.getMacAddress() + " at index " + nicnum); + return new PlugNicAnswer(command, true, "success"); + } + nicnum++; + } + VifDriver vifDriver = libvirtComputingResource.getVifDriver(nic.getType()); + InterfaceDef interfaceDef = vifDriver.plug(nic, "Other PV", ""); + vm.attachDevice(interfaceDef.toString()); + + return new PlugNicAnswer(command, true, "success"); + } catch (final LibvirtException e) { + final String msg = " Plug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new PlugNicAnswer(command, false, msg); + } catch (final InternalErrorException e) { + final String msg = " Plug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new PlugNicAnswer(command, false, msg); + } finally { + if (vm != null) { + try { + vm.free(); + } catch (final LibvirtException l) { + s_logger.trace("Ignoring libvirt error.", l); + } + } + } + } +} \ 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 23248c4a6d2..148075b8575 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 @@ -44,6 +44,7 @@ import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; +import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.OvsCreateTunnelCommand; import com.cloud.agent.api.OvsDestroyBridgeCommand; import com.cloud.agent.api.OvsDestroyTunnelCommand; @@ -52,12 +53,14 @@ import com.cloud.agent.api.OvsSetupBridgeCommand; import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; @@ -130,6 +133,9 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CreateVolumeFromSnapshotCommand.class, new LibvirtCreateVolumeFromSnapshotCommandWrapper()); linbvirtCommands.put(FenceCommand.class, new LibvirtFenceCommandWrapper()); linbvirtCommands.put(SecurityGroupRulesCmd.class, new LibvirtSecurityGroupRulesCommandWrapper()); + linbvirtCommands.put(PlugNicCommand.class, new LibvirtPlugNicCommandWrapper()); + linbvirtCommands.put(UnPlugNicCommand.class, new LibvirtUnPlugNicCommandWrapper()); + linbvirtCommands.put(NetworkUsageCommand.class, new LibvirtNetworkUsageCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java new file mode 100644 index 00000000000..4ce14f2c824 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java @@ -0,0 +1,80 @@ +// +// 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 java.util.List; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.UnPlugNicAnswer; +import com.cloud.agent.api.UnPlugNicCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; +import com.cloud.hypervisor.kvm.resource.VifDriver; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtUnPlugNicCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtUnPlugNicCommandWrapper.class); + + @Override + public Answer execute(final UnPlugNicCommand command, final LibvirtComputingResource libvirtComputingResource) { + final NicTO nic = command.getNic(); + final String vmName = command.getVmName(); + Domain vm = null; + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(vmName); + vm = libvirtComputingResource.getDomain(conn, vmName); + final List pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName); + + for (final InterfaceDef pluggedNic : pluggedNics) { + if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) { + vm.detachDevice(pluggedNic.toString()); + // We don't know which "traffic type" is associated with + // each interface at this point, so inform all vif drivers + for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) { + vifDriver.unplug(pluggedNic); + } + return new UnPlugNicAnswer(command, true, "success"); + } + } + return new UnPlugNicAnswer(command, true, "success"); + } catch (final LibvirtException e) { + final String msg = " Unplug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new UnPlugNicAnswer(command, false, msg); + } finally { + if (vm != null) { + try { + vm.free(); + } catch (final LibvirtException l) { + s_logger.trace("Ignoring libvirt error.", l); + } + } + } + } +} \ No newline at end of file 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 15ba52b251d..9b0be08cb06 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 @@ -86,6 +86,7 @@ import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; +import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.OvsCreateTunnelCommand; import com.cloud.agent.api.OvsDestroyBridgeCommand; import com.cloud.agent.api.OvsDestroyTunnelCommand; @@ -98,6 +99,7 @@ import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand.Vm; import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Acl; import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; @@ -105,6 +107,7 @@ import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshCommand; @@ -2928,4 +2931,482 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testPlugNicCommandMatchMack() { + final NicTO nic = Mockito.mock(NicTO.class); + final String instanceName = "Test"; + final Type vmtype = Type.DomainRouter; + + final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + final Domain vm = Mockito.mock(Domain.class); + + final List nics = new ArrayList(); + final InterfaceDef intDef = Mockito.mock(InterfaceDef.class); + nics.add(intDef); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); + + when(intDef.getDevName()).thenReturn("eth0"); + when(intDef.getBrName()).thenReturn("br0"); + when(intDef.getMacAddress()).thenReturn("00:00:00:00"); + + when(nic.getMac()).thenReturn("00:00:00:00"); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPlugNicCommandNoMatchMack() { + final NicTO nic = Mockito.mock(NicTO.class); + final String instanceName = "Test"; + final Type vmtype = Type.DomainRouter; + + final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + final Domain vm = Mockito.mock(Domain.class); + final VifDriver vifDriver = Mockito.mock(VifDriver.class); + final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); + + final List nics = new ArrayList(); + final InterfaceDef intDef = Mockito.mock(InterfaceDef.class); + nics.add(intDef); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); + + when(intDef.getDevName()).thenReturn("eth0"); + when(intDef.getBrName()).thenReturn("br0"); + when(intDef.getMacAddress()).thenReturn("00:00:00:00"); + + when(nic.getMac()).thenReturn("00:00:00:01"); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); + + when(libvirtComputingResource.getVifDriver(nic.getType())).thenReturn(vifDriver); + + when(vifDriver.plug(nic, "Other PV", "")).thenReturn(interfaceDef); + when(interfaceDef.toString()).thenReturn("Interface"); + + final String interfaceDefStr = interfaceDef.toString(); + doNothing().when(vm).attachDevice(interfaceDefStr); + + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); + verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType()); + verify(vifDriver, times(1)).plug(nic, "Other PV", ""); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testPlugNicCommandLibvirtException() { + final NicTO nic = Mockito.mock(NicTO.class); + final String instanceName = "Test"; + final Type vmtype = Type.DomainRouter; + + final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testPlugNicCommandInternalError() { + final NicTO nic = Mockito.mock(NicTO.class); + final String instanceName = "Test"; + final Type vmtype = Type.DomainRouter; + + final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + final Domain vm = Mockito.mock(Domain.class); + final VifDriver vifDriver = Mockito.mock(VifDriver.class); + + final List nics = new ArrayList(); + final InterfaceDef intDef = Mockito.mock(InterfaceDef.class); + nics.add(intDef); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); + + when(intDef.getDevName()).thenReturn("eth0"); + when(intDef.getBrName()).thenReturn("br0"); + when(intDef.getMacAddress()).thenReturn("00:00:00:00"); + + when(nic.getMac()).thenReturn("00:00:00:01"); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); + + when(libvirtComputingResource.getVifDriver(nic.getType())).thenReturn(vifDriver); + + when(vifDriver.plug(nic, "Other PV", "")).thenThrow(InternalErrorException.class); + + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); + verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType()); + verify(vifDriver, times(1)).plug(nic, "Other PV", ""); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + } + + @Test + public void testUnPlugNicCommandMatchMack() { + final NicTO nic = Mockito.mock(NicTO.class); + final String instanceName = "Test"; + + final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + final Domain vm = Mockito.mock(Domain.class); + final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); + + final List nics = new ArrayList(); + final InterfaceDef intDef = Mockito.mock(InterfaceDef.class); + nics.add(intDef); + + final VifDriver vifDriver = Mockito.mock(VifDriver.class); + final List drivers = new ArrayList(); + drivers.add(vifDriver); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); + + when(intDef.getDevName()).thenReturn("eth0"); + when(intDef.getBrName()).thenReturn("br0"); + when(intDef.getMacAddress()).thenReturn("00:00:00:00"); + + when(nic.getMac()).thenReturn("00:00:00:00"); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); + + when(interfaceDef.toString()).thenReturn("Interface"); + + final String interfaceDefStr = interfaceDef.toString(); + doNothing().when(vm).detachDevice(interfaceDefStr); + + when(libvirtComputingResource.getAllVifDrivers()).thenReturn(drivers); + + doNothing().when(vifDriver).unplug(intDef); + + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); + verify(libvirtComputingResource, times(1)).getAllVifDrivers(); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testUnPlugNicCommandNoNics() { + final NicTO nic = Mockito.mock(NicTO.class); + final String instanceName = "Test"; + + final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final Connect conn = Mockito.mock(Connect.class); + final Domain vm = Mockito.mock(Domain.class); + + final List nics = new ArrayList(); + + final VifDriver vifDriver = Mockito.mock(VifDriver.class); + final List drivers = new ArrayList(); + drivers.add(vifDriver); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testUnPlugNicCommandLibvirtException() { + final NicTO nic = Mockito.mock(NicTO.class); + final String instanceName = "Test"; + + final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testNetworkUsageCommandNonVpc() { + final String privateIP = "169.16.16.16"; + final String domRName = "domR"; + final boolean forVpc = false; + final String gatewayIP = "10.1.1.1"; + + final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP); + + libvirtComputingResource.getNetworkStats(command.getPrivateIP()); + + when(libvirtComputingResource.getNetworkStats(command.getPrivateIP())).thenReturn(new long[]{10l, 10l}); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + //Being called twice, although I did not find the second place yet. + verify(libvirtComputingResource, times(2)).getNetworkStats(command.getPrivateIP()); + } + + @Test + public void testNetworkUsageCommandNonVpcCreate() { + final String privateIP = "169.16.16.16"; + final String domRName = "domR"; + final boolean forVpc = false; + + final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, "create", forVpc); + + libvirtComputingResource.getNetworkStats(command.getPrivateIP()); + + when(libvirtComputingResource.networkUsage(command.getPrivateIP(), "create", null)).thenReturn("SUCCESS"); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + //Being called twice, although I did not find the second place yet. + verify(libvirtComputingResource, times(1)).networkUsage(command.getPrivateIP(), "create", null); + } + + @Test + public void testNetworkUsageCommandVpcCreate() { + final String privateIP = "169.16.16.16"; + final String domRName = "domR"; + final boolean forVpc = true; + final String gatewayIP = "10.1.1.1"; + final String vpcCidr = "10.1.1.0/24"; + + final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP, vpcCidr); + + libvirtComputingResource.getNetworkStats(command.getPrivateIP()); + + when(libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR())).thenReturn("SUCCESS"); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + //Being called twice, although I did not find the second place yet. + verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR()); + } + + @Test + public void testNetworkUsageCommandVpcGet() { + final String privateIP = "169.16.16.16"; + final String domRName = "domR"; + final boolean forVpc = true; + final String gatewayIP = "10.1.1.1"; + + final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, forVpc, gatewayIP); + + libvirtComputingResource.getNetworkStats(command.getPrivateIP()); + + when(libvirtComputingResource.getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption())).thenReturn(new long[]{10l, 10l}); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + //Being called twice, although I did not find the second place yet. + verify(libvirtComputingResource, times(1)).getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption()); + } + + @Test + public void testNetworkUsageCommandVpcVpn() { + final String privateIP = "169.16.16.16"; + final String domRName = "domR"; + final boolean forVpc = true; + final String gatewayIP = "10.1.1.1"; + + final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, "vpn", forVpc, gatewayIP); + + libvirtComputingResource.getNetworkStats(command.getPrivateIP()); + + when(libvirtComputingResource.getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption())).thenReturn(new long[]{10l, 10l}); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + //Being called twice, although I did not find the second place yet. + verify(libvirtComputingResource, times(1)).getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption()); + } + + @Test + public void testNetworkUsageCommandVpcNoOption() { + final String privateIP = "169.16.16.16"; + final String domRName = "domR"; + final boolean forVpc = true; + final String gatewayIP = "10.1.1.1"; + + final NetworkUsageCommand command = new NetworkUsageCommand(privateIP, domRName, null, forVpc, gatewayIP); + + libvirtComputingResource.getNetworkStats(command.getPrivateIP()); + + when(libvirtComputingResource.configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR())).thenReturn("FAILURE"); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + //Being called twice, although I did not find the second place yet. + verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR()); + } } \ No newline at end of file From bcf78d3b4304800d9a60db72742fb169c470093b Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Tue, 5 May 2015 11:48:55 +0200 Subject: [PATCH 26/36] Refactoring the LibvirtComputingResource - Adding LibvirtBackupSnapshotCommandWrapper, LibvirtCreatePrivateTemplateFromVolumeCommandWrapper and LibvirtManageSnapshotCommandWrapper - 3 unit tests added - KVM hypervisor plugin with 18.3% coverage Less tests added to those classes because the code is quite complex and way too long. The tests added are just covering the new flow, to make sure it works fine. I will come back to those classes later. --- .../resource/LibvirtComputingResource.java | 402 +----------------- .../LibvirtBackupSnapshotCommandWrapper.java | 204 +++++++++ ...ivateTemplateFromVolumeCommandWrapper.java | 176 ++++++++ .../LibvirtManageSnapshotCommandWrapper.java | 163 +++++++ .../wrapper/LibvirtRequestWrapper.java | 6 + .../LibvirtComputingResourceTest.java | 137 +++++- 6 files changed, 699 insertions(+), 389 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtBackupSnapshotCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java 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 3c40c908071..4e8b4cf0c81 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 @@ -16,26 +16,20 @@ // under the License. package com.cloud.hypervisor.kvm.resource; -import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; -import java.text.DateFormat; -import java.text.MessageFormat; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -54,10 +48,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.cloudstack.utils.qemu.QemuImg; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; -import org.apache.cloudstack.utils.qemu.QemuImgException; -import org.apache.cloudstack.utils.qemu.QemuImgFile; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; @@ -67,26 +58,14 @@ import org.libvirt.DomainBlockStats; import org.libvirt.DomainInfo; import org.libvirt.DomainInfo.DomainState; import org.libvirt.DomainInterfaceStats; -import org.libvirt.DomainSnapshot; import org.libvirt.LibvirtException; import org.libvirt.NodeInfo; import org.libvirt.StorageVol; -import com.ceph.rados.IoCTX; -import com.ceph.rados.Rados; -import com.ceph.rados.RadosException; -import com.ceph.rbd.Rbd; -import com.ceph.rbd.RbdException; -import com.ceph.rbd.RbdImage; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BackupSnapshotAnswer; -import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; -import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.HostVmStateReportEntry; -import com.cloud.agent.api.ManageSnapshotAnswer; -import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; @@ -156,7 +135,6 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; import com.cloud.storage.Volume; @@ -234,7 +212,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv public static final String SSHPUBKEYPATH = SSHKEYSPATH + File.separator + "id_rsa.pub.cloud"; private String _mountPoint = "/mnt"; - StorageLayer _storage; + private StorageLayer _storage; private KVMStoragePoolManager _storagePoolMgr; private VifDriver _defaultVifDriver; @@ -276,9 +254,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private final Map _pifs = new HashMap(); private final Map _vmStats = new ConcurrentHashMap(); - protected static final MessageFormat SnapshotXML = new MessageFormat(" " + " {0}" + " " - + " {1}" + " " + " "); - protected static final HashMap s_powerStatesTable; static { s_powerStatesTable = new HashMap(); @@ -414,6 +389,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _monitor; } + public StorageLayer getStorage() { + return _storage; + } + + public String createTmplPath() { + return _createTmplPath; + } + + public int getCmdsTimeout() { + return _cmdsTimeout; + } + + public String manageSnapshotPath() { + return _manageSnapshotPath; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1261,13 +1252,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) { - return execute((CreatePrivateTemplateFromVolumeCommand)cmd); - } else if (cmd instanceof ManageSnapshotCommand) { - return execute((ManageSnapshotCommand)cmd); - } else if (cmd instanceof BackupSnapshotCommand) { - return execute((BackupSnapshotCommand)cmd); - } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { + if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { return execute((CreatePrivateTemplateFromSnapshotCommand)cmd); } else if (cmd instanceof StartCommand) { return execute((StartCommand)cmd); @@ -1899,248 +1884,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ExecutionResult(true, null); } - protected ManageSnapshotAnswer execute(final ManageSnapshotCommand cmd) { - final String snapshotName = cmd.getSnapshotName(); - final String snapshotPath = cmd.getSnapshotPath(); - final String vmName = cmd.getVmName(); - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - DomainState state = null; - Domain vm = null; - if (vmName != null) { - try { - vm = getDomain(conn, cmd.getVmName()); - state = vm.getInfo().state; - } catch (final LibvirtException e) { - s_logger.trace("Ignoring libvirt error.", e); - } - } - - final KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPool().getUuid()); - - final KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(cmd.getVolumePath()); - if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) { - final String vmUuid = vm.getUUIDString(); - final Object[] args = new Object[] {snapshotName, vmUuid}; - final String snapshot = SnapshotXML.format(args); - s_logger.debug(snapshot); - if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { - vm.snapshotCreateXML(snapshot); - } else { - final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); - snap.delete(0); - } - - /* - * libvirt on RHEL6 doesn't handle resume event emitted from - * qemu - */ - vm = getDomain(conn, cmd.getVmName()); - state = vm.getInfo().state; - if (state == DomainState.VIR_DOMAIN_PAUSED) { - vm.resume(); - } - } else { - /** - * For RBD we can't use libvirt to do our snapshotting or any Bash scripts. - * libvirt also wants to store the memory contents of the Virtual Machine, - * but that's not possible with RBD since there is no way to store the memory - * contents in RBD. - * - * So we rely on the Java bindings for RBD to create our snapshot - * - * This snapshot might not be 100% consistent due to writes still being in the - * memory of the Virtual Machine, but if the VM runs a kernel which supports - * barriers properly (>2.6.32) this won't be any different then pulling the power - * cord out of a running machine. - */ - if (primaryPool.getType() == StoragePoolType.RBD) { - try { - final Rados r = new Rados(primaryPool.getAuthUserName()); - r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort()); - r.confSet("key", primaryPool.getAuthSecret()); - r.confSet("client_mount_timeout", "30"); - r.connect(); - s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host")); - - final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir()); - final Rbd rbd = new Rbd(io); - final RbdImage image = rbd.open(disk.getName()); - - if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { - s_logger.debug("Attempting to create RBD snapshot " + disk.getName() + "@" + snapshotName); - image.snapCreate(snapshotName); - } else { - s_logger.debug("Attempting to remove RBD snapshot " + disk.getName() + "@" + snapshotName); - image.snapRemove(snapshotName); - } - - rbd.close(image); - r.ioCtxDestroy(io); - } catch (final Exception e) { - s_logger.error("A RBD snapshot operation on " + disk.getName() + " failed. The error was: " + e.getMessage()); - } - } else { - /* VM is not running, create a snapshot by ourself */ - final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); - if (cmd.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { - command.add("-c", disk.getPath()); - } else { - command.add("-d", snapshotPath); - } - - command.add("-n", snapshotName); - final String result = command.execute(); - if (result != null) { - s_logger.debug("Failed to manage snapshot: " + result); - return new ManageSnapshotAnswer(cmd, false, "Failed to manage snapshot: " + result); - } - } - } - return new ManageSnapshotAnswer(cmd, cmd.getSnapshotId(), disk.getPath() + File.separator + snapshotName, true, null); - } catch (final LibvirtException e) { - s_logger.debug("Failed to manage snapshot: " + e.toString()); - return new ManageSnapshotAnswer(cmd, false, "Failed to manage snapshot: " + e.toString()); - } - - } - - protected BackupSnapshotAnswer execute(final BackupSnapshotCommand cmd) { - final Long dcId = cmd.getDataCenterId(); - final Long accountId = cmd.getAccountId(); - final Long volumeId = cmd.getVolumeId(); - final String secondaryStoragePoolUrl = cmd.getSecondaryStorageUrl(); - final String snapshotName = cmd.getSnapshotName(); - String snapshotDestPath = null; - String snapshotRelPath = null; - final String vmName = cmd.getVmName(); - KVMStoragePool secondaryStoragePool = null; - try { - final Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - - secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl); - - final String ssPmountPath = secondaryStoragePool.getLocalPath(); - snapshotRelPath = File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; - - snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; - final KVMStoragePool primaryPool = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPrimaryStoragePoolNameLabel()); - final KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(cmd.getVolumePath()); - - /** - * RBD snapshots can't be copied using qemu-img, so we have to use - * the Java bindings for librbd here. - * - * These bindings will read the snapshot and write the contents to - * the secondary storage directly - * - * It will stop doing so if the amount of time spend is longer then - * cmds.timeout - */ - if (primaryPool.getType() == StoragePoolType.RBD) { - try { - final Rados r = new Rados(primaryPool.getAuthUserName()); - r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort()); - r.confSet("key", primaryPool.getAuthSecret()); - r.confSet("client_mount_timeout", "30"); - r.connect(); - s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host")); - - final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir()); - final Rbd rbd = new Rbd(io); - final RbdImage image = rbd.open(snapshotDisk.getName(), snapshotName); - final File fh = new File(snapshotDestPath); - try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fh));) { - final int chunkSize = 4194304; - long offset = 0; - s_logger.debug("Backuping up RBD snapshot " + snapshotName + " to " + snapshotDestPath); - while (true) { - final byte[] buf = new byte[chunkSize]; - final int bytes = image.read(offset, buf, chunkSize); - if (bytes <= 0) { - break; - } - bos.write(buf, 0, bytes); - offset += bytes; - } - s_logger.debug("Completed backing up RBD snapshot " + snapshotName + " to " + snapshotDestPath + ". Bytes written: " + offset); - }catch(final IOException ex) - { - s_logger.error("BackupSnapshotAnswer:Exception:"+ ex.getMessage()); - } - r.ioCtxDestroy(io); - } catch (final RadosException e) { - s_logger.error("A RADOS operation failed. The error was: " + e.getMessage()); - return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); - } catch (final RbdException e) { - s_logger.error("A RBD operation on " + snapshotDisk.getName() + " failed. The error was: " + e.getMessage()); - return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); - } - } else { - final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); - command.add("-b", snapshotDisk.getPath()); - command.add("-n", snapshotName); - command.add("-p", snapshotDestPath); - command.add("-t", snapshotName); - final String result = command.execute(); - if (result != null) { - s_logger.debug("Failed to backup snaptshot: " + result); - return new BackupSnapshotAnswer(cmd, false, result, null, true); - } - } - /* Delete the snapshot on primary */ - - DomainState state = null; - Domain vm = null; - if (vmName != null) { - try { - vm = getDomain(conn, cmd.getVmName()); - state = vm.getInfo().state; - } catch (final LibvirtException e) { - s_logger.trace("Ignoring libvirt error.", e); - } - } - - final KVMStoragePool primaryStorage = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPool().getUuid()); - if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) { - final String vmUuid = vm.getUUIDString(); - final Object[] args = new Object[] {snapshotName, vmUuid}; - final String snapshot = SnapshotXML.format(args); - s_logger.debug(snapshot); - final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); - snap.delete(0); - - /* - * libvirt on RHEL6 doesn't handle resume event emitted from - * qemu - */ - vm = getDomain(conn, cmd.getVmName()); - state = vm.getInfo().state; - if (state == DomainState.VIR_DOMAIN_PAUSED) { - vm.resume(); - } - } else { - final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); - command.add("-d", snapshotDisk.getPath()); - command.add("-n", snapshotName); - final String result = command.execute(); - if (result != null) { - s_logger.debug("Failed to backup snapshot: " + result); - return new BackupSnapshotAnswer(cmd, false, "Failed to backup snapshot: " + result, null, true); - } - } - } catch (final LibvirtException e) { - return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); - } catch (final CloudRuntimeException e) { - return new BackupSnapshotAnswer(cmd, false, e.toString(), null, true); - } finally { - if (secondaryStoragePool != null) { - _storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid()); - } - } - return new BackupSnapshotAnswer(cmd, true, null, snapshotRelPath + File.separator + snapshotName, true); - } - protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) { final String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId(); final String templateInstallFolder = "template/tmpl/" + templateFolder; @@ -2198,115 +1941,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromVolumeCommand cmd) { - final String secondaryStorageURL = cmd.getSecondaryStorageUrl(); - - KVMStoragePool secondaryStorage = null; - KVMStoragePool primary = null; - try { - final String templateFolder = cmd.getAccountId() + File.separator + cmd.getTemplateId() + File.separator; - final String templateInstallFolder = "/template/tmpl/" + templateFolder; - - secondaryStorage = _storagePoolMgr.getStoragePoolByURI(secondaryStorageURL); - - try { - primary = _storagePoolMgr.getStoragePool(cmd.getPool().getType(), cmd.getPrimaryStoragePoolNameLabel()); - } catch (final CloudRuntimeException e) { - if (e.getMessage().contains("not found")) { - primary = - _storagePoolMgr.createStoragePool(cmd.getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(), cmd.getPool().getPath(), - cmd.getPool().getUserInfo(), cmd.getPool().getType()); - } else { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } - } - - final KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); - final String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateInstallFolder; - _storage.mkdirs(tmpltPath); - - if (primary.getType() != StoragePoolType.RBD) { - final Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger); - command.add("-f", disk.getPath()); - command.add("-t", tmpltPath); - command.add("-n", cmd.getUniqueName() + ".qcow2"); - - final String result = command.execute(); - - if (result != null) { - s_logger.debug("failed to create template: " + result); - return new CreatePrivateTemplateAnswer(cmd, false, result); - } - } else { - s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + cmd.getUniqueName()); - - final QemuImgFile srcFile = - new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), primary.getSourcePort(), primary.getAuthUserName(), - primary.getAuthSecret(), disk.getPath())); - srcFile.setFormat(PhysicalDiskFormat.RAW); - - final QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + cmd.getUniqueName() + ".qcow2"); - destFile.setFormat(PhysicalDiskFormat.QCOW2); - - final QemuImg q = new QemuImg(0); - try { - q.convert(srcFile, destFile); - } catch (final QemuImgException e) { - s_logger.error("Failed to create new template while converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + - e.getMessage()); - } - - final File templateProp = new File(tmpltPath + "/template.properties"); - if (!templateProp.exists()) { - templateProp.createNewFile(); - } - - String templateContent = "filename=" + cmd.getUniqueName() + ".qcow2" + System.getProperty("line.separator"); - - final DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy"); - final Date date = new Date(); - templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator"); - - try(FileOutputStream templFo = new FileOutputStream(templateProp);) { - templFo.write(templateContent.getBytes()); - templFo.flush(); - }catch(final IOException ex) - { - s_logger.error("CreatePrivateTemplateAnswer:Exception:"+ex.getMessage()); - } - - } - - final Map params = new HashMap(); - params.put(StorageLayer.InstanceConfigKey, _storage); - final Processor qcow2Processor = new QCOW2Processor(); - - qcow2Processor.configure("QCOW2 Processor", params); - - final FormatInfo info = qcow2Processor.process(tmpltPath, null, cmd.getUniqueName()); - - final TemplateLocation loc = new TemplateLocation(_storage, tmpltPath); - loc.create(1, true, cmd.getUniqueName()); - loc.addFormat(info); - loc.save(); - - return new CreatePrivateTemplateAnswer(cmd, true, null, templateInstallFolder + cmd.getUniqueName() + ".qcow2", info.virtualSize, info.size, - cmd.getUniqueName(), ImageFormat.QCOW2); - } catch (final InternalErrorException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); - } catch (final IOException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); - } catch (final ConfigurationException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); - } catch (final CloudRuntimeException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); - } finally { - if (secondaryStorage != null) { - _storagePoolMgr.deleteStoragePool(secondaryStorage.getType(), secondaryStorage.getUuid()); - } - } - } - protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtBackupSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtBackupSnapshotCommandWrapper.java new file mode 100644 index 00000000000..afbbf73e0fb --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtBackupSnapshotCommandWrapper.java @@ -0,0 +1,204 @@ +// +// 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 java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.MessageFormat; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainInfo.DomainState; +import org.libvirt.DomainSnapshot; +import org.libvirt.LibvirtException; + +import com.ceph.rados.IoCTX; +import com.ceph.rados.Rados; +import com.ceph.rados.RadosException; +import com.ceph.rbd.Rbd; +import com.ceph.rbd.RbdException; +import com.ceph.rbd.RbdImage; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.BackupSnapshotAnswer; +import com.cloud.agent.api.BackupSnapshotCommand; +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.utils.script.Script; + +public final class LibvirtBackupSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtBackupSnapshotCommandWrapper.class); + + @Override + public Answer execute(final BackupSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) { + final Long dcId = command.getDataCenterId(); + final Long accountId = command.getAccountId(); + final Long volumeId = command.getVolumeId(); + final String secondaryStoragePoolUrl = command.getSecondaryStorageUrl(); + final String snapshotName = command.getSnapshotName(); + String snapshotDestPath = null; + String snapshotRelPath = null; + final String vmName = command.getVmName(); + KVMStoragePool secondaryStoragePool = null; + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(vmName); + + secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl); + + final String ssPmountPath = secondaryStoragePool.getLocalPath(); + snapshotRelPath = File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; + + snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId; + final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel()); + final KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(command.getVolumePath()); + + final String manageSnapshotPath = libvirtComputingResource.manageSnapshotPath(); + final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout(); + + /** + * RBD snapshots can't be copied using qemu-img, so we have to use + * the Java bindings for librbd here. + * + * These bindings will read the snapshot and write the contents to + * the secondary storage directly + * + * It will stop doing so if the amount of time spend is longer then + * cmds.timeout + */ + if (primaryPool.getType() == StoragePoolType.RBD) { + try { + final Rados r = new Rados(primaryPool.getAuthUserName()); + r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort()); + r.confSet("key", primaryPool.getAuthSecret()); + r.confSet("client_mount_timeout", "30"); + r.connect(); + s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host")); + + final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir()); + final Rbd rbd = new Rbd(io); + final RbdImage image = rbd.open(snapshotDisk.getName(), snapshotName); + final File fh = new File(snapshotDestPath); + try(BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fh));) { + final int chunkSize = 4194304; + long offset = 0; + s_logger.debug("Backuping up RBD snapshot " + snapshotName + " to " + snapshotDestPath); + while (true) { + final byte[] buf = new byte[chunkSize]; + final int bytes = image.read(offset, buf, chunkSize); + if (bytes <= 0) { + break; + } + bos.write(buf, 0, bytes); + offset += bytes; + } + s_logger.debug("Completed backing up RBD snapshot " + snapshotName + " to " + snapshotDestPath + ". Bytes written: " + offset); + }catch(final IOException ex) + { + s_logger.error("BackupSnapshotAnswer:Exception:"+ ex.getMessage()); + } + r.ioCtxDestroy(io); + } catch (final RadosException e) { + s_logger.error("A RADOS operation failed. The error was: " + e.getMessage()); + return new BackupSnapshotAnswer(command, false, e.toString(), null, true); + } catch (final RbdException e) { + s_logger.error("A RBD operation on " + snapshotDisk.getName() + " failed. The error was: " + e.getMessage()); + return new BackupSnapshotAnswer(command, false, e.toString(), null, true); + } + } else { + final Script scriptCommand = new Script(manageSnapshotPath, cmdsTimeout, s_logger); + scriptCommand.add("-b", snapshotDisk.getPath()); + scriptCommand.add("-n", snapshotName); + scriptCommand.add("-p", snapshotDestPath); + scriptCommand.add("-t", snapshotName); + final String result = scriptCommand.execute(); + + if (result != null) { + s_logger.debug("Failed to backup snaptshot: " + result); + return new BackupSnapshotAnswer(command, false, result, null, true); + } + } + /* Delete the snapshot on primary */ + + DomainState state = null; + Domain vm = null; + if (vmName != null) { + try { + vm = libvirtComputingResource.getDomain(conn, command.getVmName()); + state = vm.getInfo().state; + } catch (final LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); + } + } + + final KVMStoragePool primaryStorage = storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPool().getUuid()); + + if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) { + final MessageFormat snapshotXML = new MessageFormat(" " + " {0}" + " " + + " {1}" + " " + " "); + + final String vmUuid = vm.getUUIDString(); + final Object[] args = new Object[] {snapshotName, vmUuid}; + final String snapshot = snapshotXML.format(args); + s_logger.debug(snapshot); + final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); + snap.delete(0); + + /* + * libvirt on RHEL6 doesn't handle resume event emitted from + * qemu + */ + vm = libvirtComputingResource.getDomain(conn, command.getVmName()); + state = vm.getInfo().state; + if (state == DomainState.VIR_DOMAIN_PAUSED) { + vm.resume(); + } + } else { + final Script scriptCommand = new Script(manageSnapshotPath, cmdsTimeout, s_logger); + scriptCommand.add("-d", snapshotDisk.getPath()); + scriptCommand.add("-n", snapshotName); + final String result = scriptCommand.execute(); + if (result != null) { + s_logger.debug("Failed to backup snapshot: " + result); + return new BackupSnapshotAnswer(command, false, "Failed to backup snapshot: " + result, null, true); + } + } + } catch (final LibvirtException e) { + return new BackupSnapshotAnswer(command, false, e.toString(), null, true); + } catch (final CloudRuntimeException e) { + return new BackupSnapshotAnswer(command, false, e.toString(), null, true); + } finally { + if (secondaryStoragePool != null) { + storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid()); + } + } + return new BackupSnapshotAnswer(command, true, null, snapshotRelPath + File.separator + snapshotName, true); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java new file mode 100644 index 00000000000..f3bfe1ffd19 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.java @@ -0,0 +1,176 @@ +// +// 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 java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.utils.qemu.QemuImg; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.cloudstack.utils.qemu.QemuImgException; +import org.apache.cloudstack.utils.qemu.QemuImgFile; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; +import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; +import com.cloud.exception.InternalErrorException; +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.ImageFormat; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.StorageLayer; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.Processor.FormatInfo; +import com.cloud.storage.template.QCOW2Processor; +import com.cloud.storage.template.TemplateLocation; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; + +public final class LibvirtCreatePrivateTemplateFromVolumeCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtCreatePrivateTemplateFromVolumeCommandWrapper.class); + + @Override + public Answer execute(final CreatePrivateTemplateFromVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String secondaryStorageURL = command.getSecondaryStorageUrl(); + + KVMStoragePool secondaryStorage = null; + KVMStoragePool primary = null; + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + try { + final String templateFolder = command.getAccountId() + File.separator + command.getTemplateId() + File.separator; + final String templateInstallFolder = "/template/tmpl/" + templateFolder; + + secondaryStorage = storagePoolMgr.getStoragePoolByURI(secondaryStorageURL); + + try { + primary = storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel()); + } catch (final CloudRuntimeException e) { + if (e.getMessage().contains("not found")) { + primary = + storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), + command.getPool().getUserInfo(), command.getPool().getType()); + } else { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } + } + + final KVMPhysicalDisk disk = primary.getPhysicalDisk(command.getVolumePath()); + final String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateInstallFolder; + final StorageLayer storage = libvirtComputingResource.getStorage(); + storage.mkdirs(tmpltPath); + + if (primary.getType() != StoragePoolType.RBD) { + final String createTmplPath = libvirtComputingResource.createTmplPath(); + final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout(); + + final Script scriptCommand = new Script(createTmplPath, cmdsTimeout, s_logger); + scriptCommand.add("-f", disk.getPath()); + scriptCommand.add("-t", tmpltPath); + scriptCommand.add("-n", command.getUniqueName() + ".qcow2"); + + final String result = scriptCommand.execute(); + + if (result != null) { + s_logger.debug("failed to create template: " + result); + return new CreatePrivateTemplateAnswer(command, false, result); + } + } else { + s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + command.getUniqueName()); + + final QemuImgFile srcFile = + new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), primary.getSourcePort(), primary.getAuthUserName(), + primary.getAuthSecret(), disk.getPath())); + srcFile.setFormat(PhysicalDiskFormat.RAW); + + final QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + command.getUniqueName() + ".qcow2"); + destFile.setFormat(PhysicalDiskFormat.QCOW2); + + final QemuImg q = new QemuImg(0); + try { + q.convert(srcFile, destFile); + } catch (final QemuImgException e) { + s_logger.error("Failed to create new template while converting " + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + + e.getMessage()); + } + + final File templateProp = new File(tmpltPath + "/template.properties"); + if (!templateProp.exists()) { + templateProp.createNewFile(); + } + + String templateContent = "filename=" + command.getUniqueName() + ".qcow2" + System.getProperty("line.separator"); + + final DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy"); + final Date date = new Date(); + templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator"); + + try(FileOutputStream templFo = new FileOutputStream(templateProp);) { + templFo.write(templateContent.getBytes()); + templFo.flush(); + }catch(final IOException ex) + { + s_logger.error("CreatePrivateTemplateAnswer:Exception:"+ex.getMessage()); + } + + } + + final Map params = new HashMap(); + params.put(StorageLayer.InstanceConfigKey, storage); + final Processor qcow2Processor = new QCOW2Processor(); + + qcow2Processor.configure("QCOW2 Processor", params); + + final FormatInfo info = qcow2Processor.process(tmpltPath, null, command.getUniqueName()); + + final TemplateLocation loc = new TemplateLocation(storage, tmpltPath); + loc.create(1, true, command.getUniqueName()); + loc.addFormat(info); + loc.save(); + + return new CreatePrivateTemplateAnswer(command, true, null, templateInstallFolder + command.getUniqueName() + ".qcow2", info.virtualSize, info.size, + command.getUniqueName(), ImageFormat.QCOW2); + } catch (final InternalErrorException e) { + return new CreatePrivateTemplateAnswer(command, false, e.toString()); + } catch (final IOException e) { + return new CreatePrivateTemplateAnswer(command, false, e.toString()); + } catch (final ConfigurationException e) { + return new CreatePrivateTemplateAnswer(command, false, e.toString()); + } catch (final CloudRuntimeException e) { + return new CreatePrivateTemplateAnswer(command, false, e.toString()); + } finally { + if (secondaryStorage != null) { + storagePoolMgr.deleteStoragePool(secondaryStorage.getType(), secondaryStorage.getUuid()); + } + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java new file mode 100644 index 00000000000..9a991a15e61 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java @@ -0,0 +1,163 @@ +// +// 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 java.io.File; +import java.text.MessageFormat; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainInfo.DomainState; +import org.libvirt.DomainSnapshot; +import org.libvirt.LibvirtException; + +import com.ceph.rados.IoCTX; +import com.ceph.rados.Rados; +import com.ceph.rbd.Rbd; +import com.ceph.rbd.RbdImage; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ManageSnapshotAnswer; +import com.cloud.agent.api.ManageSnapshotCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; +import com.cloud.hypervisor.kvm.storage.KVMStoragePool; +import com.cloud.resource.CommandWrapper; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.utils.script.Script; + +public final class LibvirtManageSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtManageSnapshotCommandWrapper.class); + + @Override + public Answer execute(final ManageSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String snapshotName = command.getSnapshotName(); + final String snapshotPath = command.getSnapshotPath(); + final String vmName = command.getVmName(); + try { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(vmName); + DomainState state = null; + Domain vm = null; + if (vmName != null) { + try { + vm = libvirtComputingResource.getDomain(conn, command.getVmName()); + state = vm.getInfo().state; + } catch (final LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); + } + } + + final KVMStoragePool primaryPool = libvirtComputingResource.getStoragePoolMgr().getStoragePool(command.getPool().getType(), command.getPool().getUuid()); + + final KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(command.getVolumePath()); + if (state == DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) { + + final MessageFormat snapshotXML = new MessageFormat(" " + " {0}" + " " + + " {1}" + " " + " "); + + final String vmUuid = vm.getUUIDString(); + final Object[] args = new Object[] {snapshotName, vmUuid}; + final String snapshot = snapshotXML.format(args); + s_logger.debug(snapshot); + if (command.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { + vm.snapshotCreateXML(snapshot); + } else { + final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); + snap.delete(0); + } + + /* + * libvirt on RHEL6 doesn't handle resume event emitted from + * qemu + */ + vm = libvirtComputingResource.getDomain(conn, command.getVmName()); + state = vm.getInfo().state; + if (state == DomainState.VIR_DOMAIN_PAUSED) { + vm.resume(); + } + } else { + /** + * For RBD we can't use libvirt to do our snapshotting or any Bash scripts. + * libvirt also wants to store the memory contents of the Virtual Machine, + * but that's not possible with RBD since there is no way to store the memory + * contents in RBD. + * + * So we rely on the Java bindings for RBD to create our snapshot + * + * This snapshot might not be 100% consistent due to writes still being in the + * memory of the Virtual Machine, but if the VM runs a kernel which supports + * barriers properly (>2.6.32) this won't be any different then pulling the power + * cord out of a running machine. + */ + if (primaryPool.getType() == StoragePoolType.RBD) { + try { + final Rados r = new Rados(primaryPool.getAuthUserName()); + r.confSet("mon_host", primaryPool.getSourceHost() + ":" + primaryPool.getSourcePort()); + r.confSet("key", primaryPool.getAuthSecret()); + r.confSet("client_mount_timeout", "30"); + r.connect(); + s_logger.debug("Succesfully connected to Ceph cluster at " + r.confGet("mon_host")); + + final IoCTX io = r.ioCtxCreate(primaryPool.getSourceDir()); + final Rbd rbd = new Rbd(io); + final RbdImage image = rbd.open(disk.getName()); + + if (command.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { + s_logger.debug("Attempting to create RBD snapshot " + disk.getName() + "@" + snapshotName); + image.snapCreate(snapshotName); + } else { + s_logger.debug("Attempting to remove RBD snapshot " + disk.getName() + "@" + snapshotName); + image.snapRemove(snapshotName); + } + + rbd.close(image); + r.ioCtxDestroy(io); + } catch (final Exception e) { + s_logger.error("A RBD snapshot operation on " + disk.getName() + " failed. The error was: " + e.getMessage()); + } + } else { + /* VM is not running, create a snapshot by ourself */ + final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout(); + final String manageSnapshotPath = libvirtComputingResource.manageSnapshotPath(); + + final Script scriptCommand = new Script(manageSnapshotPath, cmdsTimeout, s_logger); + if (command.getCommandSwitch().equalsIgnoreCase(ManageSnapshotCommand.CREATE_SNAPSHOT)) { + scriptCommand.add("-c", disk.getPath()); + } else { + scriptCommand.add("-d", snapshotPath); + } + + scriptCommand.add("-n", snapshotName); + final String result = scriptCommand.execute(); + if (result != null) { + s_logger.debug("Failed to manage snapshot: " + result); + return new ManageSnapshotAnswer(command, false, "Failed to manage snapshot: " + result); + } + } + } + return new ManageSnapshotAnswer(command, command.getSnapshotId(), disk.getPath() + File.separator + snapshotName, true, null); + } catch (final LibvirtException e) { + s_logger.debug("Failed to manage snapshot: " + e.toString()); + return new ManageSnapshotAnswer(command, false, "Failed to manage snapshot: " + 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 148075b8575..2656037f456 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 @@ -23,12 +23,14 @@ import java.util.Hashtable; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; +import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; @@ -39,6 +41,7 @@ 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.ManageSnapshotCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; @@ -136,6 +139,9 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(PlugNicCommand.class, new LibvirtPlugNicCommandWrapper()); linbvirtCommands.put(UnPlugNicCommand.class, new LibvirtUnPlugNicCommandWrapper()); linbvirtCommands.put(NetworkUsageCommand.class, new LibvirtNetworkUsageCommandWrapper()); + linbvirtCommands.put(CreatePrivateTemplateFromVolumeCommand.class, new LibvirtCreatePrivateTemplateFromVolumeCommandWrapper()); + linbvirtCommands.put(ManageSnapshotCommand.class, new LibvirtManageSnapshotCommandWrapper()); + linbvirtCommands.put(BackupSnapshotCommand.class, new LibvirtBackupSnapshotCommandWrapper()); 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 9b0be08cb06..b0c273404b7 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 @@ -66,11 +66,13 @@ import org.xml.sax.SAXException; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; +import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; +import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; @@ -81,6 +83,7 @@ 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.ManageSnapshotCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.ModifyStoragePoolCommand; @@ -3313,7 +3316,6 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); - //Being called twice, although I did not find the second place yet. verify(libvirtComputingResource, times(1)).networkUsage(command.getPrivateIP(), "create", null); } @@ -3337,7 +3339,6 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); - //Being called twice, although I did not find the second place yet. verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), "create", command.getVpcCIDR()); } @@ -3360,7 +3361,6 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); - //Being called twice, although I did not find the second place yet. verify(libvirtComputingResource, times(1)).getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption()); } @@ -3383,7 +3383,6 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); - //Being called twice, although I did not find the second place yet. verify(libvirtComputingResource, times(1)).getVPCNetworkStats(command.getPrivateIP(), command.getGatewayIP(), command.getOption()); } @@ -3406,7 +3405,135 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); - //Being called twice, although I did not find the second place yet. verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR()); } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromVolumeCommand() { + //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working. + //The code is way to big and complex. Will finish the refactor and come back to this to add more cases. + + final StoragePool pool = Mockito.mock(StoragePool.class);; + final String secondaryStorageUrl = "nfs:/192.168.2.2/storage/secondary"; + final long templateId = 1l; + final long accountId = 1l; + final String userSpecifiedName = "User"; + final String uniqueName = "Unique"; + final String volumePath = "/123/vol"; + final String vmName = "Test"; + final int wait = 0; + + final CreatePrivateTemplateFromVolumeCommand command = new CreatePrivateTemplateFromVolumeCommand(pool, secondaryStorageUrl, templateId, accountId, userSpecifiedName, uniqueName, volumePath, vmName, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryStorage = Mockito.mock(KVMStoragePool.class); + //final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl)).thenReturn(secondaryStorage); + when(storagePoolMgr.getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel())).thenThrow(new CloudRuntimeException("error")); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(secondaryStorageUrl); + verify(storagePoolMgr, times(1)).getStoragePool(command.getPool().getType(), command.getPrimaryStoragePoolNameLabel()); + } + + @SuppressWarnings("unchecked") + @Test + public void testManageSnapshotCommandLibvirtException() { + //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working. + //The code is way to big and complex. Will finish the refactor and come back to this to add more cases. + + final StoragePool pool = Mockito.mock(StoragePool.class);; + final String volumePath = "/123/vol"; + final String vmName = "Test"; + + final long snapshotId = 1l; + final String preSnapshotPath = "/snapshot/path"; + final String snapshotName = "snap"; + + final ManageSnapshotCommand command = new ManageSnapshotCommand(snapshotId, volumePath, pool, preSnapshotPath, snapshotName, vmName); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + //final Connect conn = Mockito.mock(Connect.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testBackupSnapshotCommandLibvirtException() { + //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working. + //The code is way to big and complex. Will finish the refactor and come back to this to add more cases. + + final StoragePool pool = Mockito.mock(StoragePool.class);; + final String secondaryStorageUrl = "nfs:/192.168.2.2/storage/secondary"; + final long accountId = 1l; + final String volumePath = "/123/vol"; + final String vmName = "Test"; + final int wait = 0; + + final long snapshotId = 1l; + final String snapshotName = "snap"; + + final Long dcId = 1l; + final Long volumeId = 1l; + final Long secHostId = 1l; + final String snapshotUuid = "9a0afe7c-26a7-4585-bf87-abf82ae106d9"; + final String prevBackupUuid = "003a0cc2-2e04-417a-bee0-534ef1724561"; + final boolean isVolumeInactive = false; + final String prevSnapshotUuid = "1791efae-f22d-474b-87c6-92547d6c5877"; + + final BackupSnapshotCommand command = new BackupSnapshotCommand(secondaryStorageUrl, dcId, accountId, volumeId, snapshotId, secHostId, volumePath, pool, snapshotUuid, snapshotName, prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, wait); + + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + //final Connect conn = Mockito.mock(Connect.class); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + + try { + when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + try { + verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From b3913ca1fbd3b400961608a4434cd7619cf1606d Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Tue, 5 May 2015 12:53:10 +0200 Subject: [PATCH 27/36] Refactoring the LibvirtComputingResource - Adding LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper - 5 unit tests added - KVM hypervisor plugin with 19.5% coverage --- .../resource/LibvirtComputingResource.java | 67 +--- .../wrapper/LibvirtConnectionWrapper.java | 33 +- ...ateTemplateFromSnapshotCommandWrapper.java | 113 ++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 354 ++++++++++++++++++ 5 files changed, 502 insertions(+), 67 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java 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 4e8b4cf0c81..977288b2c86 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 @@ -64,7 +64,6 @@ import org.libvirt.StorageVol; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; @@ -84,7 +83,6 @@ 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.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; @@ -140,10 +138,6 @@ import com.cloud.storage.StorageLayer; import com.cloud.storage.Volume; import com.cloud.storage.resource.StorageSubsystemCommandHandler; import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; -import com.cloud.storage.template.Processor; -import com.cloud.storage.template.Processor.FormatInfo; -import com.cloud.storage.template.QCOW2Processor; -import com.cloud.storage.template.TemplateLocation; import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -1252,9 +1246,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } try { - if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { - return execute((CreatePrivateTemplateFromSnapshotCommand)cmd); - } else if (cmd instanceof StartCommand) { + if (cmd instanceof StartCommand) { return execute((StartCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest((NetworkElementCommand)cmd); @@ -1884,63 +1876,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ExecutionResult(true, null); } - protected CreatePrivateTemplateAnswer execute(final CreatePrivateTemplateFromSnapshotCommand cmd) { - final String templateFolder = cmd.getAccountId() + File.separator + cmd.getNewTemplateId(); - final String templateInstallFolder = "template/tmpl/" + templateFolder; - final String tmplName = UUID.randomUUID().toString(); - final String tmplFileName = tmplName + ".qcow2"; - KVMStoragePool secondaryPool = null; - KVMStoragePool snapshotPool = null; - try { - String snapshotPath = cmd.getSnapshotUuid(); - final int index = snapshotPath.lastIndexOf("/"); - snapshotPath = snapshotPath.substring(0, index); - snapshotPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl() + snapshotPath); - final KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(cmd.getSnapshotName()); - - secondaryPool = _storagePoolMgr.getStoragePoolByURI(cmd.getSecondaryStorageUrl()); - - final String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - - _storage.mkdirs(templatePath); - - final String tmplPath = templateInstallFolder + File.separator + tmplFileName; - final Script command = new Script(_createTmplPath, _cmdsTimeout, s_logger); - command.add("-t", templatePath); - command.add("-n", tmplFileName); - command.add("-f", snapshot.getPath()); - command.execute(); - - final Map params = new HashMap(); - params.put(StorageLayer.InstanceConfigKey, _storage); - final Processor qcow2Processor = new QCOW2Processor(); - qcow2Processor.configure("QCOW2 Processor", params); - final FormatInfo info = qcow2Processor.process(templatePath, null, tmplName); - - final TemplateLocation loc = new TemplateLocation(_storage, templatePath); - loc.create(1, true, tmplName); - loc.addFormat(info); - loc.save(); - - return new CreatePrivateTemplateAnswer(cmd, true, "", tmplPath, info.virtualSize, info.size, tmplName, info.format); - } catch (final ConfigurationException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (final InternalErrorException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (final IOException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } catch (final CloudRuntimeException e) { - return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage()); - } finally { - if (secondaryPool != null) { - _storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid()); - } - if (snapshotPool != null) { - _storagePoolMgr.deleteStoragePool(snapshotPool.getType(), snapshotPool.getUuid()); - } - } - } - protected PowerState convertToPowerState(final DomainState ps) { final PowerState state = s_powerStatesTable.get(ps); return state == null ? PowerState.PowerUnknown : state; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java index e6743ace118..3a51a37e376 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java @@ -16,13 +16,25 @@ // under the License. package com.cloud.hypervisor.kvm.resource.wrapper; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import javax.naming.ConfigurationException; + import org.libvirt.Connect; import org.libvirt.LibvirtException; import com.cloud.hypervisor.kvm.resource.LibvirtConnection; +import com.cloud.storage.StorageLayer; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.QCOW2Processor; +import com.cloud.storage.template.TemplateLocation; /** - * This class is used to wrap the calls to LibvirtConnection and ease the burden of the unit tests. + * This class is used to wrap the calls to several static methods. By doing so, we make easier to mock this class + * and the methods wrapped here. + * * Please do not instantiate this class directly, but inject it using the {@code @Inject} annotation. */ public class LibvirtConnectionWrapper { @@ -34,4 +46,23 @@ public class LibvirtConnectionWrapper { public Connect getConnection() throws LibvirtException { return LibvirtConnection.getConnection(); } + + public TemplateLocation buildTemplateLocation(final StorageLayer storage, final String templatePath) { + final TemplateLocation location = new TemplateLocation(storage, templatePath); + return location; + } + + public Processor buildQCOW2Processor(final StorageLayer storage) throws ConfigurationException { + final Map params = new HashMap(); + params.put(StorageLayer.InstanceConfigKey, storage); + + final Processor qcow2Processor = new QCOW2Processor(); + qcow2Processor.configure("QCOW2 Processor", params); + + return qcow2Processor; + } + + public String buildTemplateUUIDName() { + return UUID.randomUUID().toString(); + } } \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java new file mode 100644 index 00000000000..20bebad81d4 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java @@ -0,0 +1,113 @@ +// +// 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 java.io.File; +import java.io.IOException; + +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; +import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; +import com.cloud.exception.InternalErrorException; +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.StorageLayer; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.Processor.FormatInfo; +import com.cloud.storage.template.TemplateLocation; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; + +public final class LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.class); + + @Override + public Answer execute(final CreatePrivateTemplateFromSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) { + final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplName = libvirtConnectionWrapper.buildTemplateUUIDName(); + final String tmplFileName = tmplName + ".qcow2"; + + KVMStoragePool secondaryPool = null; + KVMStoragePool snapshotPool = null; + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + + try { + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + snapshotPool = storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + secondaryPool = storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl()); + + final KVMPhysicalDisk snapshot = snapshotPool.getPhysicalDisk(command.getSnapshotName()); + + final String templatePath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + final StorageLayer storage = libvirtComputingResource.getStorage(); + storage.mkdirs(templatePath); + + final String tmplPath = templateInstallFolder + File.separator + tmplFileName; + final String createTmplPath = libvirtComputingResource.createTmplPath(); + final int cmdsTimeout = libvirtComputingResource.getCmdsTimeout(); + + final Script scriptCommand = new Script(createTmplPath, cmdsTimeout, s_logger); + scriptCommand.add("-t", templatePath); + scriptCommand.add("-n", tmplFileName); + scriptCommand.add("-f", snapshot.getPath()); + scriptCommand.execute(); + + final Processor qcow2Processor = libvirtConnectionWrapper.buildQCOW2Processor(storage); + final FormatInfo info = qcow2Processor.process(templatePath, null, tmplName); + final TemplateLocation loc = libvirtConnectionWrapper.buildTemplateLocation(storage, templatePath); + + loc.create(1, true, tmplName); + loc.addFormat(info); + loc.save(); + + return new CreatePrivateTemplateAnswer(command, true, "", tmplPath, info.virtualSize, info.size, tmplName, info.format); + } catch (final ConfigurationException e) { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } catch (final InternalErrorException e) { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } catch (final IOException e) { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } catch (final CloudRuntimeException e) { + return new CreatePrivateTemplateAnswer(command, false, e.getMessage()); + } finally { + if (secondaryPool != null) { + storagePoolMgr.deleteStoragePool(secondaryPool.getType(), secondaryPool.getUuid()); + } + if (snapshotPool != null) { + storagePoolMgr.deleteStoragePool(snapshotPool.getType(), snapshotPool.getUuid()); + } + } + } +} \ 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 2656037f456..7e732640c50 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 @@ -30,6 +30,7 @@ import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; @@ -142,6 +143,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CreatePrivateTemplateFromVolumeCommand.class, new LibvirtCreatePrivateTemplateFromVolumeCommandWrapper()); linbvirtCommands.put(ManageSnapshotCommand.class, new LibvirtManageSnapshotCommandWrapper()); linbvirtCommands.put(BackupSnapshotCommand.class, new LibvirtBackupSnapshotCommandWrapper()); + linbvirtCommands.put(CreatePrivateTemplateFromSnapshotCommand.class, new LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper()); 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 b0c273404b7..5f9c50ad012 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 @@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; @@ -37,6 +38,7 @@ import java.util.List; import java.util.Random; import java.util.UUID; +import javax.naming.ConfigurationException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathConstants; @@ -72,6 +74,7 @@ import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; +import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; @@ -139,8 +142,12 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkSetupInfo; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.StorageLayer; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.Processor.FormatInfo; +import com.cloud.storage.template.TemplateLocation; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; @@ -3536,4 +3543,351 @@ public class LibvirtComputingResourceTest { fail(e.getMessage()); } } + + @Test + public void testCreatePrivateTemplateFromSnapshotCommand() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final String templatePath = "/template/path"; + final String localPath = "/mnt/local"; + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final StorageLayer storage = Mockito.mock(StorageLayer.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final TemplateLocation location = Mockito.mock(TemplateLocation.class); + final Processor qcow2Processor = Mockito.mock(Processor.class); + final FormatInfo info = Mockito.mock(FormatInfo.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(secondaryPool.getLocalPath()).thenReturn(localPath); + when(libvirtComputingResource.getStorage()).thenReturn(storage); + + when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath); + when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + try { + when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); + } catch (final ConfigurationException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromSnapshotCommandConfigurationException() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final String templatePath = "/template/path"; + final String localPath = "/mnt/local"; + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final StorageLayer storage = Mockito.mock(StorageLayer.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final TemplateLocation location = Mockito.mock(TemplateLocation.class); + final Processor qcow2Processor = Mockito.mock(Processor.class); + final FormatInfo info = Mockito.mock(FormatInfo.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(secondaryPool.getLocalPath()).thenReturn(localPath); + when(libvirtComputingResource.getStorage()).thenReturn(storage); + + when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath); + when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + try { + when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenThrow(ConfigurationException.class); + when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); + } catch (final ConfigurationException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromSnapshotCommandInternalErrorException() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final String templatePath = "/template/path"; + final String localPath = "/mnt/local"; + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final StorageLayer storage = Mockito.mock(StorageLayer.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final TemplateLocation location = Mockito.mock(TemplateLocation.class); + final Processor qcow2Processor = Mockito.mock(Processor.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(secondaryPool.getLocalPath()).thenReturn(localPath); + when(libvirtComputingResource.getStorage()).thenReturn(storage); + + when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath); + when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + try { + when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(qcow2Processor.process(tmplPath, null, tmplName)).thenThrow(InternalErrorException.class); + } catch (final ConfigurationException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromSnapshotCommandIOException() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final String templatePath = "/template/path"; + final String localPath = "/mnt/local"; + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); + final StorageLayer storage = Mockito.mock(StorageLayer.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final TemplateLocation location = Mockito.mock(TemplateLocation.class); + final Processor qcow2Processor = Mockito.mock(Processor.class); + final FormatInfo info = Mockito.mock(FormatInfo.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).thenReturn(snapshot); + when(secondaryPool.getLocalPath()).thenReturn(localPath); + when(libvirtComputingResource.getStorage()).thenReturn(storage); + + when(libvirtComputingResource.createTmplPath()).thenReturn(templatePath); + when(libvirtComputingResource.getCmdsTimeout()).thenReturn(1); + + final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); + final String templateInstallFolder = "template/tmpl/" + templateFolder; + final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + try { + when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); + + when(location.create(1, true, tmplName)).thenThrow(IOException.class); + + } catch (final ConfigurationException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final IOException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreatePrivateTemplateFromSnapshotCommandCloudRuntime() { + final StoragePool pool = Mockito.mock(StoragePool.class); + final String secondaryStoragePoolURL = "nfs:/192.168.2.2/storage/secondary"; + final Long dcId = 1l; + final Long accountId = 1l; + final Long volumeId = 1l; + final String backedUpSnapshotUuid = "/run/9a0afe7c-26a7-4585-bf87-abf82ae106d9/"; + final String backedUpSnapshotName = "snap"; + final String origTemplateInstallPath = "/install/path/"; + final Long newTemplateId = 2l; + final String templateName = "templ"; + final int wait = 0; + + final CreatePrivateTemplateFromSnapshotCommand command = new CreatePrivateTemplateFromSnapshotCommand(pool, secondaryStoragePoolURL, dcId, accountId, volumeId, backedUpSnapshotUuid, backedUpSnapshotName, origTemplateInstallPath, newTemplateId, templateName, wait); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); + final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); + final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + + final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + + String snapshotPath = command.getSnapshotUuid(); + final int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); + when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); + when(snapshotPool.getPhysicalDisk(command.getSnapshotName())).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(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath); + verify(storagePoolMgr, times(1)).getStoragePoolByURI(command.getSecondaryStorageUrl()); + } } \ No newline at end of file From 885b9e45d767d9c1e97f9f89323733446b0815f0 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Tue, 5 May 2015 13:44:52 +0200 Subject: [PATCH 28/36] Renaming LibvirtConnectionWrapper to LibvirtUtilitiesHelper - Gave it a better, more suggestive, name since I now added other methods to the class. - It makes easier to mock objects and get a better coverage of the classes --- .../spring-kvm-compute-context.xml | 4 +- .../resource/LibvirtComputingResource.java | 8 +- .../LibvirtAttachIsoCommandWrapper.java | 4 +- .../LibvirtAttachVolumeCommandWrapper.java | 4 +- .../LibvirtBackupSnapshotCommandWrapper.java | 4 +- ...virtCheckVirtualMachineCommandWrapper.java | 4 +- ...ateTemplateFromSnapshotCommandWrapper.java | 8 +- .../LibvirtGetVmDiskStatsCommandWrapper.java | 4 +- .../LibvirtGetVmStatsCommandWrapper.java | 4 +- .../LibvirtGetVncPortCommandWrapper.java | 4 +- .../LibvirtManageSnapshotCommandWrapper.java | 4 +- .../wrapper/LibvirtMigrateCommandWrapper.java | 4 +- ...irtNetworkRulesSystemVmCommandWrapper.java | 4 +- ...tworkRulesVmSecondaryIpCommandWrapper.java | 4 +- .../wrapper/LibvirtPlugNicCommandWrapper.java | 4 +- ...virtPrepareForMigrationCommandWrapper.java | 4 +- .../wrapper/LibvirtRebootCommandWrapper.java | 4 +- ...bvirtSecurityGroupRulesCommandWrapper.java | 4 +- .../wrapper/LibvirtStopCommandWrapper.java | 6 +- .../LibvirtUnPlugNicCommandWrapper.java | 4 +- ...apper.java => LibvirtUtilitiesHelper.java} | 2 +- .../LibvirtComputingResourceTest.java | 376 +++++++++--------- 22 files changed, 234 insertions(+), 234 deletions(-) rename plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/{LibvirtConnectionWrapper.java => LibvirtUtilitiesHelper.java} (98%) diff --git a/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml b/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml index de6853e3b9d..10f33ec6322 100644 --- a/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml +++ b/plugins/hypervisors/kvm/resources/META-INF/cloudstack/kvm-compute/spring-kvm-compute-context.xml @@ -31,7 +31,7 @@ - + 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 977288b2c86..a9410fb1c32 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 @@ -119,7 +119,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VirtioSerialDef; -import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; +import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; import com.cloud.hypervisor.kvm.storage.KVMStoragePool; @@ -272,7 +272,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected int _stopTimeout; @Inject - private LibvirtConnectionWrapper libvirtConnectionWrapper; + private LibvirtUtilitiesHelper libvirtUtilitiesHelper; @Override public ExecutionResult executeInVR(final String routerIp, final String script, final String args) { @@ -335,8 +335,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ExecutionResult(true, null); } - public LibvirtConnectionWrapper getLibvirtConnectionWrapper() { - return libvirtConnectionWrapper; + public LibvirtUtilitiesHelper getLibvirtConnectionWrapper() { + return libvirtUtilitiesHelper; } public VirtualRoutingResource getVirtRouterResource() { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java index 4380b666494..9c128456d33 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java @@ -35,9 +35,9 @@ public final class LibvirtAttachIsoCommandWrapper extends CommandWrapper vmNames = command.getVmNames(); - final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtConnectionWrapper(); try { final HashMap> vmDiskStatsNameMap = new HashMap>(); - final Connect conn = libvirtConnectionWrapper.getConnection(); + final Connect conn = libvirtUtilitiesHelper.getConnection(); for (final String vmName : vmNames) { final List statEntry = libvirtComputingResource.getVmDiskStat(conn, vmName); if (statEntry == null) { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java index e0649dae837..f1ddca1d14a 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java @@ -44,9 +44,9 @@ public final class LibvirtGetVmStatsCommandWrapper extends CommandWrapper vmStatsNameMap = new HashMap(); for (final String vmName : vmNames) { - final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtConnectionWrapper(); - final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(vmName); + final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName); final VmStatsEntry statEntry = libvirtComputingResource.getVmStat(conn, vmName); if (statEntry == null) { continue; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java index 9b76374d4c3..d7c182088ca 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java @@ -33,9 +33,9 @@ public final class LibvirtGetVncPortCommandWrapper extends CommandWrapper " + e.getLocalizedMessage()); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java index 7e6f642964a..692f79e7777 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPlugNicCommandWrapper.java @@ -46,8 +46,8 @@ public final class LibvirtPlugNicCommandWrapper extends CommandWrapper pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java index 108b0d2f3d7..b9bf770a5a8 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPrepareForMigrationCommandWrapper.java @@ -54,9 +54,9 @@ public final class LibvirtPrepareForMigrationCommandWrapper extends CommandWrapp final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); try { - final LibvirtConnectionWrapper libvirtConnectionWrapper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtConnectionWrapper(); - final Connect conn = libvirtConnectionWrapper.getConnectionByVmName(vm.getName()); + final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vm.getName()); for (final NicTO nic : nics) { libvirtComputingResource.getVifDriver(nic.getType()).plug(nic, null, ""); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java index e91604a7399..414fcd661a2 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRebootCommandWrapper.java @@ -35,10 +35,10 @@ public final class LibvirtRebootCommandWrapper extends CommandWrapper nics = libvirtComputingResource.getInterfaces(conn, command.getVmName()); vif = nics.get(0).getDevName(); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java index 280c7f1e7de..0d5f8920f52 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java @@ -44,11 +44,11 @@ public final class LibvirtStopCommandWrapper extends CommandWrapper disks = libvirtComputingResource.getDisks(conn, vmName); final List ifaces = libvirtComputingResource.getInterfaces(conn, vmName); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java index 4ce14f2c824..b3016fa0f5c 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUnPlugNicCommandWrapper.java @@ -45,9 +45,9 @@ public final class LibvirtUnPlugNicCommandWrapper extends CommandWrapper pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java similarity index 98% rename from plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java rename to plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java index 3a51a37e376..5930bf0015b 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtConnectionWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java @@ -37,7 +37,7 @@ import com.cloud.storage.template.TemplateLocation; * * Please do not instantiate this class directly, but inject it using the {@code @Inject} annotation. */ -public class LibvirtConnectionWrapper { +public class LibvirtUtilitiesHelper { public Connect getConnectionByVmName(final String vmName) throws LibvirtException { return LibvirtConnection.getConnectionByVmName(vmName); 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 5f9c50ad012..1504f707d35 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 @@ -133,7 +133,7 @@ import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.kvm.resource.KVMHABase.NfsStoragePool; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; -import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtConnectionWrapper; +import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; import com.cloud.hypervisor.kvm.storage.KVMStoragePool; @@ -475,14 +475,14 @@ public class LibvirtComputingResourceTest { @Test public void testStopCommandNoCheck() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final StopCommand command = new StopCommand(vmName, false, false); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -496,7 +496,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -505,15 +505,15 @@ public class LibvirtComputingResourceTest { @Test public void testStopCommandCheck() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Domain domain = Mockito.mock(Domain.class); final String vmName = "Test"; final StopCommand command = new StopCommand(vmName, false, true); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); when(conn.domainLookupByName(command.getVmName())).thenReturn(domain); } catch (final LibvirtException e) { fail(e.getMessage()); @@ -528,7 +528,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(2)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(2)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -537,7 +537,7 @@ public class LibvirtComputingResourceTest { @Test public void testGetVmStatsCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; @@ -546,9 +546,9 @@ public class LibvirtComputingResourceTest { final GetVmStatsCommand command = new GetVmStatsCommand(vms, uuid, "hostname"); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -561,7 +561,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -570,7 +570,7 @@ public class LibvirtComputingResourceTest { @Test public void testGetVmDiskStatsCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; @@ -579,9 +579,9 @@ public class LibvirtComputingResourceTest { final GetVmDiskStatsCommand command = new GetVmDiskStatsCommand(vms, uuid, "hostname"); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnection()).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnection()).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -594,7 +594,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnection(); + verify(libvirtUtilitiesHelper, times(1)).getConnection(); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -604,7 +604,7 @@ public class LibvirtComputingResourceTest { @Test public void testGetVmDiskStatsCommandException() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6"; @@ -613,9 +613,9 @@ public class LibvirtComputingResourceTest { final GetVmDiskStatsCommand command = new GetVmDiskStatsCommand(vms, uuid, "hostname"); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnection()).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnection()).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -628,7 +628,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnection(); + verify(libvirtUtilitiesHelper, times(1)).getConnection(); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -637,14 +637,14 @@ public class LibvirtComputingResourceTest { @Test public void testRebootCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final RebootCommand command = new RebootCommand(vmName); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -657,7 +657,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -667,15 +667,15 @@ public class LibvirtComputingResourceTest { public void testRebootRouterCommand() { final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class); final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final RebootRouterCommand command = new RebootRouterCommand(vmName, "192.168.0.10"); when(libvirtComputingResource.getVirtRouterResource()).thenReturn(routingResource); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -690,7 +690,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -700,16 +700,16 @@ public class LibvirtComputingResourceTest { public void testRebootRouterCommandConnect() { final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class); final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final RebootRouterCommand command = new RebootRouterCommand(vmName, "192.168.0.10"); when(libvirtComputingResource.getVirtRouterResource()).thenReturn(routingResource); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(routingResource.connect(command.getPrivateIpAddress())).thenReturn(true); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -723,7 +723,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getVirtRouterResource(); verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -758,7 +758,7 @@ public class LibvirtComputingResourceTest { @Test public void testPrepareForMigrationCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); @@ -768,9 +768,9 @@ public class LibvirtComputingResourceTest { final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -792,7 +792,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -806,7 +806,7 @@ public class LibvirtComputingResourceTest { @Test public void testPrepareForMigrationCommandMigration() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); @@ -816,9 +816,9 @@ public class LibvirtComputingResourceTest { final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -841,7 +841,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -855,7 +855,7 @@ public class LibvirtComputingResourceTest { @SuppressWarnings("unchecked") @Test public void testPrepareForMigrationCommandLibvirtException() { - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); @@ -864,9 +864,9 @@ public class LibvirtComputingResourceTest { final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -885,7 +885,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -898,7 +898,7 @@ public class LibvirtComputingResourceTest { @Test public void testPrepareForMigrationCommandURISyntaxException() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); @@ -908,9 +908,9 @@ public class LibvirtComputingResourceTest { final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -939,7 +939,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -954,7 +954,7 @@ public class LibvirtComputingResourceTest { @Test public void testPrepareForMigrationCommandInternalErrorException() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); final KVMStoragePoolManager storagePoolManager = Mockito.mock(KVMStoragePoolManager.class); @@ -963,9 +963,9 @@ public class LibvirtComputingResourceTest { final PrepareForMigrationCommand command = new PrepareForMigrationCommand(vm); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vm.getName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vm.getName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -991,7 +991,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vm.getName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vm.getName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1007,7 +1007,7 @@ public class LibvirtComputingResourceTest { // Will keep it expecting the UnsatisfiedLinkError and fix later. final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final String destIp = "10.1.1.100"; @@ -1017,9 +1017,9 @@ public class LibvirtComputingResourceTest { final MigrateCommand command = new MigrateCommand(vmName, destIp, isWindows, vmTO, executeInSequence ); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1058,7 +1058,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1109,14 +1109,14 @@ public class LibvirtComputingResourceTest { @Test public void testCheckVirtualMachineCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final CheckVirtualMachineCommand command = new CheckVirtualMachineCommand(vmName); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1131,7 +1131,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1141,14 +1141,14 @@ public class LibvirtComputingResourceTest { @Test public void testExceptionCheckVirtualMachineCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final CheckVirtualMachineCommand command = new CheckVirtualMachineCommand(vmName); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1163,7 +1163,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1183,14 +1183,14 @@ public class LibvirtComputingResourceTest { @Test public void testAttachIsoCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1203,7 +1203,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1212,14 +1212,14 @@ public class LibvirtComputingResourceTest { @SuppressWarnings("unchecked") @Test public void testAttachIsoCommandLibvirtException() { - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1232,7 +1232,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1241,14 +1241,14 @@ public class LibvirtComputingResourceTest { @SuppressWarnings("unchecked") @Test public void testAttachIsoCommandURISyntaxException() { - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(URISyntaxException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(URISyntaxException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1261,7 +1261,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1270,14 +1270,14 @@ public class LibvirtComputingResourceTest { @SuppressWarnings("unchecked") @Test public void testAttachIsoCommandInternalErrorException() { - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; final AttachIsoCommand command = new AttachIsoCommand(vmName, "/path", true); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(InternalErrorException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(InternalErrorException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1290,7 +1290,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1299,7 +1299,7 @@ public class LibvirtComputingResourceTest { @Test public void testAttachVolumeCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final boolean attach = true; final boolean managed = true; @@ -1316,9 +1316,9 @@ public class LibvirtComputingResourceTest { final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1335,7 +1335,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1344,7 +1344,7 @@ public class LibvirtComputingResourceTest { @SuppressWarnings("unchecked") @Test public void testAttachVolumeCommandLibvirtException() { - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final boolean attach = true; final boolean managed = true; @@ -1361,9 +1361,9 @@ public class LibvirtComputingResourceTest { final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1380,7 +1380,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1389,7 +1389,7 @@ public class LibvirtComputingResourceTest { @SuppressWarnings("unchecked") @Test public void testAttachVolumeCommandInternalErrorException() { - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final boolean attach = true; final boolean managed = true; @@ -1406,9 +1406,9 @@ public class LibvirtComputingResourceTest { final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class); final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(vmName)).thenThrow(InternalErrorException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(InternalErrorException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1425,7 +1425,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(vmName); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1467,13 +1467,13 @@ public class LibvirtComputingResourceTest { @Test public void testGetVncPortCommand() { final Connect conn = Mockito.mock(Connect.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final GetVncPortCommand command = new GetVncPortCommand(1l, "host"); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1486,7 +1486,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1495,13 +1495,13 @@ public class LibvirtComputingResourceTest { @SuppressWarnings("unchecked") @Test public void testGetVncPortCommandLibvirtException() { - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final GetVncPortCommand command = new GetVncPortCommand(1l, "host"); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -1514,7 +1514,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2242,12 +2242,12 @@ public class LibvirtComputingResourceTest { final NetworkRulesVmSecondaryIpCommand command = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, action ); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2260,7 +2260,7 @@ public class LibvirtComputingResourceTest { assertTrue(answer.getResult()); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2278,11 +2278,11 @@ public class LibvirtComputingResourceTest { final NetworkRulesVmSecondaryIpCommand command = new NetworkRulesVmSecondaryIpCommand(vmName, vmMac, secondaryIp, action ); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2293,7 +2293,7 @@ public class LibvirtComputingResourceTest { assertFalse(answer.getResult()); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2307,12 +2307,12 @@ public class LibvirtComputingResourceTest { final NetworkRulesSystemVmCommand command = new NetworkRulesSystemVmCommand(vmName, type); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2325,7 +2325,7 @@ public class LibvirtComputingResourceTest { assertTrue(answer.getResult()); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2341,11 +2341,11 @@ public class LibvirtComputingResourceTest { final NetworkRulesSystemVmCommand command = new NetworkRulesSystemVmCommand(vmName, type); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2357,7 +2357,7 @@ public class LibvirtComputingResourceTest { assertFalse(answer.getResult()); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2799,17 +2799,17 @@ public class LibvirtComputingResourceTest { final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); final List nics = new ArrayList(); final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); nics.add(interfaceDef); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2832,7 +2832,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2851,17 +2851,17 @@ public class LibvirtComputingResourceTest { final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); final List nics = new ArrayList(); final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); nics.add(interfaceDef); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2893,7 +2893,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2913,17 +2913,17 @@ public class LibvirtComputingResourceTest { final SecurityGroupRulesCmd command = new SecurityGroupRulesCmd(guestIp, guestMac, vmName, vmId, signature, seqNum, ingressRuleSet, egressRuleSet); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); final List nics = new ArrayList(); final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); nics.add(interfaceDef); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2936,7 +2936,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -2950,7 +2950,7 @@ public class LibvirtComputingResourceTest { final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); final Domain vm = Mockito.mock(Domain.class); @@ -2958,7 +2958,7 @@ public class LibvirtComputingResourceTest { final InterfaceDef intDef = Mockito.mock(InterfaceDef.class); nics.add(intDef); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); when(intDef.getDevName()).thenReturn("eth0"); @@ -2968,7 +2968,7 @@ public class LibvirtComputingResourceTest { when(nic.getMac()).thenReturn("00:00:00:00"); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); } catch (final LibvirtException e) { fail(e.getMessage()); @@ -2982,7 +2982,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); } catch (final LibvirtException e) { fail(e.getMessage()); @@ -2997,7 +2997,7 @@ public class LibvirtComputingResourceTest { final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); final Domain vm = Mockito.mock(Domain.class); final VifDriver vifDriver = Mockito.mock(VifDriver.class); @@ -3007,7 +3007,7 @@ public class LibvirtComputingResourceTest { final InterfaceDef intDef = Mockito.mock(InterfaceDef.class); nics.add(intDef); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); when(intDef.getDevName()).thenReturn("eth0"); @@ -3017,7 +3017,7 @@ public class LibvirtComputingResourceTest { when(nic.getMac()).thenReturn("00:00:00:01"); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); when(libvirtComputingResource.getVifDriver(nic.getType())).thenReturn(vifDriver); @@ -3042,7 +3042,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType()); verify(vifDriver, times(1)).plug(nic, "Other PV", ""); @@ -3062,12 +3062,12 @@ public class LibvirtComputingResourceTest { final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -3080,7 +3080,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -3095,7 +3095,7 @@ public class LibvirtComputingResourceTest { final PlugNicCommand command = new PlugNicCommand(nic, instanceName, vmtype); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); final Domain vm = Mockito.mock(Domain.class); final VifDriver vifDriver = Mockito.mock(VifDriver.class); @@ -3104,7 +3104,7 @@ public class LibvirtComputingResourceTest { final InterfaceDef intDef = Mockito.mock(InterfaceDef.class); nics.add(intDef); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); when(intDef.getDevName()).thenReturn("eth0"); @@ -3114,7 +3114,7 @@ public class LibvirtComputingResourceTest { when(nic.getMac()).thenReturn("00:00:00:01"); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); when(libvirtComputingResource.getVifDriver(nic.getType())).thenReturn(vifDriver); @@ -3135,7 +3135,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); verify(libvirtComputingResource, times(1)).getVifDriver(nic.getType()); verify(vifDriver, times(1)).plug(nic, "Other PV", ""); @@ -3153,7 +3153,7 @@ public class LibvirtComputingResourceTest { final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); final Domain vm = Mockito.mock(Domain.class); final InterfaceDef interfaceDef = Mockito.mock(InterfaceDef.class); @@ -3166,7 +3166,7 @@ public class LibvirtComputingResourceTest { final List drivers = new ArrayList(); drivers.add(vifDriver); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); when(intDef.getDevName()).thenReturn("eth0"); @@ -3176,7 +3176,7 @@ public class LibvirtComputingResourceTest { when(nic.getMac()).thenReturn("00:00:00:00"); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); when(interfaceDef.toString()).thenReturn("Interface"); @@ -3200,7 +3200,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); verify(libvirtComputingResource, times(1)).getAllVifDrivers(); } catch (final LibvirtException e) { @@ -3215,7 +3215,7 @@ public class LibvirtComputingResourceTest { final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final Connect conn = Mockito.mock(Connect.class); final Domain vm = Mockito.mock(Domain.class); @@ -3225,11 +3225,11 @@ public class LibvirtComputingResourceTest { final List drivers = new ArrayList(); drivers.add(vifDriver); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenReturn(conn); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenReturn(conn); when(libvirtComputingResource.getDomain(conn, instanceName)).thenReturn(vm); } catch (final LibvirtException e) { fail(e.getMessage()); @@ -3243,7 +3243,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); } catch (final LibvirtException e) { fail(e.getMessage()); @@ -3258,12 +3258,12 @@ public class LibvirtComputingResourceTest { final UnPlugNicCommand command = new UnPlugNicCommand(nic, instanceName); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -3276,7 +3276,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -3468,13 +3468,13 @@ public class LibvirtComputingResourceTest { final ManageSnapshotCommand command = new ManageSnapshotCommand(snapshotId, volumePath, pool, preSnapshotPath, snapshotName, vmName); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); //final Connect conn = Mockito.mock(Connect.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -3487,7 +3487,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -3519,13 +3519,13 @@ public class LibvirtComputingResourceTest { final BackupSnapshotCommand command = new BackupSnapshotCommand(secondaryStorageUrl, dcId, accountId, volumeId, snapshotId, secHostId, volumePath, pool, snapshotUuid, snapshotName, prevSnapshotUuid, prevBackupUuid, isVolumeInactive, vmName, wait); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); //final Connect conn = Mockito.mock(Connect.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); try { - when(libvirtConnectionWrapper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); + when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -3538,7 +3538,7 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); try { - verify(libvirtConnectionWrapper, times(1)).getConnectionByVmName(command.getVmName()); + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -3569,7 +3569,7 @@ public class LibvirtComputingResourceTest { final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); final StorageLayer storage = Mockito.mock(StorageLayer.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final TemplateLocation location = Mockito.mock(TemplateLocation.class); final Processor qcow2Processor = Mockito.mock(Processor.class); final FormatInfo info = Mockito.mock(FormatInfo.class); @@ -3593,12 +3593,12 @@ public class LibvirtComputingResourceTest { final String templateInstallFolder = "template/tmpl/" + templateFolder; final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); - when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); - when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); try { - when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); } catch (final ConfigurationException e) { fail(e.getMessage()); @@ -3643,7 +3643,7 @@ public class LibvirtComputingResourceTest { final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); final StorageLayer storage = Mockito.mock(StorageLayer.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final TemplateLocation location = Mockito.mock(TemplateLocation.class); final Processor qcow2Processor = Mockito.mock(Processor.class); final FormatInfo info = Mockito.mock(FormatInfo.class); @@ -3667,12 +3667,12 @@ public class LibvirtComputingResourceTest { final String templateInstallFolder = "template/tmpl/" + templateFolder; final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); - when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); - when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); try { - when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenThrow(ConfigurationException.class); + when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenThrow(ConfigurationException.class); when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); } catch (final ConfigurationException e) { fail(e.getMessage()); @@ -3717,7 +3717,7 @@ public class LibvirtComputingResourceTest { final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); final StorageLayer storage = Mockito.mock(StorageLayer.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final TemplateLocation location = Mockito.mock(TemplateLocation.class); final Processor qcow2Processor = Mockito.mock(Processor.class); @@ -3740,12 +3740,12 @@ public class LibvirtComputingResourceTest { final String templateInstallFolder = "template/tmpl/" + templateFolder; final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); - when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); - when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); try { - when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); when(qcow2Processor.process(tmplPath, null, tmplName)).thenThrow(InternalErrorException.class); } catch (final ConfigurationException e) { fail(e.getMessage()); @@ -3790,7 +3790,7 @@ public class LibvirtComputingResourceTest { final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); final KVMPhysicalDisk snapshot = Mockito.mock(KVMPhysicalDisk.class); final StorageLayer storage = Mockito.mock(StorageLayer.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final TemplateLocation location = Mockito.mock(TemplateLocation.class); final Processor qcow2Processor = Mockito.mock(Processor.class); final FormatInfo info = Mockito.mock(FormatInfo.class); @@ -3814,12 +3814,12 @@ public class LibvirtComputingResourceTest { final String templateInstallFolder = "template/tmpl/" + templateFolder; final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); - when(libvirtConnectionWrapper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); - when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); + when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); try { - when(libvirtConnectionWrapper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); + when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); when(qcow2Processor.process(tmplPath, null, tmplName)).thenReturn(info); when(location.create(1, true, tmplName)).thenThrow(IOException.class); @@ -3863,7 +3863,7 @@ public class LibvirtComputingResourceTest { final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); final KVMStoragePool secondaryPool = Mockito.mock(KVMStoragePool.class); final KVMStoragePool snapshotPool = Mockito.mock(KVMStoragePool.class); - final LibvirtConnectionWrapper libvirtConnectionWrapper = Mockito.mock(LibvirtConnectionWrapper.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String tmplName = "ce97bbc1-34fe-4259-9202-74bbce2562ab"; @@ -3873,8 +3873,8 @@ public class LibvirtComputingResourceTest { final int index = snapshotPath.lastIndexOf("/"); snapshotPath = snapshotPath.substring(0, index); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtConnectionWrapper); - when(libvirtConnectionWrapper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); From 0b1b2b6d925ec919e5b467ce5da1fc91f60673cb Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 6 May 2015 07:38:51 +0200 Subject: [PATCH 29/36] Refactoring the LibvirtComputingResource - Adding LibvirtCopyVolumeCommandWrapper Refactoring the LibvirtUtilitiesHelper - Changing method name Did not add any test to this commit due to the refactor mentioned abot. Will proceed and add the tests i# Please enter the commit message for your changes. Lines starting --- .../resource/LibvirtComputingResource.java | 63 +----- .../LibvirtAttachIsoCommandWrapper.java | 2 +- .../LibvirtAttachVolumeCommandWrapper.java | 2 +- .../LibvirtBackupSnapshotCommandWrapper.java | 2 +- ...virtCheckVirtualMachineCommandWrapper.java | 2 +- .../LibvirtCopyVolumeCommandWrapper.java | 99 ++++++++++ ...ateTemplateFromSnapshotCommandWrapper.java | 4 +- .../LibvirtGetVmDiskStatsCommandWrapper.java | 2 +- .../LibvirtGetVmStatsCommandWrapper.java | 2 +- .../LibvirtGetVncPortCommandWrapper.java | 2 +- .../LibvirtManageSnapshotCommandWrapper.java | 2 +- .../wrapper/LibvirtMigrateCommandWrapper.java | 2 +- ...irtNetworkRulesSystemVmCommandWrapper.java | 2 +- ...tworkRulesVmSecondaryIpCommandWrapper.java | 2 +- .../wrapper/LibvirtPlugNicCommandWrapper.java | 2 +- ...virtPrepareForMigrationCommandWrapper.java | 2 +- .../wrapper/LibvirtRebootCommandWrapper.java | 2 +- .../wrapper/LibvirtRequestWrapper.java | 2 + ...bvirtSecurityGroupRulesCommandWrapper.java | 2 +- .../wrapper/LibvirtStopCommandWrapper.java | 2 +- .../LibvirtUnPlugNicCommandWrapper.java | 2 +- .../wrapper/LibvirtUtilitiesHelper.java | 2 +- .../LibvirtComputingResourceTest.java | 184 +++++++++--------- 23 files changed, 215 insertions(+), 173 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java 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 a9410fb1c32..8b74b1c3b58 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 @@ -81,8 +81,6 @@ import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; 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.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; @@ -119,8 +117,8 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VideoDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VirtioSerialDef; -import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper; import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper; +import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; import com.cloud.hypervisor.kvm.storage.KVMStoragePool; import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; @@ -335,7 +333,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return new ExecutionResult(true, null); } - public LibvirtUtilitiesHelper getLibvirtConnectionWrapper() { + public LibvirtUtilitiesHelper getLibvirtUtilitiesHelper() { return libvirtUtilitiesHelper; } @@ -1250,8 +1248,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((StartCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest((NetworkElementCommand)cmd); - } else if (cmd instanceof CopyVolumeCommand) { - return execute((CopyVolumeCommand)cmd); } else if (cmd instanceof ResizeVolumeCommand) { return execute((ResizeVolumeCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { @@ -1343,61 +1339,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - private CopyVolumeAnswer execute(final CopyVolumeCommand cmd) { - /** - This method is only used for copying files from Primary Storage TO Secondary Storage - - It COULD also do it the other way around, but the code in the ManagementServerImpl shows - that it always sets copyToSecondary to true - - */ - final boolean copyToSecondary = cmd.toSecondaryStorage(); - String volumePath = cmd.getVolumePath(); - final StorageFilerTO pool = cmd.getPool(); - final String secondaryStorageUrl = cmd.getSecondaryStorageURL(); - KVMStoragePool secondaryStoragePool = null; - KVMStoragePool primaryPool = null; - try { - try { - primaryPool = _storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid()); - } catch (final CloudRuntimeException e) { - if (e.getMessage().contains("not found")) { - primaryPool = - _storagePoolMgr.createStoragePool(cmd.getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(), cmd.getPool().getPath(), - cmd.getPool().getUserInfo(), cmd.getPool().getType()); - } else { - return new CopyVolumeAnswer(cmd, false, e.getMessage(), null, null); - } - } - - final String volumeName = UUID.randomUUID().toString(); - - if (copyToSecondary) { - final String destVolumeName = volumeName + ".qcow2"; - final KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(cmd.getVolumePath()); - final String volumeDestPath = "/volumes/" + cmd.getVolumeId() + File.separator; - secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl); - secondaryStoragePool.createFolder(volumeDestPath); - _storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid()); - secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumeDestPath); - _storagePoolMgr.copyPhysicalDisk(volume, destVolumeName, secondaryStoragePool, 0); - return new CopyVolumeAnswer(cmd, true, null, null, volumeName); - } else { - volumePath = "/volumes/" + cmd.getVolumeId() + File.separator; - secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumePath); - final KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(cmd.getVolumePath() + ".qcow2"); - _storagePoolMgr.copyPhysicalDisk(volume, volumeName, primaryPool, 0); - return new CopyVolumeAnswer(cmd, true, null, null, volumeName); - } - } catch (final CloudRuntimeException e) { - return new CopyVolumeAnswer(cmd, false, e.toString(), null, null); - } finally { - if (secondaryStoragePool != null) { - _storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid()); - } - } - } - protected Storage.StorageResourceType getStorageResourceType() { return Storage.StorageResourceType.STORAGE_POOL; } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java index 9c128456d33..a85ea54ebf7 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtAttachIsoCommandWrapper.java @@ -35,7 +35,7 @@ public final class LibvirtAttachIsoCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CopyVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { + /** + This method is only used for copying files from Primary Storage TO Secondary Storage + + It COULD also do it the other way around, but the code in the ManagementServerImpl shows + that it always sets copyToSecondary to true + + */ + final boolean copyToSecondary = command.toSecondaryStorage(); + String volumePath = command.getVolumePath(); + final StorageFilerTO pool = command.getPool(); + final String secondaryStorageUrl = command.getSecondaryStorageURL(); + KVMStoragePool secondaryStoragePool = null; + KVMStoragePool primaryPool = null; + + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + try { + try { + primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid()); + } catch (final CloudRuntimeException e) { + if (e.getMessage().contains("not found")) { + primaryPool = + storagePoolMgr.createStoragePool(command.getPool().getUuid(), command.getPool().getHost(), command.getPool().getPort(), command.getPool().getPath(), + command.getPool().getUserInfo(), command.getPool().getType()); + } else { + return new CopyVolumeAnswer(command, false, e.getMessage(), null, null); + } + } + + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); + final String volumeName = libvirtUtilitiesHelper.generatereUUIDName(); + + if (copyToSecondary) { + final String destVolumeName = volumeName + ".qcow2"; + final KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(command.getVolumePath()); + final String volumeDestPath = "/volumes/" + command.getVolumeId() + File.separator; + + secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl); + secondaryStoragePool.createFolder(volumeDestPath); + storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid()); + secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumeDestPath); + storagePoolMgr.copyPhysicalDisk(volume, destVolumeName, secondaryStoragePool, 0); + + return new CopyVolumeAnswer(command, true, null, null, volumeName); + } else { + volumePath = "/volumes/" + command.getVolumeId() + File.separator; + secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStorageUrl + volumePath); + + final KVMPhysicalDisk volume = secondaryStoragePool.getPhysicalDisk(command.getVolumePath() + ".qcow2"); + storagePoolMgr.copyPhysicalDisk(volume, volumeName, primaryPool, 0); + + return new CopyVolumeAnswer(command, true, null, null, volumeName); + } + } catch (final CloudRuntimeException e) { + return new CopyVolumeAnswer(command, false, e.toString(), null, null); + } finally { + if (secondaryStoragePool != null) { + storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(), secondaryStoragePool.getUuid()); + } + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java index 0778586437f..35c14f86dcd 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper.java @@ -48,11 +48,11 @@ public final class LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper extend @Override public Answer execute(final CreatePrivateTemplateFromSnapshotCommand command, final LibvirtComputingResource libvirtComputingResource) { - final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); final String templateFolder = command.getAccountId() + File.separator + command.getNewTemplateId(); final String templateInstallFolder = "template/tmpl/" + templateFolder; - final String tmplName = libvirtUtilitiesHelper.buildTemplateUUIDName(); + final String tmplName = libvirtUtilitiesHelper.generatereUUIDName(); final String tmplFileName = tmplName + ".qcow2"; KVMStoragePool secondaryPool = null; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java index 7c76833ff31..4a8ee49b88d 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmDiskStatsCommandWrapper.java @@ -40,7 +40,7 @@ public final class LibvirtGetVmDiskStatsCommandWrapper extends CommandWrapper vmNames = command.getVmNames(); - final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); try { final HashMap> vmDiskStatsNameMap = new HashMap>(); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java index f1ddca1d14a..2e6f0a78d1f 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmStatsCommandWrapper.java @@ -44,7 +44,7 @@ public final class LibvirtGetVmStatsCommandWrapper extends CommandWrapper vmStatsNameMap = new HashMap(); for (final String vmName : vmNames) { - final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtConnectionWrapper(); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName); final VmStatsEntry statEntry = libvirtComputingResource.getVmStat(conn, vmName); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java index d7c182088ca..abd9bf9ad0e 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVncPortCommandWrapper.java @@ -33,7 +33,7 @@ public final class LibvirtGetVncPortCommandWrapper extends CommandWrapper nics = libvirtComputingResource.getInterfaces(conn, command.getVmName()); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java index 0d5f8920f52..59a44fc01ea 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStopCommandWrapper.java @@ -44,7 +44,7 @@ public final class LibvirtStopCommandWrapper extends CommandWrapper drivers = new ArrayList(); drivers.add(vifDriver); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); when(intDef.getDevName()).thenReturn("eth0"); @@ -3198,7 +3198,7 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); - verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); try { verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); @@ -3225,7 +3225,7 @@ public class LibvirtComputingResourceTest { final List drivers = new ArrayList(); drivers.add(vifDriver); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); when(libvirtComputingResource.getInterfaces(conn, command.getVmName())).thenReturn(nics); try { @@ -3241,7 +3241,7 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); - verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); try { verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); verify(libvirtComputingResource, times(1)).getDomain(conn, instanceName); @@ -3260,7 +3260,7 @@ public class LibvirtComputingResourceTest { final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); try { when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); @@ -3274,7 +3274,7 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertFalse(answer.getResult()); - verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); try { verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { @@ -3471,7 +3471,7 @@ public class LibvirtComputingResourceTest { final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); //final Connect conn = Mockito.mock(Connect.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); try { when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); @@ -3485,7 +3485,7 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertFalse(answer.getResult()); - verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); try { verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { @@ -3522,7 +3522,7 @@ public class LibvirtComputingResourceTest { final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); //final Connect conn = Mockito.mock(Connect.class); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); try { when(libvirtUtilitiesHelper.getConnectionByVmName(command.getVmName())).thenThrow(LibvirtException.class); @@ -3536,7 +3536,7 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertFalse(answer.getResult()); - verify(libvirtComputingResource, times(1)).getLibvirtConnectionWrapper(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); try { verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(command.getVmName()); } catch (final LibvirtException e) { @@ -3593,9 +3593,9 @@ public class LibvirtComputingResourceTest { final String templateInstallFolder = "template/tmpl/" + templateFolder; final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); - when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtUtilitiesHelper.generatereUUIDName()).thenReturn(tmplName); try { when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); @@ -3667,9 +3667,9 @@ public class LibvirtComputingResourceTest { final String templateInstallFolder = "template/tmpl/" + templateFolder; final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); - when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtUtilitiesHelper.generatereUUIDName()).thenReturn(tmplName); try { when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenThrow(ConfigurationException.class); @@ -3740,9 +3740,9 @@ public class LibvirtComputingResourceTest { final String templateInstallFolder = "template/tmpl/" + templateFolder; final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); - when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtUtilitiesHelper.generatereUUIDName()).thenReturn(tmplName); try { when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); @@ -3814,9 +3814,9 @@ public class LibvirtComputingResourceTest { final String templateInstallFolder = "template/tmpl/" + templateFolder; final String tmplPath = secondaryPool.getLocalPath() + File.separator + templateInstallFolder; - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); when(libvirtUtilitiesHelper.buildTemplateLocation(storage, tmplPath)).thenReturn(location); - when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtUtilitiesHelper.generatereUUIDName()).thenReturn(tmplName); try { when(libvirtUtilitiesHelper.buildQCOW2Processor(storage)).thenReturn(qcow2Processor); @@ -3873,8 +3873,8 @@ public class LibvirtComputingResourceTest { final int index = snapshotPath.lastIndexOf("/"); snapshotPath = snapshotPath.substring(0, index); - when(libvirtComputingResource.getLibvirtConnectionWrapper()).thenReturn(libvirtUtilitiesHelper); - when(libvirtUtilitiesHelper.buildTemplateUUIDName()).thenReturn(tmplName); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + when(libvirtUtilitiesHelper.generatereUUIDName()).thenReturn(tmplName); when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl() + snapshotPath)).thenReturn(snapshotPool); when(storagePoolMgr.getStoragePoolByURI(command.getSecondaryStorageUrl())).thenReturn(secondaryPool); From 7fd43f33d35fc514cc480c0e15f934e58be2cfdc Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 6 May 2015 08:48:24 +0200 Subject: [PATCH 30/36] Refactoring the LibvirtComputingResource - 5 unit tests added - KVM hypervisor plugin with 20.1% coverage --- .../LibvirtCopyVolumeCommandWrapper.java | 15 +- .../LibvirtComputingResourceTest.java | 210 +++++++++++++++++- 2 files changed, 216 insertions(+), 9 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java index d14b045ce0e..348c421edbd 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtCopyVolumeCommandWrapper.java @@ -37,11 +37,12 @@ public final class LibvirtCopyVolumeCommandWrapper extends CommandWrapper Date: Wed, 6 May 2015 11:38:00 +0200 Subject: [PATCH 31/36] Refactoring the LibvirtComputingResource - Addin LibvirtPvlanSetupCommandWrapper - 6 unit tests added - KVM hypervisor plugin with 21% coverage From the 6 tests added, 2 were extra tests to increase the coverage of the LibvirtStopCommandWrapper - Increased from 35% to 78.7% --- .../resource/LibvirtComputingResource.java | 70 +----- .../LibvirtPvlanSetupCommandWrapper.java | 105 ++++++++ .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtComputingResourceTest.java | 236 +++++++++++++++++- 4 files changed, 352 insertions(+), 61 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java 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 8b74b1c3b58..31a9ed71234 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 @@ -68,7 +68,6 @@ import com.cloud.agent.api.HostVmStateReportEntry; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; -import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -397,6 +396,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _manageSnapshotPath; } + public String getGuestBridgeName() { + return _guestBridgeName; + } + + public String getOvsPvlanDhcpHostPath() { + return _ovsPvlanDhcpHostPath; + } + + public String getOvsPvlanVmPath() { + return _ovsPvlanVmPath; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1252,8 +1263,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((ResizeVolumeCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); - } else if (cmd instanceof PvlanSetupCommand) { - return execute((PvlanSetupCommand)cmd); } else { s_logger.warn("Unsupported command "); return Answer.createUnsupportedCommandAnswer(cmd); @@ -1519,61 +1528,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private Answer execute(final PvlanSetupCommand cmd) { - final String primaryPvlan = cmd.getPrimary(); - final String isolatedPvlan = cmd.getIsolated(); - final String op = cmd.getOp(); - final String dhcpName = cmd.getDhcpName(); - final String dhcpMac = cmd.getDhcpMac(); - final String dhcpIp = cmd.getDhcpIp(); - final String vmMac = cmd.getVmMac(); - boolean add = true; - - String opr = "-A"; - if (op.equals("delete")) { - opr = "-D"; - add = false; - } - - String result = null; - Connect conn; - try { - if (cmd.getType() == PvlanSetupCommand.Type.DHCP) { - final Script script = new Script(_ovsPvlanDhcpHostPath, _timeout, s_logger); - if (add) { - conn = LibvirtConnection.getConnectionByVmName(dhcpName); - final List ifaces = getInterfaces(conn, dhcpName); - final InterfaceDef guestNic = ifaces.get(0); - script.add(opr, "-b", _guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName, "-d", dhcpIp, "-m", dhcpMac, "-I", - guestNic.getDevName()); - } else { - script.add(opr, "-b", _guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName, "-d", dhcpIp, "-m", dhcpMac); - } - result = script.execute(); - if (result != null) { - s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac); - return new Answer(cmd, false, result); - } else { - s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac); - } - } else if (cmd.getType() == PvlanSetupCommand.Type.VM) { - final Script script = new Script(_ovsPvlanVmPath, _timeout, s_logger); - script.add(opr, "-b", _guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-v", vmMac); - result = script.execute(); - if (result != null) { - s_logger.warn("Failed to program pvlan for vm with mac " + vmMac); - return new Answer(cmd, false, result); - } else { - s_logger.info("Programmed pvlan for vm with mac " + vmMac); - } - } - } catch (final LibvirtException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return new Answer(cmd, true, result); - } - private void VifHotPlug(final Connect conn, final String vmName, final String broadcastUri, final String macAddr) throws InternalErrorException, LibvirtException { final NicTO nicTO = new NicTO(); nicTO.setMac(macAddr); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java new file mode 100644 index 00000000000..7233723ae1a --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtPvlanSetupCommandWrapper.java @@ -0,0 +1,105 @@ +// +// 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 java.util.List; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.PvlanSetupCommand; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.script.Script; + +public final class LibvirtPvlanSetupCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtPvlanSetupCommandWrapper.class); + + @Override + public Answer execute(final PvlanSetupCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String primaryPvlan = command.getPrimary(); + final String isolatedPvlan = command.getIsolated(); + final String op = command.getOp(); + final String dhcpName = command.getDhcpName(); + final String dhcpMac = command.getDhcpMac(); + final String dhcpIp = command.getDhcpIp(); + final String vmMac = command.getVmMac(); + boolean add = true; + + String opr = "-A"; + if (op.equals("delete")) { + opr = "-D"; + add = false; + } + + String result = null; + try { + final String guestBridgeName = libvirtComputingResource.getGuestBridgeName(); + final int timeout = libvirtComputingResource.getTimeout(); + + if (command.getType() == PvlanSetupCommand.Type.DHCP) { + final String ovsPvlanDhcpHostPath = libvirtComputingResource.getOvsPvlanDhcpHostPath(); + final Script script = new Script(ovsPvlanDhcpHostPath, timeout, s_logger); + + if (add) { + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); + final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(dhcpName); + + final List ifaces = libvirtComputingResource.getInterfaces(conn, dhcpName); + final InterfaceDef guestNic = ifaces.get(0); + script.add(opr, "-b", guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName, "-d", dhcpIp, "-m", dhcpMac, "-I", + guestNic.getDevName()); + } else { + script.add(opr, "-b", guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-n", dhcpName, "-d", dhcpIp, "-m", dhcpMac); + } + + result = script.execute(); + + if (result != null) { + s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac); + return new Answer(command, false, result); + } else { + s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac); + } + } else if (command.getType() == PvlanSetupCommand.Type.VM) { + final String ovsPvlanVmPath = libvirtComputingResource.getOvsPvlanVmPath(); + + final Script script = new Script(ovsPvlanVmPath, timeout, s_logger); + script.add(opr, "-b", guestBridgeName, "-p", primaryPvlan, "-i", isolatedPvlan, "-v", vmMac); + result = script.execute(); + + if (result != null) { + s_logger.warn("Failed to program pvlan for vm with mac " + vmMac); + return new Answer(command, false, result); + } else { + s_logger.info("Programmed pvlan for vm with mac " + vmMac); + } + } + } catch (final LibvirtException e) { + s_logger.error("Error whislt executing OVS Setup command! ==> " + e.getMessage()); + return new Answer(command, false, e.getMessage()); + } + return new Answer(command, true, result); + } +} \ 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 1ee14a1dfe9..c103ef397b8 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 @@ -59,6 +59,7 @@ import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; @@ -146,6 +147,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(BackupSnapshotCommand.class, new LibvirtBackupSnapshotCommandWrapper()); linbvirtCommands.put(CreatePrivateTemplateFromSnapshotCommand.class, new LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper()); linbvirtCommands.put(CopyVolumeCommand.class, new LibvirtCopyVolumeCommandWrapper()); + linbvirtCommands.put(PvlanSetupCommand.class, new LibvirtPvlanSetupCommandWrapper()); 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 86ff007917c..ad75b532751 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 @@ -31,6 +31,7 @@ import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; @@ -54,6 +55,7 @@ import org.libvirt.Connect; import org.libvirt.Domain; import org.libvirt.DomainBlockStats; import org.libvirt.DomainInfo; +import org.libvirt.DomainInfo.DomainState; import org.libvirt.DomainInterfaceStats; import org.libvirt.LibvirtException; import org.libvirt.NodeInfo; @@ -107,6 +109,7 @@ import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand.Acl; import com.cloud.agent.api.PingTestCommand; import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; @@ -504,10 +507,13 @@ public class LibvirtComputingResourceTest { } @Test - public void testStopCommandCheck() { + public void testStopCommandCheckVmNOTRunning() { final Connect conn = Mockito.mock(Connect.class); final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); - final Domain domain = Mockito.mock(Domain.class); + final Domain vm = Mockito.mock(Domain.class); + final DomainInfo info = Mockito.mock(DomainInfo.class); + final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_SHUTDOWN; + info.state = state; final String vmName = "Test"; final StopCommand command = new StopCommand(vmName, false, true); @@ -515,7 +521,10 @@ public class LibvirtComputingResourceTest { when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); try { when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); - when(conn.domainLookupByName(command.getVmName())).thenReturn(domain); + when(conn.domainLookupByName(command.getVmName())).thenReturn(vm); + + when(vm.getInfo()).thenReturn(info); + } catch (final LibvirtException e) { fail(e.getMessage()); } @@ -535,6 +544,83 @@ public class LibvirtComputingResourceTest { } } + @SuppressWarnings("unchecked") + @Test + public void testStopCommandCheckException1() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Domain vm = Mockito.mock(Domain.class); + final DomainInfo info = Mockito.mock(DomainInfo.class); + final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING; + info.state = state; + + final String vmName = "Test"; + final StopCommand command = new StopCommand(vmName, false, true); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); + when(conn.domainLookupByName(command.getVmName())).thenReturn(vm); + + when(vm.getInfo()).thenReturn(info); + + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(2)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testStopCommandCheckVmRunning() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Domain vm = Mockito.mock(Domain.class); + final DomainInfo info = Mockito.mock(DomainInfo.class); + final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING; + info.state = state; + + final String vmName = "Test"; + final StopCommand command = new StopCommand(vmName, false, true); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); + when(conn.domainLookupByName(command.getVmName())).thenReturn(vm); + + when(vm.getInfo()).thenReturn(info); + + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + @Test public void testGetVmStatsCommand() { final Connect conn = Mockito.mock(Connect.class); @@ -4098,4 +4184,148 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); } + + @Test + public void testPvlanSetupCommandDhcpAdd() { + final String op = "add"; + final URI uri = URI.create("http://localhost"); + final String networkTag = "/105"; + final String dhcpName = "dhcp"; + final String dhcpMac = "00:00:00:00"; + final String dhcpIp = "172.10.10.10"; + + final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp); + + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Connect conn = Mockito.mock(Connect.class); + + final String guestBridgeName = "br0"; + when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName); + + final int timeout = 0; + when(libvirtComputingResource.getTimeout()).thenReturn(timeout); + final String ovsPvlanDhcpHostPath = "/pvlan"; + when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + + final List ifaces = new ArrayList(); + final InterfaceDef nic = Mockito.mock(InterfaceDef.class); + ifaces.add(nic); + + try { + when(libvirtUtilitiesHelper.getConnectionByVmName(dhcpName)).thenReturn(conn); + when(libvirtComputingResource.getInterfaces(conn, dhcpName)).thenReturn(ifaces); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(dhcpName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPvlanSetupCommandVm() { + final String op = "add"; + final URI uri = URI.create("http://localhost"); + final String networkTag = "/105"; + final String vmMac = "00:00:00:00"; + + final PvlanSetupCommand command = PvlanSetupCommand.createVmSetup(op, uri, networkTag, vmMac); + + final String guestBridgeName = "br0"; + when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName); + final int timeout = 0; + when(libvirtComputingResource.getTimeout()).thenReturn(timeout); + + final String ovsPvlanVmPath = "/pvlan"; + when(libvirtComputingResource.getOvsPvlanVmPath()).thenReturn(ovsPvlanVmPath); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } + + @SuppressWarnings("unchecked") + @Test + public void testPvlanSetupCommandDhcpException() { + final String op = "add"; + final URI uri = URI.create("http://localhost"); + final String networkTag = "/105"; + final String dhcpName = "dhcp"; + final String dhcpMac = "00:00:00:00"; + final String dhcpIp = "172.10.10.10"; + + final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp); + + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + + final String guestBridgeName = "br0"; + when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName); + + final int timeout = 0; + when(libvirtComputingResource.getTimeout()).thenReturn(timeout); + final String ovsPvlanDhcpHostPath = "/pvlan"; + when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + + try { + when(libvirtUtilitiesHelper.getConnectionByVmName(dhcpName)).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(dhcpName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPvlanSetupCommandDhcpDelete() { + final String op = "delete"; + final URI uri = URI.create("http://localhost"); + final String networkTag = "/105"; + final String dhcpName = "dhcp"; + final String dhcpMac = "00:00:00:00"; + final String dhcpIp = "172.10.10.10"; + + final PvlanSetupCommand command = PvlanSetupCommand.createDhcpSetup(op, uri, networkTag, dhcpName, dhcpMac, dhcpIp); + + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + + final String guestBridgeName = "br0"; + when(libvirtComputingResource.getGuestBridgeName()).thenReturn(guestBridgeName); + + final int timeout = 0; + when(libvirtComputingResource.getTimeout()).thenReturn(timeout); + final String ovsPvlanDhcpHostPath = "/pvlan"; + when(libvirtComputingResource.getOvsPvlanDhcpHostPath()).thenReturn(ovsPvlanDhcpHostPath); + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } } \ No newline at end of file From 08106e34d0eb8e4a182b32aa24e625f294555724 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 6 May 2015 13:36:15 +0200 Subject: [PATCH 32/36] Refactoring the LibvirtComputingResource - Adding LibvirtResizeVolumeCommandWrapper - 5 unit tests added - KVM hypervisor plugin with 22.1% coverage --- .../resource/LibvirtComputingResource.java | 98 +--------- .../wrapper/LibvirtRequestWrapper.java | 2 + .../LibvirtResizeVolumeCommandWrapper.java | 136 +++++++++++++ .../LibvirtComputingResourceTest.java | 178 ++++++++++++++++++ 4 files changed, 321 insertions(+), 93 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtResizeVolumeCommandWrapper.java 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 31a9ed71234..e98e9459698 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 @@ -60,7 +60,6 @@ import org.libvirt.DomainInfo.DomainState; import org.libvirt.DomainInterfaceStats; import org.libvirt.LibvirtException; import org.libvirt.NodeInfo; -import org.libvirt.StorageVol; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; @@ -80,15 +79,12 @@ import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.storage.ResizeVolumeAnswer; -import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.IpAddressTO; 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.resource.virtualnetwork.VirtualRouterDeployer; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; @@ -408,6 +404,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _ovsPvlanVmPath; } + public String getResizeVolumePath() { + return _resizeVolumePath; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1259,8 +1259,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((StartCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest((NetworkElementCommand)cmd); - } else if (cmd instanceof ResizeVolumeCommand) { - return execute((ResizeVolumeCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else { @@ -1401,7 +1399,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private String getResizeScriptType(final KVMStoragePool pool, final KVMPhysicalDisk vol) { + public String getResizeScriptType(final KVMStoragePool pool, final KVMPhysicalDisk vol) { final StoragePoolType poolType = pool.getType(); final PhysicalDiskFormat volFormat = vol.getFormat(); @@ -1417,92 +1415,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv throw new CloudRuntimeException("Cannot determine resize type from pool type " + pool.getType()); } - /* uses a local script now, eventually support for virStorageVolResize() will maybe work on - qcow2 and lvm and we can do this in libvirt calls */ - public Answer execute(final ResizeVolumeCommand cmd) { - final String volid = cmd.getPath(); - final long newSize = cmd.getNewSize(); - final long currentSize = cmd.getCurrentSize(); - final String vmInstanceName = cmd.getInstanceName(); - final boolean shrinkOk = cmd.getShrinkOk(); - final StorageFilerTO spool = cmd.getPool(); - final String notifyOnlyType = "NOTIFYONLY"; - - if ( currentSize == newSize) { - // nothing to do - s_logger.info("No need to resize volume: current size " + currentSize + " is same as new size " + newSize); - return new ResizeVolumeAnswer(cmd, true, "success", currentSize); - } - - try { - KVMStoragePool pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid()); - final KVMPhysicalDisk vol = pool.getPhysicalDisk(volid); - final String path = vol.getPath(); - String type = getResizeScriptType(pool, vol); - - if (pool.getType() != StoragePoolType.RBD) { - if (type.equals("QCOW2") && shrinkOk) { - return new ResizeVolumeAnswer(cmd, false, "Unable to shrink volumes of type " + type); - } - } else { - s_logger.debug("Volume " + path + " is on a RBD storage pool. No need to query for additional information."); - } - - s_logger.debug("Resizing volume: " + path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk); - - /* libvirt doesn't support resizing (C)LVM devices, and corrupts QCOW2 in some scenarios, so we have to do these via Bash script */ - if (pool.getType() != StoragePoolType.CLVM && vol.getFormat() != PhysicalDiskFormat.QCOW2) { - s_logger.debug("Volume " + path + " can be resized by libvirt. Asking libvirt to resize the volume."); - try { - final Connect conn = LibvirtConnection.getConnection(); - final StorageVol v = conn.storageVolLookupByPath(path); - int flags = 0; - - if (conn.getLibVirVersion() > 1001000 && vol.getFormat() == PhysicalDiskFormat.RAW && pool.getType() != StoragePoolType.RBD) { - flags = 1; - } - if (shrinkOk) { - flags = 4; - } - - v.resize(newSize, flags); - type = notifyOnlyType; - } catch (final LibvirtException e) { - return new ResizeVolumeAnswer(cmd, false, e.toString()); - } - } - s_logger.debug("Invoking resize script to handle type " + type); - final Script resizecmd = new Script(_resizeVolumePath, _cmdsTimeout, s_logger); - resizecmd.add("-s", String.valueOf(newSize)); - resizecmd.add("-c", String.valueOf(currentSize)); - resizecmd.add("-p", path); - resizecmd.add("-t", type); - resizecmd.add("-r", String.valueOf(shrinkOk)); - resizecmd.add("-v", vmInstanceName); - final String result = resizecmd.execute(); - - if (result != null) { - if(type.equals(notifyOnlyType)) { - return new ResizeVolumeAnswer(cmd, true, "Resize succeeded, but need reboot to notify guest"); - } else { - return new ResizeVolumeAnswer(cmd, false, result); - } - } - - /* fetch new size as seen from libvirt, don't want to assume anything */ - pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid()); - pool.refresh(); - final long finalSize = pool.getPhysicalDisk(volid).getVirtualSize(); - s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize); - return new ResizeVolumeAnswer(cmd, true, "success", finalSize); - } catch (final CloudRuntimeException e) { - final String error = "Failed to resize volume: " + e.getMessage(); - s_logger.debug(error); - return new ResizeVolumeAnswer(cmd, false, error); - } - - } - 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/LibvirtRequestWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtRequestWrapper.java index c103ef397b8..363981d47cc 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 @@ -74,6 +74,7 @@ import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.resource.CommandWrapper; import com.cloud.resource.RequestWrapper; @@ -148,6 +149,7 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CreatePrivateTemplateFromSnapshotCommand.class, new LibvirtCreatePrivateTemplateFromSnapshotCommandWrapper()); linbvirtCommands.put(CopyVolumeCommand.class, new LibvirtCopyVolumeCommandWrapper()); linbvirtCommands.put(PvlanSetupCommand.class, new LibvirtPvlanSetupCommandWrapper()); + linbvirtCommands.put(ResizeVolumeCommand.class, new LibvirtResizeVolumeCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtResizeVolumeCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtResizeVolumeCommandWrapper.java new file mode 100644 index 00000000000..bbcba4756e5 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtResizeVolumeCommandWrapper.java @@ -0,0 +1,136 @@ +// +// 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.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.LibvirtException; +import org.libvirt.StorageVol; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.ResizeVolumeAnswer; +import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.agent.api.to.StorageFilerTO; +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.utils.script.Script; + +/* + * Uses a local script now, eventually support for virStorageVolResize() will maybe work on qcow2 and lvm and we can do this in libvirt calls + */ +public final class LibvirtResizeVolumeCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtResizeVolumeCommandWrapper.class); + + @Override + public Answer execute(final ResizeVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) { + final String volid = command.getPath(); + final long newSize = command.getNewSize(); + final long currentSize = command.getCurrentSize(); + final String vmInstanceName = command.getInstanceName(); + final boolean shrinkOk = command.getShrinkOk(); + final StorageFilerTO spool = command.getPool(); + final String notifyOnlyType = "NOTIFYONLY"; + + if ( currentSize == newSize) { + // nothing to do + s_logger.info("No need to resize volume: current size " + currentSize + " is same as new size " + newSize); + return new ResizeVolumeAnswer(command, true, "success", currentSize); + } + + try { + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + KVMStoragePool pool = storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid()); + + final KVMPhysicalDisk vol = pool.getPhysicalDisk(volid); + final String path = vol.getPath(); + String type = libvirtComputingResource.getResizeScriptType(pool, vol); + + if (pool.getType() != StoragePoolType.RBD) { + if (type.equals("QCOW2") && shrinkOk) { + return new ResizeVolumeAnswer(command, false, "Unable to shrink volumes of type " + type); + } + } else { + s_logger.debug("Volume " + path + " is on a RBD storage pool. No need to query for additional information."); + } + + s_logger.debug("Resizing volume: " + path + "," + currentSize + "," + newSize + "," + type + "," + vmInstanceName + "," + shrinkOk); + + /* libvirt doesn't support resizing (C)LVM devices, and corrupts QCOW2 in some scenarios, so we have to do these via Bash script */ + if (pool.getType() != StoragePoolType.CLVM && vol.getFormat() != PhysicalDiskFormat.QCOW2) { + s_logger.debug("Volume " + path + " can be resized by libvirt. Asking libvirt to resize the volume."); + try { + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); + + final Connect conn = libvirtUtilitiesHelper.getConnection(); + final StorageVol v = conn.storageVolLookupByPath(path); + int flags = 0; + + if (conn.getLibVirVersion() > 1001000 && vol.getFormat() == PhysicalDiskFormat.RAW && pool.getType() != StoragePoolType.RBD) { + flags = 1; + } + if (shrinkOk) { + flags = 4; + } + + v.resize(newSize, flags); + type = notifyOnlyType; + } catch (final LibvirtException e) { + return new ResizeVolumeAnswer(command, false, e.toString()); + } + } + s_logger.debug("Invoking resize script to handle type " + type); + + final Script resizecmd = new Script(libvirtComputingResource.getResizeVolumePath(), libvirtComputingResource.getCmdsTimeout(), s_logger); + resizecmd.add("-s", String.valueOf(newSize)); + resizecmd.add("-c", String.valueOf(currentSize)); + resizecmd.add("-p", path); + resizecmd.add("-t", type); + resizecmd.add("-r", String.valueOf(shrinkOk)); + resizecmd.add("-v", vmInstanceName); + final String result = resizecmd.execute(); + + if (result != null) { + if(type.equals(notifyOnlyType)) { + return new ResizeVolumeAnswer(command, true, "Resize succeeded, but need reboot to notify guest"); + } else { + return new ResizeVolumeAnswer(command, false, result); + } + } + + /* fetch new size as seen from libvirt, don't want to assume anything */ + pool = storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid()); + pool.refresh(); + final long finalSize = pool.getPhysicalDisk(volid).getVirtualSize(); + s_logger.debug("after resize, size reports as " + finalSize + ", requested " + newSize); + return new ResizeVolumeAnswer(command, true, "success", finalSize); + } catch (final CloudRuntimeException e) { + final String error = "Failed to resize volume: " + e.getMessage(); + s_logger.debug(error); + return new ResizeVolumeAnswer(command, false, error); + } + } +} \ No newline at end of file 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 ad75b532751..4e8d7bdc52c 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 @@ -46,6 +46,7 @@ import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.commons.lang.SystemUtils; import org.junit.Assert; import org.junit.Assume; @@ -59,6 +60,7 @@ import org.libvirt.DomainInfo.DomainState; import org.libvirt.DomainInterfaceStats; import org.libvirt.LibvirtException; import org.libvirt.NodeInfo; +import org.libvirt.StorageVol; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; @@ -126,6 +128,7 @@ import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; @@ -4328,4 +4331,179 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertFalse(answer.getResult()); } + + @Test + public void testResizeVolumeCommand() { + final String path = "nfs:/192.168.2.2/storage/secondary"; + final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class); + final Long currentSize = 100l; + final Long newSize = 200l; + final boolean shrinkOk = true; + final String vmInstance = "Test"; + + final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Connect conn = Mockito.mock(Connect.class); + final StorageVol v = Mockito.mock(StorageVol.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool); + when(storagePool.getPhysicalDisk(path)).thenReturn(vol); + when(vol.getPath()).thenReturn(path); + when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("FILE"); + when(storagePool.getType()).thenReturn(StoragePoolType.RBD); + when(vol.getFormat()).thenReturn(PhysicalDiskFormat.FILE); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnection()).thenReturn(conn); + when(conn.storageVolLookupByPath(path)).thenReturn(v); + + when(conn.getLibVirVersion()).thenReturn(10010l); + + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnection(); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testResizeVolumeCommandSameSize() { + final String path = "nfs:/192.168.2.2/storage/secondary"; + final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class); + final Long currentSize = 100l; + final Long newSize = 100l; + final boolean shrinkOk = false; + final String vmInstance = "Test"; + + final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + } + + @Test + public void testResizeVolumeCommandShrink() { + final String path = "nfs:/192.168.2.2/storage/secondary"; + final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class); + final Long currentSize = 100l; + final Long newSize = 200l; + final boolean shrinkOk = true; + final String vmInstance = "Test"; + + final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool); + when(storagePool.getPhysicalDisk(path)).thenReturn(vol); + when(vol.getPath()).thenReturn(path); + when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("QCOW2"); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } + + @SuppressWarnings("unchecked") + @Test + public void testResizeVolumeCommandException() { + final String path = "nfs:/192.168.2.2/storage/secondary"; + final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class); + final Long currentSize = 100l; + final Long newSize = 200l; + final boolean shrinkOk = false; + final String vmInstance = "Test"; + + final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class); + final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool); + when(storagePool.getPhysicalDisk(path)).thenReturn(vol); + when(vol.getPath()).thenReturn(path); + when(libvirtComputingResource.getResizeScriptType(storagePool, vol)).thenReturn("FILE"); + when(storagePool.getType()).thenReturn(StoragePoolType.RBD); + when(vol.getFormat()).thenReturn(PhysicalDiskFormat.FILE); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnection()).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnection(); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testResizeVolumeCommandException2() { + final String path = "nfs:/192.168.2.2/storage/secondary"; + final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class); + final Long currentSize = 100l; + final Long newSize = 200l; + final boolean shrinkOk = false; + final String vmInstance = "Test"; + + final ResizeVolumeCommand command = new ResizeVolumeCommand(path, pool, currentSize, newSize, shrinkOk, vmInstance); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool storagePool = Mockito.mock(KVMStoragePool.class); + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(storagePool); + when(storagePool.getPhysicalDisk(path)).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(); + } } \ No newline at end of file From 09656ca84ef1afbc2603b2cd70186c52430daa5c Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 6 May 2015 14:31:02 +0200 Subject: [PATCH 33/36] Refactoring the LibvirtComputingResource - Adding LibvirtNetworkElementCommandWrapper and LibvirtStorageSubSystemCommandWrapper - 2 unit tests added - KVM hypervisor plugin with 22.2% coverage I also refactored the StorageSubSystemCommand interface into an abstract class - Remove the pseudo-multiple-inheritance implementation - The StorageSubSystemCommand was an interface, not related to the Command class and its implementation were extending the Command class anyway. The whole structure is better now. --- .../storage/command/AttachCommand.java | 13 +++---- .../command/AttachPrimaryDataStoreCmd.java | 7 ++-- .../storage/command/CopyCommand.java | 31 +++++++-------- .../storage/command/CreateObjectCommand.java | 7 ++-- .../command/CreatePrimaryDataStoreCmd.java | 11 +++--- .../storage/command/DeleteCommand.java | 7 ++-- .../storage/command/DettachCommand.java | 19 +++++---- .../storage/command/ForgetObjectCmd.java | 9 ++--- .../storage/command/IntroduceObjectCmd.java | 9 ++--- .../command/SnapshotAndCopyCommand.java | 14 +++---- .../command/StorageSubSystemCommand.java | 8 ++-- .../resource/LibvirtComputingResource.java | 9 ++--- .../LibvirtNetworkElementCommandWrapper.java | 35 +++++++++++++++++ .../wrapper/LibvirtRequestWrapper.java | 5 +++ ...LibvirtStorageSubSystemCommandWrapper.java | 36 +++++++++++++++++ .../LibvirtComputingResourceTest.java | 39 +++++++++++++++++++ 16 files changed, 182 insertions(+), 77 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapper.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStorageSubSystemCommandWrapper.java diff --git a/core/src/org/apache/cloudstack/storage/command/AttachCommand.java b/core/src/org/apache/cloudstack/storage/command/AttachCommand.java index 795deb2c064..34aaac92778 100644 --- a/core/src/org/apache/cloudstack/storage/command/AttachCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/AttachCommand.java @@ -19,15 +19,14 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DiskTO; -public final class AttachCommand extends Command implements StorageSubSystemCommand { +public final class AttachCommand extends StorageSubSystemCommand { private DiskTO disk; private String vmName; - private boolean inSeq = false; + private boolean inSeq; - public AttachCommand(DiskTO disk, String vmName) { + public AttachCommand(final DiskTO disk, final String vmName) { super(); this.disk = disk; this.vmName = vmName; @@ -42,7 +41,7 @@ public final class AttachCommand extends Command implements StorageSubSystemComm return disk; } - public void setDisk(DiskTO disk) { + public void setDisk(final DiskTO disk) { this.disk = disk; } @@ -50,12 +49,12 @@ public final class AttachCommand extends Command implements StorageSubSystemComm return vmName; } - public void setVmName(String vmName) { + public void setVmName(final String vmName) { this.vmName = vmName; } @Override - public void setExecuteInSequence(boolean inSeq) { + public void setExecuteInSequence(final boolean inSeq) { this.inSeq = inSeq; } } diff --git a/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java b/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java index 4a72c970587..9f4d14eb7ab 100644 --- a/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java +++ b/core/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java @@ -19,17 +19,16 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; -public final class AttachPrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { +public final class AttachPrimaryDataStoreCmd extends StorageSubSystemCommand { @Override - public void setExecuteInSequence(boolean inSeq) { + public void setExecuteInSequence(final boolean inSeq) { } private final String dataStore; - public AttachPrimaryDataStoreCmd(String uri) { + public AttachPrimaryDataStoreCmd(final String uri) { super(); dataStore = uri; } diff --git a/core/src/org/apache/cloudstack/storage/command/CopyCommand.java b/core/src/org/apache/cloudstack/storage/command/CopyCommand.java index cfede148300..f1895a4ae51 100644 --- a/core/src/org/apache/cloudstack/storage/command/CopyCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -22,10 +22,9 @@ package org.apache.cloudstack.storage.command; import java.util.HashMap; import java.util.Map; -import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; -public final class CopyCommand extends Command implements StorageSubSystemCommand { +public final class CopyCommand extends StorageSubSystemCommand { private DataTO srcTO; private DataTO destTO; private DataTO cacheTO; @@ -33,28 +32,28 @@ public final class CopyCommand extends Command implements StorageSubSystemComman private Map options = new HashMap(); private Map options2 = new HashMap(); - public CopyCommand(DataTO srcData, DataTO destData, int timeout, boolean executeInSequence) { + public CopyCommand(final DataTO srcData, final DataTO destData, final int timeout, final boolean executeInSequence) { super(); - this.srcTO = srcData; - this.destTO = destData; - this.setWait(timeout); + srcTO = srcData; + destTO = destData; + setWait(timeout); this.executeInSequence = executeInSequence; } public DataTO getDestTO() { - return this.destTO; + return destTO; } - public void setSrcTO(DataTO srcTO) { + public void setSrcTO(final DataTO srcTO) { this.srcTO = srcTO; } - public void setDestTO(DataTO destTO) { + public void setDestTO(final DataTO destTO) { this.destTO = destTO; } public DataTO getSrcTO() { - return this.srcTO; + return srcTO; } @Override @@ -66,15 +65,15 @@ public final class CopyCommand extends Command implements StorageSubSystemComman return cacheTO; } - public void setCacheTO(DataTO cacheTO) { + public void setCacheTO(final DataTO cacheTO) { this.cacheTO = cacheTO; } public int getWaitInMillSeconds() { - return this.getWait() * 1000; + return getWait() * 1000; } - public void setOptions(Map options) { + public void setOptions(final Map options) { this.options = options; } @@ -82,7 +81,7 @@ public final class CopyCommand extends Command implements StorageSubSystemComman return options; } - public void setOptions2(Map options2) { + public void setOptions2(final Map options2) { this.options2 = options2; } @@ -91,7 +90,7 @@ public final class CopyCommand extends Command implements StorageSubSystemComman } @Override - public void setExecuteInSequence(boolean inSeq) { - this.executeInSequence = inSeq; + public void setExecuteInSequence(final boolean inSeq) { + executeInSequence = inSeq; } } diff --git a/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java b/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java index 6079a95b735..88a582d0316 100644 --- a/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java @@ -19,13 +19,12 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; -public final class CreateObjectCommand extends Command implements StorageSubSystemCommand { +public final class CreateObjectCommand extends StorageSubSystemCommand { private DataTO data; - public CreateObjectCommand(DataTO obj) { + public CreateObjectCommand(final DataTO obj) { super(); data = obj; } @@ -44,7 +43,7 @@ public final class CreateObjectCommand extends Command implements StorageSubSyst } @Override - public void setExecuteInSequence(boolean inSeq) { + public void setExecuteInSequence(final boolean inSeq) { } } diff --git a/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java b/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java index 0017dd2038c..b1f32a9d321 100644 --- a/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java +++ b/core/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java @@ -19,18 +19,17 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; -public final class CreatePrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { +public final class CreatePrimaryDataStoreCmd extends StorageSubSystemCommand { private final String dataStore; - public CreatePrimaryDataStoreCmd(String uri) { + public CreatePrimaryDataStoreCmd(final String uri) { super(); - this.dataStore = uri; + dataStore = uri; } public String getDataStore() { - return this.dataStore; + return dataStore; } @Override @@ -39,7 +38,7 @@ public final class CreatePrimaryDataStoreCmd extends Command implements StorageS } @Override - public void setExecuteInSequence(boolean inSeq) { + public void setExecuteInSequence(final boolean inSeq) { } } diff --git a/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java index 5683f41784d..6f82fa97818 100644 --- a/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/DeleteCommand.java @@ -19,13 +19,12 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; -public final class DeleteCommand extends Command implements StorageSubSystemCommand { +public final class DeleteCommand extends StorageSubSystemCommand { private DataTO data; - public DeleteCommand(DataTO data) { + public DeleteCommand(final DataTO data) { super(); this.data = data; } @@ -44,7 +43,7 @@ public final class DeleteCommand extends Command implements StorageSubSystemComm } @Override - public void setExecuteInSequence(boolean inSeq) { + public void setExecuteInSequence(final boolean inSeq) { } } diff --git a/core/src/org/apache/cloudstack/storage/command/DettachCommand.java b/core/src/org/apache/cloudstack/storage/command/DettachCommand.java index b6998629e5e..8d89dd501e9 100644 --- a/core/src/org/apache/cloudstack/storage/command/DettachCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/DettachCommand.java @@ -19,10 +19,9 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DiskTO; -public class DettachCommand extends Command implements StorageSubSystemCommand { +public class DettachCommand extends StorageSubSystemCommand { private DiskTO disk; private String vmName; private boolean _managed; @@ -30,7 +29,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand { private String _storageHost; private int _storagePort; - public DettachCommand(DiskTO disk, String vmName) { + public DettachCommand(final DiskTO disk, final String vmName) { super(); this.disk = disk; this.vmName = vmName; @@ -45,7 +44,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand { return disk; } - public void setDisk(DiskTO disk) { + public void setDisk(final DiskTO disk) { this.disk = disk; } @@ -53,11 +52,11 @@ public class DettachCommand extends Command implements StorageSubSystemCommand { return vmName; } - public void setVmName(String vmName) { + public void setVmName(final String vmName) { this.vmName = vmName; } - public void setManaged(boolean managed) { + public void setManaged(final boolean managed) { _managed = managed; } @@ -65,7 +64,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand { return _managed; } - public void set_iScsiName(String iScsiName) { + public void set_iScsiName(final String iScsiName) { _iScsiName = iScsiName; } @@ -73,7 +72,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand { return _iScsiName; } - public void setStorageHost(String storageHost) { + public void setStorageHost(final String storageHost) { _storageHost = storageHost; } @@ -81,7 +80,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand { return _storageHost; } - public void setStoragePort(int storagePort) { + public void setStoragePort(final int storagePort) { _storagePort = storagePort; } @@ -90,7 +89,7 @@ public class DettachCommand extends Command implements StorageSubSystemCommand { } @Override - public void setExecuteInSequence(boolean inSeq) { + public void setExecuteInSequence(final boolean inSeq) { } } diff --git a/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java b/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java index 9bcaa62fe11..c47ee882c91 100644 --- a/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java +++ b/core/src/org/apache/cloudstack/storage/command/ForgetObjectCmd.java @@ -19,13 +19,12 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; -public class ForgetObjectCmd extends Command implements StorageSubSystemCommand { - private DataTO dataTO; +public class ForgetObjectCmd extends StorageSubSystemCommand { + private final DataTO dataTO; - public ForgetObjectCmd(DataTO data) { + public ForgetObjectCmd(final DataTO data) { dataTO = data; } @@ -39,7 +38,7 @@ public class ForgetObjectCmd extends Command implements StorageSubSystemCommand } @Override - public void setExecuteInSequence(boolean inSeq) { + public void setExecuteInSequence(final boolean inSeq) { } } diff --git a/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java b/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java index c20c50faf3c..8c3bc5e5cc7 100644 --- a/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java +++ b/core/src/org/apache/cloudstack/storage/command/IntroduceObjectCmd.java @@ -19,13 +19,12 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; -public class IntroduceObjectCmd extends Command implements StorageSubSystemCommand { - private DataTO dataTO; +public class IntroduceObjectCmd extends StorageSubSystemCommand { + private final DataTO dataTO; - public IntroduceObjectCmd(DataTO dataTO) { + public IntroduceObjectCmd(final DataTO dataTO) { this.dataTO = dataTO; } @@ -39,7 +38,7 @@ public class IntroduceObjectCmd extends Command implements StorageSubSystemComma } @Override - public void setExecuteInSequence(boolean inSeq) { + public void setExecuteInSequence(final boolean inSeq) { } } diff --git a/core/src/org/apache/cloudstack/storage/command/SnapshotAndCopyCommand.java b/core/src/org/apache/cloudstack/storage/command/SnapshotAndCopyCommand.java index c5999161765..0a1a84d4fc3 100644 --- a/core/src/org/apache/cloudstack/storage/command/SnapshotAndCopyCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/SnapshotAndCopyCommand.java @@ -19,18 +19,16 @@ package org.apache.cloudstack.storage.command; -import com.cloud.agent.api.Command; - import java.util.Map; -public final class SnapshotAndCopyCommand extends Command implements StorageSubSystemCommand { - private String _uuidOfSourceVdi; - private Map _sourceDetails; - private Map _destDetails; +public final class SnapshotAndCopyCommand extends StorageSubSystemCommand { + private final String _uuidOfSourceVdi; + private final Map _sourceDetails; + private final Map _destDetails; private boolean _executeInSequence = true; - public SnapshotAndCopyCommand(String uuidOfSourceVdi, Map sourceDetails, Map destDetails) { + public SnapshotAndCopyCommand(final String uuidOfSourceVdi, final Map sourceDetails, final Map destDetails) { _uuidOfSourceVdi = uuidOfSourceVdi; _sourceDetails = sourceDetails; _destDetails = destDetails; @@ -49,7 +47,7 @@ public final class SnapshotAndCopyCommand extends Command implements StorageSubS } @Override - public void setExecuteInSequence(boolean executeInSequence) { + public void setExecuteInSequence(final boolean executeInSequence) { _executeInSequence = executeInSequence; } diff --git a/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java b/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java index 5893f62587f..6507bb08ccd 100644 --- a/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java @@ -19,6 +19,8 @@ package org.apache.cloudstack.storage.command; -public interface StorageSubSystemCommand { - void setExecuteInSequence(boolean inSeq); -} +import com.cloud.agent.api.Command; + +public abstract class StorageSubSystemCommand extends Command { + abstract void setExecuteInSequence(boolean inSeq); +} \ No newline at end of file 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 e98e9459698..d7b4b1877cb 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 @@ -45,7 +45,6 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; @@ -408,6 +407,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return _resizeVolumePath; } + public StorageSubsystemCommandHandler getStorageHandler() { + return storageHandler; + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -1257,10 +1260,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { if (cmd instanceof StartCommand) { return execute((StartCommand)cmd); - } else if (cmd instanceof NetworkElementCommand) { - return _virtRouterResource.executeRequest((NetworkElementCommand)cmd); - } else if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else { s_logger.warn("Unsupported command "); return Answer.createUnsupportedCommandAnswer(cmd); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapper.java new file mode 100644 index 00000000000..3046b09ffc7 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtNetworkElementCommandWrapper.java @@ -0,0 +1,35 @@ +// +// 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.routing.NetworkElementCommand; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; + +public final class LibvirtNetworkElementCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final NetworkElementCommand command, final LibvirtComputingResource libvirtComputingResource) { + final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource(); + return virtRouterResource.executeRequest(command); + } +} \ 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 363981d47cc..e8b7b8c3bad 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 @@ -20,6 +20,8 @@ package com.cloud.hypervisor.kvm.resource.wrapper; import java.util.Hashtable; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeCommand; @@ -70,6 +72,7 @@ import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; @@ -150,6 +153,8 @@ public class LibvirtRequestWrapper extends RequestWrapper { linbvirtCommands.put(CopyVolumeCommand.class, new LibvirtCopyVolumeCommandWrapper()); linbvirtCommands.put(PvlanSetupCommand.class, new LibvirtPvlanSetupCommandWrapper()); linbvirtCommands.put(ResizeVolumeCommand.class, new LibvirtResizeVolumeCommandWrapper()); + linbvirtCommands.put(NetworkElementCommand.class, new LibvirtNetworkElementCommandWrapper()); + linbvirtCommands.put(StorageSubSystemCommand.class, new LibvirtStorageSubSystemCommandWrapper()); resources.put(LibvirtComputingResource.class, linbvirtCommands); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStorageSubSystemCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStorageSubSystemCommandWrapper.java new file mode 100644 index 00000000000..d2044ed693d --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStorageSubSystemCommandWrapper.java @@ -0,0 +1,36 @@ +// +// 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.cloudstack.storage.command.StorageSubSystemCommand; + +import com.cloud.agent.api.Answer; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.storage.resource.StorageSubsystemCommandHandler; + +public final class LibvirtStorageSubSystemCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final StorageSubSystemCommand command, final LibvirtComputingResource libvirtComputingResource) { + final StorageSubsystemCommandHandler handler = libvirtComputingResource.getStorageHandler(); + return handler.handleStorageCommands(command); + } +} \ No newline at end of file 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 4e8d7bdc52c..140262fa850 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 @@ -46,6 +46,8 @@ import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import org.apache.cloudstack.storage.command.AttachAnswer; +import org.apache.cloudstack.storage.command.AttachCommand; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.commons.lang.SystemUtils; import org.junit.Assert; @@ -76,6 +78,8 @@ import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostCommand; +import com.cloud.agent.api.CheckRouterAnswer; +import com.cloud.agent.api.CheckRouterCommand; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; @@ -152,6 +156,7 @@ import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; +import com.cloud.storage.resource.StorageSubsystemCommandHandler; import com.cloud.storage.template.Processor; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.TemplateLocation; @@ -4506,4 +4511,38 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); } + + @Test + public void testNetworkElementCommand() { + final CheckRouterCommand command = new CheckRouterCommand(); + + final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class); + when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource); + + when(virtRouterResource.executeRequest(command)).thenReturn(new CheckRouterAnswer(command, "mock_resource")); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + } + + @Test + public void testStorageSubSystemCommand() { + final DiskTO disk = Mockito.mock(DiskTO.class); + final String vmName = "Test"; + final AttachCommand command = new AttachCommand(disk, vmName); + + final StorageSubsystemCommandHandler handler = Mockito.mock(StorageSubsystemCommandHandler.class); + when(libvirtComputingResource.getStorageHandler()).thenReturn(handler); + + when(handler.handleStorageCommands(command)).thenReturn(new AttachAnswer(disk)); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + } } \ No newline at end of file From 74ad48db55d141f697b6e8235e7ac472d844dd57 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 6 May 2015 16:11:49 +0200 Subject: [PATCH 34/36] Refactoring the LibvirtComputingResource - Adding LibvirtStartCommandWrapper - 8 unit tests added - KVM hypervisor plugin with 23.2% coverage --- .../resource/LibvirtComputingResource.java | 150 +----- .../LibvirtManageSnapshotCommandWrapper.java | 6 +- .../wrapper/LibvirtRequestWrapper.java | 2 + .../wrapper/LibvirtStartCommandWrapper.java | 151 ++++++ .../wrapper/LibvirtUtilitiesHelper.java | 4 + .../LibvirtComputingResourceTest.java | 502 ++++++++++++++++++ 6 files changed, 672 insertions(+), 143 deletions(-) create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtStartCommandWrapper.java 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 d7b4b1877cb..a04074bee94 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 @@ -67,8 +67,6 @@ import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.SetupGuestNetworkCommand; -import com.cloud.agent.api.StartAnswer; -import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupStorageCommand; @@ -118,7 +116,6 @@ import com.cloud.hypervisor.kvm.storage.KVMStoragePool; import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; import com.cloud.hypervisor.kvm.storage.KVMStorageProcessor; import com.cloud.network.Networks.BroadcastDomainType; -import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.network.Networks.TrafficType; import com.cloud.resource.ServerResource; @@ -1173,7 +1170,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return "0".equals(command.execute(null)); } - private boolean passCmdLine(final String vmName, final String cmdLine) throws InternalErrorException { + public boolean passCmdLine(final String vmName, final String cmdLine) throws InternalErrorException { final Script command = new Script(_patchViaSocketPath, 5 * 1000, s_logger); String result; command.add("-n", vmName); @@ -1199,7 +1196,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected String startVM(final Connect conn, final String vmName, final String domainXML) throws LibvirtException, InternalErrorException { + public String startVM(final Connect conn, final String vmName, final String domainXML) throws LibvirtException, InternalErrorException { try { /* We create a transient domain here. When this method gets @@ -1253,19 +1250,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv try { return wrapper.execute(cmd, this); } catch (final Exception e) { - //[TODO] ignore for now, we still need to finish the other commands. - //return Answer.createUnsupportedCommandAnswer(cmd); - } - - try { - if (cmd instanceof StartCommand) { - return execute((StartCommand)cmd); - } else { - s_logger.warn("Unsupported command "); - return Answer.createUnsupportedCommandAnswer(cmd); - } - } catch (final IllegalArgumentException e) { - return new Answer(cmd, false, e.getMessage()); + return Answer.createUnsupportedCommandAnswer(cmd); } } @@ -1791,7 +1776,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return stats; } - protected void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVMDef vm) { + public void handleVmStartFailure(final Connect conn, final String vmName, final LibvirtVMDef vm) { if (vm != null && vm.getDevices() != null) { cleanupVMNetworks(conn, vm.getDevices().getInterfaces()); } @@ -1814,25 +1799,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return uuid; } - private void getOsVersion() { - final String version = Script.runSimpleBashScript("cat /etc/redhat-release | awk '{print $7}'"); - if (version != null) { - final String[] versions = version.split("\\."); - if (versions.length == 2) { - final String major = versions[0]; - final String minor = versions[1]; - try { - final Integer m = Integer.parseInt(major); - final Integer min = Integer.parseInt(minor); - hostOsVersion = new Pair<>(m, min); - } catch(final NumberFormatException e) { - - } - } - } - } - - protected LibvirtVMDef createVMFromSpec(final VirtualMachineTO vmTO) { + public LibvirtVMDef createVMFromSpec(final VirtualMachineTO vmTO) { final LibvirtVMDef vm = new LibvirtVMDef(); vm.setDomainName(vmTO.getName()); String uuid = vmTO.getUuid(); @@ -1972,7 +1939,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return vm; } - protected void createVifs(final VirtualMachineTO vmSpec, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException { + public void createVifs(final VirtualMachineTO vmSpec, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException { final NicTO[] nics = vmSpec.getNics(); final Map params = vmSpec.getDetails(); String nicAdapter = ""; @@ -1988,107 +1955,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected StartAnswer execute(final StartCommand cmd) { - final VirtualMachineTO vmSpec = cmd.getVirtualMachine(); - vmSpec.setVncAddr(cmd.getHostIp()); - final String vmName = vmSpec.getName(); - LibvirtVMDef vm = null; - - DomainState state = DomainState.VIR_DOMAIN_SHUTOFF; - Connect conn = null; - try { - final NicTO[] nics = vmSpec.getNics(); - - for (final NicTO nic : nics) { - if (vmSpec.getType() != VirtualMachine.Type.User) { - nic.setPxeDisable(true); - } - } - - vm = createVMFromSpec(vmSpec); - - conn = LibvirtConnection.getConnectionByType(vm.getHvsType()); - - createVbd(conn, vmSpec, vmName, vm); - - if (!_storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)) { - return new StartAnswer(cmd, "Failed to connect physical disks to host"); - } - - createVifs(vmSpec, vm); - - s_logger.debug("starting " + vmName + ": " + vm.toString()); - startVM(conn, vmName, vm.toString()); - - for (final NicTO nic : nics) { - if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { - if (vmSpec.getType() != VirtualMachine.Type.User) { - configureDefaultNetworkRulesForSystemVm(conn, vmName); - break; - } else { - final List nicSecIps = nic.getNicSecIps(); - String secIpsStr; - final StringBuilder sb = new StringBuilder(); - if (nicSecIps != null) { - for (final String ip : nicSecIps) { - sb.append(ip).append(":"); - } - secIpsStr = sb.toString(); - } else { - secIpsStr = "0:"; - } - default_network_rules(conn, vmName, nic, vmSpec.getId(), secIpsStr); - } - } - } - - // pass cmdline info to system vms - if (vmSpec.getType() != VirtualMachine.Type.User) { - //wait and try passCmdLine for 5 minutes at most for CLOUDSTACK-2823 - String controlIp = null; - for (final NicTO nic : nics) { - if (nic.getType() == TrafficType.Control) { - controlIp = nic.getIp(); - break; - } - } - for (int count = 0; count < 30; count++) { - passCmdLine(vmName, vmSpec.getBootArgs()); - //check router is up? - final boolean result = _virtRouterResource.connect(controlIp, 1, 5000); - if (result) { - break; - } - } - } - - state = DomainState.VIR_DOMAIN_RUNNING; - return new StartAnswer(cmd); - } catch (final LibvirtException e) { - s_logger.warn("LibvirtException ", e); - if (conn != null) { - handleVmStartFailure(conn, vmName, vm); - } - return new StartAnswer(cmd, e.getMessage()); - } catch (final InternalErrorException e) { - s_logger.warn("InternalErrorException ", e); - if (conn != null) { - handleVmStartFailure(conn, vmName, vm); - } - return new StartAnswer(cmd, e.getMessage()); - } catch (final URISyntaxException e) { - s_logger.warn("URISyntaxException ", e); - if (conn != null) { - handleVmStartFailure(conn, vmName, vm); - } - return new StartAnswer(cmd, e.getMessage()); - } finally { - if (state != DomainState.VIR_DOMAIN_RUNNING) { - _storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vmSpec); - } - } - } - public String getVolumePath(final Connect conn, final DiskTO volume) throws LibvirtException, URISyntaxException { final DataTO data = volume.getData(); final DataStoreTO store = data.getDataStore(); @@ -2107,7 +1973,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - protected void createVbd(final Connect conn, final VirtualMachineTO vmSpec, final String vmName, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException { + public void createVbd(final Connect conn, final VirtualMachineTO vmSpec, final String vmName, final LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException { final List disks = Arrays.asList(vmSpec.getDisks()); Collections.sort(disks, new Comparator() { @Override @@ -3197,7 +3063,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return true; } - protected boolean default_network_rules(final Connect conn, final String vmName, final NicTO nic, final Long vmId, final String secIpStr) { + public boolean defaultNetworkRules(final Connect conn, final String vmName, final NicTO nic, final Long vmId, final String secIpStr) { if (!_canBridgeFirewall) { return false; } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java index 966a4314979..225634005c5 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtManageSnapshotCommandWrapper.java @@ -36,9 +36,11 @@ import com.ceph.rbd.RbdImage; import com.cloud.agent.api.Answer; import com.cloud.agent.api.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; +import com.cloud.agent.api.to.StorageFilerTO; 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.script.Script; @@ -66,7 +68,9 @@ public final class LibvirtManageSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtStartCommandWrapper.class); + + @Override + public Answer execute(final StartCommand command, final LibvirtComputingResource libvirtComputingResource) { + final VirtualMachineTO vmSpec = command.getVirtualMachine(); + vmSpec.setVncAddr(command.getHostIp()); + final String vmName = vmSpec.getName(); + LibvirtVMDef vm = null; + + DomainState state = DomainState.VIR_DOMAIN_SHUTOFF; + final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); + Connect conn = null; + try { + final NicTO[] nics = vmSpec.getNics(); + + for (final NicTO nic : nics) { + if (vmSpec.getType() != VirtualMachine.Type.User) { + nic.setPxeDisable(true); + } + } + + vm = libvirtComputingResource.createVMFromSpec(vmSpec); + conn = libvirtUtilitiesHelper.getConnectionByType(vm.getHvsType()); + libvirtComputingResource.createVbd(conn, vmSpec, vmName, vm); + + if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)) { + return new StartAnswer(command, "Failed to connect physical disks to host"); + } + + libvirtComputingResource.createVifs(vmSpec, vm); + + s_logger.debug("starting " + vmName + ": " + vm.toString()); + libvirtComputingResource.startVM(conn, vmName, vm.toString()); + + for (final NicTO nic : nics) { + if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { + if (vmSpec.getType() != VirtualMachine.Type.User) { + libvirtComputingResource.configureDefaultNetworkRulesForSystemVm(conn, vmName); + break; + } else { + final List nicSecIps = nic.getNicSecIps(); + String secIpsStr; + final StringBuilder sb = new StringBuilder(); + if (nicSecIps != null) { + for (final String ip : nicSecIps) { + sb.append(ip).append(":"); + } + secIpsStr = sb.toString(); + } else { + secIpsStr = "0:"; + } + libvirtComputingResource.defaultNetworkRules(conn, vmName, nic, vmSpec.getId(), secIpsStr); + } + } + } + + // pass cmdline info to system vms + if (vmSpec.getType() != VirtualMachine.Type.User) { + //wait and try passCmdLine for 5 minutes at most for CLOUDSTACK-2823 + String controlIp = null; + for (final NicTO nic : nics) { + if (nic.getType() == TrafficType.Control) { + controlIp = nic.getIp(); + break; + } + } + for (int count = 0; count < 30; count++) { + libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs()); + //check router is up? + final VirtualRoutingResource virtRouterResource = libvirtComputingResource.getVirtRouterResource(); + final boolean result = virtRouterResource.connect(controlIp, 1, 5000); + if (result) { + break; + } + } + } + + state = DomainState.VIR_DOMAIN_RUNNING; + return new StartAnswer(command); + } catch (final LibvirtException e) { + s_logger.warn("LibvirtException ", e); + if (conn != null) { + libvirtComputingResource.handleVmStartFailure(conn, vmName, vm); + } + return new StartAnswer(command, e.getMessage()); + } catch (final InternalErrorException e) { + s_logger.warn("InternalErrorException ", e); + if (conn != null) { + libvirtComputingResource.handleVmStartFailure(conn, vmName, vm); + } + return new StartAnswer(command, e.getMessage()); + } catch (final URISyntaxException e) { + s_logger.warn("URISyntaxException ", e); + if (conn != null) { + libvirtComputingResource.handleVmStartFailure(conn, vmName, vm); + } + return new StartAnswer(command, e.getMessage()); + } finally { + if (state != DomainState.VIR_DOMAIN_RUNNING) { + storagePoolMgr.disconnectPhysicalDisksViaVmSpec(vmSpec); + } + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java index c0f1cb55ca4..74a41c651b9 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelper.java @@ -65,4 +65,8 @@ public class LibvirtUtilitiesHelper { public String generatereUUIDName() { return UUID.randomUUID().toString(); } + + public Connect getConnectionByType(final String hvsType) throws LibvirtException { + return LibvirtConnection.getConnectionByType(hvsType); + } } \ No newline at end of file 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 140262fa850..4a1dcc43be5 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 @@ -24,6 +24,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -121,6 +122,7 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; +import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; @@ -758,6 +760,96 @@ public class LibvirtComputingResourceTest { } } + @SuppressWarnings("unchecked") + @Test + public void testRebootCommandException1() { + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + + final String vmName = "Test"; + final RebootCommand command = new RebootCommand(vmName); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testRebootCommandError() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + + final String vmName = "Test"; + final RebootCommand command = new RebootCommand(vmName); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtComputingResource.rebootVM(conn, command.getVmName())).thenReturn("error"); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testRebootCommandException2() { + final Connect conn = Mockito.mock(Connect.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + + final String vmName = "Test"; + final RebootCommand command = new RebootCommand(vmName); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtComputingResource.rebootVM(conn, command.getVmName())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + @Test public void testRebootRouterCommand() { final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class); @@ -3588,6 +3680,65 @@ public class LibvirtComputingResourceTest { } } + @Test + public void testManageSnapshotCommandLibvirt() { + final StoragePool storagePool = Mockito.mock(StoragePool.class);; + final String volumePath = "/123/vol"; + final String vmName = "Test"; + final long snapshotId = 1l; + final String preSnapshotPath = "/snapshot/path"; + final String snapshotName = "snap"; + + final ManageSnapshotCommand command = new ManageSnapshotCommand(snapshotId, volumePath, storagePool, preSnapshotPath, snapshotName, vmName); + + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Connect conn = Mockito.mock(Connect.class); + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final KVMStoragePool primaryPool = Mockito.mock(KVMStoragePool.class); + final Domain vm = Mockito.mock(Domain.class); + final DomainInfo info = Mockito.mock(DomainInfo.class); + final DomainState state = DomainInfo.DomainState.VIR_DOMAIN_RUNNING; + info.state = state; + + final KVMPhysicalDisk disk = Mockito.mock(KVMPhysicalDisk.class); + + final StorageFilerTO pool = command.getPool(); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByVmName(vmName)).thenReturn(conn); + when(libvirtComputingResource.getDomain(conn, command.getVmName())).thenReturn(vm); + when(vm.getInfo()).thenReturn(info); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primaryPool); + when(primaryPool.getPhysicalDisk(command.getVolumePath())).thenReturn(disk); + when(primaryPool.isExternalSnapshot()).thenReturn(false); + + try { + when(vm.getUUIDString()).thenReturn("cdb18980-546d-4153-b916-70ee9edf0908"); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByVmName(vmName); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + @SuppressWarnings("unchecked") @Test public void testBackupSnapshotCommandLibvirtException() { @@ -4545,4 +4696,355 @@ public class LibvirtComputingResourceTest { final Answer answer = wrapper.execute(command, libvirtComputingResource); assertTrue(answer.getResult()); } + + @Test + public void testStartCommandFailedConnect() { + final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class); + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + final boolean executeInSequence = false; + + final StartCommand command = new StartCommand(vmSpec, host, executeInSequence); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Connect conn = Mockito.mock(Connect.class); + final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class); + + final NicTO nic = Mockito.mock(NicTO.class); + final NicTO[] nics = new NicTO[]{nic}; + + final String vmName = "Test"; + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(vmSpec.getNics()).thenReturn(nics); + when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter); + when(vmSpec.getName()).thenReturn(vmName); + when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn); + doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } + + when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(false); + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void testStartCommandLibvirtException() { + final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class); + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + final boolean executeInSequence = false; + + final StartCommand command = new StartCommand(vmSpec, host, executeInSequence); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class); + + final NicTO nic = Mockito.mock(NicTO.class); + final NicTO[] nics = new NicTO[]{nic}; + + final String vmName = "Test"; + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(vmSpec.getNics()).thenReturn(nics); + when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter); + when(vmSpec.getName()).thenReturn(vmName); + when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenThrow(LibvirtException.class); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testStartCommandInternalError() { + final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class); + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + final boolean executeInSequence = false; + + final StartCommand command = new StartCommand(vmSpec, host, executeInSequence); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Connect conn = Mockito.mock(Connect.class); + final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class); + + final NicTO nic = Mockito.mock(NicTO.class); + final NicTO[] nics = new NicTO[]{nic}; + + final String vmName = "Test"; + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(vmSpec.getNics()).thenReturn(nics); + when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter); + when(vmSpec.getName()).thenReturn(vmName); + when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn); + doThrow(InternalErrorException.class).when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testStartCommandUriException() { + final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class); + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + final boolean executeInSequence = false; + + final StartCommand command = new StartCommand(vmSpec, host, executeInSequence); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Connect conn = Mockito.mock(Connect.class); + final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class); + + final NicTO nic = Mockito.mock(NicTO.class); + final NicTO[] nics = new NicTO[]{nic}; + + final String vmName = "Test"; + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(vmSpec.getNics()).thenReturn(nics); + when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter); + when(vmSpec.getName()).thenReturn(vmName); + when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn); + doThrow(URISyntaxException.class).when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertFalse(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testStartCommand() { + final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class); + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + final boolean executeInSequence = false; + + final StartCommand command = new StartCommand(vmSpec, host, executeInSequence); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Connect conn = Mockito.mock(Connect.class); + final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class); + final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class); + + final NicTO nic = Mockito.mock(NicTO.class); + final NicTO[] nics = new NicTO[]{nic}; + + final String vmName = "Test"; + final String controlIp = "169.122.10.10"; + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(vmSpec.getNics()).thenReturn(nics); + when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter); + when(vmSpec.getName()).thenReturn(vmName); + when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn); + doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } + + when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true); + try { + doNothing().when(libvirtComputingResource).createVifs(vmSpec, vmDef); + + when(libvirtComputingResource.startVM(conn, vmName, vmDef.toString())).thenReturn("SUCCESS"); + + when(vmSpec.getBootArgs()).thenReturn("ls -lart"); + when(libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())).thenReturn(true); + + when(nic.getIp()).thenReturn(controlIp); + when(nic.getType()).thenReturn(TrafficType.Control); + when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource); + when(virtRouterResource.connect(controlIp, 1, 5000)).thenReturn(true); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } + + @Test + public void testStartCommandIsolationEc2() { + final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class); + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + final boolean executeInSequence = false; + + final StartCommand command = new StartCommand(vmSpec, host, executeInSequence); + + final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); + final Connect conn = Mockito.mock(Connect.class); + final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class); + final VirtualRoutingResource virtRouterResource = Mockito.mock(VirtualRoutingResource.class); + + final NicTO nic = Mockito.mock(NicTO.class); + final NicTO[] nics = new NicTO[]{nic}; + + final String vmName = "Test"; + final String controlIp = "169.122.10.10"; + + when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr); + when(vmSpec.getNics()).thenReturn(nics); + when(vmSpec.getType()).thenReturn(VirtualMachine.Type.DomainRouter); + when(vmSpec.getName()).thenReturn(vmName); + when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef); + + when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper); + try { + when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn); + doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } + + when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true); + try { + doNothing().when(libvirtComputingResource).createVifs(vmSpec, vmDef); + + when(libvirtComputingResource.startVM(conn, vmName, vmDef.toString())).thenReturn("SUCCESS"); + + when(nic.isSecurityGroupEnabled()).thenReturn(true); + when(nic.getIsolationUri()).thenReturn(new URI("ec2://test")); + + + when(vmSpec.getBootArgs()).thenReturn("ls -lart"); + when(libvirtComputingResource.passCmdLine(vmName, vmSpec.getBootArgs())).thenReturn(true); + + when(nic.getIp()).thenReturn(controlIp); + when(nic.getType()).thenReturn(TrafficType.Control); + when(libvirtComputingResource.getVirtRouterResource()).thenReturn(virtRouterResource); + when(virtRouterResource.connect(controlIp, 1, 5000)).thenReturn(true); + } catch (final InternalErrorException e) { + fail(e.getMessage()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } catch (final URISyntaxException e) { + fail(e.getMessage()); + } + + final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(command, libvirtComputingResource); + assertTrue(answer.getResult()); + + verify(libvirtComputingResource, times(1)).getStoragePoolMgr(); + verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper(); + try { + verify(libvirtUtilitiesHelper, times(1)).getConnectionByType(vmDef.getHvsType()); + } catch (final LibvirtException e) { + fail(e.getMessage()); + } + } } \ No newline at end of file From b284b841929c74a8e5273f8a31a26ed9bba5d139 Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Wed, 6 May 2015 16:55:03 +0200 Subject: [PATCH 35/36] Fixing method call on KVMGuru to reach StorageSubSystemCommand --- .../cloudstack/storage/command/StorageSubSystemCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java b/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java index 6507bb08ccd..f50a5fb5759 100644 --- a/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java @@ -22,5 +22,5 @@ package org.apache.cloudstack.storage.command; import com.cloud.agent.api.Command; public abstract class StorageSubSystemCommand extends Command { - abstract void setExecuteInSequence(boolean inSeq); + public abstract void setExecuteInSequence(boolean inSeq); } \ No newline at end of file From f575206ad4348fb7fc0fe312a1e797bac23d011b Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 8 May 2015 19:53:03 +0200 Subject: [PATCH 36/36] Fixing testModifySshKeysCommand in the LibvirtComputingResourceTest class - The test was okay, but when running in an environment where a /root/.ssh/id_rsa existed, it would return true then fail - We now mock the calls to methods that return the key paths, instead of relying in the static variables --- .../LibvirtModifySshKeysCommandWrapper.java | 27 ++++++++++++------- .../wrapper/LibvirtUtilitiesHelper.java | 13 +++++++++ .../LibvirtComputingResourceTest.java | 7 +++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java index d5943c5f034..1295e7d3e54 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtModifySshKeysCommandWrapper.java @@ -38,21 +38,28 @@ public final class LibvirtModifySshKeysCommandWrapper extends CommandWrapper