Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id AA13F17950 for ; Thu, 2 Apr 2015 18:22:57 +0000 (UTC) Received: (qmail 58746 invoked by uid 500); 2 Apr 2015 18:22:44 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 58702 invoked by uid 500); 2 Apr 2015 18:22:44 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 57377 invoked by uid 99); 2 Apr 2015 18:22:43 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 02 Apr 2015 18:22:43 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 0E3ADE2F66; Thu, 2 Apr 2015 18:22:43 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: bhaisaab@apache.org To: commits@cloudstack.apache.org Date: Thu, 02 Apr 2015 18:23:13 -0000 Message-Id: <3d2f53818c814474814a6be66f2675b0@git.apache.org> In-Reply-To: <6a8fce03a2e842598ff8434e61a9df66@git.apache.org> References: <6a8fce03a2e842598ff8434e61a9df66@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [32/39] git commit: updated refs/heads/master to 3e28747 http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4600eef8/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 6ef756c..ee9fd2b 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -19,7 +19,6 @@ package com.cloud.hypervisor.xenserver.resource; import java.io.BufferedReader; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URI; @@ -32,7 +31,6 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -61,87 +59,19 @@ import org.xml.sax.SAXException; import com.cloud.agent.IAgentControl; 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.CheckHealthAnswer; -import com.cloud.agent.api.CheckHealthCommand; -import com.cloud.agent.api.CheckNetworkAnswer; -import com.cloud.agent.api.CheckNetworkCommand; -import com.cloud.agent.api.CheckOnHostAnswer; -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.ClusterVMMetaDataSyncAnswer; -import com.cloud.agent.api.ClusterVMMetaDataSyncCommand; import com.cloud.agent.api.Command; -import com.cloud.agent.api.CreateStoragePoolCommand; -import com.cloud.agent.api.CreateVMSnapshotAnswer; -import com.cloud.agent.api.CreateVMSnapshotCommand; -import com.cloud.agent.api.DeleteStoragePoolCommand; -import com.cloud.agent.api.DeleteVMSnapshotAnswer; -import com.cloud.agent.api.DeleteVMSnapshotCommand; -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; import com.cloud.agent.api.HostVmStateReportEntry; -import com.cloud.agent.api.MaintainAnswer; -import com.cloud.agent.api.MaintainCommand; -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; -import com.cloud.agent.api.NetworkRulesSystemVmCommand; -import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; -import com.cloud.agent.api.OvsCreateGreTunnelAnswer; -import com.cloud.agent.api.OvsCreateGreTunnelCommand; -import com.cloud.agent.api.OvsCreateTunnelAnswer; -import com.cloud.agent.api.OvsCreateTunnelCommand; -import com.cloud.agent.api.OvsDeleteFlowCommand; -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.OvsSetTagAndFlowAnswer; import com.cloud.agent.api.OvsSetTagAndFlowCommand; -import com.cloud.agent.api.OvsSetupBridgeCommand; -import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; -import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; -import com.cloud.agent.api.PerformanceMonitorAnswer; -import com.cloud.agent.api.PerformanceMonitorCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PingRoutingWithOvsCommand; -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; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; -import com.cloud.agent.api.RebootRouterCommand; -import com.cloud.agent.api.RevertToVMSnapshotAnswer; -import com.cloud.agent.api.RevertToVMSnapshotCommand; -import com.cloud.agent.api.ScaleVmAnswer; -import com.cloud.agent.api.ScaleVmCommand; -import com.cloud.agent.api.SecurityGroupRuleAnswer; -import com.cloud.agent.api.SecurityGroupRulesCmd; -import com.cloud.agent.api.SetupAnswer; -import com.cloud.agent.api.SetupCommand; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -151,29 +81,13 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.agent.api.UnPlugNicAnswer; -import com.cloud.agent.api.UnPlugNicCommand; -import com.cloud.agent.api.UpdateHostPasswordCommand; -import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.VgpuTypesInfo; 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; import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; -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; -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; @@ -181,9 +95,7 @@ import com.cloud.agent.api.to.GPUDeviceTO; 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.api.to.VolumeTO; import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.exception.InternalErrorException; @@ -194,7 +106,6 @@ import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetworkSetupInfo; import com.cloud.resource.ServerResource; import com.cloud.resource.hypervisor.HypervisorResource; import com.cloud.storage.Storage; @@ -203,7 +114,6 @@ import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.resource.StorageSubsystemCommandHandler; import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; -import com.cloud.storage.template.TemplateProp; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; @@ -215,10 +125,8 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SSHCmdHelper; import com.cloud.utils.ssh.SshHelper; -import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; -import com.cloud.vm.snapshot.VMSnapshot; import com.trilead.ssh2.SCPClient; import com.xensource.xenapi.Bond; import com.xensource.xenapi.Connection; @@ -260,57 +168,8 @@ import com.xensource.xenapi.XenAPIObject; @Local(value = ServerResource.class) public abstract class CitrixResourceBase implements ServerResource, HypervisorResource, VirtualRouterDeployer { - private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class); - - static final Random Rand = new Random(System.currentTimeMillis()); - protected static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance(); - - protected String _name; - protected String _username; - protected Queue _password = new LinkedList(); - protected final int _retry = 100; - protected final int _sleep = 10000; - protected long _dcId; - protected String _pod; - protected String _cluster; - protected String _privateNetworkName; - protected String _linkLocalPrivateNetworkName; - protected String _publicNetworkName; - protected String _storageNetworkName1; - protected String _storageNetworkName2; - protected String _guestNetworkName; - protected int _wait; - protected int _migratewait; - protected String _instance; //instance name (default is usually "VM") - protected boolean _securityGroupEnabled; - protected IAgentControl _agentControl; - - final int _maxWeight = 256; - protected int _heartbeatTimeout = 120; - protected int _heartbeatInterval = 60; - protected final XsHost _host = new XsHost(); - - // Guest and Host Performance Statistics - protected String _consolidationFunction = "AVERAGE"; - protected int _pollingIntervalInSeconds = 60; - - //Hypervisor specific params with generic value, may need to be overridden for specific versions - long _xsMemoryUsed = 128 * 1024 * 1024L; // xenserver hypervisor used 128 M - double _xsVirtualizationFactor = 63.0 / 64.0; // 1 - virtualization overhead - - //static min values for guests on xenserver - private static final long mem_128m = 134217728L; - - protected boolean _canBridgeFirewall = false; - protected boolean _isOvs = false; - protected List _tmpDom0Vif = new ArrayList(); - protected StorageSubsystemCommandHandler storageHandler; - protected int _maxNics = 7; - - protected VirtualRoutingResource _vrResource; - public enum SRType { - NFS, LVM, ISCSI, ISO, LVMOISCSI, LVMOHBA, EXT, FILE; + EXT, FILE, ISCSI, ISO, LVM, LVMOHBA, LVMOISCSI, NFS; String _str; @@ -318,17 +177,24 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe _str = super.toString().toLowerCase(); } + public boolean equals(final String type) { + return _str.equalsIgnoreCase(type); + } + @Override public String toString() { return _str; } - - public boolean equals(final String type) { - return _str.equalsIgnoreCase(type); - } } + protected static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance(); + //static min values for guests on xenserver + private static final long mem_128m = 134217728L; + + static final Random Rand = new Random(System.currentTimeMillis()); + private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class); protected static final HashMap s_powerStatesTable; + static { s_powerStatesTable = new HashMap(); s_powerStatesTable.put(VmPowerState.HALTED, PowerState.PowerOff); @@ -338,44 +204,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_powerStatesTable.put(VmPowerState.UNRECOGNIZED, PowerState.PowerUnknown); } - public XsHost getHost() { - return _host; - } - - public String getVMInstanceName() { - return _instance; - } - - public void addToPwdQueue(final String password) { - _password.add(password); - } - - public VirtualRoutingResource getVirtualRoutingResource() { - return _vrResource; - } - - public boolean isOvs() { - return _isOvs; - } - - public void setIsOvs(final boolean isOvs) { - _isOvs = isOvs; - } - - public boolean isSecurityGroupEnabled() { - return _securityGroupEnabled; - } - - public void setCanBridgeFirewall(final boolean canBridgeFirewall) { - _canBridgeFirewall = canBridgeFirewall; - } - - public boolean canBridgeFirewall() { - return _canBridgeFirewall; - } - - public boolean canBridgeFirewall(final Connection conn) { - return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.getUuid(), "instance", _instance)); + private static PowerState convertToPowerState(final VmPowerState ps) { + final PowerState powerState = s_powerStatesTable.get(ps); + return powerState == null ? PowerState.PowerUnknown : powerState; } private static boolean isAlienVm(final VM vm, final Connection conn) throws XenAPIException, XmlRpcException { @@ -388,184 +219,89 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return true; } - public boolean cleanupHaltedVms(final Connection conn) throws XenAPIException, XmlRpcException { - final Host host = Host.getByUuid(conn, _host.getUuid()); - final Map vms = VM.getAllRecords(conn); - boolean success = true; - if(vms != null && !vms.isEmpty()) { - for (final Map.Entry entry : vms.entrySet()) { - final VM vm = entry.getKey(); - final VM.Record vmRec = entry.getValue(); - if (vmRec.isATemplate || vmRec.isControlDomain) { - continue; - } - - if (VmPowerState.HALTED.equals(vmRec.powerState) && vmRec.affinity.equals(host) && !isAlienVm(vm, conn)) { - try { - vm.destroy(conn); - } catch (final Exception e) { - s_logger.warn("Catch Exception " + e.getClass().getName() + ": unable to destroy VM " + vmRec.nameLabel + " due to ", e); - success = false; - } - } - } - } - return success; - } - - public boolean isRefNull(final XenAPIObject object) { - return object == null || object.toWireString().equals("OpaqueRef:NULL") || object.toWireString().equals(""); - } + protected IAgentControl _agentControl; + protected boolean _canBridgeFirewall = false; + protected String _cluster; + // Guest and Host Performance Statistics + protected String _consolidationFunction = "AVERAGE"; + protected long _dcId; + protected String _guestNetworkName; + protected int _heartbeatInterval = 60; + protected int _heartbeatTimeout = 120; + protected final XsHost _host = new XsHost(); + protected String _instance; //instance name (default is usually "VM") + protected boolean _isOvs = false; + protected String _linkLocalPrivateNetworkName; + protected int _maxNics = 7; - @Override - public void disconnected() { - } + final int _maxWeight = 256; + protected int _migratewait; + protected String _name; + protected Queue _password = new LinkedList(); - protected boolean pingdomr(final Connection conn, final String host, final String port) { - String status; - status = callHostPlugin(conn, "vmops", "pingdomr", "host", host, "port", port); + protected String _pod; + protected int _pollingIntervalInSeconds = 60; - if (status == null || status.isEmpty()) { - return false; - } + protected String _privateNetworkName; + protected String _publicNetworkName; - return true; + protected final int _retry = 100; - } + protected boolean _securityGroupEnabled; + protected final int _sleep = 10000; + protected String _storageNetworkName1; + protected String _storageNetworkName2; + protected List _tmpDom0Vif = new ArrayList(); - public boolean pingXAPI() { - final Connection conn = getConnection(); - try { - final Host host = Host.getByUuid(conn, _host.getUuid()); - if( !host.getEnabled(conn) ) { - s_logger.debug("Host " + _host.getIp() + " is not enabled!"); - return false; - } - } catch (final Exception e) { - s_logger.debug("cannot get host enabled status, host " + _host.getIp() + " due to " + e.toString(), e); - return false; - } - try { - callHostPlugin(conn, "echo", "main"); - } catch (final Exception e) { - s_logger.debug("cannot ping host " + _host.getIp() + " due to " + e.toString(), e); - return false; - } - return true; - } + protected String _username; + protected VirtualRoutingResource _vrResource; - protected String logX(final XenAPIObject obj, final String msg) { - return new StringBuilder("Host ").append(_host.getIp()).append(" ").append(obj.toWireString()).append(": ").append(msg).toString(); - } + protected int _wait; + //Hypervisor specific params with generic value, may need to be overridden for specific versions + long _xsMemoryUsed = 128 * 1024 * 1024L; // xenserver hypervisor used 128 M - @Override - public Answer executeRequest(final Command cmd) { + double _xsVirtualizationFactor = 63.0 / 64.0; // 1 - virtualization overhead - // We need this one because the StorageSubSystemCommand is from another hierarchy. - if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); - } + protected StorageSubsystemCommandHandler storageHandler; - final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); - try { - return wrapper.execute(cmd, this); - } catch (final Exception e) { - return Answer.createUnsupportedCommandAnswer(cmd); - } + public CitrixResourceBase() { } - @Override - public ExecutionResult executeInVR(final String routerIP, final String script, final String args, final int timeout) { - Pair result; - String cmdline = "/opt/cloud/bin/router_proxy.sh " + script + " " + routerIP + " " + args; - // semicolon need to be escape for bash - cmdline = cmdline.replaceAll(";", "\\\\;"); - try { - s_logger.debug("Executing command in VR: " + cmdline); - result = SshHelper.sshExecute(_host.getIp(), 22, _username, null, _password.peek(), cmdline, - 60000, 60000, timeout * 1000); - } catch (final Exception e) { - return new ExecutionResult(false, e.getMessage()); - } - return new ExecutionResult(result.first(), result.second()); + public void addToPwdQueue(final String password) { + _password.add(password); } - @Override - public ExecutionResult executeInVR(final String routerIP, final String script, final String args) { - // Timeout is 120 seconds by default - return executeInVR(routerIP, script, args, 120); + protected StorageSubsystemCommandHandler buildStorageHandler() { + final XenServerStorageProcessor processor = new XenServerStorageProcessor(this); + return new StorageSubsystemCommandHandlerBase(processor); } - @Override - public ExecutionResult createFileInVR(final String routerIp, final String path, final String filename, final String content) { - final Connection conn = getConnection(); - final String hostPath = "/tmp/"; - - s_logger.debug("Copying VR with ip " + routerIp +" config file into host "+ _host.getIp() ); + public String callHostPlugin(final Connection conn, final String plugin, final String cmd, final String... params) { + final Map args = new HashMap(); + String msg; try { - SshHelper.scpTo(_host.getIp(), 22, _username, null, _password.peek(), hostPath, content.getBytes(Charset.defaultCharset()), filename, null); - } catch (final Exception e) { - s_logger.warn("scp VR config file into host " + _host.getIp() + " failed with exception " + e.getMessage().toString()); - } + for (int i = 0; i < params.length; i += 2) { + args.put(params[i], params[i + 1]); + } - final String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "srcfilepath", hostPath + filename, "dstfilepath", path); - s_logger.debug ("VR Config file " + filename + " got created in VR, ip " + routerIp + " with content \n" + content); - - return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); - } - - @Override - public ExecutionResult prepareCommand(final NetworkElementCommand cmd) { - //Update IP used to access router - cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); - assert cmd.getRouterAccessIp() != null; - - if (cmd instanceof IpAssocVpcCommand) { - return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); - } else if (cmd instanceof IpAssocCommand) { - return prepareNetworkElementCommand((IpAssocCommand)cmd); - } else if (cmd instanceof SetupGuestNetworkCommand) { - return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); - } else if (cmd instanceof SetSourceNatCommand) { - return prepareNetworkElementCommand((SetSourceNatCommand)cmd); - } else if (cmd instanceof SetNetworkACLCommand) { - return prepareNetworkElementCommand((SetNetworkACLCommand)cmd); - } - return new ExecutionResult(true, null); - } - - @Override - public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) { - if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) { - return cleanupNetworkElementCommand((IpAssocCommand)cmd); - } - return new ExecutionResult(true, null); - } - - private Answer execute(final PerformanceMonitorCommand cmd) { - final Connection conn = getConnection(); - final String perfMon = getPerfMon(conn, cmd.getParams(), cmd.getWait()); - if (perfMon == null) { - return new PerformanceMonitorAnswer(cmd, false, perfMon); - } else { - return new PerformanceMonitorAnswer(cmd, true, perfMon); - } - } - - public String getPerfMon(final Connection conn, final Map params, - final int wait) { - String result = null; - try { - result = callHostPluginAsync(conn, "vmopspremium", "asmonitor", 60, - params); - if (result != null) { - return result; + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); } - } catch (final Exception e) { - s_logger.error("Can not get performance monitor for AS due to ", e); + final Host host = Host.getByUuid(conn, _host.getUuid()); + final String result = host.callPlugin(conn, plugin, cmd, args); + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin Result: " + result); + } + return result.replace("\n", ""); + } catch (final XenAPIException e) { + msg = "callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(); + s_logger.warn(msg); + } catch (final XmlRpcException e) { + msg = "callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(); + s_logger.debug(msg); } - return null; + throw new CloudRuntimeException(msg); } protected String callHostPluginAsync(final Connection conn, final String plugin, @@ -614,866 +350,662 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return null; } - public void scaleVM(final Connection conn, final VM vm, final VirtualMachineTO vmSpec, final Host host) throws XenAPIException, XmlRpcException { - - final Long staticMemoryMax = vm.getMemoryStaticMax(conn); - final Long staticMemoryMin = vm.getMemoryStaticMin(conn); - final Long newDynamicMemoryMin = vmSpec.getMinRam(); - final Long newDynamicMemoryMax = vmSpec.getMaxRam(); - if (staticMemoryMin > newDynamicMemoryMin || newDynamicMemoryMax > staticMemoryMax) { - throw new CloudRuntimeException("Cannot scale up the vm because of memory constraint violation: " + "0 <= memory-static-min(" + staticMemoryMin + - ") <= memory-dynamic-min(" + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")"); - } - - vm.setMemoryDynamicRange(conn, newDynamicMemoryMin, newDynamicMemoryMax); - vm.setVCPUsNumberLive(conn, (long)vmSpec.getCpus()); - - final Integer speed = vmSpec.getMinSpeed(); - if (speed != null) { - - int cpuWeight = _maxWeight; //cpu_weight - - // weight based allocation - - cpuWeight = (int)(speed * 0.99 / _host.getSpeed() * _maxWeight); - if (cpuWeight > _maxWeight) { - cpuWeight = _maxWeight; - } - - if (vmSpec.getLimitCpuUse()) { - long utilization = 0; // max CPU cap, default is unlimited - utilization = (int)(vmSpec.getMaxSpeed() * 0.99 * vmSpec.getCpus() / _host.getSpeed() * 100); - //vm.addToVCPUsParamsLive(conn, "cap", Long.toString(utilization)); currently xenserver doesnot support Xapi to add VCPUs params live. - callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", Long.toString(utilization), "vmname", vmSpec.getName()); - } - //vm.addToVCPUsParamsLive(conn, "weight", Integer.toString(cpuWeight)); - callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", Integer.toString(cpuWeight), "vmname", vmSpec.getName()); - } - } - - public ScaleVmAnswer execute(final ScaleVmCommand cmd) { - final VirtualMachineTO vmSpec = cmd.getVirtualMachine(); - final String vmName = vmSpec.getName(); + protected String callHostPluginAsync(final Connection conn, final String plugin, final String cmd, final int wait, final String... params) { + final int timeout = wait * 1000; + final Map args = new HashMap(); + Task task = null; try { - final Connection conn = getConnection(); - final Set vms = VM.getByNameLabel(conn, vmName); - final Host host = Host.getByUuid(conn, _host.getUuid()); - - // If DMC is not enable then don't execute this command. - if (!isDmcEnabled(conn, host)) { - throw new CloudRuntimeException("Unable to scale the vm: " + vmName + " as DMC - Dynamic memory control is not enabled for the XenServer:" + _host.getUuid() + - " ,check your license and hypervisor version."); + for (int i = 0; i < params.length; i += 2) { + args.put(params[i], params[i + 1]); } - - // stop vm which is running on this host or is in halted state - final Iterator iter = vms.iterator(); - while (iter.hasNext()) { - final VM vm = iter.next(); - final VM.Record vmr = vm.getRecord(conn); - - if (vmr.powerState == VmPowerState.HALTED || - vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.getUuid())) { - iter.remove(); - } + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); } - - if (vms.size() == 0) { - s_logger.info("No running VM " + vmName + " exists on XenServer" + _host.getUuid()); - return new ScaleVmAnswer(cmd, false, "VM does not exist"); + final Host host = Host.getByUuid(conn, _host.getUuid()); + task = host.callPluginAsync(conn, plugin, cmd, args); + // poll every 1 seconds + waitForTask(conn, task, 1000, timeout); + checkForSuccess(conn, task); + final String result = task.getResult(conn); + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin Result: " + result); } - - for (final VM vm : vms) { - vm.getRecord(conn); + return result.replace("", "").replace("", "").replace("\n", ""); + } catch (final Types.HandleInvalid e) { + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + + e.handle); + } catch (final XenAPIException e) { + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); + } catch (final Exception e) { + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(), e); + } finally { + if (task != null) { try { - scaleVM(conn, vm, vmSpec, host); - } catch (final Exception e) { - final String msg = "Catch exception " + e.getClass().getName() + " when scaling VM:" + vmName + " due to " + e.toString(); - s_logger.debug(msg); - return new ScaleVmAnswer(cmd, false, msg); + task.destroy(conn); + } catch (final Exception e1) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString()); } - } - final String msg = "scaling VM " + vmName + " is successful on host " + host; - s_logger.debug(msg); - return new ScaleVmAnswer(cmd, true, msg); - - } catch (final XenAPIException e) { - final String msg = "Upgrade Vm " + vmName + " fail due to " + e.toString(); - s_logger.warn(msg, e); - return new ScaleVmAnswer(cmd, false, msg); - } catch (final XmlRpcException e) { - final String msg = "Upgrade Vm " + vmName + " fail due to " + e.getMessage(); - s_logger.warn(msg, e); - return new ScaleVmAnswer(cmd, false, msg); - } catch (final Exception e) { - final String msg = "Unable to upgrade " + vmName + " due to " + e.getMessage(); - s_logger.warn(msg, e); - return new ScaleVmAnswer(cmd, false, msg); } + return null; } - private Answer execute(final RevertToVMSnapshotCommand cmd) { - final String vmName = cmd.getVmName(); - final List listVolumeTo = cmd.getVolumeTOs(); - final VMSnapshot.Type vmSnapshotType = cmd.getTarget().getType(); - final Boolean snapshotMemory = vmSnapshotType == VMSnapshot.Type.DiskAndMemory; - final Connection conn = getConnection(); - PowerState vmState = null; - VM vm = null; - try { - - final Set vmSnapshots = VM.getByNameLabel(conn, cmd.getTarget().getSnapshotName()); - if (vmSnapshots.size() == 0) { - return new RevertToVMSnapshotAnswer(cmd, false, "Cannot find vmSnapshot with name: " + cmd.getTarget().getSnapshotName()); - } - - final VM vmSnapshot = vmSnapshots.iterator().next(); + public String callHostPluginPremium(final Connection conn, final String cmd, final String... params) { + return callHostPlugin(conn, "vmopspremium", cmd, params); + } - // find target VM or creating a work VM - try { - vm = getVM(conn, vmName); - } catch (final Exception e) { - vm = createWorkingVM(conn, vmName, cmd.getGuestOSType(), cmd.getPlatformEmulator(), listVolumeTo); - } + protected String callHostPluginThroughMaster(final Connection conn, final String plugin, final String cmd, final String... params) { + final Map args = new HashMap(); - if (vm == null) { - return new RevertToVMSnapshotAnswer(cmd, false, "Revert to VM Snapshot Failed due to can not find vm: " + vmName); + try { + final Map poolRecs = Pool.getAllRecords(conn); + if (poolRecs.size() != 1) { + throw new CloudRuntimeException("There are " + poolRecs.size() + " pool for host :" + _host.getUuid()); } - - // call plugin to execute revert - revertToSnapshot(conn, vmSnapshot, vmName, vm.getUuid(conn), snapshotMemory, _host.getUuid()); - vm = getVM(conn, vmName); - final Set vbds = vm.getVBDs(conn); - final Map vdiMap = new HashMap(); - // get vdi:vbdr to a map - for (final VBD vbd : vbds) { - final VBD.Record vbdr = vbd.getRecord(conn); - if (vbdr.type == Types.VbdType.DISK) { - final VDI vdi = vbdr.VDI; - vdiMap.put(vbdr.userdevice, vdi); - } + final Host master = poolRecs.values().iterator().next().master; + for (int i = 0; i < params.length; i += 2) { + args.put(params[i], params[i + 1]); } - if (!snapshotMemory) { - vm.destroy(conn); - vmState = PowerState.PowerOff; - } else { - vmState = PowerState.PowerOn; + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); } - - // after revert, VM's volumes path have been changed, need to report to manager - for (final VolumeObjectTO volumeTo : listVolumeTo) { - final Long deviceId = volumeTo.getDeviceId(); - final VDI vdi = vdiMap.get(deviceId.toString()); - volumeTo.setPath(vdi.getUuid(conn)); + final String result = master.callPlugin(conn, plugin, cmd, args); + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin Result: " + result); } - - return new RevertToVMSnapshotAnswer(cmd, listVolumeTo, vmState); - } catch (final Exception e) { - s_logger.error("revert vm " + vmName + " to snapshot " + cmd.getTarget().getSnapshotName() + " failed due to " + e.getMessage()); - return new RevertToVMSnapshotAnswer(cmd, false, e.getMessage()); + return result.replace("\n", ""); + } catch (final Types.HandleInvalid e) { + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + + e.handle); + } catch (final XenAPIException e) { + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); + } catch (final XmlRpcException e) { + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(), e); } + return null; } - public String revertToSnapshot(final Connection conn, final VM vmSnapshot, final String vmName, final String oldVmUuid, final Boolean snapshotMemory, final String hostUUID) throws XenAPIException, - XmlRpcException { + public boolean canBridgeFirewall() { + return _canBridgeFirewall; + } - final String results = - callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid", - oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID); - String errMsg = null; - if (results == null || results.isEmpty()) { - errMsg = "revert_memory_snapshot return null"; - } else { - if (results.equals("0")) { - return results; - } else { - errMsg = "revert_memory_snapshot exception"; - } - } - s_logger.warn(errMsg); - throw new CloudRuntimeException(errMsg); + public boolean canBridgeFirewall(final Connection conn) { + return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.getUuid(), "instance", _instance)); } - public XsLocalNetwork getNativeNetworkForTraffic(final Connection conn, final TrafficType type, final String name) throws XenAPIException, XmlRpcException { - if (name != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Looking for network named " + name); + public void checkForSuccess(final Connection c, final Task task) throws XenAPIException, XmlRpcException { + if (task.getStatus(c) == Types.TaskStatusType.SUCCESS) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") completed"); } - return getNetworkByName(conn, name); - } - - if (type == TrafficType.Guest) { - return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getGuestNetwork()), null, PIF.getByUuid(conn, _host.getGuestPif()), null); - } else if (type == TrafficType.Control) { - setupLinkLocalNetwork(conn); - return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getLinkLocalNetwork())); - } else if (type == TrafficType.Management) { - return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getPrivateNetwork()), null, PIF.getByUuid(conn, _host.getPrivatePif()), null); - } else if (type == TrafficType.Public) { - return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getPublicNetwork()), null, PIF.getByUuid(conn, _host.getPublicPif()), null); - } else if (type == TrafficType.Storage) { - /* TrafficType.Storage is for secondary storage, while storageNetwork1 is for primary storage, we need better name here */ - return new XsLocalNetwork(this, Network.getByUuid(conn, _host.getStorageNetwork1()), null, PIF.getByUuid(conn, _host.getStoragePif1()), null); + return; + } else { + final String msg = "Task failed! Task record: " + task.getRecord(c); + s_logger.warn(msg); + task.cancel(c); + task.destroy(c); + throw new Types.BadAsyncResult(msg); } - - throw new CloudRuntimeException("Unsupported network type: " + type); } - public synchronized Network setupvSwitchNetwork(final Connection conn) { + protected boolean checkSR(final Connection conn, final SR sr) { try { - if (_host.getVswitchNetwork() == null) { - Network vswitchNw = null; - final Network.Record rec = new Network.Record(); - final String nwName = Networks.BroadcastScheme.VSwitch.toString(); - final Set networks = Network.getByNameLabel(conn, nwName); - - if (networks.size() == 0) { - rec.nameDescription = "vswitch network for " + nwName; - rec.nameLabel = nwName; - vswitchNw = Network.create(conn, rec); - } else { - vswitchNw = networks.iterator().next(); - } - _host.setVswitchNetwork(vswitchNw); + final SR.Record srr = sr.getRecord(conn); + final Set pbds = sr.getPBDs(conn); + if (pbds.size() == 0) { + final String msg = "There is no PBDs for this SR: " + srr.nameLabel + " on host:" + _host.getUuid(); + s_logger.warn(msg); + return false; } - return _host.getVswitchNetwork(); - } catch (final BadServerResponse e) { - s_logger.error("Failed to setup vswitch network", e); - } catch (final XenAPIException e) { - s_logger.error("Failed to setup vswitch network", e); - } catch (final XmlRpcException e) { - s_logger.error("Failed to setup vswitch network", e); - } - - return null; - } - - /** - * This method just creates a XenServer network following the tunnel network naming convention - */ - public synchronized Network findOrCreateTunnelNetwork(final Connection conn, final String nwName) { - try { - Network nw = null; - final Network.Record rec = new Network.Record(); - final Set networks = Network.getByNameLabel(conn, nwName); - - if (networks.size() == 0) { - rec.nameDescription = "tunnel network id# " + nwName; - rec.nameLabel = nwName; - //Initialize the ovs-host-setup to avoid error when doing get-param in plugin - final Map otherConfig = new HashMap(); - otherConfig.put("ovs-host-setup", ""); - // Mark 'internal network' as shared so bridge gets automatically created on each host in the cluster - // when VM with vif connected to this internal network is started - otherConfig.put("assume_network_is_shared", "true"); - rec.otherConfig = otherConfig; - nw = Network.create(conn, rec); - s_logger.debug("### XenServer network for tunnels created:" + nwName); - } else { - nw = networks.iterator().next(); - s_logger.debug("XenServer network for tunnels found:" + nwName); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Checking " + srr.nameLabel + " or SR " + srr.uuid + " on " + _host); } - return nw; - } catch (final Exception e) { - s_logger.warn("createTunnelNetwork failed", e); - return null; - } - } + if (srr.shared) { + if (SRType.NFS.equals(srr.type) ){ + final Map smConfig = srr.smConfig; + if( !smConfig.containsKey("nosubdir")) { + smConfig.put("nosubdir", "true"); + sr.setSmConfig(conn,smConfig); + } + } - /** - * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network - */ - public synchronized Network configureTunnelNetwork(final Connection conn, final Long networkId, final long hostId, final String bridgeName) { - try { - final Network nw = findOrCreateTunnelNetwork(conn, bridgeName); - final String nwName = bridgeName; - //Invoke plugin to setup the bridge which will be used by this network - final String bridge = nw.getBridge(conn); - final Map nwOtherConfig = nw.getOtherConfig(conn); - final String configuredHosts = nwOtherConfig.get("ovs-host-setup"); - boolean configured = false; - if (configuredHosts != null) { - final String hostIdsStr[] = configuredHosts.split(","); - for (final String hostIdStr : hostIdsStr) { - if (hostIdStr.equals(((Long)hostId).toString())) { - configured = true; + final Host host = Host.getByUuid(conn, _host.getUuid()); + boolean found = false; + for (final PBD pbd : pbds) { + final PBD.Record pbdr = pbd.getRecord(conn); + if (host.equals(pbdr.host)) { + if (!pbdr.currentlyAttached) { + pbdPlug(conn, pbd, pbdr.uuid); + } + found = true; break; } } - } - - if (!configured) { - String result; - if (bridgeName.startsWith("OVS-DR-VPC-Bridge")) { - result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge_for_distributed_routing", "bridge", bridge, - "key", bridgeName, - "xs_nw_uuid", nw.getUuid(conn), - "cs_host_id", ((Long)hostId).toString()); - } else { - result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge, - "key", bridgeName, - "xs_nw_uuid", nw.getUuid(conn), - "cs_host_id", ((Long)hostId).toString()); + if (!found) { + final PBD.Record pbdr = srr.PBDs.iterator().next().getRecord(conn); + pbdr.host = host; + pbdr.uuid = ""; + final PBD pbd = PBD.create(conn, pbdr); + pbdPlug(conn, pbd, pbd.getUuid(conn)); } - - //Note down the fact that the ovs bridge has been setup - final String[] res = result.split(":"); - if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) { - //TODO: Should make this error not fatal? - throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge ); + } else { + for (final PBD pbd : pbds) { + final PBD.Record pbdr = pbd.getRecord(conn); + if (!pbdr.currentlyAttached) { + pbdPlug(conn, pbd, pbdr.uuid); + } } } - return nw; - } catch (final Exception e) { - s_logger.warn("createandConfigureTunnelNetwork failed", e); - return null; - } - } - public synchronized void destroyTunnelNetwork(final Connection conn, final Network nw, final long hostId) { - try { - final String bridge = nw.getBridge(conn); - final String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge, - "cs_host_id", ((Long)hostId).toString()); - final String[] res = result.split(":"); - if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) { - //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 + ":" + result); - } - return; } catch (final Exception e) { - s_logger.warn("destroyTunnelNetwork failed:", e); - return; + final String msg = "checkSR failed host:" + _host + " due to " + e.toString(); + s_logger.warn(msg, e); + return false; } + return true; } - public Network getNetwork(final Connection conn, final NicTO nic) throws XenAPIException, XmlRpcException { - final String name = nic.getName(); - final XsLocalNetwork network = getNativeNetworkForTraffic(conn, nic.getType(), name); - if (network == null) { - s_logger.error("Network is not configured on the backend for nic " + nic.toString()); - throw new CloudRuntimeException("Network for the backend is not configured correctly for network broadcast domain: " + nic.getBroadcastUri()); + private void CheckXenHostInfo() throws ConfigurationException { + final Connection conn = ConnPool.getConnect(_host.getIp(), _username, _password); + if( conn == null ) { + throw new ConfigurationException("Can not create connection to " + _host.getIp()); } - final URI uri = nic.getBroadcastUri(); - final BroadcastDomainType type = nic.getBroadcastType(); - if (uri != null && uri.toString().contains("untagged")) { - return network.getNetwork(); - } else if (uri != null && type == BroadcastDomainType.Vlan) { - assert BroadcastDomainType.getSchemeValue(uri) == BroadcastDomainType.Vlan; - final long vlan = Long.parseLong(BroadcastDomainType.getValue(uri)); - return enableVlanNetwork(conn, vlan, network); - } else if (type == BroadcastDomainType.Native || type == BroadcastDomainType.LinkLocal || - type == BroadcastDomainType.Vsp) { - return network.getNetwork(); - } else if (uri != null && type == BroadcastDomainType.Vswitch) { - final String header = uri.toString().substring(Networks.BroadcastDomainType.Vswitch.scheme().length() + "://".length()); - if (header.startsWith("vlan")) { - _isOvs = true; - return setupvSwitchNetwork(conn); - } else { - return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(uri.getAuthority())); + try { + Host.Record hostRec = null; + try { + final Host host = Host.getByUuid(conn, _host.getUuid()); + hostRec = host.getRecord(conn); + final Pool.Record poolRec = Pool.getAllRecords(conn).values().iterator().next(); + _host.setPool(poolRec.uuid); + + } catch (final Exception e) { + throw new ConfigurationException("Can not get host information from " + _host.getIp()); } - } else if (type == BroadcastDomainType.Storage) { - if (uri == null) { - return network.getNetwork(); - } else { - final long vlan = Long.parseLong(BroadcastDomainType.getValue(uri)); - return enableVlanNetwork(conn, vlan, network); + if (!hostRec.address.equals(_host.getIp())) { + final String msg = "Host " + _host.getIp() + " seems be reinstalled, please remove this host and readd"; + s_logger.error(msg); + throw new ConfigurationException(msg); } - } else if (type == BroadcastDomainType.Lswitch) { - // Nicira Logical Switch - return network.getNetwork(); - } else if (uri != null && type == BroadcastDomainType.Pvlan) { - assert BroadcastDomainType.getSchemeValue(uri) == BroadcastDomainType.Pvlan; - // should we consider moving this NetUtils method to BroadcastDomainType? - final long vlan = Long.parseLong(NetUtils.getPrimaryPvlanFromUri(uri)); - return enableVlanNetwork(conn, vlan, network); - } - - throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri()); - } - - private String getOvsTunnelNetworkName(final String broadcastUri) { - if (broadcastUri.contains(".")) { - final String[] parts = broadcastUri.split("\\."); - return "OVS-DR-VPC-Bridge"+parts[0]; - } else { + } finally { try { - return "OVSTunnel" + broadcastUri; + Session.logout(conn); } catch (final Exception e) { - return null; } } } - public VIF createVif(final Connection conn, final String vmName, final VM vm, final VirtualMachineTO vmSpec, final NicTO nic) throws XmlRpcException, XenAPIException { - assert nic.getUuid() != null : "Nic should have a uuid value"; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VIF for " + vmName + " on nic " + nic); - } - VIF.Record vifr = new VIF.Record(); - vifr.VM = vm; - vifr.device = Integer.toString(nic.getDeviceId()); - vifr.MAC = nic.getMac(); - - // Nicira needs these IDs to find the NIC - vifr.otherConfig = new HashMap(); - vifr.otherConfig.put("nicira-iface-id", nic.getUuid()); - vifr.otherConfig.put("nicira-vm-id", vm.getUuid(conn)); - // Provide XAPI with the cloudstack vm and nic uids. - vifr.otherConfig.put("cloudstack-nic-id", nic.getUuid()); - if (vmSpec != null) { - vifr.otherConfig.put("cloudstack-vm-id", vmSpec.getUuid()); + @Override + public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) { + if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) { + return cleanupNetworkElementCommand((IpAssocCommand)cmd); } + return new ExecutionResult(true, null); + } - // OVS plugin looks at network UUID in the vif 'otherconfig' details to group VIF's & tunnel ports as part of tier - // when bridge is setup for distributed routing - vifr.otherConfig.put("cloudstack-network-id", nic.getNetworkUuid()); - // Nuage Vsp needs Virtual Router IP to be passed in the otherconfig - // get the virtual router IP information from broadcast uri - final URI broadcastUri = nic.getBroadcastUri(); - if (broadcastUri != null && broadcastUri.getScheme().equalsIgnoreCase(Networks.BroadcastDomainType.Vsp.scheme())) { - final String path = broadcastUri.getPath(); - vifr.otherConfig.put("vsp-vr-ip", path.substring(1)); - } - vifr.network = getNetwork(conn, nic); - - if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) { - vifr.qosAlgorithmType = "ratelimit"; - vifr.qosAlgorithmParams = new HashMap(); - // convert mbs to kilobyte per second - vifr.qosAlgorithmParams.put("kbps", Integer.toString(nic.getNetworkRateMbps() * 128)); - } + public boolean cleanupHaltedVms(final Connection conn) throws XenAPIException, XmlRpcException { + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Map vms = VM.getAllRecords(conn); + boolean success = true; + if(vms != null && !vms.isEmpty()) { + for (final Map.Entry entry : vms.entrySet()) { + final VM vm = entry.getKey(); + final VM.Record vmRec = entry.getValue(); + if (vmRec.isATemplate || vmRec.isControlDomain) { + continue; + } - vifr.lockingMode = Types.VifLockingMode.NETWORK_DEFAULT; - final VIF vif = VIF.create(conn, vifr); - if (s_logger.isDebugEnabled()) { - vifr = vif.getRecord(conn); - if(vifr != null) { - s_logger.debug("Created a vif " + vifr.uuid + " on " + nic.getDeviceId()); + if (VmPowerState.HALTED.equals(vmRec.powerState) && vmRec.affinity.equals(host) && !isAlienVm(vm, conn)) { + try { + vm.destroy(conn); + } catch (final Exception e) { + s_logger.warn("Catch Exception " + e.getClass().getName() + ": unable to destroy VM " + vmRec.nameLabel + " due to ", e); + success = false; + } + } } } - - return vif; + return success; } - public void prepareISO(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException { + protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) { + final Connection conn = getConnection(); + final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + final String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + try { + final IpAddressTO[] ips = cmd.getIpAddresses(); + final int ipsCount = ips.length; + for (final IpAddressTO ip : ips) { - final Set vms = VM.getByNameLabel(conn, vmName); - if (vms == null || vms.size() != 1) { - throw new CloudRuntimeException("There are " + (vms == null ? "0" : vms.size()) + " VMs named " + vmName); - } - final VM vm = vms.iterator().next(); - final Set vbds = vm.getVBDs(conn); - for (final VBD vbd : vbds) { - final VBD.Record vbdr = vbd.getRecord(conn); - if (vbdr.type == Types.VbdType.CD && vbdr.empty == false) { - final VDI vdi = vbdr.VDI; - final SR sr = vdi.getSR(conn); - final Set pbds = sr.getPBDs(conn); - if (pbds == null) { - throw new CloudRuntimeException("There is no pbd for sr " + sr); + final VM router = getVM(conn, routerName); + + final NicTO nic = new NicTO(); + nic.setMac(ip.getVifMacAddress()); + nic.setType(ip.getTrafficType()); + if (ip.getBroadcastUri()== null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); + nic.setBroadcastUri(uri); } - for (final PBD pbd : pbds) { - final PBD.Record pbdr = pbd.getRecord(conn); - if (pbdr.host.getUuid(conn).equals(_host.getUuid())) { - return; + nic.setDeviceId(0); + nic.setNetworkRateMbps(ip.getNetworkRate()); + nic.setName(ip.getNetworkName()); + + Network network = getNetwork(conn, nic); + + + // If we are disassociating the last IP address in the VLAN, we need + // to remove a VIF + boolean removeVif = false; + + //there is only one ip in this public vlan and removing it, so remove the nic + if (ipsCount == 1 && !ip.isAdd()) { + removeVif = true; + } + + if (removeVif) { + + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + final VIF correctVif = getCorrectVif(conn, router, network); + if (correctVif != null) { + network = correctVif.getNetwork(conn); + + // Mark this vif to be removed from network usage + networkUsage(conn, routerIp, "deleteVif", "eth" + correctVif.getDevice(conn)); + + // Remove the VIF from DomR + correctVif.unplug(conn); + correctVif.destroy(conn); + + // Disable the VLAN network if necessary + disableVlanNetwork(conn, network); } } - sr.setShared(conn, true); - final Host host = Host.getByUuid(conn, _host.getUuid()); - final PBD.Record pbdr = pbds.iterator().next().getRecord(conn); - pbdr.host = host; - pbdr.uuid = ""; - final PBD pbd = PBD.create(conn, pbdr); - pbdPlug(conn, pbd, pbd.getUuid(conn)); - break; } + } catch (final Exception e) { + s_logger.debug("Ip Assoc failure on applying one ip due to exception: ", e); + return new ExecutionResult(false, e.getMessage()); } + return new ExecutionResult(true, null); } - protected VDI mount(final Connection conn, final String vmName, final DiskTO volume) throws XmlRpcException, XenAPIException { - final DataTO data = volume.getData(); - final Volume.Type type = volume.getType(); - if (type == Volume.Type.ISO) { - final TemplateObjectTO iso = (TemplateObjectTO)data; - final DataStoreTO store = iso.getDataStore(); - - if (store == null) { - //It's a fake iso - return null; + public void cleanupTemplateSR(final Connection conn) { + Set pbds = null; + try { + final Host host = Host.getByUuid(conn, _host.getUuid()); + pbds = host.getPBDs(conn); + } catch (final XenAPIException e) { + s_logger.warn("Unable to get the SRs " + e.toString(), e); + throw new CloudRuntimeException("Unable to get SRs " + e.toString(), e); + } catch (final Exception e) { + throw new CloudRuntimeException("Unable to get SRs " + e.getMessage(), e); + } + for (final PBD pbd : pbds) { + SR sr = null; + SR.Record srRec = null; + try { + sr = pbd.getSR(conn); + srRec = sr.getRecord(conn); + } catch (final Exception e) { + s_logger.warn("pbd.getSR get Exception due to ", e); + continue; } - - //corer case, xenserver pv driver iso - final String templateName = iso.getName(); - if (templateName.startsWith("xs-tools")) { + final String type = srRec.type; + if (srRec.shared) { + continue; + } + if (SRType.NFS.equals(type) || SRType.ISO.equals(type) && srRec.nameDescription.contains("template")) { try { - final Set vdis = VDI.getByNameLabel(conn, templateName); - if (vdis.isEmpty()) { - throw new CloudRuntimeException("Could not find ISO with URL: " + templateName); - } - return vdis.iterator().next(); - } catch (final XenAPIException e) { - throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString()); + pbd.unplug(conn); + pbd.destroy(conn); + sr.forget(conn); } catch (final Exception e) { - throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString()); + s_logger.warn("forget SR catch Exception due to ", e); } } + } + } - if (!(store instanceof NfsTO)) { - throw new CloudRuntimeException("only support mount iso on nfs"); - } - final NfsTO nfsStore = (NfsTO)store; - final String isoPath = nfsStore.getUrl() + File.separator + iso.getPath(); - final int index = isoPath.lastIndexOf("/"); + public void cleanUpTmpDomVif(final Connection conn, final Network nw) throws XenAPIException, XmlRpcException { - final String mountpoint = isoPath.substring(0, index); - URI uri; + final Pair vm = getControlDomain(conn); + final VM dom0 = vm.first(); + final Set dom0Vifs = dom0.getVIFs(conn); + for (final VIF v : dom0Vifs) { + String vifName = "unknown"; try { - uri = new URI(mountpoint); - } catch (final URISyntaxException e) { - throw new CloudRuntimeException("Incorrect uri " + mountpoint, e); - } - final SR isoSr = createIsoSRbyURI(conn, uri, vmName, false); - - final String isoname = isoPath.substring(index + 1); - - final VDI isoVdi = getVDIbyLocationandSR(conn, isoname, isoSr); - - if (isoVdi == null) { - throw new CloudRuntimeException("Unable to find ISO " + isoPath); + final VIF.Record vifr = v.getRecord(conn); + if (v.getNetwork(conn).getUuid(conn).equals(nw.getUuid(conn))) { + if(vifr != null) { + final Map config = vifr.otherConfig; + vifName = config.get("nameLabel"); + } + s_logger.debug("A VIF in dom0 for the network is found - so destroy the vif"); + v.destroy(conn); + s_logger.debug("Destroy temp dom0 vif" + vifName + " success"); + } + } catch (final Exception e) { + s_logger.warn("Destroy temp dom0 vif " + vifName + "failed", e); } - return isoVdi; - } else { - final VolumeObjectTO vol = (VolumeObjectTO)data; - return VDI.getByUuid(conn, vol.getPath()); } } - public VBD createVbd(final Connection conn, final DiskTO volume, final String vmName, final VM vm, final BootloaderType bootLoaderType, VDI vdi) throws XmlRpcException, XenAPIException { - final Volume.Type type = volume.getType(); - - if (vdi == null) { - vdi = mount(conn, vmName, volume); + protected VDI cloudVDIcopy(final Connection conn, final VDI vdi, final SR sr, int wait) throws Exception { + Task task = null; + if (wait == 0) { + wait = 2 * 60 * 60; } - - if (vdi != null) { - if ("detached".equals(vdi.getNameLabel(conn))) { - vdi.setNameLabel(conn, vmName + "-DATA"); - } - - final Map smConfig = vdi.getSmConfig(conn); - for (final String key : smConfig.keySet()) { - if (key.startsWith("host_")) { - vdi.removeFromSmConfig(conn, key); - break; + try { + task = vdi.copyAsync(conn, sr); + // poll every 1 seconds , timeout after 2 hours + waitForTask(conn, task, 1000, (long)wait * 1000); + checkForSuccess(conn, task); + final VDI dvdi = Types.toVDI(task, conn); + return dvdi; + } finally { + if (task != null) { + try { + task.destroy(conn); + } catch (final Exception e) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e.toString()); } } } - final VBD.Record vbdr = new VBD.Record(); - vbdr.VM = vm; - if (vdi != null) { - vbdr.VDI = vdi; - } else { - vbdr.empty = true; - } - if (type == Volume.Type.ROOT && bootLoaderType == BootloaderType.PyGrub) { - vbdr.bootable = true; - } else if (type == Volume.Type.ISO && bootLoaderType == BootloaderType.CD) { - vbdr.bootable = true; - } - - vbdr.userdevice = Long.toString(volume.getDiskSeq()); - if (volume.getType() == Volume.Type.ISO) { - vbdr.mode = Types.VbdMode.RO; - vbdr.type = Types.VbdType.CD; - } else if (volume.getType() == Volume.Type.ROOT) { - vbdr.mode = Types.VbdMode.RW; - vbdr.type = Types.VbdType.DISK; - vbdr.unpluggable = false; - } else { - vbdr.mode = Types.VbdMode.RW; - vbdr.type = Types.VbdType.DISK; - vbdr.unpluggable = true; - } - final VBD vbd = VBD.create(conn, vbdr); + } - if (s_logger.isDebugEnabled()) { - s_logger.debug("VBD " + vbd.getUuid(conn) + " created for " + volume); + public HashMap clusterVMMetaDataSync(final Connection conn) { + final HashMap vmMetaDatum = new HashMap(); + try { + final Map vm_map = VM.getAllRecords(conn); //USE THIS TO GET ALL VMS FROM A CLUSTER + if(vm_map != null) { + for (final VM.Record record : vm_map.values()) { + if (record.isControlDomain || record.isASnapshot || record.isATemplate) { + continue; // Skip DOM0 + } + vmMetaDatum.put(record.nameLabel, StringUtils.mapToString(record.platform)); + } + } + } catch (final Throwable e) { + final String msg = "Unable to get vms through host " + _host.getUuid() + " due to to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg); } - - return vbd; + return vmMetaDatum; } + @Override + public boolean configure(final String name, final Map params) throws ConfigurationException { + _name = name; - private long getStaticMax(final String os, final boolean b, final long dynamicMinRam, final long dynamicMaxRam){ - final long recommendedValue = CitrixHelper.getXenServerStaticMax(os, b); - if(recommendedValue == 0){ - s_logger.warn("No recommended value found for dynamic max, setting static max and dynamic max equal"); - return dynamicMaxRam; - } - final long staticMax = Math.min(recommendedValue, 4l * dynamicMinRam); // XS constraint for stability - if (dynamicMaxRam > staticMax){ // XS contraint that dynamic max <= static max - s_logger.warn("dynamixMax " + dynamicMaxRam + " cant be greater than static max " + staticMax + ", can lead to stability issues. Setting static max as much as dynamic max "); - return dynamicMaxRam; + try { + _dcId = Long.parseLong((String)params.get("zone")); + } catch (final NumberFormatException e) { + throw new ConfigurationException("Unable to get the zone " + params.get("zone")); } - return staticMax; - } + _host.setUuid((String)params.get("guid")); - private long getStaticMin(final String os, final boolean b, final long dynamicMinRam, final long dynamicMaxRam) { - final long recommendedValue = CitrixHelper.getXenServerStaticMin(os, b); - if (recommendedValue == 0) { - s_logger.warn("No recommended value found for dynamic min"); - return dynamicMinRam; - } + _name = _host.getUuid(); + _host.setIp((String)params.get("ipaddress")); - if (dynamicMinRam < recommendedValue) { // XS contraint that dynamic min > static min - s_logger.warn("Vm is set to dynamixMin " + dynamicMinRam + " less than the recommended static min " + recommendedValue + ", could lead to stability issues"); + _username = (String)params.get("username"); + _password.add((String)params.get("password")); + _pod = (String)params.get("pod"); + _cluster = (String)params.get("cluster"); + _privateNetworkName = (String)params.get("private.network.device"); + _publicNetworkName = (String)params.get("public.network.device"); + _guestNetworkName = (String)params.get("guest.network.device"); + _instance = (String)params.get("instance.name"); + _securityGroupEnabled = Boolean.parseBoolean((String)params.get("securitygroupenabled")); + + _linkLocalPrivateNetworkName = (String)params.get("private.linkLocal.device"); + if (_linkLocalPrivateNetworkName == null) { + _linkLocalPrivateNetworkName = "cloud_link_local_network"; } - return dynamicMinRam; - } + _storageNetworkName1 = (String)params.get("storage.network.device1"); + _storageNetworkName2 = (String)params.get("storage.network.device2"); - public HashMap> getGPUGroupDetails(final Connection conn) throws XenAPIException, XmlRpcException { - return null; - } + _heartbeatTimeout = NumbersUtil.parseInt((String)params.get("xenserver.heartbeat.timeout"), 120); + _heartbeatInterval = NumbersUtil.parseInt((String)params.get("xenserver.heartbeat.interval"), 60); - public void createVGPU(final Connection conn, final StartCommand cmd, final VM vm, final GPUDeviceTO gpuDevice) throws XenAPIException, XmlRpcException { - } + String value = (String)params.get("wait"); + _wait = NumbersUtil.parseInt(value, 600); - public VM createVmFromTemplate(final Connection conn, final VirtualMachineTO vmSpec, final Host host) throws XenAPIException, XmlRpcException { - final String guestOsTypeName = getGuestOsType(vmSpec.getOs(), vmSpec.getPlatformEmulator(), vmSpec.getBootloader() == BootloaderType.CD); - final Set templates = VM.getByNameLabel(conn, guestOsTypeName); - if ( templates == null || templates.isEmpty()) { - throw new CloudRuntimeException("Cannot find template " + guestOsTypeName + " on XenServer host"); - } - assert templates.size() == 1 : "Should only have 1 template but found " + templates.size(); - final VM template = templates.iterator().next(); + value = (String)params.get("migratewait"); + _migratewait = NumbersUtil.parseInt(value, 3600); - final VM.Record vmr = template.getRecord(conn); - vmr.affinity = host; - vmr.otherConfig.remove("disks"); - vmr.otherConfig.remove("default_template"); - vmr.otherConfig.remove("mac_seed"); - vmr.isATemplate = false; - vmr.nameLabel = vmSpec.getName(); - vmr.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY; - vmr.actionsAfterShutdown = Types.OnNormalExit.DESTROY; - vmr.otherConfig.put("vm_uuid", vmSpec.getUuid()); - vmr.VCPUsMax = (long) vmSpec.getCpus(); // FIX ME: In case of dynamic scaling this VCPU max should be the minumum of - // recommended value for that template and capacity remaining on host + _maxNics = NumbersUtil.parseInt((String)params.get("xenserver.nics.max"), 7); - if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) { - //scaling is allowed - vmr.memoryStaticMin = getStaticMin(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD, vmSpec.getMinRam(), vmSpec.getMaxRam()); - vmr.memoryStaticMax = getStaticMax(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD, vmSpec.getMinRam(), vmSpec.getMaxRam()); - vmr.memoryDynamicMin = vmSpec.getMinRam(); - vmr.memoryDynamicMax = vmSpec.getMaxRam(); - if (guestOsTypeName.toLowerCase().contains("windows")) { - vmr.VCPUsMax = (long) vmSpec.getCpus(); - } else { - if (vmSpec.getVcpuMaxLimit() != null) { - vmr.VCPUsMax = (long) vmSpec.getVcpuMaxLimit(); - } - } - } else { - //scaling disallowed, set static memory target - if (vmSpec.isEnableDynamicallyScaleVm() && !isDmcEnabled(conn, host)) { - s_logger.warn("Host " + host.getHostname(conn) + " does not support dynamic scaling, so the vm " + vmSpec.getName() + " is not dynamically scalable"); - } - vmr.memoryStaticMin = vmSpec.getMinRam(); - vmr.memoryStaticMax = vmSpec.getMaxRam(); - vmr.memoryDynamicMin = vmSpec.getMinRam();; - vmr.memoryDynamicMax = vmSpec.getMaxRam(); + if (_pod == null) { + throw new ConfigurationException("Unable to get the pod"); + } - vmr.VCPUsMax = (long) vmSpec.getCpus(); + if (_host.getIp() == null) { + throw new ConfigurationException("Unable to get the host address"); } - vmr.VCPUsAtStartup = (long) vmSpec.getCpus(); - vmr.consoles.clear(); + if (_username == null) { + throw new ConfigurationException("Unable to get the username"); + } - final VM vm = VM.create(conn, vmr); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Created VM " + vm.getUuid(conn) + " for " + vmSpec.getName()); + if (_password.peek() == null) { + throw new ConfigurationException("Unable to get the password"); } - final Map vcpuParams = new HashMap(); + if (_host.getUuid() == null) { + throw new ConfigurationException("Unable to get the uuid"); + } - final Integer speed = vmSpec.getMinSpeed(); - if (speed != null) { + CheckXenHostInfo(); - int cpuWeight = _maxWeight; // cpu_weight - int utilization = 0; // max CPU cap, default is unlimited + storageHandler = buildStorageHandler(); - // weight based allocation, CPU weight is calculated per VCPU - cpuWeight = (int)(speed * 0.99 / _host.getSpeed() * _maxWeight); - if (cpuWeight > _maxWeight) { - cpuWeight = _maxWeight; - } + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, params)) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } + return true; + } - if (vmSpec.getLimitCpuUse()) { - // CPU cap is per VM, so need to assign cap based on the number of vcpus - utilization = (int)(vmSpec.getMaxSpeed() * 0.99 * vmSpec.getCpus() / _host.getSpeed() * 100); + /** + * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network + */ + public synchronized Network configureTunnelNetwork(final Connection conn, final Long networkId, final long hostId, final String bridgeName) { + try { + final Network nw = findOrCreateTunnelNetwork(conn, bridgeName); + //Invoke plugin to setup the bridge which will be used by this network + final String bridge = nw.getBridge(conn); + final Map nwOtherConfig = nw.getOtherConfig(conn); + final String configuredHosts = nwOtherConfig.get("ovs-host-setup"); + boolean configured = false; + if (configuredHosts != null) { + final String hostIdsStr[] = configuredHosts.split(","); + for (final String hostIdStr : hostIdsStr) { + if (hostIdStr.equals(((Long)hostId).toString())) { + configured = true; + break; + } + } } - vcpuParams.put("weight", Integer.toString(cpuWeight)); - vcpuParams.put("cap", Integer.toString(utilization)); + if (!configured) { + String result; + if (bridgeName.startsWith("OVS-DR-VPC-Bridge")) { + result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge_for_distributed_routing", "bridge", bridge, + "key", bridgeName, + "xs_nw_uuid", nw.getUuid(conn), + "cs_host_id", ((Long)hostId).toString()); + } else { + result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge, + "key", bridgeName, + "xs_nw_uuid", nw.getUuid(conn), + "cs_host_id", ((Long)hostId).toString()); + } + //Note down the fact that the ovs bridge has been setup + final String[] res = result.split(":"); + if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) { + //TODO: Should make this error not fatal? + throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge ); + } + } + return nw; + } catch (final Exception e) { + s_logger.warn("createandConfigureTunnelNetwork failed", e); + return null; } + } - if (vcpuParams.size() > 0) { - vm.setVCPUsParams(conn, vcpuParams); - } + public String connect(final Connection conn, final String vmname, final String ipAddress) { + return connect(conn, vmname, ipAddress, 3922); + } - final String bootArgs = vmSpec.getBootArgs(); - if (bootArgs != null && bootArgs.length() > 0) { - String pvargs = vm.getPVArgs(conn); - pvargs = pvargs + vmSpec.getBootArgs().replaceAll(" ", "%"); + public String connect(final Connection conn, final String vmName, final String ipAddress, final int port) { + for (int i = 0; i <= _retry; i++) { + try { + final Set vms = VM.getByNameLabel(conn, vmName); + if (vms.size() < 1) { + final String msg = "VM " + vmName + " is not running"; + s_logger.warn(msg); + return msg; + } + } catch (final Exception e) { + final String msg = "VM.getByNameLabel " + vmName + " failed due to " + e.toString(); + s_logger.warn(msg, e); + return msg; + } if (s_logger.isDebugEnabled()) { - s_logger.debug("PV args are " + pvargs); + s_logger.debug("Trying to connect to " + ipAddress + " attempt " + i + " of " + _retry); + } + if (pingdomr(conn, ipAddress, Integer.toString(port))) { + return null; + } + try { + Thread.sleep(_sleep); + } catch (final InterruptedException e) { } - vm.setPVArgs(conn, pvargs); } + final String msg = "Timeout, Unable to logon to " + ipAddress; + s_logger.debug(msg); - if (!(guestOsTypeName.startsWith("Windows") || guestOsTypeName.startsWith("Citrix") || guestOsTypeName.startsWith("Other"))) { - if (vmSpec.getBootloader() == BootloaderType.CD) { - final DiskTO[] disks = vmSpec.getDisks(); - for (final DiskTO disk : disks) { - if (disk.getType() == Volume.Type.ISO) { - final TemplateObjectTO iso = (TemplateObjectTO)disk.getData(); - final String osType = iso.getGuestOsType(); - if (osType != null) { - final String isoGuestOsName = getGuestOsType(osType, vmSpec.getPlatformEmulator(), vmSpec.getBootloader() == BootloaderType.CD); - if (!isoGuestOsName.equals(guestOsTypeName)) { - vmSpec.setBootloader(BootloaderType.PyGrub); - } - } - } - } - } - if (vmSpec.getBootloader() == BootloaderType.CD) { - vm.setPVBootloader(conn, "eliloader"); - if (!vm.getOtherConfig(conn).containsKey("install-repository")) { - vm.addToOtherConfig(conn, "install-repository", "cdrom"); - } - } else if (vmSpec.getBootloader() == BootloaderType.PyGrub) { - vm.setPVBootloader(conn, "pygrub"); + return msg; + } + + public String copyVhdFromSecondaryStorage(final Connection conn, final String mountpoint, final String sruuid, final int wait) { + final String nameLabel = "cloud-" + UUID.randomUUID().toString(); + final String results = + callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel); + String errMsg = null; + if (results == null || results.isEmpty()) { + errMsg = "copy_vhd_from_secondarystorage return null"; + } else { + final String[] tmp = results.split("#"); + final String status = tmp[0]; + if (status.equals("0")) { + return tmp[1]; } else { - vm.destroy(conn); - throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader()); + errMsg = tmp[1]; } } - try { - finalizeVmMetaData(vm, conn, vmSpec); - } catch (final Exception e) { - throw new CloudRuntimeException("Unable to finalize VM MetaData: " + vmSpec); + final String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1); + if (killCopyProcess(conn, source)) { + destroyVDIbyNameLabel(conn, nameLabel); } - return vm; + s_logger.warn(errMsg); + throw new CloudRuntimeException(errMsg); } + @Override + public ExecutionResult createFileInVR(final String routerIp, final String path, final String filename, final String content) { + final Connection conn = getConnection(); + final String hostPath = "/tmp/"; - protected void finalizeVmMetaData(final VM vm, final Connection conn, final VirtualMachineTO vmSpec) throws Exception { - - final Map details = vmSpec.getDetails(); - if (details != null) { - final String platformstring = details.get("platform"); - if (platformstring != null && !platformstring.isEmpty()) { - final Map platform = StringUtils.stringToMap(platformstring); - vm.setPlatform(conn, platform); - } else { - final String timeoffset = details.get("timeoffset"); - if (timeoffset != null) { - final Map platform = vm.getPlatform(conn); - platform.put("timeoffset", timeoffset); - vm.setPlatform(conn, platform); - } - final String coresPerSocket = details.get("cpu.corespersocket"); - if (coresPerSocket != null) { - final Map platform = vm.getPlatform(conn); - platform.put("cores-per-socket", coresPerSocket); - vm.setPlatform(conn, platform); - } - } - if ( !BootloaderType.CD.equals(vmSpec.getBootloader())) { - final String xenservertoolsversion = details.get("hypervisortoolsversion"); - if ((xenservertoolsversion == null || !xenservertoolsversion.equalsIgnoreCase("xenserver61")) && vmSpec.getGpuDevice() == null) { - final Map platform = vm.getPlatform(conn); - platform.remove("device_id"); - vm.setPlatform(conn, platform); - } - } + s_logger.debug("Copying VR with ip " + routerIp +" config file into host "+ _host.getIp() ); + try { + SshHelper.scpTo(_host.getIp(), 22, _username, null, _password.peek(), hostPath, content.getBytes(Charset.defaultCharset()), filename, null); + } catch (final Exception e) { + s_logger.warn("scp VR config file into host " + _host.getIp() + " failed with exception " + e.getMessage().toString()); } + + final String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "srcfilepath", hostPath + filename, "dstfilepath", path); + s_logger.debug ("VR Config file " + filename + " got created in VR, ip " + routerIp + " with content \n" + content); + + return new ExecutionResult(