diff --git a/api/src/com/cloud/agent/api/Answer.java b/api/src/com/cloud/agent/api/Answer.java index 9d106115d91..fd6a0d1b46a 100644 --- a/api/src/com/cloud/agent/api/Answer.java +++ b/api/src/com/cloud/agent/api/Answer.java @@ -26,16 +26,16 @@ public class Answer extends Command { this(null); } - public Answer(Command command) { + public Answer(final Command command) { this(command, true, null); } - public Answer(Command command, boolean success, String details) { + public Answer(final Command command, final boolean success, final String details) { result = success; this.details = details; } - public Answer(Command command, Exception e) { + public Answer(final Command command, final Exception e) { this(command, false, ExceptionUtil.toString(e)); } @@ -52,11 +52,11 @@ public class Answer extends Command { return false; } - public static UnsupportedAnswer createUnsupportedCommandAnswer(Command cmd) { - return new UnsupportedAnswer(cmd, "Unsupported command issued:" + cmd.toString() + ". Are you sure you got the right type of server?"); + public static UnsupportedAnswer createUnsupportedCommandAnswer(final Command cmd) { + return new UnsupportedAnswer(cmd, "Unsupported command issued: " + cmd.toString() + ". Are you sure you got the right type of server?"); } - public static UnsupportedAnswer createUnsupportedVersionAnswer(Command cmd) { + public static UnsupportedAnswer createUnsupportedVersionAnswer(final Command cmd) { return new UnsupportedAnswer(cmd, "Unsuppored Version."); } -} +} \ No newline at end of file diff --git a/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java b/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java index 0bde5e37941..0670eefd944 100644 --- a/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java +++ b/core/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java @@ -31,8 +31,8 @@ public abstract class AbstractDownloadCommand extends SsCommand { protected AbstractDownloadCommand() { } - protected AbstractDownloadCommand(String name, String url, ImageFormat format, Long accountId) { - assert (url != null); + protected AbstractDownloadCommand(final String name, String url, final ImageFormat format, final Long accountId) { + assert url != null; url = url.replace('\\', '/'); this.url = url; @@ -41,14 +41,14 @@ public abstract class AbstractDownloadCommand extends SsCommand { this.name = name; } - protected AbstractDownloadCommand(AbstractDownloadCommand that) { + protected AbstractDownloadCommand(final AbstractDownloadCommand that) { super(that); - assert (that.url != null); + assert that.url != null; - this.url = that.url.replace('\\', '/'); - this.format = that.format; - this.accountId = that.accountId; - this.name = that.name; + url = that.url.replace('\\', '/'); + format = that.format; + accountId = that.accountId; + name = that.name; } public String getUrl() { @@ -73,7 +73,7 @@ public abstract class AbstractDownloadCommand extends SsCommand { } public void setUrl(String url) { - assert (url != null); + assert url != null; url = url.replace('\\', '/'); this.url = url; } diff --git a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java index f8b88c963a4..ce8ed217a56 100644 --- a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java +++ b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java @@ -37,22 +37,13 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand { String primaryStorageUrl; protected PrimaryStorageDownloadCommand() { - } - public PrimaryStorageDownloadCommand(String url, StoragePool pool, int wait) { - super(null, url, null, null); - this.poolId = pool.getId(); - this.poolUuid = pool.getUuid(); - this.primaryPool = new StorageFilerTO(pool); - setWait(wait); - } - - public PrimaryStorageDownloadCommand(String name, String url, ImageFormat format, long accountId, StoragePool pool, int wait) { + public PrimaryStorageDownloadCommand(final String name, final String url, final ImageFormat format, final long accountId, final StoragePool pool, final int wait) { super(name, url, format, accountId); - this.poolId = pool.getId(); - this.poolUuid = pool.getUuid(); - this.primaryPool = new StorageFilerTO(pool); + poolId = pool.getId(); + poolUuid = pool.getUuid(); + primaryPool = new StorageFilerTO(pool); setWait(wait); } @@ -68,15 +59,15 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand { return primaryPool; } - public void setLocalPath(String path) { - this.localPath = path; + public void setLocalPath(final String path) { + localPath = path; } public String getLocalPath() { return localPath; } - public void setSecondaryStorageUrl(String url) { + public void setSecondaryStorageUrl(final String url) { secondaryStorageUrl = url; } @@ -84,7 +75,7 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand { return secondaryStorageUrl; } - public void setPrimaryStorageUrl(String url) { + public void setPrimaryStorageUrl(final String url) { primaryStorageUrl = url; } diff --git a/core/src/com/cloud/resource/CommandWrapper.java b/core/src/com/cloud/resource/CommandWrapper.java new file mode 100644 index 00000000000..15f7b080992 --- /dev/null +++ b/core/src/com/cloud/resource/CommandWrapper.java @@ -0,0 +1,98 @@ +// +// 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.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 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)); + 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/test/com/cloud/ha/XenServerFencerTest.java b/core/src/com/cloud/resource/RequestWrapper.java similarity index 65% rename from plugins/hypervisors/xenserver/test/com/cloud/ha/XenServerFencerTest.java rename to core/src/com/cloud/resource/RequestWrapper.java index bd1d8f80b23..6fd1c668855 100644 --- a/plugins/hypervisors/xenserver/test/com/cloud/ha/XenServerFencerTest.java +++ b/core/src/com/cloud/resource/RequestWrapper.java @@ -1,3 +1,4 @@ +// // 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 @@ -14,26 +15,18 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// -package com.cloud.ha; +package com.cloud.resource; -import static org.junit.Assert.assertEquals; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; -import org.junit.Test; +public abstract class RequestWrapper { - -public class XenServerFencerTest { - - @Test - public void testSetAndGetName() throws Exception { - XenServerFencer xenServerFencer = new XenServerFencer(); - String name = "name"; - - xenServerFencer.setName(name); - String actual = xenServerFencer.getName(); - - assertEquals(name, actual); - - } - -} + /** + * @param command to be executed. + * @return an Answer for the executed command. + */ + public abstract Answer execute(Command command, ServerResource serverResource); +} \ No newline at end of file diff --git a/core/test/org/apache/cloudstack/api/agent/test/AnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/AnswerTest.java index c685d682975..608791736ac 100644 --- a/core/test/org/apache/cloudstack/api/agent/test/AnswerTest.java +++ b/core/test/org/apache/cloudstack/api/agent/test/AnswerTest.java @@ -34,19 +34,19 @@ public class AnswerTest { @Test public void testExecuteInSequence() { - boolean b = a.executeInSequence(); + final boolean b = a.executeInSequence(); assertFalse(b); } @Test public void testGetResult() { - boolean b = a.getResult(); + final boolean b = a.getResult(); assertTrue(b); } @Test public void testGetDetails() { - String d = a.getDetails(); + final String d = a.getDetails(); assertTrue(d.equals("details")); } @@ -60,7 +60,7 @@ public class AnswerTest { assertFalse(b); String d = usa.getDetails(); - assertTrue(d.equals("Unsupported command issued:" + acc.toString() + ". Are you sure you got the right type of server?")); + assertTrue(d.contains("Unsupported command issued: " + acc.toString() + ". Are you sure you got the right type of server?")); usa = Answer.createUnsupportedVersionAnswer(acc); b = usa.executeInSequence(); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java index 5bc80363e17..265573d7e4a 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java @@ -16,11 +16,8 @@ // under the License. package com.cloud.hypervisor.xenserver.resource; -import java.util.ArrayList; import java.util.HashMap; -import org.apache.log4j.Logger; - import com.xensource.xenapi.Host; /** @@ -28,18 +25,13 @@ import com.xensource.xenapi.Host; * */ public class CitrixHelper { - private static final Logger s_logger = Logger.getLogger(CitrixHelper.class); - - private static final HashMap XenServerGuestOsMemoryMap = new HashMap(70); - private static final ArrayList GuestOsList = new ArrayList(70); - public static class MemoryValues { long max; long min; - public MemoryValues(long min, long max) { + public MemoryValues(final long min, final long max) { this.min = min * 1024 * 1024; this.max = max * 1024 * 1024; } @@ -53,8 +45,6 @@ public class CitrixHelper { } } - - static { XenServerGuestOsMemoryMap.put("CentOS 4.5 (32-bit)", new MemoryValues(256l, 16 * 1024l)); XenServerGuestOsMemoryMap.put("CentOS 4.6 (32-bit)", new MemoryValues(256l, 16 * 1024l)); @@ -207,37 +197,37 @@ public class CitrixHelper { XenServerGuestOsMemoryMap.put("Windows XP SP3 (32-bit)", new MemoryValues(256l, 4 * 1024l)); XenServerGuestOsMemoryMap.put("Ubuntu 10.04 (32-bit)", new MemoryValues(128l, 512l)); XenServerGuestOsMemoryMap.put("Ubuntu 10.04 (64-bit)", new MemoryValues(128l, 32 * 1024l)); - XenServerGuestOsMemoryMap.put("Ubuntu 10.10 (32-bit)", new MemoryValues(512l, 16*1024l)); - XenServerGuestOsMemoryMap.put("Ubuntu 10.10 (64-bit)", new MemoryValues(512l, 16*1024l)); + XenServerGuestOsMemoryMap.put("Ubuntu 10.10 (32-bit)", new MemoryValues(512l, 16 * 1024l)); + XenServerGuestOsMemoryMap.put("Ubuntu 10.10 (64-bit)", new MemoryValues(512l, 16 * 1024l)); XenServerGuestOsMemoryMap.put("Ubuntu 12.04 (32-bit)", new MemoryValues(512l, 32 * 1024l)); XenServerGuestOsMemoryMap.put("Ubuntu 12.04 (64-bit)", new MemoryValues(512l, 128 * 1024l)); XenServerGuestOsMemoryMap.put("Ubuntu 14.04 (32-bit)", new MemoryValues(512l, 32 * 1024l)); XenServerGuestOsMemoryMap.put("Ubuntu 14.04 (64-bit)", new MemoryValues(512l, 128 * 1024l)); } - public static long getXenServerStaticMax(String stdType, boolean bootFromCD) { - MemoryValues recommendedMaxMinMemory = XenServerGuestOsMemoryMap.get(stdType); + public static long getXenServerStaticMax(final String stdType, final boolean bootFromCD) { + final MemoryValues recommendedMaxMinMemory = XenServerGuestOsMemoryMap.get(stdType); if (recommendedMaxMinMemory == null) { return 0l; } return recommendedMaxMinMemory.getMax(); } - public static long getXenServerStaticMin(String stdType, boolean bootFromCD) { - MemoryValues recommendedMaxMinMemory = XenServerGuestOsMemoryMap.get(stdType); + public static long getXenServerStaticMin(final String stdType, final boolean bootFromCD) { + final MemoryValues recommendedMaxMinMemory = XenServerGuestOsMemoryMap.get(stdType); if (recommendedMaxMinMemory == null) { return 0l; } return recommendedMaxMinMemory.getMin(); } - public static String getProductVersion(Host.Record record) { + public static String getProductVersion(final Host.Record record) { String prodVersion = record.softwareVersion.get("product_version"); if (prodVersion == null) { prodVersion = record.softwareVersion.get("platform_version").trim(); } else { prodVersion = prodVersion.trim(); - String[] items = prodVersion.split("\\."); + final String[] items = prodVersion.split("\\."); if (Integer.parseInt(items[0]) > 6) { prodVersion = "6.5.0"; } else if (Integer.parseInt(items[0]) == 6 && Integer.parseInt(items[1]) >= 4) { 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 96374e4ca8d..77296365810 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,17 @@ 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 +79,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,19 +93,16 @@ 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; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.xenserver.resource.wrapper.CitrixRequestWrapper; 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; @@ -202,7 +111,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; @@ -214,10 +122,7 @@ 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; @@ -238,76 +143,27 @@ import com.xensource.xenapi.Types.VmPowerState; import com.xensource.xenapi.Types.XenAPIException; import com.xensource.xenapi.VBD; import com.xensource.xenapi.VDI; -import com.xensource.xenapi.VGPU; import com.xensource.xenapi.VIF; import com.xensource.xenapi.VLAN; import com.xensource.xenapi.VM; import com.xensource.xenapi.XenAPIObject; /** - * CitrixResourceBase encapsulates the calls to the XenServer Xapi process - * to perform the required functionalities for CloudStack. + * CitrixResourceBase encapsulates the calls to the XenServer Xapi process to + * perform the required functionalities for CloudStack. * - * ==============> READ THIS <============== - * Because the XenServer objects can expire when the session expires, we cannot - * keep any of the actual XenServer objects in this class. The only - * thing that is constant is the UUID of the XenServer objects but not the - * objects themselves! This is very important before you do any changes in - * this code here. + * ==============> READ THIS <============== Because the XenServer objects can + * expire when the session expires, we cannot keep any of the actual XenServer + * objects in this class. The only thing that is constant is the UUID of the + * XenServer objects but not the objects themselves! This is very important + * before you do any changes in this code here. * */ @Local(value = ServerResource.class) public abstract class CitrixResourceBase implements ServerResource, HypervisorResource, VirtualRouterDeployer { - private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class); - 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") - static final Random Rand = new Random(System.currentTimeMillis()); - 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; @@ -315,17 +171,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); @@ -335,12 +198,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_powerStatesTable.put(VmPowerState.UNRECOGNIZED, PowerState.PowerUnknown); } - public XsHost getHost() { - return _host; + 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 { - // TODO : we need a better way to tell whether or not the VM belongs to CloudStack + // TODO : we need a better way to tell whether or not the VM belongs to + // CloudStack final String vmName = vm.getNameLabel(conn); if (vmName.matches("^[ivs]-\\d+-.+")) { return false; @@ -349,11 +214,325 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return true; } - protected boolean cleanupHaltedVms(final Connection conn) throws XenAPIException, XmlRpcException { - final Host host = Host.getByUuid(conn, _host.uuid); + 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; + + final int _maxWeight = 256; + protected int _migratewait; + protected String _name; + protected Queue _password = new LinkedList(); + + protected String _pod; + protected int _pollingIntervalInSeconds = 60; + + protected String _privateNetworkName; + protected String _publicNetworkName; + + protected final int _retry = 100; + + protected boolean _securityGroupEnabled; + protected final int _sleep = 10000; + protected String _storageNetworkName1; + protected String _storageNetworkName2; + protected List _tmpDom0Vif = new ArrayList(); + + protected String _username; + + protected VirtualRoutingResource _vrResource; + + 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 + + double _xsVirtualizationFactor = 63.0 / 64.0; // 1 - virtualization overhead + + protected StorageSubsystemCommandHandler storageHandler; + + public CitrixResourceBase() { + } + + public void addToPwdQueue(final String password) { + _password.add(password); + } + + protected StorageSubsystemCommandHandler buildStorageHandler() { + final XenServerStorageProcessor processor = new XenServerStorageProcessor(this); + return new StorageSubsystemCommandHandlerBase(processor); + } + + public String callHostPlugin(final Connection conn, final String plugin, final String cmd, final String... params) { + final Map args = new HashMap(); + String msg; + try { + for (int i = 0; i < params.length; i += 2) { + args.put(params[i], params[i + 1]); + } + + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); + } + 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); + } + throw new CloudRuntimeException(msg); + } + + protected String callHostPluginAsync(final Connection conn, final String plugin, final String cmd, final int wait, final Map params) { + final int timeout = wait * 1000; + final Map args = new HashMap(); + Task task = null; + try { + for (final Map.Entry entry : params.entrySet()) { + args.put(entry.getKey(), entry.getValue()); + } + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); + } + 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); + } + 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 Exception e) { + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); + } finally { + if (task != null) { + try { + task.destroy(conn); + } catch (final Exception e1) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString()); + } + } + } + return null; + } + + 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 { + for (int i = 0; i < params.length; i += 2) { + args.put(params[i], params[i + 1]); + } + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); + } + 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); + } + 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 { + task.destroy(conn); + } catch (final Exception e1) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString()); + } + } + } + return null; + } + + public String callHostPluginPremium(final Connection conn, final String cmd, final String... params) { + return callHostPlugin(conn, "vmopspremium", cmd, params); + } + + protected String callHostPluginThroughMaster(final Connection conn, final String plugin, final String cmd, final String... params) { + final Map args = new HashMap(); + + try { + final Map poolRecs = Pool.getAllRecords(conn); + if (poolRecs.size() != 1) { + throw new CloudRuntimeException("There are " + poolRecs.size() + " pool for host :" + _host.getUuid()); + } + 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 (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); + } + final String result = master.callPlugin(conn, plugin, cmd, args); + if (s_logger.isTraceEnabled()) { + s_logger.trace("callHostPlugin Result: " + result); + } + 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 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)); + } + + 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; + } 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); + } + } + + protected boolean checkSR(final Connection conn, final SR sr) { + try { + 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; + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Checking " + srr.nameLabel + " or SR " + srr.uuid + " on " + _host); + } + 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); + } + } + + 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 (!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)); + } + } else { + for (final PBD pbd : pbds) { + final PBD.Record pbdr = pbd.getRecord(conn); + if (!pbdr.currentlyAttached) { + pbdPlug(conn, pbd, pbdr.uuid); + } + } + } + + } catch (final Exception e) { + final String msg = "checkSR failed host:" + _host + " due to " + e.toString(); + s_logger.warn(msg, e); + return false; + } + return true; + } + + 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()); + } + 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()); + } + 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); + } + } finally { + try { + Session.logout(conn); + } catch (final Exception e) { + } + } + } + + @Override + public ExecutionResult cleanupCommand(final NetworkElementCommand cmd) { + if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) { + return cleanupNetworkElementCommand((IpAssocCommand) cmd); + } + return new ExecutionResult(true, null); + } + + 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()) { + if (vms != null && !vms.isEmpty()) { for (final Map.Entry entry : vms.entrySet()) { final VM vm = entry.getKey(); final VM.Record vmRec = entry.getValue(); @@ -374,592 +553,265 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return success; } - protected boolean isRefNull(final XenAPIObject object) { - return object == null || object.toWireString().equals("OpaqueRef:NULL") || object.toWireString().equals(""); - } - - @Override - public void disconnected() { - } - - protected boolean pingdomr(final Connection conn, final String host, final String port) { - String status; - status = callHostPlugin(conn, "vmops", "pingdomr", "host", host, "port", port); - - if (status == null || status.isEmpty()) { - return false; - } - - return true; - - } - - protected boolean pingXAPI() { + 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 Host host = Host.getByUuid(conn, _host.uuid); - if( !host.getEnabled(conn) ) { - s_logger.debug("Host " + _host.ip + " is not enabled!"); - return false; + final IpAddressTO[] ips = cmd.getIpAddresses(); + final int ipsCount = ips.length; + for (final IpAddressTO ip : ips) { + + 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); + } + 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); + } + } } } catch (final Exception e) { - s_logger.debug("cannot get host enabled status, host " + _host.ip + " due to " + e.toString(), e); - return false; - } - try { - callHostPlugin(conn, "echo", "main"); - } catch (final Exception e) { - s_logger.debug("cannot ping host " + _host.ip + " due to " + e.toString(), e); - return false; - } - return true; - } - - - protected String logX(final XenAPIObject obj, final String msg) { - return new StringBuilder("Host ").append(_host.ip).append(" ").append(obj.toWireString()).append(": ").append(msg).toString(); - } - - @Override - public Answer executeRequest(final Command cmd) { - final Class clazz = cmd.getClass(); - if (clazz == CreateCommand.class) { - return execute((CreateCommand)cmd); - } else if (cmd instanceof NetworkElementCommand) { - return _vrResource.executeRequest((NetworkElementCommand)cmd); - } else if (clazz == CheckConsoleProxyLoadCommand.class) { - return execute((CheckConsoleProxyLoadCommand)cmd); - } else if (clazz == WatchConsoleProxyLoadCommand.class) { - return execute((WatchConsoleProxyLoadCommand)cmd); - } else if (clazz == ReadyCommand.class) { - return execute((ReadyCommand)cmd); - } else if (clazz == GetHostStatsCommand.class) { - return execute((GetHostStatsCommand)cmd); - } else if (clazz == GetVmStatsCommand.class) { - return execute((GetVmStatsCommand)cmd); - } else if (clazz == GetVmDiskStatsCommand.class) { - return execute((GetVmDiskStatsCommand)cmd); - } else if (clazz == CheckHealthCommand.class) { - return execute((CheckHealthCommand)cmd); - } else if (clazz == StopCommand.class) { - return execute((StopCommand)cmd); - } else if (clazz == RebootRouterCommand.class) { - return execute((RebootRouterCommand)cmd); - } else if (clazz == RebootCommand.class) { - return execute((RebootCommand)cmd); - } else if (clazz == CheckVirtualMachineCommand.class) { - return execute((CheckVirtualMachineCommand)cmd); - } else if (clazz == PrepareForMigrationCommand.class) { - return execute((PrepareForMigrationCommand)cmd); - } else if (clazz == MigrateCommand.class) { - return execute((MigrateCommand)cmd); - } else if (clazz == DestroyCommand.class) { - return execute((DestroyCommand)cmd); - } else if (clazz == CreateStoragePoolCommand.class) { - return execute((CreateStoragePoolCommand)cmd); - } else if (clazz == ModifyStoragePoolCommand.class) { - return execute((ModifyStoragePoolCommand)cmd); - } else if (clazz == DeleteStoragePoolCommand.class) { - return execute((DeleteStoragePoolCommand) cmd); - }else if (clazz == ResizeVolumeCommand.class) { - return execute((ResizeVolumeCommand) cmd); - } else if (clazz == AttachVolumeCommand.class) { - return execute((AttachVolumeCommand)cmd); - } else if (clazz == AttachIsoCommand.class) { - return execute((AttachIsoCommand) cmd); - } else if (clazz == UpgradeSnapshotCommand.class) { - return execute((UpgradeSnapshotCommand)cmd); - } else if (clazz == GetStorageStatsCommand.class) { - return execute((GetStorageStatsCommand)cmd); - } else if (clazz == PrimaryStorageDownloadCommand.class) { - return execute((PrimaryStorageDownloadCommand)cmd); - } else if (clazz == GetVncPortCommand.class) { - return execute((GetVncPortCommand)cmd); - } else if (clazz == SetupCommand.class) { - return execute((SetupCommand)cmd); - } else if (clazz == MaintainCommand.class) { - return execute((MaintainCommand)cmd); - } else if (clazz == PingTestCommand.class) { - return execute((PingTestCommand)cmd); - } else if (clazz == CheckOnHostCommand.class) { - return execute((CheckOnHostCommand)cmd); - } else if (clazz == ModifySshKeysCommand.class) { - return execute((ModifySshKeysCommand)cmd); - } else if (clazz == StartCommand.class) { - return execute((StartCommand)cmd); - } else if (clazz == CheckSshCommand.class) { - return execute((CheckSshCommand)cmd); - } else if (clazz == SecurityGroupRulesCmd.class) { - return execute((SecurityGroupRulesCmd)cmd); - } else if (clazz == OvsFetchInterfaceCommand.class) { - return execute((OvsFetchInterfaceCommand)cmd); - } else if (clazz == OvsCreateGreTunnelCommand.class) { - return execute((OvsCreateGreTunnelCommand)cmd); - } else if (clazz == OvsSetTagAndFlowCommand.class) { - return execute((OvsSetTagAndFlowCommand)cmd); - } else if (clazz == OvsDeleteFlowCommand.class) { - return execute((OvsDeleteFlowCommand)cmd); - } else if (clazz == OvsVpcPhysicalTopologyConfigCommand.class) { - return execute((OvsVpcPhysicalTopologyConfigCommand) cmd); - } else if (clazz == OvsVpcRoutingPolicyConfigCommand.class) { - return execute((OvsVpcRoutingPolicyConfigCommand) cmd); - } else if (clazz == CleanupNetworkRulesCmd.class) { - return execute((CleanupNetworkRulesCmd)cmd); - } else if (clazz == NetworkRulesSystemVmCommand.class) { - return execute((NetworkRulesSystemVmCommand)cmd); - } else if (clazz == OvsCreateTunnelCommand.class) { - return execute((OvsCreateTunnelCommand)cmd); - } else if (clazz == OvsSetupBridgeCommand.class) { - return execute((OvsSetupBridgeCommand)cmd); - } else if (clazz == OvsDestroyBridgeCommand.class) { - return execute((OvsDestroyBridgeCommand)cmd); - } else if (clazz == OvsDestroyTunnelCommand.class) { - return execute((OvsDestroyTunnelCommand)cmd); - } else if (clazz == UpdateHostPasswordCommand.class) { - return execute((UpdateHostPasswordCommand)cmd); - } else if (cmd instanceof ClusterVMMetaDataSyncCommand) { - return execute((ClusterVMMetaDataSyncCommand)cmd); - } else if (clazz == CheckNetworkCommand.class) { - return execute((CheckNetworkCommand)cmd); - } else if (clazz == PlugNicCommand.class) { - return execute((PlugNicCommand)cmd); - } else if (clazz == UnPlugNicCommand.class) { - return execute((UnPlugNicCommand) cmd); - } else if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); - } else if (clazz == CreateVMSnapshotCommand.class) { - return execute((CreateVMSnapshotCommand) cmd); - } else if (clazz == DeleteVMSnapshotCommand.class) { - return execute((DeleteVMSnapshotCommand) cmd); - } else if (clazz == RevertToVMSnapshotCommand.class) { - return execute((RevertToVMSnapshotCommand) cmd); - } else if (clazz == NetworkRulesVmSecondaryIpCommand.class) { - return execute((NetworkRulesVmSecondaryIpCommand) cmd); - } else if (clazz == ScaleVmCommand.class) { - return execute((ScaleVmCommand)cmd); - } else if (clazz == PvlanSetupCommand.class) { - return execute((PvlanSetupCommand)cmd); - } else if (clazz == PerformanceMonitorCommand.class) { - return execute((PerformanceMonitorCommand)cmd); - } else { - return Answer.createUnsupportedCommandAnswer(cmd); - } - } - - @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.ip, 22, _username, null, _password.peek(), cmdline, - 60000, 60000, timeout * 1000); - } 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(result.first(), result.second()); + return new ExecutionResult(true, null); } - @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); - } - - @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.ip ); + public void cleanupTemplateSR(final Connection conn) { + Set pbds = null; try { - SshHelper.scpTo(_host.ip, 22, _username, null, _password.peek(), hostPath, content.getBytes(Charset.defaultCharset()), filename, null); + 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) { - s_logger.warn("scp VR config file into host " + _host.ip + " failed with exception " + e.getMessage().toString()); + throw new CloudRuntimeException("Unable to get SRs " + e.getMessage(), e); } - - 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); - } - } - - private 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; + 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; + } + final String type = srRec.type; + if (srRec.shared) { + continue; + } + if (SRType.NFS.equals(type) || SRType.ISO.equals(type) && srRec.nameDescription.contains("template")) { + try { + pbd.unplug(conn); + pbd.destroy(conn); + sr.forget(conn); + } catch (final Exception e) { + s_logger.warn("forget SR catch Exception due to ", e); + } } - } catch (final Exception e) { - s_logger.error("Can not get performance monitor for AS due to ", e); } - return null; } - protected String callHostPluginAsync(final Connection conn, final String plugin, - final String cmd, final int wait, final Map params) { - final int timeout = wait * 1000; - final Map args = new HashMap(); + public void cleanUpTmpDomVif(final Connection conn, final Network nw) throws XenAPIException, XmlRpcException { + + 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 { + 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); + } + } + } + + 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; + } try { - for (final Map.Entry< String, String > entry : params.entrySet()) { - args.put(entry.getKey(), entry.getValue()); - } - if (s_logger.isTraceEnabled()) { - s_logger.trace("callHostPlugin executing for command " + cmd - + " with " + getArgsString(args)); - } - final Host host = Host.getByUuid(conn, _host.uuid); - task = host.callPluginAsync(conn, plugin, cmd, args); - // poll every 1 seconds - waitForTask(conn, task, 1000, timeout); + task = vdi.copyAsync(conn, sr); + // poll every 1 seconds , timeout after 2 hours + waitForTask(conn, task, 1000, (long) wait * 1000); checkForSuccess(conn, task); - final String result = task.getResult(conn); - if (s_logger.isTraceEnabled()) { - s_logger.trace("callHostPlugin Result: " + result); - } - 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 Exception e) { - s_logger.warn( - "callHostPlugin failed for cmd: " + cmd + " with args " - + getArgsString(args) + " due to " + e.toString(), - e); + final VDI dvdi = Types.toVDI(task, conn); + return dvdi; } finally { if (task != null) { try { task.destroy(conn); - } catch (final Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e1.toString()); - } - } - } - return null; - } - - protected 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.speed * _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.speed * 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(); - try { - final Connection conn = getConnection(); - final Set vms = VM.getByNameLabel(conn, vmName); - final Host host = Host.getByUuid(conn, _host.uuid); - - // 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.uuid + - " ,check your license and hypervisor version."); - } - - // 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.uuid)) { - iter.remove(); - } - } - - if (vms.size() == 0) { - s_logger.info("No running VM " + vmName + " exists on XenServer" + _host.uuid); - return new ScaleVmAnswer(cmd, false, "VM does not exist"); - } - - for (final VM vm : vms) { - vm.getRecord(conn); - 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); + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e.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); } } - 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; + public HashMap clusterVMMetaDataSync(final Connection conn) { + final HashMap vmMetaDatum = new HashMap(); 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(); - - // 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); - } - - if (vm == null) { - return new RevertToVMSnapshotAnswer(cmd, false, "Revert to VM Snapshot Failed due to can not find vm: " + vmName); - } - - // call plugin to execute revert - revertToSnapshot(conn, vmSnapshot, vmName, vm.getUuid(conn), snapshotMemory, _host.uuid); - 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 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)); } } - - if (!snapshotMemory) { - vm.destroy(conn); - vmState = PowerState.PowerOff; - } else { - vmState = PowerState.PowerOn; - } - - // 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)); - } - - 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()); + } 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 vmMetaDatum; } - protected String revertToSnapshot(final Connection conn, final VM vmSnapshot, final String vmName, final String oldVmUuid, final Boolean snapshotMemory, final String hostUUID) throws XenAPIException, - XmlRpcException { + @Override + public boolean configure(final String name, final Map params) throws ConfigurationException { + _name = name; - 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); - } - - protected 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); - } - return getNetworkByName(conn, name); - } - - if (type == TrafficType.Guest) { - return new XsLocalNetwork(Network.getByUuid(conn, _host.guestNetwork), null, PIF.getByUuid(conn, _host.guestPif), null); - } else if (type == TrafficType.Control) { - setupLinkLocalNetwork(conn); - return new XsLocalNetwork(Network.getByUuid(conn, _host.linkLocalNetwork)); - } else if (type == TrafficType.Management) { - return new XsLocalNetwork(Network.getByUuid(conn, _host.privateNetwork), null, PIF.getByUuid(conn, _host.privatePif), null); - } else if (type == TrafficType.Public) { - return new XsLocalNetwork(Network.getByUuid(conn, _host.publicNetwork), null, PIF.getByUuid(conn, _host.publicPif), 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(Network.getByUuid(conn, _host.storageNetwork1), null, PIF.getByUuid(conn, _host.storagePif1), null); - } - - throw new CloudRuntimeException("Unsupported network type: " + type); - } - - private synchronized Network setupvSwitchNetwork(final Connection conn) { try { - if (_host.vswitchNetwork == 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.vswitchNetwork = vswitchNw; - } - return _host.vswitchNetwork; - } 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); + _dcId = Long.parseLong((String) params.get("zone")); + } catch (final NumberFormatException e) { + throw new ConfigurationException("Unable to get the zone " + params.get("zone")); } - return null; + _host.setUuid((String) params.get("guid")); + + _name = _host.getUuid(); + _host.setIp((String) params.get("ipaddress")); + + _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"; + } + + _storageNetworkName1 = (String) params.get("storage.network.device1"); + _storageNetworkName2 = (String) params.get("storage.network.device2"); + + _heartbeatTimeout = NumbersUtil.parseInt((String) params.get("xenserver.heartbeat.timeout"), 120); + _heartbeatInterval = NumbersUtil.parseInt((String) params.get("xenserver.heartbeat.interval"), 60); + + String value = (String) params.get("wait"); + _wait = NumbersUtil.parseInt(value, 600); + + value = (String) params.get("migratewait"); + _migratewait = NumbersUtil.parseInt(value, 3600); + + _maxNics = NumbersUtil.parseInt((String) params.get("xenserver.nics.max"), 7); + + if (_pod == null) { + throw new ConfigurationException("Unable to get the pod"); + } + + if (_host.getIp() == null) { + throw new ConfigurationException("Unable to get the host address"); + } + + if (_username == null) { + throw new ConfigurationException("Unable to get the username"); + } + + if (_password.peek() == null) { + throw new ConfigurationException("Unable to get the password"); + } + + if (_host.getUuid() == null) { + throw new ConfigurationException("Unable to get the uuid"); + } + + CheckXenHostInfo(); + + storageHandler = buildStorageHandler(); + + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, params)) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } + return true; } /** - * This method just creates a XenServer network following the tunnel network naming convention + * This method creates a XenServer network and configures it for being used + * as a L2-in-L3 tunneled network */ - private 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); - } - return nw; - } catch (final Exception e) { - s_logger.warn("createTunnelNetwork failed", e); - return null; - } - } - - /** - * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network - */ - private synchronized Network configureTunnelNetwork(final Connection conn, final Long networkId, final long hostId, final String bridgeName) { + 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 + // 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"); @@ -967,7 +819,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (configuredHosts != null) { final String hostIdsStr[] = configuredHosts.split(","); for (final String hostIdStr : hostIdsStr) { - if (hostIdStr.equals(((Long)hostId).toString())) { + if (hostIdStr.equals(((Long) hostId).toString())) { configured = true; break; } @@ -977,22 +829,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe 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()); + 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()); + 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 + // 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 ); + // TODO: Should make this error not fatal? + throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge); } } return nw; @@ -1002,231 +850,221 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - private 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; - } + public String connect(final Connection conn, final String vmname, final String ipAddress) { + return connect(conn, vmname, ipAddress, 3922); } - protected 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()); - } - 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())); - } - } 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); - } - } 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 { + public String connect(final Connection conn, final String vmName, final String ipAddress, final int port) { + for (int i = 0; i <= _retry; i++) { try { - return "OVSTunnel" + broadcastUri; + 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("Trying to connect to " + ipAddress + " attempt " + i + " of " + _retry); + } + if (pingdomr(conn, ipAddress, Integer.toString(port))) { return null; } - } - } - - protected 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()); - } - - // 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)); - } - - 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()); - } - } - - return vif; - } - - protected void prepareISO(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException { - - 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); - } - for (final PBD pbd : pbds) { - final PBD.Record pbdr = pbd.getRecord(conn); - if (pbdr.host.getUuid(conn).equals(_host.uuid)) { - return; - } - } - sr.setShared(conn, true); - final Host host = Host.getByUuid(conn, _host.uuid); - 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; - } - } - } - - 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; - } - - //corer case, xenserver pv driver iso - final String templateName = iso.getName(); - if (templateName.startsWith("xs-tools")) { - 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()); - } catch (final Exception e) { - throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString()); - } - } - - 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("/"); - - final String mountpoint = isoPath.substring(0, index); - URI uri; try { - uri = new URI(mountpoint); - } catch (final URISyntaxException e) { - throw new CloudRuntimeException("Incorrect uri " + mountpoint, e); + Thread.sleep(_sleep); + } catch (final InterruptedException e) { } - final SR isoSr = createIsoSRbyURI(conn, uri, vmName, false); + } + final String msg = "Timeout, Unable to logon to " + ipAddress; + s_logger.debug(msg); - final String isoname = isoPath.substring(index + 1); + return msg; + } - final VDI isoVdi = getVDIbyLocationandSR(conn, isoname, isoSr); - - if (isoVdi == null) { - throw new CloudRuntimeException("Unable to find ISO " + isoPath); - } - return isoVdi; + 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 VolumeObjectTO vol = (VolumeObjectTO)data; - return VDI.getByUuid(conn, vol.getPath()); + final String[] tmp = results.split("#"); + final String status = tmp[0]; + if (status.equals("0")) { + return tmp[1]; + } else { + errMsg = tmp[1]; + } + } + final String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1); + if (killCopyProcess(conn, source)) { + destroyVDIbyNameLabel(conn, nameLabel); + } + 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/"; + + 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(rc.startsWith("succ#"), rc.substring(5)); + } + + protected SR createIsoSRbyURI(final Connection conn, final URI uri, final String vmName, final boolean shared) { + try { + final Map deviceConfig = new HashMap(); + String path = uri.getPath(); + path = path.replace("//", "/"); + deviceConfig.put("location", uri.getHost() + ":" + path); + final Host host = Host.getByUuid(conn, _host.getUuid()); + final SR sr = SR.create(conn, host, deviceConfig, new Long(0), uri.getHost() + path, "iso", "iso", "iso", shared, new HashMap()); + sr.setNameLabel(conn, vmName + "-ISO"); + sr.setNameDescription(conn, deviceConfig.get("location")); + + sr.scan(conn); + return sr; + } catch (final XenAPIException e) { + final String msg = "createIsoSRbyURI failed! mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } catch (final Exception e) { + final String msg = "createIsoSRbyURI failed! mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.getMessage(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); } } - protected VBD createVbd(final Connection conn, final DiskTO volume, final String vmName, final VM vm, final BootloaderType bootLoaderType, VDI vdi) throws XmlRpcException, XenAPIException { + protected SR createNfsSRbyURI(final Connection conn, final URI uri, final boolean shared) { + try { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating a " + (shared ? "shared SR for " : "not shared SR for ") + uri); + } + + final Map deviceConfig = new HashMap(); + String path = uri.getPath(); + path = path.replace("//", "/"); + deviceConfig.put("server", uri.getHost()); + deviceConfig.put("serverpath", path); + final String name = UUID.nameUUIDFromBytes(new String(uri.getHost() + path).getBytes()).toString(); + if (!shared) { + final Set srs = SR.getByNameLabel(conn, name); + for (final SR sr : srs) { + final SR.Record record = sr.getRecord(conn); + if (SRType.NFS.equals(record.type) && record.contentType.equals("user") && !record.shared) { + removeSRSync(conn, sr); + } + } + } + + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Map smConfig = new HashMap(); + smConfig.put("nosubdir", "true"); + final SR sr = SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, smConfig); + + if (!checkSR(conn, sr)) { + throw new Exception("no attached PBD"); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug(logX(sr, "Created a SR; UUID is " + sr.getUuid(conn) + " device config is " + deviceConfig)); + } + sr.scan(conn); + return sr; + } catch (final XenAPIException e) { + final String msg = "Can not create second storage SR mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } catch (final Exception e) { + final String msg = "Can not create second storage SR mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.getMessage(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } + } + + public VBD createPatchVbd(final Connection conn, final String vmName, final VM vm) throws XmlRpcException, XenAPIException { + + if (_host.getSystemvmisouuid() == null) { + final Set srs = SR.getByNameLabel(conn, "XenServer Tools"); + if (srs.size() != 1) { + throw new CloudRuntimeException("There are " + srs.size() + " SRs with name XenServer Tools"); + } + final SR sr = srs.iterator().next(); + sr.scan(conn); + + final SR.Record srr = sr.getRecord(conn); + + if (_host.getSystemvmisouuid() == null) { + for (final VDI vdi : srr.VDIs) { + final VDI.Record vdir = vdi.getRecord(conn); + if (vdir.nameLabel.contains("systemvm.iso")) { + _host.setSystemvmisouuid(vdir.uuid); + break; + } + } + } + if (_host.getSystemvmisouuid() == null) { + throw new CloudRuntimeException("can not find systemvmiso"); + } + } + + final VBD.Record cdromVBDR = new VBD.Record(); + cdromVBDR.VM = vm; + cdromVBDR.empty = true; + cdromVBDR.bootable = false; + cdromVBDR.userdevice = "3"; + cdromVBDR.mode = Types.VbdMode.RO; + cdromVBDR.type = Types.VbdType.CD; + final VBD cdromVBD = VBD.create(conn, cdromVBDR); + cdromVBD.insert(conn, VDI.getByUuid(conn, _host.getSystemvmisouuid())); + + return cdromVBD; + } + + protected boolean createSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String newFolder) { + final String result = callHostPlugin(conn, "vmopsSnapshot", "create_secondary_storage_folder", "remoteMountPath", remoteMountPath, "newFolder", newFolder); + return result != null; + } + + String createTemplateFromSnapshot(final Connection conn, final String templatePath, final String snapshotPath, final int wait) { + final String tmpltLocalDir = UUID.randomUUID().toString(); + final String results = callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, + "tmpltLocalDir", tmpltLocalDir); + String errMsg = null; + if (results == null || results.isEmpty()) { + errMsg = "create_privatetemplate_from_snapshot return null"; + } else { + final String[] tmp = results.split("#"); + final String status = tmp[0]; + if (status.equals("0")) { + return results; + } else { + errMsg = "create_privatetemplate_from_snapshot failed due to " + tmp[1]; + } + } + final String source = "cloud_mount/" + tmpltLocalDir; + killCopyProcess(conn, source); + s_logger.warn(errMsg); + throw new CloudRuntimeException(errMsg); + } + + 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) { @@ -1281,47 +1119,89 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return vbd; } + public VDI createVdi(final SR sr, final String vdiNameLabel, final Long volumeSize) throws Types.XenAPIException, XmlRpcException { + final Connection conn = getConnection(); - 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; - } - return staticMax; - } + final VDI.Record vdir = new VDI.Record(); + vdir.nameLabel = vdiNameLabel; + vdir.SR = sr; + vdir.type = Types.VdiType.USER; - 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; + final long totalSrSpace = sr.getPhysicalSize(conn); + final long unavailableSrSpace = sr.getPhysicalUtilisation(conn); + final long availableSrSpace = totalSrSpace - unavailableSrSpace; + + if (availableSrSpace < volumeSize) { + throw new CloudRuntimeException("Available space for SR cannot be less than " + volumeSize + "."); } - 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"); + vdir.virtualSize = volumeSize; + + return VDI.create(conn, vdir); + } + + public void createVGPU(final Connection conn, final StartCommand cmd, final VM vm, final GPUDeviceTO gpuDevice) throws XenAPIException, XmlRpcException { + } + + 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); } - return dynamicMinRam; + 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()); + } + + // 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)); + } + + 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()); + } + } + + return vif; } - - protected HashMap> getGPUGroupDetails(final Connection conn) throws XenAPIException, XmlRpcException { - return null; - } - - protected void createVGPU(final Connection conn, final StartCommand cmd, final VM vm, final GPUDeviceTO gpuDevice) throws XenAPIException, XmlRpcException { - } - - protected VM createVmFromTemplate(final Connection conn, final VirtualMachineTO vmSpec, final Host host) throws XenAPIException, XmlRpcException { + 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()) { + 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(); @@ -1337,11 +1217,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe 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 + 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 if (isDmcEnabled(conn, host) && vmSpec.isEnableDynamicallyScaleVm()) { - //scaling is allowed + // 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(); @@ -1354,13 +1236,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } } else { - //scaling disallowed, set static memory target + // 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.memoryDynamicMin = vmSpec.getMinRam(); + ; vmr.memoryDynamicMax = vmSpec.getMaxRam(); vmr.VCPUsMax = (long) vmSpec.getCpus(); @@ -1383,14 +1266,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe int utilization = 0; // max CPU cap, default is unlimited // weight based allocation, CPU weight is calculated per VCPU - cpuWeight = (int)(speed * 0.99 / _host.speed * _maxWeight); + cpuWeight = (int) (speed * 0.99 / _host.getSpeed() * _maxWeight); if (cpuWeight > _maxWeight) { cpuWeight = _maxWeight; } 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.speed * 100); + // 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); } vcpuParams.put("weight", Integer.toString(cpuWeight)); @@ -1417,7 +1301,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe final DiskTO[] disks = vmSpec.getDisks(); for (final DiskTO disk : disks) { if (disk.getType() == Volume.Type.ISO) { - final TemplateObjectTO iso = (TemplateObjectTO)disk.getData(); + 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); @@ -1448,6 +1332,447 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return vm; } + public VM createWorkingVM(final Connection conn, final String vmName, final String guestOSType, final String platformEmulator, final List listVolumeTo) + throws BadServerResponse, Types.VmBadPowerState, Types.SrFull, Types.OperationNotAllowed, XenAPIException, XmlRpcException { + // below is redundant but keeping for consistency and code readabilty + final String guestOsTypeName = platformEmulator; + if (guestOsTypeName == null) { + final String msg = " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + + ". you can choose 'Other install media' to run it as HVM"; + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + final VM template = getVM(conn, guestOsTypeName); + final VM vm = template.createClone(conn, vmName); + vm.setIsATemplate(conn, false); + final Map vdiMap = new HashMap(); + for (final VolumeObjectTO volume : listVolumeTo) { + final String vdiUuid = volume.getPath(); + try { + final VDI vdi = VDI.getByUuid(conn, vdiUuid); + vdiMap.put(vdi, volume); + } catch (final Types.UuidInvalid e) { + s_logger.warn("Unable to find vdi by uuid: " + vdiUuid + ", skip it"); + } + } + for (final Map.Entry entry : vdiMap.entrySet()) { + final VDI vdi = entry.getKey(); + final VolumeObjectTO volumeTO = entry.getValue(); + final VBD.Record vbdr = new VBD.Record(); + vbdr.VM = vm; + vbdr.VDI = vdi; + if (volumeTO.getVolumeType() == Volume.Type.ROOT) { + vbdr.bootable = true; + vbdr.unpluggable = false; + } else { + vbdr.bootable = false; + vbdr.unpluggable = true; + } + vbdr.userdevice = Long.toString(volumeTO.getDeviceId()); + vbdr.mode = Types.VbdMode.RW; + vbdr.type = Types.VbdType.DISK; + VBD.create(conn, vbdr); + } + return vm; + } + + protected boolean deleteSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String folder) { + final String details = callHostPlugin(conn, "vmopsSnapshot", "delete_secondary_storage_folder", "remoteMountPath", remoteMountPath, "folder", folder); + return details != null && details.equals("1"); + } + + protected String deleteSnapshotBackup(final Connection conn, final Long dcId, final Long accountId, final Long volumeId, final String secondaryStorageMountPath, + final String backupUUID) { + + // If anybody modifies the formatting below again, I'll skin them + final String result = callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), + "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath); + + return result; + } + + public void destroyPatchVbd(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException { + try { + if (!vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-")) { + return; + } + final Set vms = VM.getByNameLabel(conn, vmName); + for (final VM vm : vms) { + final Set vbds = vm.getVBDs(conn); + for (final VBD vbd : vbds) { + if (vbd.getType(conn) == Types.VbdType.CD) { + vbd.eject(conn); + vbd.destroy(conn); + break; + } + } + } + } catch (final Exception e) { + s_logger.debug("Cannot destory CD-ROM device for VM " + vmName + " due to " + e.toString(), e); + } + } + + 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; + } + } + + void destroyVDIbyNameLabel(final Connection conn, final String nameLabel) { + try { + final Set vdis = VDI.getByNameLabel(conn, nameLabel); + if (vdis.size() != 1) { + s_logger.warn("destoryVDIbyNameLabel failed due to there are " + vdis.size() + " VDIs with name " + nameLabel); + return; + } + for (final VDI vdi : vdis) { + try { + vdi.destroy(conn); + } catch (final Exception e) { + final String msg = "Failed to destroy VDI : " + nameLabel + "due to " + e.toString() + "\n Force deleting VDI using system 'rm' command"; + s_logger.warn(msg); + try { + final String srUUID = vdi.getSR(conn).getUuid(conn); + final String vdiUUID = vdi.getUuid(conn); + final String vdifile = "/var/run/sr-mount/" + srUUID + "/" + vdiUUID + ".vhd"; + callHostPluginAsync(conn, "vmopspremium", "remove_corrupt_vdi", 10, "vdifile", vdifile); + } catch (final Exception e2) { + s_logger.warn(e2); + } + } + } + } catch (final Exception e) { + } + } + + public void disableVlanNetwork(final Connection conn, final Network network) { + } + + @Override + public void disconnected() { + } + + public boolean doPingTest(final Connection conn, final String computingHostIp) { + final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22); + try { + sshConnection.connect(null, 60000, 60000); + if (!sshConnection.authenticateWithPassword(_username, _password.peek())) { + throw new CloudRuntimeException("Unable to authenticate"); + } + + final String cmd = "ping -c 2 " + computingHostIp; + if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) { + throw new CloudRuntimeException("Cannot ping host " + computingHostIp + " from host " + _host.getIp()); + } + return true; + } catch (final Exception e) { + s_logger.warn("Catch exception " + e.toString(), e); + return false; + } finally { + sshConnection.close(); + } + } + + public boolean doPingTest(final Connection conn, final String domRIp, final String vmIp) { + final String args = "-i " + domRIp + " -p " + vmIp; + final String result = callHostPlugin(conn, "vmops", "pingtest", "args", args); + if (result == null || result.isEmpty()) { + return false; + } + return true; + } + + /** + * enableVlanNetwork creates a Network object, Vlan object, and thereby a + * tagged PIF object in Xapi. + * + * In XenServer, VLAN is added by - Create a network, which is unique + * cluster wide. - Find the PIF that you want to create the VLAN on. - + * Create a VLAN using the network and the PIF. As a result of this + * operation, a tagged PIF object is also created. + * + * Here is a list of problems with clustered Xapi implementation that we are + * trying to circumvent. - There can be multiple Networks with the same + * name-label so searching using name-label is not unique. - There are no + * other ways to search for Networks other than listing all of them which is + * not efficient in our implementation because we can have over 4000 VLAN + * networks. - In a clustered situation, it's possible for both hosts to + * detect that the Network is missing and both creates it. This causes a lot + * of problems as one host may be using one Network and another may be using + * a different network for their VMs. This causes problems in migration + * because the VMs are logically attached to different networks in Xapi's + * database but in reality, they are attached to the same network. + * + * To work around these problems, we do the following. + * + * - When creating the VLAN network, we name it as VLAN-UUID of the Network + * it is created on-VLAN Tag. Because VLAN tags is unique with one + * particular network, this is a unique name-label to quickly retrieve the + * the VLAN network with when we need it again. - When we create the VLAN + * network, we add a timestamp and a random number as a tag into the + * network. Then instead of creating VLAN on that network, we actually + * retrieve the Network again and this time uses the VLAN network with + * lowest timestamp or lowest random number as the VLAN network. This allows + * VLAN creation to happen on multiple hosts concurrently but even if two + * VLAN networks were created with the same name, only one of them is used. + * + * One cavaet about this approach is that it relies on the timestamp to be + * relatively accurate among different hosts. + * + * @param conn + * Xapi Connection + * @param tag + * VLAN tag + * @param network + * network on this host to create the VLAN on. + * @return VLAN Network created. + * @throws XenAPIException + * @throws XmlRpcException + */ + protected Network enableVlanNetwork(final Connection conn, final long tag, final XsLocalNetwork network) throws XenAPIException, XmlRpcException { + Network vlanNetwork = null; + final String oldName = "VLAN" + Long.toString(tag); + final String newName = "VLAN-" + network.getNetworkRecord(conn).uuid + "-" + tag; + XsLocalNetwork vlanNic = getNetworkByName(conn, newName); + if (vlanNic == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Couldn't find vlan network with the new name so trying old name: " + oldName); + } + vlanNic = getNetworkByName(conn, oldName); + if (vlanNic != null) { + s_logger.info("Renaming VLAN with old name " + oldName + " to " + newName); + vlanNic.getNetwork().setNameLabel(conn, newName); + } + } + if (vlanNic == null) { // Can't find it, then create it. + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating VLAN network for " + tag + " on host " + _host.getIp()); + } + final Network.Record nwr = new Network.Record(); + nwr.nameLabel = newName; + nwr.tags = new HashSet(); + nwr.tags.add(generateTimeStamp()); + vlanNetwork = Network.create(conn, nwr); + vlanNic = getNetworkByName(conn, newName); + if (vlanNic == null) { // Still vlanNic is null means we could not + // create it for some reason and no exception + // capture happened. + throw new CloudRuntimeException("Could not find/create vlan network with name: " + newName); + } + } + + final PIF nPif = network.getPif(conn); + final PIF.Record nPifr = network.getPifRecord(conn); + + vlanNetwork = vlanNic.getNetwork(); + if (vlanNic.getPif(conn) != null) { + return vlanNetwork; + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating VLAN " + tag + " on host " + _host.getIp() + " on device " + nPifr.device); + } + final VLAN vlan = VLAN.create(conn, nPif, tag, vlanNetwork); + if (vlan != null) { + final VLAN.Record vlanr = vlan.getRecord(conn); + if (vlanr != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("VLAN is created for " + tag + ". The uuid is " + vlanr.uuid); + } + } + } + return vlanNetwork; + } + + @Override + public RebootAnswer execute(final RebootCommand cmd) { + throw new CloudRuntimeException("The method has been replaced but the implementation CitrixRebootCommandWrapper. " + + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper."); + } + + @Override + public StartAnswer execute(final StartCommand cmd) { + throw new CloudRuntimeException("The method has been replaced but the implementation CitrixStartCommandWrapper. " + + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper."); + } + + @Override + public StopAnswer execute(final StopCommand cmd) { + throw new CloudRuntimeException("The method has been replaced but the implementation CitrixStopCommandWrapper. " + + "Please use the new design in order to keep compatibility. Once all ServerResource implementation are refactored those methods will dissapper."); + } + + @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); + } + + @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()); + } + + @Override + public Answer executeRequest(final Command cmd) { + + // We need this one because the StorageSubSystemCommand is from another + // hierarchy. + if (cmd instanceof StorageSubSystemCommand) { + return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); + } + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + try { + return wrapper.execute(cmd, this); + } catch (final Exception e) { + return Answer.createUnsupportedCommandAnswer(cmd); + } + } + + protected void fillHostInfo(final Connection conn, final StartupRoutingCommand cmd) { + final StringBuilder caps = new StringBuilder(); + try { + + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Host.Record hr = host.getRecord(conn); + + Map details = cmd.getHostDetails(); + if (details == null) { + details = new HashMap(); + } + + String productBrand = hr.softwareVersion.get("product_brand"); + if (productBrand == null) { + productBrand = hr.softwareVersion.get("platform_name"); + } + details.put("product_brand", productBrand); + details.put("product_version", _host.getProductVersion()); + if (hr.softwareVersion.get("product_version_text_short") != null) { + details.put("product_version_text_short", hr.softwareVersion.get("product_version_text_short")); + cmd.setHypervisorVersion(hr.softwareVersion.get("product_version_text_short")); + + cmd.setHypervisorVersion(_host.getProductVersion()); + } + if (_privateNetworkName != null) { + details.put("private.network.device", _privateNetworkName); + } + + cmd.setHostDetails(details); + cmd.setName(hr.nameLabel); + cmd.setGuid(_host.getUuid()); + cmd.setPool(_host.getPool()); + cmd.setDataCenter(Long.toString(_dcId)); + for (final String cap : hr.capabilities) { + if (cap.length() > 0) { + caps.append(cap).append(" , "); + } + } + if (caps.length() > 0) { + caps.delete(caps.length() - 3, caps.length()); + } + cmd.setCaps(caps.toString()); + + cmd.setSpeed(_host.getSpeed()); + cmd.setCpuSockets(_host.getCpuSockets()); + cmd.setCpus(_host.getCpus()); + + final HostMetrics hm = host.getMetrics(conn); + + long ram = 0; + long dom0Ram = 0; + ram = hm.getMemoryTotal(conn); + final Set vms = host.getResidentVMs(conn); + for (final VM vm : vms) { + if (vm.getIsControlDomain(conn)) { + dom0Ram = vm.getMemoryStaticMax(conn); + break; + } + } + + ram = (long) ((ram - dom0Ram - _xsMemoryUsed) * _xsVirtualizationFactor); + cmd.setMemory(ram); + cmd.setDom0MinMemory(dom0Ram); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Total Ram: " + ram + " dom0 Ram: " + dom0Ram); + } + + PIF pif = PIF.getByUuid(conn, _host.getPrivatePif()); + PIF.Record pifr = pif.getRecord(conn); + if (pifr.IP != null && pifr.IP.length() > 0) { + cmd.setPrivateIpAddress(pifr.IP); + cmd.setPrivateMacAddress(pifr.MAC); + cmd.setPrivateNetmask(pifr.netmask); + } else { + cmd.setPrivateIpAddress(_host.getIp()); + cmd.setPrivateMacAddress(pifr.MAC); + cmd.setPrivateNetmask("255.255.255.0"); + } + + pif = PIF.getByUuid(conn, _host.getPublicPif()); + pifr = pif.getRecord(conn); + if (pifr.IP != null && pifr.IP.length() > 0) { + cmd.setPublicIpAddress(pifr.IP); + cmd.setPublicMacAddress(pifr.MAC); + cmd.setPublicNetmask(pifr.netmask); + } + + if (_host.getStoragePif1() != null) { + pif = PIF.getByUuid(conn, _host.getStoragePif1()); + pifr = pif.getRecord(conn); + if (pifr.IP != null && pifr.IP.length() > 0) { + cmd.setStorageIpAddress(pifr.IP); + cmd.setStorageMacAddress(pifr.MAC); + cmd.setStorageNetmask(pifr.netmask); + } + } + + if (_host.getStoragePif2() != null) { + pif = PIF.getByUuid(conn, _host.getStoragePif2()); + pifr = pif.getRecord(conn); + if (pifr.IP != null && pifr.IP.length() > 0) { + cmd.setStorageIpAddressDeux(pifr.IP); + cmd.setStorageMacAddressDeux(pifr.MAC); + cmd.setStorageNetmaskDeux(pifr.netmask); + } + } + + final Map configs = hr.otherConfig; + cmd.setIqn(configs.get("iscsi_iqn")); + + cmd.setPod(_pod); + cmd.setVersion(CitrixResourceBase.class.getPackage().getImplementationVersion()); + + } catch (final XmlRpcException e) { + throw new CloudRuntimeException("XML RPC Exception" + e.getMessage(), e); + } catch (final XenAPIException e) { + throw new CloudRuntimeException("XenAPIException" + e.toString(), e); + } + } protected void finalizeVmMetaData(final VM vm, final Connection conn, final VirtualMachineTO vmSpec) throws Exception { @@ -1471,7 +1796,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vm.setPlatform(conn, platform); } } - if ( !BootloaderType.CD.equals(vmSpec.getBootloader())) { + 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); @@ -1482,7 +1807,1556 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected String handleVmStartFailure(final Connection conn, final String vmName, final VM vm, final String message, final Throwable th) { + /** + * 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); + } + return nw; + } catch (final Exception e) { + s_logger.warn("createTunnelNetwork failed", e); + return null; + } + } + + void forceShutdownVM(final Connection conn, final VM vm) { + try { + final Long domId = vm.getDomid(conn); + callHostPlugin(conn, "vmopspremium", "forceShutdownVM", "domId", domId.toString()); + vm.powerStateReset(conn); + vm.destroy(conn); + } catch (final Exception e) { + final String msg = "forceShutdown failed due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg); + } + } + + protected String generateTimeStamp() { + return new StringBuilder("CsCreateTime-").append(System.currentTimeMillis()).append("-").append(Rand.nextInt(Integer.MAX_VALUE)).toString(); + } + + @Override + public IAgentControl getAgentControl() { + return _agentControl; + } + + protected String getArgsString(final Map args) { + final StringBuilder argString = new StringBuilder(); + for (final Map.Entry arg : args.entrySet()) { + argString.append(arg.getKey() + ": " + arg.getValue() + ", "); + } + return argString.toString(); + } + + @Override + public Map getConfigParams() { + return null; + } + + public Connection getConnection() { + return ConnPool.connect(_host.getUuid(), _host.getPool(), _host.getIp(), _username, _password, _wait); + } + + protected Pair getControlDomain(final Connection conn) throws XenAPIException, XmlRpcException { + final Host host = Host.getByUuid(conn, _host.getUuid()); + Set vms = null; + vms = host.getResidentVMs(conn); + for (final VM vm : vms) { + if (vm.getIsControlDomain(conn)) { + return new Pair(vm, vm.getRecord(conn)); + } + } + + throw new CloudRuntimeException("Com'on no control domain? What the crap?!#@!##$@"); + } + + protected VIF getCorrectVif(final Connection conn, final VM router, final IpAddressTO ip) throws XmlRpcException, XenAPIException { + final NicTO nic = new NicTO(); + nic.setType(ip.getTrafficType()); + nic.setName(ip.getNetworkName()); + if (ip.getBroadcastUri() == null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); + nic.setBroadcastUri(uri); + } + final Network network = getNetwork(conn, nic); + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + final Set routerVIFs = router.getVIFs(conn); + for (final VIF vif : routerVIFs) { + final Network vifNetwork = vif.getNetwork(conn); + if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) { + return vif; + } + } + return null; + } + + protected VIF getCorrectVif(final Connection conn, final VM router, final Network network) throws XmlRpcException, XenAPIException { + final Set routerVIFs = router.getVIFs(conn); + for (final VIF vif : routerVIFs) { + final Network vifNetwork = vif.getNetwork(conn); + if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) { + return vif; + } + } + + return null; + } + + @Override + public PingCommand getCurrentStatus(final long id) { + try { + if (!pingXAPI()) { + Thread.sleep(1000); + if (!pingXAPI()) { + s_logger.warn("can not ping xenserver " + _host.getUuid()); + return null; + } + } + final Connection conn = getConnection(); + if (!_canBridgeFirewall && !_isOvs) { + return new PingRoutingCommand(getType(), id, getHostVmStateReport(conn)); + } else if (_isOvs) { + final List> ovsStates = ovsFullSyncStates(); + return new PingRoutingWithOvsCommand(getType(), id, getHostVmStateReport(conn), ovsStates); + } else { + final HashMap> nwGrpStates = syncNetworkGroups(conn, id); + return new PingRoutingWithNwGroupsCommand(getType(), id, getHostVmStateReport(conn), nwGrpStates); + } + } catch (final Exception e) { + s_logger.warn("Unable to get current status", e); + return null; + } + } + + protected double getDataAverage(final Node dataNode, final int col, final int numRows) { + double value = 0; + final double dummy = 0; + int numRowsUsed = 0; + for (int row = 0; row < numRows; row++) { + final Node data = dataNode.getChildNodes().item(numRows - 1 - row).getChildNodes().item(col + 1); + final Double currentDataAsDouble = Double.valueOf(getXMLNodeValue(data)); + if (!currentDataAsDouble.equals(Double.NaN)) { + numRowsUsed += 1; + value += currentDataAsDouble; + } + } + + if (numRowsUsed == 0) { + if (!Double.isInfinite(value) && !Double.isNaN(value)) { + return value; + } else { + s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows=0"); + return dummy; + } + } else { + if (!Double.isInfinite(value / numRowsUsed) && !Double.isNaN(value / numRowsUsed)) { + return value / numRowsUsed; + } else { + s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows>0"); + return dummy; + } + } + + } + + public HashMap> getGPUGroupDetails(final Connection conn) throws XenAPIException, XmlRpcException { + return null; + } + + protected String getGuestOsType(final String stdType, String platformEmulator, final boolean bootFromCD) { + if (platformEmulator == null) { + s_logger.debug("no guest OS type, start it as HVM guest"); + platformEmulator = "Other install media"; + } + return platformEmulator; + } + + public XsHost getHost() { + return _host; + } + + protected boolean getHostInfo(final Connection conn) throws IllegalArgumentException { + try { + final Host myself = Host.getByUuid(conn, _host.getUuid()); + Set hcs = null; + for (int i = 0; i < 10; i++) { + hcs = myself.getHostCPUs(conn); + if (hcs != null) { + _host.setCpus(hcs.size()); + if (_host.getCpus() > 0) { + break; + } + } + Thread.sleep(5000); + } + if (_host.getCpus() <= 0) { + throw new CloudRuntimeException("Cannot get the numbers of cpu from XenServer host " + _host.getIp()); + } + final Map cpuInfo = myself.getCpuInfo(conn); + if (cpuInfo.get("socket_count") != null) { + _host.setCpuSockets(Integer.parseInt(cpuInfo.get("socket_count"))); + } + // would hcs be null we would have thrown an exception on condition + // (_host.getCpus() <= 0) by now + for (final HostCpu hc : hcs) { + _host.setSpeed(hc.getSpeed(conn).intValue()); + break; + } + final Host.Record hr = myself.getRecord(conn); + _host.setProductVersion(CitrixHelper.getProductVersion(hr)); + + final XsLocalNetwork privateNic = getManagementNetwork(conn); + _privateNetworkName = privateNic.getNetworkRecord(conn).nameLabel; + _host.setPrivatePif(privateNic.getPifRecord(conn).uuid); + _host.setPrivateNetwork(privateNic.getNetworkRecord(conn).uuid); + _host.setSystemvmisouuid(null); + + XsLocalNetwork guestNic = null; + if (_guestNetworkName != null && !_guestNetworkName.equals(_privateNetworkName)) { + guestNic = getNetworkByName(conn, _guestNetworkName); + if (guestNic == null) { + s_logger.warn("Unable to find guest network " + _guestNetworkName); + throw new IllegalArgumentException("Unable to find guest network " + _guestNetworkName + " for host " + _host.getIp()); + } + } else { + guestNic = privateNic; + _guestNetworkName = _privateNetworkName; + } + _host.setGuestNetwork(guestNic.getNetworkRecord(conn).uuid); + _host.setGuestPif(guestNic.getPifRecord(conn).uuid); + + XsLocalNetwork publicNic = null; + if (_publicNetworkName != null && !_publicNetworkName.equals(_guestNetworkName)) { + publicNic = getNetworkByName(conn, _publicNetworkName); + if (publicNic == null) { + s_logger.warn("Unable to find public network " + _publicNetworkName + " for host " + _host.getIp()); + throw new IllegalArgumentException("Unable to find public network " + _publicNetworkName + " for host " + _host.getIp()); + } + } else { + publicNic = guestNic; + _publicNetworkName = _guestNetworkName; + } + _host.setPublicPif(publicNic.getPifRecord(conn).uuid); + _host.setPublicNetwork(publicNic.getNetworkRecord(conn).uuid); + if (_storageNetworkName1 == null) { + _storageNetworkName1 = _guestNetworkName; + } + XsLocalNetwork storageNic1 = null; + storageNic1 = getNetworkByName(conn, _storageNetworkName1); + if (storageNic1 == null) { + s_logger.warn("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.getIp()); + throw new IllegalArgumentException("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.getIp()); + } else { + _host.setStorageNetwork1(storageNic1.getNetworkRecord(conn).uuid); + _host.setStoragePif1(storageNic1.getPifRecord(conn).uuid); + } + + XsLocalNetwork storageNic2 = null; + if (_storageNetworkName2 != null) { + storageNic2 = getNetworkByName(conn, _storageNetworkName2); + if (storageNic2 != null) { + _host.setStoragePif2(storageNic2.getPifRecord(conn).uuid); + } + } + + s_logger.info("XenServer Version is " + _host.getProductVersion() + " for host " + _host.getIp()); + s_logger.info("Private Network is " + _privateNetworkName + " for host " + _host.getIp()); + s_logger.info("Guest Network is " + _guestNetworkName + " for host " + _host.getIp()); + s_logger.info("Public Network is " + _publicNetworkName + " for host " + _host.getIp()); + + return true; + } catch (final XenAPIException e) { + s_logger.warn("Unable to get host information for " + _host.getIp(), e); + return false; + } catch (final Exception e) { + s_logger.warn("Unable to get host information for " + _host.getIp(), e); + return false; + } + } + + public HostStatsEntry getHostStats(final Connection conn, final GetHostStatsCommand cmd, final String hostGuid, final long hostId) { + + final HostStatsEntry hostStats = new HostStatsEntry(hostId, 0, 0, 0, "host", 0, 0, 0, 0); + final Object[] rrdData = getRRDData(conn, 1); // call rrd method with 1 + // for host + + if (rrdData == null) { + return null; + } + + final Integer numRows = (Integer) rrdData[0]; + final Integer numColumns = (Integer) rrdData[1]; + final Node legend = (Node) rrdData[2]; + final Node dataNode = (Node) rrdData[3]; + + final NodeList legendChildren = legend.getChildNodes(); + for (int col = 0; col < numColumns; col++) { + + if (legendChildren == null || legendChildren.item(col) == null) { + continue; + } + + final String columnMetadata = getXMLNodeValue(legendChildren.item(col)); + + if (columnMetadata == null) { + continue; + } + + final String[] columnMetadataList = columnMetadata.split(":"); + + if (columnMetadataList.length != 4) { + continue; + } + + final String type = columnMetadataList[1]; + final String param = columnMetadataList[3]; + + if (type.equalsIgnoreCase("host")) { + + if (param.matches("pif_eth0_rx")) { + hostStats.setNetworkReadKBs(getDataAverage(dataNode, col, numRows) / 1000); + } else if (param.matches("pif_eth0_tx")) { + hostStats.setNetworkWriteKBs(getDataAverage(dataNode, col, numRows) / 1000); + } else if (param.contains("memory_total_kib")) { + hostStats.setTotalMemoryKBs(getDataAverage(dataNode, col, numRows)); + } else if (param.contains("memory_free_kib")) { + hostStats.setFreeMemoryKBs(getDataAverage(dataNode, col, numRows)); + } else if (param.matches("cpu_avg")) { + // hostStats.setNumCpus(hostStats.getNumCpus() + 1); + hostStats.setCpuUtilization(hostStats.getCpuUtilization() + getDataAverage(dataNode, col, numRows)); + } + + /* + * if (param.contains("loadavg")) { + * hostStats.setAverageLoad((hostStats.getAverageLoad() + + * getDataAverage(dataNode, col, numRows))); } + */ + } + } + + // add the host cpu utilization + /* + * if (hostStats.getNumCpus() != 0) { + * hostStats.setCpuUtilization(hostStats.getCpuUtilization() / + * hostStats.getNumCpus()); s_logger.debug("Host cpu utilization " + + * hostStats.getCpuUtilization()); } + */ + + return hostStats; + } + + protected HashMap getHostVmStateReport(final Connection conn) { + + // TODO : new VM sync model does not require a cluster-scope report, we + // need to optimize + // the report accordingly + final HashMap vmStates = new HashMap(); + Map vm_map = null; + for (int i = 0; i < 2; i++) { + try { + vm_map = VM.getAllRecords(conn); // USE THIS TO GET ALL VMS FROM + // A CLUSTER + break; + } catch (final Throwable e) { + s_logger.warn("Unable to get vms", e); + } + try { + Thread.sleep(1000); + } catch (final InterruptedException ex) { + + } + } + + if (vm_map == null) { + return vmStates; + } + for (final VM.Record record : vm_map.values()) { + if (record.isControlDomain || record.isASnapshot || record.isATemplate) { + continue; // Skip DOM0 + } + + final VmPowerState ps = record.powerState; + final Host host = record.residentOn; + String host_uuid = null; + if (!isRefNull(host)) { + try { + host_uuid = host.getUuid(conn); + } catch (final BadServerResponse e) { + s_logger.error("Failed to get host uuid for host " + host.toWireString(), e); + } catch (final XenAPIException e) { + s_logger.error("Failed to get host uuid for host " + host.toWireString(), e); + } catch (final XmlRpcException e) { + s_logger.error("Failed to get host uuid for host " + host.toWireString(), e); + } + + if (host_uuid.equalsIgnoreCase(_host.getUuid())) { + vmStates.put(record.nameLabel, new HostVmStateReportEntry(convertToPowerState(ps), host_uuid)); + } + } + } + + return vmStates; + } + + public SR getIscsiSR(final Connection conn, final String srNameLabel, final String target, String path, final String chapInitiatorUsername, + final String chapInitiatorPassword, final boolean ignoreIntroduceException) { + synchronized (srNameLabel.intern()) { + final Map deviceConfig = new HashMap(); + try { + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); + } + + final String tmp[] = path.split("/"); + if (tmp.length != 3) { + final String msg = "Wrong iscsi path " + path + " it should be /targetIQN/LUN"; + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + final String targetiqn = tmp[1].trim(); + final String lunid = tmp[2].trim(); + String scsiid = ""; + + final Set srs = SR.getByNameLabel(conn, srNameLabel); + for (final SR sr : srs) { + if (!SRType.LVMOISCSI.equals(sr.getType(conn))) { + continue; + } + final Set pbds = sr.getPBDs(conn); + if (pbds.isEmpty()) { + continue; + } + final PBD pbd = pbds.iterator().next(); + final Map dc = pbd.getDeviceConfig(conn); + if (dc == null) { + continue; + } + if (dc.get("target") == null) { + continue; + } + if (dc.get("targetIQN") == null) { + continue; + } + if (dc.get("lunid") == null) { + continue; + } + if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) { + throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + dc.get("targetIQN") + + ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.getUuid()); + } + } + deviceConfig.put("target", target); + deviceConfig.put("targetIQN", targetiqn); + + if (StringUtils.isNotBlank(chapInitiatorUsername) && StringUtils.isNotBlank(chapInitiatorPassword)) { + deviceConfig.put("chapuser", chapInitiatorUsername); + deviceConfig.put("chappassword", chapInitiatorPassword); + } + + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Map smConfig = new HashMap(); + final String type = SRType.LVMOISCSI.toString(); + SR sr = null; + try { + sr = SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, type, "user", true, smConfig); + } catch (final XenAPIException e) { + final String errmsg = e.toString(); + if (errmsg.contains("SR_BACKEND_FAILURE_107")) { + final String lun[] = errmsg.split(""); + boolean found = false; + for (int i = 1; i < lun.length; i++) { + final int blunindex = lun[i].indexOf("") + 7; + final int elunindex = lun[i].indexOf(""); + String ilun = lun[i].substring(blunindex, elunindex); + ilun = ilun.trim(); + if (ilun.equals(lunid)) { + final int bscsiindex = lun[i].indexOf("") + 8; + final int escsiindex = lun[i].indexOf(""); + scsiid = lun[i].substring(bscsiindex, escsiindex); + scsiid = scsiid.trim(); + found = true; + break; + } + } + if (!found) { + final String msg = "can not find LUN " + lunid + " in " + errmsg; + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + } else { + final String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } + } + deviceConfig.put("SCSIid", scsiid); + + final String result = SR.probe(conn, host, deviceConfig, type, smConfig); + String pooluuid = null; + if (result.indexOf("") != -1) { + pooluuid = result.substring(result.indexOf("") + 6, result.indexOf("")).trim(); + } + + if (pooluuid == null || pooluuid.length() != 36) { + sr = SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, type, "user", true, smConfig); + } else { + try { + sr = SR.introduce(conn, pooluuid, srNameLabel, srNameLabel, type, "user", true, smConfig); + } catch (final XenAPIException ex) { + if (ignoreIntroduceException) { + return sr; + } + + throw ex; + } + + final Set setHosts = Host.getAll(conn); + if (setHosts == null) { + final String msg = "Unable to create Iscsi SR " + deviceConfig + " due to hosts not available."; + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + for (final Host currentHost : setHosts) { + final PBD.Record rec = new PBD.Record(); + + rec.deviceConfig = deviceConfig; + rec.host = currentHost; + rec.SR = sr; + + final PBD pbd = PBD.create(conn, rec); + + pbd.plug(conn); + } + } + sr.scan(conn); + return sr; + } catch (final XenAPIException e) { + final String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } catch (final Exception e) { + final String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.getMessage(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } + } + } + + public SR getISOSRbyVmName(final Connection conn, final String vmName) { + try { + final Set srs = SR.getByNameLabel(conn, vmName + "-ISO"); + if (srs.size() == 0) { + return null; + } else if (srs.size() == 1) { + return srs.iterator().next(); + } else { + final String msg = "getIsoSRbyVmName failed due to there are more than 1 SR having same Label"; + s_logger.warn(msg); + } + } catch (final XenAPIException e) { + final String msg = "getIsoSRbyVmName failed due to " + e.toString(); + s_logger.warn(msg, e); + } catch (final Exception e) { + final String msg = "getIsoSRbyVmName failed due to " + e.getMessage(); + s_logger.warn(msg, e); + } + return null; + } + + public VDI getIsoVDIByURL(final Connection conn, final String vmName, final String isoURL) { + SR isoSR = null; + String mountpoint = null; + if (isoURL.startsWith("xs-tools")) { + try { + final Set vdis = VDI.getByNameLabel(conn, isoURL); + if (vdis.isEmpty()) { + throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL); + } + return vdis.iterator().next(); + + } catch (final XenAPIException e) { + throw new CloudRuntimeException("Unable to get pv iso: " + isoURL + " due to " + e.toString()); + } catch (final Exception e) { + throw new CloudRuntimeException("Unable to get pv iso: " + isoURL + " due to " + e.toString()); + } + } + + final int index = isoURL.lastIndexOf("/"); + mountpoint = isoURL.substring(0, index); + + URI uri; + try { + uri = new URI(mountpoint); + } catch (final URISyntaxException e) { + throw new CloudRuntimeException("isoURL is wrong: " + isoURL); + } + isoSR = getISOSRbyVmName(conn, vmName); + if (isoSR == null) { + isoSR = createIsoSRbyURI(conn, uri, vmName, false); + } + + final String isoName = isoURL.substring(index + 1); + + final VDI isoVDI = getVDIbyLocationandSR(conn, isoName, isoSR); + + if (isoVDI != null) { + return isoVDI; + } else { + throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL); + } + } + + public String getLabel() { + final Connection conn = getConnection(); + final String result = callHostPlugin(conn, "ovstunnel", "getLabel"); + return result; + } + + protected SR getLocalEXTSR(final Connection conn) { + try { + final Map map = SR.getAllRecords(conn); + if (map != null && !map.isEmpty()) { + for (final Map.Entry entry : map.entrySet()) { + final SR.Record srRec = entry.getValue(); + if (SRType.FILE.equals(srRec.type) || SRType.EXT.equals(srRec.type)) { + final Set pbds = srRec.PBDs; + if (pbds == null) { + continue; + } + for (final PBD pbd : pbds) { + final Host host = pbd.getHost(conn); + if (!isRefNull(host) && host.getUuid(conn).equals(_host.getUuid())) { + if (!pbd.getCurrentlyAttached(conn)) { + pbd.plug(conn); + } + final SR sr = entry.getKey(); + sr.scan(conn); + return sr; + } + } + } + } + } + } catch (final XenAPIException e) { + final String msg = "Unable to get local EXTSR in host:" + _host.getUuid() + e.toString(); + s_logger.warn(msg); + } catch (final XmlRpcException e) { + final String msg = "Unable to get local EXTSR in host:" + _host.getUuid() + e.getCause(); + s_logger.warn(msg); + } + return null; + } + + protected SR getLocalLVMSR(final Connection conn) { + try { + final Map map = SR.getAllRecords(conn); + if (map != null && !map.isEmpty()) { + for (final Map.Entry entry : map.entrySet()) { + final SR.Record srRec = entry.getValue(); + if (SRType.LVM.equals(srRec.type)) { + final Set pbds = srRec.PBDs; + if (pbds == null) { + continue; + } + for (final PBD pbd : pbds) { + final Host host = pbd.getHost(conn); + if (!isRefNull(host) && host.getUuid(conn).equals(_host.getUuid())) { + if (!pbd.getCurrentlyAttached(conn)) { + pbd.plug(conn); + } + final SR sr = entry.getKey(); + sr.scan(conn); + return sr; + } + } + } + } + } + } catch (final XenAPIException e) { + final String msg = "Unable to get local LVMSR in host:" + _host.getUuid() + e.toString(); + s_logger.warn(msg); + } catch (final XmlRpcException e) { + final String msg = "Unable to get local LVMSR in host:" + _host.getUuid() + e.getCause(); + s_logger.warn(msg); + } + return null; + } + + public String getLowestAvailableVIFDeviceNum(final Connection conn, final VM vm) { + String vmName = ""; + try { + vmName = vm.getNameLabel(conn); + final List usedDeviceNums = new ArrayList(); + final Set vifs = vm.getVIFs(conn); + final Iterator vifIter = vifs.iterator(); + while (vifIter.hasNext()) { + final VIF vif = vifIter.next(); + try { + final String deviceId = vif.getDevice(conn); + if (vm.getIsControlDomain(conn) || vif.getCurrentlyAttached(conn)) { + usedDeviceNums.add(Integer.valueOf(deviceId)); + } else { + s_logger.debug("Found unplugged VIF " + deviceId + " in VM " + vmName + " destroy it"); + vif.destroy(conn); + } + } catch (final NumberFormatException e) { + final String msg = "Obtained an invalid value for an allocated VIF device number for VM: " + vmName; + s_logger.debug(msg, e); + throw new CloudRuntimeException(msg); + } + } + + for (Integer i = 0; i < _maxNics; i++) { + if (!usedDeviceNums.contains(i)) { + s_logger.debug("Lowest available Vif device number: " + i + " for VM: " + vmName); + return i.toString(); + } + } + } catch (final XmlRpcException e) { + final String msg = "Caught XmlRpcException: " + e.getMessage(); + s_logger.warn(msg, e); + } catch (final XenAPIException e) { + final String msg = "Caught XenAPIException: " + e.toString(); + s_logger.warn(msg, e); + } + + throw new CloudRuntimeException("Could not find available VIF slot in VM with name: " + vmName); + } + + protected XsLocalNetwork getManagementNetwork(final Connection conn) throws XmlRpcException, XenAPIException { + PIF mgmtPif = null; + PIF.Record mgmtPifRec = null; + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Set hostPifs = host.getPIFs(conn); + for (final PIF pif : hostPifs) { + final PIF.Record rec = pif.getRecord(conn); + if (rec.management) { + if (rec.VLAN != null && rec.VLAN != -1) { + final String msg = new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.getUuid()).append("; pif=") + .append(rec.uuid).append("; vlan=").append(rec.VLAN).toString(); + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Management network is on pif=" + rec.uuid); + } + mgmtPif = pif; + mgmtPifRec = rec; + break; + } + } + if (mgmtPif == null) { + final String msg = "Unable to find management network for " + _host.getUuid(); + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + final Bond bond = mgmtPifRec.bondSlaveOf; + if (!isRefNull(bond)) { + final String msg = "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.getUuid() + + "), please move management interface to bond!"; + s_logger.warn(msg); + throw new CloudRuntimeException(msg); + } + final Network nk = mgmtPifRec.network; + final Network.Record nkRec = nk.getRecord(conn); + return new XsLocalNetwork(this, nk, nkRec, mgmtPif, mgmtPifRec); + } + + @Override + public String getName() { + return _name; + } + + 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); + } + 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); + } + + throw new CloudRuntimeException("Unsupported network type: " + type); + } + + 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()); + } + 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())); + } + } 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); + } + } 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()); + } + + /** + * getNetworkByName() retrieves what the server thinks is the actual network + * used by the XenServer host. This method should always be used to talk to + * retrieve a network by the name. The reason is because of the problems in + * using the name label as the way to find the Network. + * + * To see how we are working around these problems, take a look at + * enableVlanNetwork(). The following description assumes you have looked at + * the description on that method. + * + * In order to understand this, we have to see what type of networks are + * within a XenServer that's under CloudStack control. + * + * - Native Networks: these are networks that are untagged on the XenServer + * and are used to crate VLAN networks on. These are created by the user and + * is assumed to be one per cluster. - VLAN Networks: these are dynamically + * created by CloudStack and can have problems with duplicated names. - + * LinkLocal Networks: these are dynamically created by CloudStack and can + * also have problems with duplicated names but these don't have actual + * PIFs. + * + * In order to speed to retrieval of a network, we do the following: - We + * retrieve by the name. If only one network is retrieved, we assume we + * retrieved the right network. - If more than one network is retrieved, we + * check to see which one has the pif for the local host and use that. - If + * a pif is not found, then we look at the tags and find the one with the + * lowest timestamp. (See enableVlanNetwork()) + * + * @param conn + * Xapi connection + * @param name + * name of the network + * @return XsNic an object that contains network, network record, pif, and + * pif record. + * @throws XenAPIException + * @throws XmlRpcException + * + * @see CitrixResourceBase#enableVlanNetwork + */ + public XsLocalNetwork getNetworkByName(final Connection conn, final String name) throws XenAPIException, XmlRpcException { + final Set networks = Network.getByNameLabel(conn, name); + if (networks.size() == 1) { + return new XsLocalNetwork(this, networks.iterator().next(), null, null, null); + } + + if (networks.size() == 0) { + return null; + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found more than one network with the name " + name); + } + Network earliestNetwork = null; + Network.Record earliestNetworkRecord = null; + long earliestTimestamp = Long.MAX_VALUE; + int earliestRandom = Integer.MAX_VALUE; + for (final Network network : networks) { + final XsLocalNetwork nic = new XsLocalNetwork(this, network); + + if (nic.getPif(conn) != null) { + return nic; + } + + final Network.Record record = network.getRecord(conn); + if (record.tags != null) { + for (final String tag : record.tags) { + final Pair stamp = parseTimestamp(tag); + if (stamp == null) { + continue; + } + + if (stamp.first() < earliestTimestamp || stamp.first() == earliestTimestamp && stamp.second() < earliestRandom) { + earliestTimestamp = stamp.first(); + earliestRandom = stamp.second(); + earliestNetwork = network; + earliestNetworkRecord = record; + } + } + } + } + + return earliestNetwork != null ? new XsLocalNetwork(this, earliestNetwork, earliestNetworkRecord, null, null) : null; + } + + public long[] getNetworkStats(final Connection conn, final String privateIP) { + final String result = networkUsage(conn, privateIP, "get", null); + final long[] stats = new long[2]; + if (result != null) { + final String[] splitResult = result.split(":"); + int i = 0; + while (i < splitResult.length - 1) { + stats[0] += new Long(splitResult[i++]).longValue(); + stats[1] += new Long(splitResult[i++]).longValue(); + } + } + return stats; + } + + public SR getNfsSR(final Connection conn, final String poolid, final String uuid, final String server, String serverpath, final String pooldesc) { + final Map deviceConfig = new HashMap(); + try { + serverpath = serverpath.replace("//", "/"); + final Set srs = SR.getAll(conn); + if (srs != null && !srs.isEmpty()) { + for (final SR sr : srs) { + if (!SRType.NFS.equals(sr.getType(conn))) { + continue; + } + + final Set pbds = sr.getPBDs(conn); + if (pbds.isEmpty()) { + continue; + } + + final PBD pbd = pbds.iterator().next(); + + final Map dc = pbd.getDeviceConfig(conn); + + if (dc == null) { + continue; + } + + if (dc.get("server") == null) { + continue; + } + + if (dc.get("serverpath") == null) { + continue; + } + + if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { + throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath") + + " for pool " + uuid + " on host:" + _host.getUuid()); + } + + } + } + deviceConfig.put("server", server); + deviceConfig.put("serverpath", serverpath); + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Map smConfig = new HashMap(); + smConfig.put("nosubdir", "true"); + final SR sr = SR.create(conn, host, deviceConfig, new Long(0), uuid, poolid, SRType.NFS.toString(), "user", true, smConfig); + sr.scan(conn); + return sr; + } catch (final XenAPIException e) { + throw new CloudRuntimeException("Unable to create NFS SR " + pooldesc, e); + } catch (final XmlRpcException e) { + throw new CloudRuntimeException("Unable to create NFS SR " + pooldesc, e); + } + } + + private String getOvsTunnelNetworkName(final String broadcastUri) { + if (broadcastUri.contains(".")) { + final String[] parts = broadcastUri.split("\\."); + return "OVS-DR-VPC-Bridge" + parts[0]; + } else { + try { + return "OVSTunnel" + broadcastUri; + } catch (final Exception e) { + return null; + } + } + } + + protected List getPatchFiles() { + return null; + } + + 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; + } + } catch (final Exception e) { + s_logger.error("Can not get performance monitor for AS due to ", e); + } + return null; + } + + protected Object[] getRRDData(final Connection conn, final int flag) { + + /* + * Note: 1 => called from host, hence host stats 2 => called from vm, + * hence vm stats + */ + Document doc = null; + + try { + doc = getStatsRawXML(conn, flag == 1 ? true : false); + } catch (final Exception e1) { + s_logger.warn("Error whilst collecting raw stats from plugin: ", e1); + return null; + } + + if (doc == null) { // stats are null when the host plugin call fails + // (host down state) + return null; + } + + final NodeList firstLevelChildren = doc.getChildNodes(); + final NodeList secondLevelChildren = firstLevelChildren.item(0).getChildNodes(); + final Node metaNode = secondLevelChildren.item(0); + final Node dataNode = secondLevelChildren.item(1); + + Integer numRows = 0; + Integer numColumns = 0; + Node legend = null; + final NodeList metaNodeChildren = metaNode.getChildNodes(); + for (int i = 0; i < metaNodeChildren.getLength(); i++) { + final Node n = metaNodeChildren.item(i); + if (n.getNodeName().equals("rows")) { + numRows = Integer.valueOf(getXMLNodeValue(n)); + } else if (n.getNodeName().equals("columns")) { + numColumns = Integer.valueOf(getXMLNodeValue(n)); + } else if (n.getNodeName().equals("legend")) { + legend = n; + } + } + + return new Object[] { numRows, numColumns, legend, dataNode }; + } + + @Override + public int getRunLevel() { + return 0; + } + + protected SR getSRByNameLabelandHost(final Connection conn, final String name) throws BadServerResponse, XenAPIException, XmlRpcException { + final Set srs = SR.getByNameLabel(conn, name); + SR ressr = null; + for (final SR sr : srs) { + Set pbds; + pbds = sr.getPBDs(conn); + for (final PBD pbd : pbds) { + final PBD.Record pbdr = pbd.getRecord(conn); + if (pbdr.host != null && pbdr.host.getUuid(conn).equals(_host.getUuid())) { + if (!pbdr.currentlyAttached) { + pbd.plug(conn); + } + ressr = sr; + break; + } + } + } + return ressr; + } + + 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; + } + return staticMax; + } + + 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; + } + + 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"); + } + return dynamicMinRam; + } + + protected Document getStatsRawXML(final Connection conn, final boolean host) { + final Date currentDate = new Date(); + String urlStr = "http://" + _host.getIp() + "/rrd_updates?"; + urlStr += "session_id=" + conn.getSessionReference(); + urlStr += "&host=" + (host ? "true" : "false"); + urlStr += "&cf=" + _consolidationFunction; + urlStr += "&interval=" + _pollingIntervalInSeconds; + urlStr += "&start=" + (currentDate.getTime() / 1000 - 1000 - 100); + + URL url; + BufferedReader in = null; + try { + url = new URL(urlStr); + url.openConnection(); + final URLConnection uc = url.openConnection(); + in = new BufferedReader(new InputStreamReader(uc.getInputStream())); + final InputSource statsSource = new InputSource(in); + return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(statsSource); + } catch (final MalformedURLException e) { + s_logger.warn("Malformed URL? come on...." + urlStr); + return null; + } catch (final IOException e) { + s_logger.warn("Problems getting stats using " + urlStr, e); + return null; + } catch (final SAXException e) { + s_logger.warn("Problems getting stats using " + urlStr, e); + return null; + } catch (final ParserConfigurationException e) { + s_logger.warn("Problems getting stats using " + urlStr, e); + return null; + } finally { + if (in != null) { + try { + in.close(); + } catch (final IOException e) { + s_logger.warn("Unable to close the buffer ", e); + } + } + } + } + + public SR getStorageRepository(final Connection conn, final String srNameLabel) { + Set srs; + try { + srs = SR.getByNameLabel(conn, srNameLabel); + } catch (final XenAPIException e) { + throw new CloudRuntimeException("Unable to get SR " + srNameLabel + " due to " + e.toString(), e); + } catch (final Exception e) { + throw new CloudRuntimeException("Unable to get SR " + srNameLabel + " due to " + e.getMessage(), e); + } + + if (srs.size() > 1) { + throw new CloudRuntimeException("More than one storage repository was found for pool with uuid: " + srNameLabel); + } else if (srs.size() == 1) { + final SR sr = srs.iterator().next(); + if (s_logger.isDebugEnabled()) { + s_logger.debug("SR retrieved for " + srNameLabel); + } + + if (checkSR(conn, sr)) { + return sr; + } + throw new CloudRuntimeException("SR check failed for storage pool: " + srNameLabel + "on host:" + _host.getUuid()); + } else { + throw new CloudRuntimeException("Can not see storage pool: " + srNameLabel + " from on host:" + _host.getUuid()); + } + } + + protected Storage.StorageResourceType getStorageResourceType() { + return Storage.StorageResourceType.STORAGE_POOL; + } + + @Override + public Type getType() { + return com.cloud.host.Host.Type.Routing; + } + + public String getUnusedDeviceNum(final Connection conn, final VM vm) { + // Figure out the disk number to attach the VM to + try { + final Set allowedVBDDevices = vm.getAllowedVBDDevices(conn); + if (allowedVBDDevices.size() == 0) { + throw new CloudRuntimeException("Could not find an available slot in VM with name: " + vm.getNameLabel(conn) + " to attach a new disk."); + } + return allowedVBDDevices.iterator().next(); + } catch (final XmlRpcException e) { + final String msg = "Catch XmlRpcException due to: " + e.getMessage(); + s_logger.warn(msg, e); + } catch (final XenAPIException e) { + final String msg = "Catch XenAPIException due to: " + e.toString(); + s_logger.warn(msg, e); + } + throw new CloudRuntimeException("Could not find an available slot in VM with name to attach a new disk."); + } + + protected VDI getVDIbyLocationandSR(final Connection conn, final String loc, final SR sr) { + try { + final Set vdis = sr.getVDIs(conn); + for (final VDI vdi : vdis) { + if (vdi.getLocation(conn).startsWith(loc)) { + return vdi; + } + } + + final String msg = "can not getVDIbyLocationandSR " + loc; + s_logger.warn(msg); + return null; + } catch (final XenAPIException e) { + final String msg = "getVDIbyLocationandSR exception " + loc + " due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } catch (final Exception e) { + final String msg = "getVDIbyLocationandSR exception " + loc + " due to " + e.getMessage(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } + + } + + public VDI getVDIbyUuid(final Connection conn, final String uuid) { + return getVDIbyUuid(conn, uuid, true); + } + + public VDI getVDIbyUuid(final Connection conn, final String uuid, final boolean throwExceptionIfNotFound) { + try { + return VDI.getByUuid(conn, uuid); + } catch (final Exception e) { + if (throwExceptionIfNotFound) { + final String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString(); + + s_logger.debug(msg); + + throw new CloudRuntimeException(msg, e); + } + + return null; + } + } + + public String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) { + final String parentUuid = callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", + isISCSI.toString()); + + if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) { + s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid); + // errString is already logged. + return null; + } + return parentUuid; + } + + public VIF getVifByMac(final Connection conn, final VM router, String mac) throws XmlRpcException, XenAPIException { + final Set routerVIFs = router.getVIFs(conn); + mac = mac.trim(); + for (final VIF vif : routerVIFs) { + final String lmac = vif.getMAC(conn); + if (lmac.trim().equals(mac)) { + return vif; + } + } + return null; + } + + public VirtualRoutingResource getVirtualRoutingResource() { + return _vrResource; + } + + public VM getVM(final Connection conn, final String vmName) { + // Look up VMs with the specified name + Set vms; + try { + vms = VM.getByNameLabel(conn, vmName); + } catch (final XenAPIException e) { + throw new CloudRuntimeException("Unable to get " + vmName + ": " + e.toString(), e); + } catch (final Exception e) { + throw new CloudRuntimeException("Unable to get " + vmName + ": " + e.getMessage(), e); + } + + // If there are no VMs, throw an exception + if (vms.size() == 0) { + throw new CloudRuntimeException("VM with name: " + vmName + " does not exist."); + } + + // If there is more than one VM, print a warning + if (vms.size() > 1) { + s_logger.warn("Found " + vms.size() + " VMs with name: " + vmName); + } + + // Return the first VM in the set + return vms.iterator().next(); + } + + public String getVMInstanceName() { + return _instance; + } + + public long getVMSnapshotChainSize(final Connection conn, final VolumeObjectTO volumeTo, final String vmName) throws BadServerResponse, XenAPIException, XmlRpcException { + final Set allvolumeVDIs = VDI.getByNameLabel(conn, volumeTo.getName()); + long size = 0; + for (final VDI vdi : allvolumeVDIs) { + try { + if (vdi.getIsASnapshot(conn) && vdi.getSmConfig(conn).get("vhd-parent") != null) { + final String parentUuid = vdi.getSmConfig(conn).get("vhd-parent"); + final VDI parentVDI = VDI.getByUuid(conn, parentUuid); + // add size of snapshot vdi node, usually this only contains + // meta data + size = size + vdi.getPhysicalUtilisation(conn); + // add size of snapshot vdi parent, this contains data + if (!isRefNull(parentVDI)) { + size = size + parentVDI.getPhysicalUtilisation(conn).longValue(); + } + } + } catch (final Exception e) { + s_logger.debug("Exception occurs when calculate snapshot capacity for volumes: due to " + e.toString()); + continue; + } + } + if (volumeTo.getVolumeType() == Volume.Type.ROOT) { + final Map allVMs = VM.getAllRecords(conn); + // add size of memory snapshot vdi + if (allVMs != null && allVMs.size() > 0) { + for (final VM vmr : allVMs.keySet()) { + try { + final String vName = vmr.getNameLabel(conn); + if (vName != null && vName.contains(vmName) && vmr.getIsASnapshot(conn)) { + final VDI memoryVDI = vmr.getSuspendVDI(conn); + if (!isRefNull(memoryVDI)) { + size = size + memoryVDI.getPhysicalUtilisation(conn); + final VDI pMemoryVDI = memoryVDI.getParent(conn); + if (!isRefNull(pMemoryVDI)) { + size = size + pMemoryVDI.getPhysicalUtilisation(conn); + } + } + } + } catch (final Exception e) { + s_logger.debug("Exception occurs when calculate snapshot capacity for memory: due to " + e.toString()); + continue; + } + } + } + } + return size; + } + + public PowerState getVmState(final Connection conn, final String vmName) { + int retry = 3; + while (retry-- > 0) { + try { + final Set vms = VM.getByNameLabel(conn, vmName); + for (final VM vm : vms) { + return convertToPowerState(vm.getPowerState(conn)); + } + } catch (final BadServerResponse e) { + // There is a race condition within xenserver such that if a vm + // is + // deleted and we + // happen to ask for it, it throws this stupid response. So + // if this happens, + // we take a nap and try again which then avoids the race + // condition because + // the vm's information is now cleaned up by xenserver. The + // error + // is as follows + // com.xensource.xenapi.Types$BadServerResponse + // [HANDLE_INVALID, VM, + // 3dde93f9-c1df-55a7-2cde-55e1dce431ab] + s_logger.info("Unable to get a vm PowerState due to " + e.toString() + ". We are retrying. Count: " + retry); + try { + Thread.sleep(3000); + } catch (final InterruptedException ex) { + + } + } catch (final XenAPIException e) { + final String msg = "Unable to get a vm PowerState due to " + e.toString(); + s_logger.warn(msg, e); + break; + } catch (final XmlRpcException e) { + final String msg = "Unable to get a vm PowerState due to " + e.getMessage(); + s_logger.warn(msg, e); + break; + } + } + + return PowerState.PowerOff; + } + + public HashMap getVmStats(final Connection conn, final GetVmStatsCommand cmd, final List vmUUIDs, final String hostGuid) { + final HashMap vmResponseMap = new HashMap(); + + for (final String vmUUID : vmUUIDs) { + vmResponseMap.put(vmUUID, new VmStatsEntry(0, 0, 0, 0, "vm")); + } + + final Object[] rrdData = getRRDData(conn, 2); // call rrddata with 2 for + // vm + + if (rrdData == null) { + return null; + } + + final Integer numRows = (Integer) rrdData[0]; + final Integer numColumns = (Integer) rrdData[1]; + final Node legend = (Node) rrdData[2]; + final Node dataNode = (Node) rrdData[3]; + + final NodeList legendChildren = legend.getChildNodes(); + for (int col = 0; col < numColumns; col++) { + + if (legendChildren == null || legendChildren.item(col) == null) { + continue; + } + + final String columnMetadata = getXMLNodeValue(legendChildren.item(col)); + + if (columnMetadata == null) { + continue; + } + + final String[] columnMetadataList = columnMetadata.split(":"); + + if (columnMetadataList.length != 4) { + continue; + } + + final String type = columnMetadataList[1]; + final String uuid = columnMetadataList[2]; + final String param = columnMetadataList[3]; + + if (type.equals("vm") && vmResponseMap.keySet().contains(uuid)) { + final VmStatsEntry vmStatsAnswer = vmResponseMap.get(uuid); + + vmStatsAnswer.setEntityType("vm"); + + if (param.contains("cpu")) { + vmStatsAnswer.setNumCPUs(vmStatsAnswer.getNumCPUs() + 1); + vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() + getDataAverage(dataNode, col, numRows)); + } else if (param.matches("vif_\\d*_rx")) { + vmStatsAnswer.setNetworkReadKBs(vmStatsAnswer.getNetworkReadKBs() + getDataAverage(dataNode, col, numRows) / 1000); + } else if (param.matches("vif_\\d*_tx")) { + vmStatsAnswer.setNetworkWriteKBs(vmStatsAnswer.getNetworkWriteKBs() + getDataAverage(dataNode, col, numRows) / 1000); + } else if (param.matches("vbd_.*_read")) { + vmStatsAnswer.setDiskReadKBs(vmStatsAnswer.getDiskReadKBs() + getDataAverage(dataNode, col, numRows) / 1000); + } else if (param.matches("vbd_.*_write")) { + vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / 1000); + } + } + } + + for (final Map.Entry entry : vmResponseMap.entrySet()) { + final VmStatsEntry vmStatsAnswer = entry.getValue(); + + if (vmStatsAnswer.getNumCPUs() != 0) { + vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() / vmStatsAnswer.getNumCPUs()); + } + + vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() * 100); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Vm cpu utilization " + vmStatsAnswer.getCPUUtilization()); + } + } + return vmResponseMap; + } + + public String getVncUrl(final Connection conn, final VM vm) { + VM.Record record; + Console c; + try { + record = vm.getRecord(conn); + final Set consoles = record.consoles; + + if (consoles.isEmpty()) { + s_logger.warn("There are no Consoles available to the vm : " + record.nameDescription); + return null; + } + final Iterator i = consoles.iterator(); + while (i.hasNext()) { + c = i.next(); + if (c.getProtocol(conn) == Types.ConsoleProtocol.RFB) { + return c.getLocation(conn); + } + } + } catch (final XenAPIException e) { + final String msg = "Unable to get console url due to " + e.toString(); + s_logger.warn(msg, e); + return null; + } catch (final XmlRpcException e) { + final String msg = "Unable to get console url due to " + e.getMessage(); + s_logger.warn(msg, e); + return null; + } + return null; + } + + protected String getXMLNodeValue(final Node n) { + return n.getChildNodes().item(0).getNodeValue(); + } + + public void handleSrAndVdiDetach(final String iqn, final Connection conn) throws Exception { + final SR sr = getStorageRepository(conn, iqn); + + removeSR(conn, sr); + } + + public String handleVmStartFailure(final Connection conn, final String vmName, final VM vm, final String message, final Throwable th) { final String msg = "Unable to start " + vmName + " due to " + message; s_logger.warn(msg, th); @@ -1496,7 +3370,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (final VIF vif : vmr.VIFs) { try { final VIF.Record rec = vif.getRecord(conn); - if(rec != null) { + if (rec != null) { networks.add(rec.network); } else { s_logger.warn("Unable to cleanup VIF: " + vif.toWireString() + " As vif record is null"); @@ -1547,95 +3421,318 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return msg; } - protected VBD createPatchVbd(final Connection conn, final String vmName, final VM vm) throws XmlRpcException, XenAPIException { - - if (_host.systemvmisouuid == null) { - final Set srs = SR.getByNameLabel(conn, "XenServer Tools"); - if (srs.size() != 1) { - throw new CloudRuntimeException("There are " + srs.size() + " SRs with name XenServer Tools"); - } - final SR sr = srs.iterator().next(); - sr.scan(conn); - - final SR.Record srr = sr.getRecord(conn); - - if (_host.systemvmisouuid == null) { - for (final VDI vdi : srr.VDIs) { - final VDI.Record vdir = vdi.getRecord(conn); - if (vdir.nameLabel.contains("systemvm.iso")) { - _host.systemvmisouuid = vdir.uuid; - break; - } - } - } - if (_host.systemvmisouuid == null) { - throw new CloudRuntimeException("can not find systemvmiso"); - } - } - - final VBD.Record cdromVBDR = new VBD.Record(); - cdromVBDR.VM = vm; - cdromVBDR.empty = true; - cdromVBDR.bootable = false; - cdromVBDR.userdevice = "3"; - cdromVBDR.mode = Types.VbdMode.RO; - cdromVBDR.type = Types.VbdType.CD; - final VBD cdromVBD = VBD.create(conn, cdromVBDR); - cdromVBD.insert(conn, VDI.getByUuid(conn, _host.systemvmisouuid)); - - return cdromVBD; - } - - protected void destroyPatchVbd(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException { - try { - if (!vmName.startsWith("r-") && !vmName.startsWith("s-") && !vmName.startsWith("v-")) { - return; - } - final Set vms = VM.getByNameLabel(conn, vmName); - for (final VM vm : vms) { - final Set vbds = vm.getVBDs(conn); - for (final VBD vbd : vbds) { - if (vbd.getType(conn) == Types.VbdType.CD) { - vbd.eject(conn); - vbd.destroy(conn); - break; - } - } - } - } catch (final Exception e) { - s_logger.debug("Cannot destory CD-ROM device for VM " + vmName + " due to " + e.toString(), e); - } - } - - protected CheckSshAnswer execute(final CheckSshCommand cmd) { + @Override + public StartupCommand[] initialize() throws IllegalArgumentException { final Connection conn = getConnection(); - 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 (!getHostInfo(conn)) { + s_logger.warn("Unable to get host information for " + _host.getIp()); + return null; } + final StartupRoutingCommand cmd = new StartupRoutingCommand(); + fillHostInfo(conn, cmd); + cmd.setHypervisorType(HypervisorType.XenServer); + cmd.setCluster(_cluster); + cmd.setPoolSync(false); try { - final String result = connect(conn, cmd.getName(), privateIp, cmdPort); - if (result != null) { - return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result); - } - //Do not destroy the disk here! It will stio the patching process. Please, don't! - //destroyPatchVbd(conn, vmName); - } catch (final Exception e) { - return new CheckSshAnswer(cmd, e); + final Pool pool = Pool.getByUuid(conn, _host.getPool()); + final Pool.Record poolr = pool.getRecord(conn); + poolr.master.getRecord(conn); + } catch (final Throwable e) { + s_logger.warn("Check for master failed, failing the FULL Cluster sync command"); } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Ping command port succeeded for vm " + vmName); + final StartupStorageCommand sscmd = initializeLocalSR(conn); + if (sscmd != null) { + return new StartupCommand[] { cmd, sscmd }; } - - return new CheckSshAnswer(cmd); + return new StartupCommand[] { cmd }; } - private HashMap parseDefaultOvsRuleComamnd(final String str) { + protected StartupStorageCommand initializeLocalSR(final Connection conn) { + final SR lvmsr = getLocalLVMSR(conn); + if (lvmsr != null) { + try { + _host.setLocalSRuuid(lvmsr.getUuid(conn)); + + final String lvmuuid = lvmsr.getUuid(conn); + final long cap = lvmsr.getPhysicalSize(conn); + if (cap > 0) { + final long avail = cap - lvmsr.getPhysicalUtilisation(conn); + lvmsr.setNameLabel(conn, lvmuuid); + final String name = "Cloud Stack Local LVM Storage Pool for " + _host.getUuid(); + lvmsr.setNameDescription(conn, name); + final Host host = Host.getByUuid(conn, _host.getUuid()); + final String address = host.getAddress(conn); + final StoragePoolInfo pInfo = new StoragePoolInfo(lvmuuid, address, SRType.LVM.toString(), SRType.LVM.toString(), StoragePoolType.LVM, cap, avail); + final StartupStorageCommand cmd = new StartupStorageCommand(); + cmd.setPoolInfo(pInfo); + cmd.setGuid(_host.getUuid()); + cmd.setDataCenter(Long.toString(_dcId)); + cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); + return cmd; + } + } catch (final XenAPIException e) { + final String msg = "build local LVM info err in host:" + _host.getUuid() + e.toString(); + s_logger.warn(msg); + } catch (final XmlRpcException e) { + final String msg = "build local LVM info err in host:" + _host.getUuid() + e.getMessage(); + s_logger.warn(msg); + } + } + + final SR extsr = getLocalEXTSR(conn); + if (extsr != null) { + try { + final String extuuid = extsr.getUuid(conn); + _host.setLocalSRuuid(extuuid); + final long cap = extsr.getPhysicalSize(conn); + if (cap > 0) { + final long avail = cap - extsr.getPhysicalUtilisation(conn); + extsr.setNameLabel(conn, extuuid); + final String name = "Cloud Stack Local EXT Storage Pool for " + _host.getUuid(); + extsr.setNameDescription(conn, name); + final Host host = Host.getByUuid(conn, _host.getUuid()); + final String address = host.getAddress(conn); + final StoragePoolInfo pInfo = new StoragePoolInfo(extuuid, address, SRType.EXT.toString(), SRType.EXT.toString(), StoragePoolType.EXT, cap, avail); + final StartupStorageCommand cmd = new StartupStorageCommand(); + cmd.setPoolInfo(pInfo); + cmd.setGuid(_host.getUuid()); + cmd.setDataCenter(Long.toString(_dcId)); + cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); + return cmd; + } + } catch (final XenAPIException e) { + final String msg = "build local EXT info err in host:" + _host.getUuid() + e.toString(); + s_logger.warn(msg); + } catch (final XmlRpcException e) { + final String msg = "build local EXT info err in host:" + _host.getUuid() + e.getMessage(); + s_logger.warn(msg); + } + } + return null; + } + + public boolean isDeviceUsed(final Connection conn, final VM vm, final Long deviceId) { + // Figure out the disk number to attach the VM to + + String msg = null; + try { + final Set allowedVBDDevices = vm.getAllowedVBDDevices(conn); + if (allowedVBDDevices.contains(deviceId.toString())) { + return false; + } + return true; + } catch (final XmlRpcException e) { + msg = "Catch XmlRpcException due to: " + e.getMessage(); + s_logger.warn(msg, e); + } catch (final XenAPIException e) { + msg = "Catch XenAPIException due to: " + e.toString(); + s_logger.warn(msg, e); + } + throw new CloudRuntimeException("When check deviceId " + msg); + } + + /** + * When Dynamic Memory Control (DMC) is enabled - xenserver allows scaling + * the guest memory while the guest is running + * + * By default this is disallowed, override the specific xenserver resource + * if this is enabled + */ + public boolean isDmcEnabled(final Connection conn, final Host host) throws XenAPIException, XmlRpcException { + return false; + } + + public boolean IsISCSI(final String type) { + return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type); + } + + public boolean isNetworkSetupByName(final String nameTag) throws XenAPIException, XmlRpcException { + if (nameTag != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Looking for network setup by name " + nameTag); + } + final Connection conn = getConnection(); + final XsLocalNetwork network = getNetworkByName(conn, nameTag); + if (network == null) { + return false; + } + } + return true; + } + + public boolean isOvs() { + return _isOvs; + } + + public boolean isRefNull(final XenAPIObject object) { + return object == null || object.toWireString().equals("OpaqueRef:NULL") || object.toWireString().equals(""); + } + + public boolean isSecurityGroupEnabled() { + return _securityGroupEnabled; + } + + public boolean isXcp() { + final Connection conn = getConnection(); + final String result = callHostPlugin(conn, "ovstunnel", "is_xcp"); + if (result.equals("XCP")) { + return true; + } + return false; + } + + boolean killCopyProcess(final Connection conn, final String nameLabel) { + final String results = callHostPluginAsync(conn, "vmops", "kill_copy_process", 60, "namelabel", nameLabel); + String errMsg = null; + if (results == null || results.equals("false")) { + errMsg = "kill_copy_process failed"; + s_logger.warn(errMsg); + return false; + } else { + return true; + } + } + + public boolean launchHeartBeat(final Connection conn) { + final String result = callHostPluginPremium(conn, "heartbeat", "host", _host.getUuid(), "timeout", Integer.toString(_heartbeatTimeout), "interval", + Integer.toString(_heartbeatInterval)); + if (result == null || !result.contains("> DONE <")) { + s_logger.warn("Unable to launch the heartbeat process on " + _host.getIp()); + return false; + } + return true; + } + + protected String logX(final XenAPIObject obj, final String msg) { + return new StringBuilder("Host ").append(_host.getIp()).append(" ").append(obj.toWireString()).append(": ").append(msg).toString(); + } + + public void migrateVM(final Connection conn, final Host destHost, final VM vm, final String vmName) throws Exception { + Task task = null; + try { + final Map other = new HashMap(); + other.put("live", "true"); + task = vm.poolMigrateAsync(conn, destHost, other); + try { + // poll every 1 seconds + final long timeout = _migratewait * 1000L; + waitForTask(conn, task, 1000, timeout); + checkForSuccess(conn, task); + } catch (final Types.HandleInvalid e) { + if (vm.getResidentOn(conn).equals(destHost)) { + task = null; + return; + } + throw new CloudRuntimeException("migrate VM catch HandleInvalid and VM is not running on dest host"); + } + } catch (final XenAPIException e) { + final String msg = "Unable to migrate VM(" + vmName + ") from host(" + _host.getUuid() + ")"; + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg); + } finally { + if (task != null) { + try { + task.destroy(conn); + } catch (final Exception e1) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString()); + } + } + } + } + + protected VDI mount(final Connection conn, final StoragePoolType poolType, final String volumeFolder, final String volumePath) { + return getVDIbyUuid(conn, volumePath); + } + + 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; + } + + // corer case, xenserver pv driver iso + final String templateName = iso.getName(); + if (templateName.startsWith("xs-tools")) { + 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()); + } catch (final Exception e) { + throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString()); + } + } + + 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("/"); + + final String mountpoint = isoPath.substring(0, index); + URI uri; + 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); + } + return isoVdi; + } else { + final VolumeObjectTO vol = (VolumeObjectTO) data; + return VDI.getByUuid(conn, vol.getPath()); + } + } + + public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) { + if (option.equals("get")) { + return "0:0"; + } + return null; + } + + private List> ovsFullSyncStates() { + final Connection conn = getConnection(); + final String result = callHostPlugin(conn, "ovsgre", "ovs_get_vm_log", "host_uuid", _host.getUuid()); + final String[] logs = result != null ? result.split(";") : new String[0]; + final List> states = new ArrayList>(); + for (final String log : logs) { + final String[] info = log.split(","); + if (info.length != 5) { + s_logger.warn("Wrong element number in ovs log(" + log + ")"); + continue; + } + + // ','.join([bridge, vmName, vmId, seqno, tag]) + try { + states.add(new Pair(info[0], Long.parseLong(info[3]))); + } catch (final NumberFormatException nfe) { + states.add(new Pair(info[0], -1L)); + } + } + return states; + } + + public HashMap parseDefaultOvsRuleComamnd(final String str) { final HashMap cmd = new HashMap(); final String[] sarr = str.split("/"); for (int i = 0; i < sarr.length; i++) { @@ -1655,244 +3752,161 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return cmd; } - private void cleanUpTmpDomVif(final Connection conn, final Network nw) throws XenAPIException, XmlRpcException { + protected Pair parseTimestamp(final String timeStampStr) { + final String[] tokens = timeStampStr.split("-"); + if (tokens.length != 3) { + s_logger.debug("timeStamp in network has wrong pattern: " + timeStampStr); + return null; + } + if (!tokens[0].equals("CsCreateTime")) { + s_logger.debug("timeStamp in network doesn't start with CsCreateTime: " + timeStampStr); + return null; + } + return new Pair(Long.parseLong(tokens[1]), Integer.parseInt(tokens[2])); + } - 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 { - 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); + private void pbdPlug(final Connection conn, final PBD pbd, final String uuid) { + try { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Plugging in PBD " + uuid + " for " + _host); } + pbd.plug(conn); + } catch (final Exception e) { + final String msg = "PBD " + uuid + " is not attached! and PBD plug failed due to " + e.toString() + ". Please check this PBD in " + _host; + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg); } } - private Answer execute(final PvlanSetupCommand cmd) { + protected boolean pingdomr(final Connection conn, final String host, final String port) { + String status; + status = callHostPlugin(conn, "vmops", "pingdomr", "host", host, "port", port); + + if (status == null || status.isEmpty()) { + return false; + } + + return true; + + } + + public boolean pingXAPI() { final Connection conn = getConnection(); - - 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(); - final String networkTag = cmd.getNetworkTag(); - - XsLocalNetwork nw = null; - String nwNameLabel = null; try { - nw = getNativeNetworkForTraffic(conn, TrafficType.Guest, networkTag); - if (nw == null) { - s_logger.error("Network is not configured on the backend for pvlan " + primaryPvlan); - throw new CloudRuntimeException("Network for the backend is not configured correctly for pvlan primary: " + primaryPvlan); + final Host host = Host.getByUuid(conn, _host.getUuid()); + if (!host.getEnabled(conn)) { + s_logger.debug("Host " + _host.getIp() + " is not enabled!"); + return false; } - nwNameLabel = nw.getNetwork().getNameLabel(conn); - } catch (final XenAPIException e) { - s_logger.warn("Fail to get network", e); - return new Answer(cmd, false, e.toString()); - } catch (final XmlRpcException e) { - s_logger.warn("Fail to get network", e); - return new Answer(cmd, false, e.toString()); + } 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 void plugDom0Vif(final Connection conn, final VIF dom0Vif) throws XmlRpcException, XenAPIException { + if (dom0Vif != null) { + dom0Vif.plug(conn); + } + } + + protected boolean postCreatePrivateTemplate(final Connection conn, final String templatePath, final String tmpltFilename, final String templateName, + String templateDescription, String checksum, final long size, final long virtualSize, final long templateId) { + + if (templateDescription == null) { + templateDescription = ""; } - String result = null; - if (cmd.getType() == PvlanSetupCommand.Type.DHCP) { - result = - callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, - "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac); - if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { - s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac); - return new Answer(cmd, false, result); + if (checksum == null) { + checksum = ""; + } + + final String result = callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, + "templateName", templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", + String.valueOf(virtualSize), "templateId", String.valueOf(templateId)); + + boolean success = false; + if (result != null && !result.isEmpty()) { + // Else, command threw an exception which has already been logged. + + if (result.equalsIgnoreCase("1")) { + s_logger.debug("Successfully created template.properties file on secondary storage for " + tmpltFilename); + success = true; } else { - s_logger.info("Programmed pvlan for dhcp server with mac " + dhcpMac); - } - } else if (cmd.getType() == PvlanSetupCommand.Type.VM) { - result = - callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, - "vm-mac", vmMac); - if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { - 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); + s_logger.warn("Could not create template.properties file on secondary storage for " + tmpltFilename + " for templateId: " + templateId); } } - return new Answer(cmd, true, result); + + return success; } @Override - public StartAnswer execute(final StartCommand cmd) { - final Connection conn = getConnection(); - final VirtualMachineTO vmSpec = cmd.getVirtualMachine(); - final String vmName = vmSpec.getName(); - VmPowerState state = VmPowerState.HALTED; - VM vm = null; - // if a VDI is created, record its UUID to send back to the CS MS - final Map iqnToPath = new HashMap(); - try { - final Set vms = VM.getByNameLabel(conn, vmName); - if (vms != null) { - for (final VM v : vms) { - final VM.Record vRec = v.getRecord(conn); - if (vRec.powerState == VmPowerState.HALTED) { - v.destroy(conn); - } else if (vRec.powerState == VmPowerState.RUNNING) { - final String host = vRec.residentOn.getUuid(conn); - final String msg = "VM " + vmName + " is runing on host " + host; - s_logger.debug(msg); - return new StartAnswer(cmd, msg, host); - } else { - final String msg = "There is already a VM having the same name " + vmName + " vm record " + vRec.toString(); - s_logger.warn(msg); - return new StartAnswer(cmd, msg); + 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); + } + + public void prepareISO(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException { + + 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); + } + for (final PBD pbd : pbds) { + final PBD.Record pbdr = pbd.getRecord(conn); + if (pbdr.host.getUuid(conn).equals(_host.getUuid())) { + return; } } - } - s_logger.debug("1. The VM " + vmName + " is in Starting state."); - - final Host host = Host.getByUuid(conn, _host.uuid); - vm = createVmFromTemplate(conn, vmSpec, host); - - final GPUDeviceTO gpuDevice = vmSpec.getGpuDevice(); - if (gpuDevice != null) { - s_logger.debug("Creating VGPU for of VGPU type: " + gpuDevice.getVgpuType() + " in GPU group " - + gpuDevice.getGpuGroup() + " for VM " + vmName ); - createVGPU(conn, cmd, vm, gpuDevice); - } - - for (final DiskTO disk : vmSpec.getDisks()) { - final VDI newVdi = prepareManagedDisk(conn, disk, vmName); - - if (newVdi != null) { - final String path = newVdi.getUuid(conn); - - iqnToPath.put(disk.getDetails().get(DiskTO.IQN), path); - } - - createVbd(conn, disk, vmName, vm, vmSpec.getBootloader(), newVdi); - } - - if (vmSpec.getType() != VirtualMachine.Type.User) { - createPatchVbd(conn, vmName, vm); - } - - for (final NicTO nic : vmSpec.getNics()) { - createVif(conn, vmName, vm, vmSpec, nic); - } - - startVM(conn, host, vm, vmName); - - if (_isOvs) { - // TODO(Salvatore-orlando): This code should go - for (final NicTO nic : vmSpec.getNics()) { - if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) { - final HashMap args = parseDefaultOvsRuleComamnd(BroadcastDomainType.getValue(nic.getBroadcastUri())); - final OvsSetTagAndFlowCommand flowCmd = - new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), Long.parseLong(args.get("vmId"))); - final OvsSetTagAndFlowAnswer r = execute(flowCmd); - if (!r.getResult()) { - s_logger.warn("Failed to set flow for VM " + r.getVmId()); - } else { - s_logger.info("Success to set flow for VM " + r.getVmId()); - } - } - } - } - - if (_canBridgeFirewall) { - String result = null; - if (vmSpec.getType() != VirtualMachine.Type.User) { - final NicTO[] nics = vmSpec.getNics(); - boolean secGrpEnabled = false; - for (final NicTO nic : nics) { - if (nic.isSecurityGroupEnabled() || - nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { - secGrpEnabled = true; - break; - } - } - if (secGrpEnabled) { - result = callHostPlugin(conn, "vmops", "default_network_rules_systemvm", "vmName", vmName); - if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { - s_logger.warn("Failed to program default network rules for " + vmName); - } else { - s_logger.info("Programmed default network rules for " + vmName); - } - } - - } else { - //For user vm, program the rules for each nic if the isolation uri scheme is ec2 - final NicTO[] nics = vmSpec.getNics(); - for (final NicTO nic : nics) { - if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && - nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { - 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:"; - } - result = - callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", - Long.toString(vmSpec.getId()), "secIps", secIpsStr); - - if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { - s_logger.warn("Failed to program default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac()); - } else { - s_logger.info("Programmed default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac()); - } - } - } - } - } - - state = VmPowerState.RUNNING; - - final StartAnswer startAnswer = new StartAnswer(cmd); - - startAnswer.setIqnToPath(iqnToPath); - - return startAnswer; - } catch (final Exception e) { - s_logger.warn("Catch Exception: " + e.getClass().toString() + " due to " + e.toString(), e); - final String msg = handleVmStartFailure(conn, vmName, vm, "", e); - - final StartAnswer startAnswer = new StartAnswer(cmd, msg); - - startAnswer.setIqnToPath(iqnToPath); - - return startAnswer; - } finally { - if (state != VmPowerState.HALTED) { - s_logger.debug("2. The VM " + vmName + " is in " + state + " state."); - } else { - s_logger.debug("The VM is in stopped state, detected problem during startup : " + vmName); + 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; } } } - // the idea here is to see if the DiskTO in question is from managed storage and + // the idea here is to see if the DiskTO in question is from managed storage + // and // does not yet have an SR // if no SR, create it and create a VDI in it - private VDI prepareManagedDisk(final Connection conn, final DiskTO disk, final String vmName) throws Exception { + public VDI prepareManagedDisk(final Connection conn, final DiskTO disk, final String vmName) throws Exception { final Map details = disk.getDetails(); if (details == null) { @@ -1946,7 +3960,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (vdi == null) { vdi = createVdi(sr, vdiNameLabel, volumeSize); } else { - // if VDI is not null, it must have already been created, so check whether a resize of the volume was performed + // if VDI is not null, it must have already been created, so check + // whether a resize of the volume was performed // if true, resize the VDI to the volume size s_logger.info("checking for the resize of the datadisk"); @@ -1954,7 +3969,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe final long vdiVirtualSize = vdi.getVirtualSize(conn); if (vdiVirtualSize != volumeSize) { - s_logger.info("resizing the data disk (vdi) from vdiVirtualsize: "+ vdiVirtualSize + " to volumeSize: " + volumeSize); + s_logger.info("resizing the data disk (vdi) from vdiVirtualsize: " + vdiVirtualSize + " to volumeSize: " + volumeSize); try { vdi.resize(conn, volumeSize); @@ -1967,93 +3982,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return vdi; } - protected Answer execute(final ModifySshKeysCommand cmd) { - return new Answer(cmd); - } - - private boolean doPingTest(final Connection conn, final String computingHostIp) { - final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.ip, 22); - try { - sshConnection.connect(null, 60000, 60000); - if (!sshConnection.authenticateWithPassword(_username, _password.peek())) { - throw new CloudRuntimeException("Unable to authenticate"); - } - - final String cmd = "ping -c 2 " + computingHostIp; - if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) { - throw new CloudRuntimeException("Cannot ping host " + computingHostIp + " from host " + _host.ip); - } - return true; - } catch (final Exception e) { - s_logger.warn("Catch exception " + e.toString(), e); - return false; - } finally { - sshConnection.close(); - } - } - - protected CheckOnHostAnswer execute(final CheckOnHostCommand cmd) { - return new CheckOnHostAnswer(cmd, null, "Not Implmeneted"); - } - - private boolean doPingTest(final Connection conn, final String domRIp, final String vmIp) { - final String args = "-i " + domRIp + " -p " + vmIp; - final String result = callHostPlugin(conn, "vmops", "pingtest", "args", args); - if (result == null || result.isEmpty()) { - return false; - } - return true; - } - - private Answer execute(final PingTestCommand cmd) { - final Connection conn = getConnection(); - boolean result = false; - final String computingHostIp = cmd.getComputingHostIp(); - - if (computingHostIp != null) { - result = doPingTest(conn, computingHostIp); - } else { - result = doPingTest(conn, cmd.getRouterIp(), cmd.getPrivateIp()); - } - - if (!result) { - return new Answer(cmd, false, "PingTestCommand failed"); - } - return new Answer(cmd); - } - - protected MaintainAnswer execute(final MaintainCommand cmd) { - final Connection conn = getConnection(); - try { - - final Host host = Host.getByUuid(conn, _host.uuid); - // remove all tags cloud stack - final Host.Record hr = host.getRecord(conn); - final Iterator it = hr.tags.iterator(); - while (it.hasNext()) { - final String tag = it.next(); - if (tag.contains("cloud")) { - it.remove(); - } - } - host.setTags(conn, hr.tags); - return new MaintainAnswer(cmd); - } catch (final XenAPIException e) { - s_logger.warn("Unable to put server in maintainence mode", e); - return new MaintainAnswer(cmd, false, e.getMessage()); - } catch (final XmlRpcException e) { - s_logger.warn("Unable to put server in maintainence mode", e); - return new MaintainAnswer(cmd, false, e.getMessage()); - } - } - - protected String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) { - if (option.equals("get")) { - return "0:0"; - } - return null; - } - protected ExecutionResult prepareNetworkElementCommand(final IpAssocCommand cmd) { final Connection conn = getConnection(); final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); @@ -2068,7 +3996,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe final NicTO nic = new NicTO(); nic.setMac(ip.getVifMacAddress()); nic.setType(ip.getTrafficType()); - if (ip.getBroadcastUri()== null) { + if (ip.getBroadcastUri() == null) { nic.setBroadcastType(BroadcastDomainType.Native); } else { final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); @@ -2081,13 +4009,16 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe final Network network = getNetwork(conn, nic); - // Determine the correct VIF on DomR to associate/disassociate the + // Determine the correct VIF on DomR to associate/disassociate + // the // IP address with VIF correctVif = getCorrectVif(conn, router, network); - // If we are associating an IP address and DomR doesn't have a VIF + // If we are associating an IP address and DomR doesn't have a + // VIF // for the specified vlan ID, we need to add a VIF - // If we are disassociating the last IP address in the VLAN, we need + // If we are disassociating the last IP address in the VLAN, we + // need // to remove a VIF boolean addVif = false; if (ip.isAdd() && correctVif == null) { @@ -2113,7 +4044,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (ip.isAdd() && correctVif == null) { throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); } - if (correctVif != null ) { + if (correctVif != null) { ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); ip.setNewNic(addVif); } @@ -2127,715 +4058,204 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new ExecutionResult(true, null); } - protected ExecutionResult cleanupNetworkElementCommand(final IpAssocCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand 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 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); - } - 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); - } - } + final VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress()); + setNicDevIdIfCorrectVifIsNotNull(conn, ip, correctVif); } } catch (final Exception e) { - s_logger.debug("Ip Assoc failure on applying one ip due to exception: ", e); + s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); return new ExecutionResult(false, e.getMessage()); } + + return new ExecutionResult(true, null); + } + + protected ExecutionResult prepareNetworkElementCommand(final SetNetworkACLCommand cmd) { + final Connection conn = getConnection(); + final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + + try { + final VM router = getVM(conn, routerName); + + final NicTO nic = cmd.getNic(); + if (nic != null) { + final VIF vif = getVifByMac(conn, router, nic.getMac()); + if (vif == null) { + final String msg = "Prepare SetNetworkACL failed due to VIF is null for : " + nic.getMac() + " with routername: " + routerName; + s_logger.error(msg); + return new ExecutionResult(false, msg); + } + nic.setDeviceId(Integer.valueOf(vif.getDevice(conn))); + } else { + final String msg = "Prepare SetNetworkACL failed due to nic is null for : " + routerName; + s_logger.error(msg); + return new ExecutionResult(false, msg); + } + } catch (final Exception e) { + final String msg = "Prepare SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new ExecutionResult(false, msg); + } return new ExecutionResult(true, null); } - protected GetVncPortAnswer execute(final GetVncPortCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) { final Connection conn = getConnection(); + final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + final IpAddressTO pubIp = cmd.getIpAddress(); try { - final Set vms = VM.getByNameLabel(conn, cmd.getName()); - if (vms.size() == 1) { - String consoleurl; - consoleurl = "consoleurl=" + getVncUrl(conn, vms.iterator().next()) + "&" + "sessionref=" + conn.getSessionReference(); - return new GetVncPortAnswer(cmd, consoleurl, -1); - } else { - return new GetVncPortAnswer(cmd, "There are " + vms.size() + " VMs named " + cmd.getName()); - } + final VM router = getVM(conn, routerName); + + final VIF correctVif = getCorrectVif(conn, router, pubIp); + + pubIp.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); + } catch (final Exception e) { - final String msg = "Unable to get vnc port due to " + e.toString(); - s_logger.warn(msg, e); - return new GetVncPortAnswer(cmd, msg); + final String msg = "Ip SNAT failure due to " + e.toString(); + s_logger.error(msg, e); + return new ExecutionResult(false, msg); } - } - - protected Storage.StorageResourceType getStorageResourceType() { - return Storage.StorageResourceType.STORAGE_POOL; - } - - protected CheckHealthAnswer execute(final CheckHealthCommand cmd) { - final boolean result = pingXAPI(); - return new CheckHealthAnswer(cmd, result); - } - - protected long[] getNetworkStats(final Connection conn, final String privateIP) { - final String result = networkUsage(conn, privateIP, "get", null); - final long[] stats = new long[2]; - if (result != null) { - final String[] splitResult = result.split(":"); - int i = 0; - while (i < splitResult.length - 1) { - stats[0] += new Long(splitResult[i++]).longValue(); - stats[1] += new Long(splitResult[i++]).longValue(); - } - } - return stats; + return new ExecutionResult(true, null); } /** - * This is the method called for getting the HOST stats - * * @param cmd * @return */ - protected GetHostStatsAnswer execute(final GetHostStatsCommand cmd) { + private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) { final Connection conn = getConnection(); + final NicTO nic = cmd.getNic(); + final String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); try { - final HostStatsEntry hostStats = getHostStats(conn, cmd, cmd.getHostGuid(), cmd.getHostId()); - return new GetHostStatsAnswer(cmd, hostStats); + final Set vms = VM.getByNameLabel(conn, domrName); + if (vms == null || vms.isEmpty()) { + return new ExecutionResult(false, "Can not find VM " + domrName); + } + final VM vm = vms.iterator().next(); + final String mac = nic.getMac(); + VIF domrVif = null; + for (final VIF vif : vm.getVIFs(conn)) { + final String lmac = vif.getMAC(conn); + if (lmac.equals(mac)) { + domrVif = vif; + // Do not break it! We have 2 routers. + // break; + } + } + if (domrVif == null) { + return new ExecutionResult(false, "Can not find vif with mac " + mac + " for VM " + domrName); + } + + nic.setDeviceId(Integer.valueOf(domrVif.getDevice(conn))); } catch (final Exception e) { - final String msg = "Unable to get Host stats" + e.toString(); + final String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); - return new GetHostStatsAnswer(cmd, null); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - protected HostStatsEntry getHostStats(final Connection conn, final GetHostStatsCommand cmd, final String hostGuid, final long hostId) { - - final HostStatsEntry hostStats = new HostStatsEntry(hostId, 0, 0, 0, "host", 0, 0, 0, 0); - final Object[] rrdData = getRRDData(conn, 1); // call rrd method with 1 for host - - if (rrdData == null) { - return null; - } - - final Integer numRows = (Integer)rrdData[0]; - final Integer numColumns = (Integer)rrdData[1]; - final Node legend = (Node)rrdData[2]; - final Node dataNode = (Node)rrdData[3]; - - final NodeList legendChildren = legend.getChildNodes(); - for (int col = 0; col < numColumns; col++) { - - if (legendChildren == null || legendChildren.item(col) == null) { - continue; - } - - final String columnMetadata = getXMLNodeValue(legendChildren.item(col)); - - if (columnMetadata == null) { - continue; - } - - final String[] columnMetadataList = columnMetadata.split(":"); - - if (columnMetadataList.length != 4) { - continue; - } - - final String type = columnMetadataList[1]; - final String param = columnMetadataList[3]; - - if (type.equalsIgnoreCase("host")) { - - if (param.matches("pif_eth0_rx")) { - hostStats.setNetworkReadKBs(getDataAverage(dataNode, col, numRows)/1000); - } else if (param.matches("pif_eth0_tx")) { - hostStats.setNetworkWriteKBs(getDataAverage(dataNode, col, numRows)/1000); - } else if (param.contains("memory_total_kib")) { - hostStats.setTotalMemoryKBs(getDataAverage(dataNode, col, numRows)); - } else if (param.contains("memory_free_kib")) { - hostStats.setFreeMemoryKBs(getDataAverage(dataNode, col, numRows)); - } else if (param.matches("cpu_avg")) { - // hostStats.setNumCpus(hostStats.getNumCpus() + 1); - hostStats.setCpuUtilization(hostStats.getCpuUtilization() + getDataAverage(dataNode, col, numRows)); - } - - /* - if (param.contains("loadavg")) { - hostStats.setAverageLoad((hostStats.getAverageLoad() + getDataAverage(dataNode, col, numRows))); - } - */ - } - } - - // add the host cpu utilization - /* - if (hostStats.getNumCpus() != 0) { - hostStats.setCpuUtilization(hostStats.getCpuUtilization() / hostStats.getNumCpus()); - s_logger.debug("Host cpu utilization " + hostStats.getCpuUtilization()); - } - */ - - return hostStats; - } - - protected GetVmStatsAnswer execute(final GetVmStatsCommand cmd) { - final Connection conn = getConnection(); - final List vmNames = cmd.getVmNames(); - final HashMap vmStatsNameMap = new HashMap(); - if (vmNames.size() == 0) { - return new GetVmStatsAnswer(cmd, vmStatsNameMap); - } + public void rebootVM(final Connection conn, final VM vm, final String vmName) throws Exception { + Task task = null; try { - - // Determine the UUIDs of the requested VMs - final List vmUUIDs = new ArrayList(); - - for (final String vmName : vmNames) { - final VM vm = getVM(conn, vmName); - vmUUIDs.add(vm.getUuid(conn)); + task = vm.cleanRebootAsync(conn); + try { + // poll every 1 seconds , timeout after 10 minutes + waitForTask(conn, task, 1000, 10 * 60 * 1000); + checkForSuccess(conn, task); + } catch (final Types.HandleInvalid e) { + if (vm.getPowerState(conn) == VmPowerState.RUNNING) { + task = null; + return; + } + throw new CloudRuntimeException("Reboot VM catch HandleInvalid and VM is not in RUNNING state"); } - - final HashMap vmStatsUUIDMap = getVmStats(conn, cmd, vmUUIDs, cmd.getHostGuid()); - if (vmStatsUUIDMap == null) { - return new GetVmStatsAnswer(cmd, vmStatsNameMap); - } - - for (final Map.Entryentry : vmStatsUUIDMap.entrySet()) { - vmStatsNameMap.put(vmNames.get(vmUUIDs.indexOf(entry.getKey())), entry.getValue()); - } - - return new GetVmStatsAnswer(cmd, vmStatsNameMap); } catch (final XenAPIException e) { - final String msg = "Unable to get VM stats" + e.toString(); - s_logger.warn(msg, e); - return new GetVmStatsAnswer(cmd, vmStatsNameMap); - } catch (final XmlRpcException e) { - final String msg = "Unable to get VM stats" + e.getMessage(); - s_logger.warn(msg, e); - return new GetVmStatsAnswer(cmd, vmStatsNameMap); - } - } - - protected HashMap getVmStats(final Connection conn, final GetVmStatsCommand cmd, final List vmUUIDs, final String hostGuid) { - final HashMap vmResponseMap = new HashMap(); - - for (final String vmUUID : vmUUIDs) { - vmResponseMap.put(vmUUID, new VmStatsEntry(0, 0, 0, 0, "vm")); - } - - final Object[] rrdData = getRRDData(conn, 2); // call rrddata with 2 for vm - - if (rrdData == null) { - return null; - } - - final Integer numRows = (Integer)rrdData[0]; - final Integer numColumns = (Integer)rrdData[1]; - final Node legend = (Node)rrdData[2]; - final Node dataNode = (Node)rrdData[3]; - - final NodeList legendChildren = legend.getChildNodes(); - for (int col = 0; col < numColumns; col++) { - - if (legendChildren == null || legendChildren.item(col) == null) { - continue; + s_logger.debug("Unable to Clean Reboot VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString() + ", try hard reboot"); + try { + vm.hardReboot(conn); + } catch (final Exception e1) { + final String msg = "Unable to hard Reboot VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString(); + s_logger.warn(msg, e1); + throw new CloudRuntimeException(msg); } - - final String columnMetadata = getXMLNodeValue(legendChildren.item(col)); - - if (columnMetadata == null) { - continue; - } - - final String[] columnMetadataList = columnMetadata.split(":"); - - if (columnMetadataList.length != 4) { - continue; - } - - final String type = columnMetadataList[1]; - final String uuid = columnMetadataList[2]; - final String param = columnMetadataList[3]; - - if (type.equals("vm") && vmResponseMap.keySet().contains(uuid)) { - final VmStatsEntry vmStatsAnswer = vmResponseMap.get(uuid); - - vmStatsAnswer.setEntityType("vm"); - - if (param.contains("cpu")) { - vmStatsAnswer.setNumCPUs(vmStatsAnswer.getNumCPUs() + 1); - vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() + getDataAverage(dataNode, col, numRows)); - } else if (param.matches("vif_\\d*_rx")) { - vmStatsAnswer.setNetworkReadKBs(vmStatsAnswer.getNetworkReadKBs() + getDataAverage(dataNode, col, numRows)/1000); - } else if (param.matches("vif_\\d*_tx")) { - vmStatsAnswer.setNetworkWriteKBs(vmStatsAnswer.getNetworkWriteKBs() + getDataAverage(dataNode, col, numRows)/1000); - } else if (param.matches("vbd_.*_read")) { - vmStatsAnswer.setDiskReadKBs(vmStatsAnswer.getDiskReadKBs() + getDataAverage(dataNode, col, numRows)/1000); - } else if (param.matches("vbd_.*_write")) { - vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows)/1000); - } - } - } - - for (final Map.Entry entry: vmResponseMap.entrySet()) { - final VmStatsEntry vmStatsAnswer = entry.getValue(); - - if (vmStatsAnswer.getNumCPUs() != 0) { - vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() / vmStatsAnswer.getNumCPUs()); - } - - vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() * 100); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Vm cpu utilization " + vmStatsAnswer.getCPUUtilization()); - } - } - return vmResponseMap; - } - - protected GetVmDiskStatsAnswer execute(final GetVmDiskStatsCommand cmd) { - return new GetVmDiskStatsAnswer(cmd, null, null, null); - } - - - protected Document getStatsRawXML(final Connection conn, final boolean host) { - final Date currentDate = new Date(); - String urlStr = "http://" + _host.ip + "/rrd_updates?"; - urlStr += "session_id=" + conn.getSessionReference(); - urlStr += "&host=" + (host ? "true" : "false"); - urlStr += "&cf=" + _consolidationFunction; - urlStr += "&interval=" + _pollingIntervalInSeconds; - urlStr += "&start=" + (currentDate.getTime() / 1000 - 1000 - 100); - - URL url; - BufferedReader in = null; - try { - url = new URL(urlStr); - url.openConnection(); - final URLConnection uc = url.openConnection(); - in = new BufferedReader(new InputStreamReader(uc.getInputStream())); - final InputSource statsSource = new InputSource(in); - return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(statsSource); - } catch (final MalformedURLException e) { - s_logger.warn("Malformed URL? come on...." + urlStr); - return null; - } catch (final IOException e) { - s_logger.warn("Problems getting stats using " + urlStr, e); - return null; - } catch (final SAXException e) { - s_logger.warn("Problems getting stats using " + urlStr, e); - return null; - } catch (final ParserConfigurationException e) { - s_logger.warn("Problems getting stats using " + urlStr, e); - return null; } finally { - if (in != null) { + if (task != null) { try { - in.close(); - } catch (final IOException e) { - s_logger.warn("Unable to close the buffer ", e); + task.destroy(conn); + } catch (final Exception e1) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString()); } } } } - - - protected Object[] getRRDData(final Connection conn, final int flag) { - - /* - * Note: 1 => called from host, hence host stats 2 => called from vm, hence vm stats - */ - Document doc = null; - - try { - doc = getStatsRawXML(conn, flag == 1 ? true : false); - } catch (final Exception e1) { - s_logger.warn("Error whilst collecting raw stats from plugin: ", e1); - return null; + public void removeSR(final Connection conn, final SR sr) { + if (sr == null) { + return; } - if (doc == null) { //stats are null when the host plugin call fails (host down state) - return null; + if (s_logger.isDebugEnabled()) { + s_logger.debug(logX(sr, "Removing SR")); } - final NodeList firstLevelChildren = doc.getChildNodes(); - final NodeList secondLevelChildren = firstLevelChildren.item(0).getChildNodes(); - final Node metaNode = secondLevelChildren.item(0); - final Node dataNode = secondLevelChildren.item(1); - - Integer numRows = 0; - Integer numColumns = 0; - Node legend = null; - final NodeList metaNodeChildren = metaNode.getChildNodes(); - for (int i = 0; i < metaNodeChildren.getLength(); i++) { - final Node n = metaNodeChildren.item(i); - if (n.getNodeName().equals("rows")) { - numRows = Integer.valueOf(getXMLNodeValue(n)); - } else if (n.getNodeName().equals("columns")) { - numColumns = Integer.valueOf(getXMLNodeValue(n)); - } else if (n.getNodeName().equals("legend")) { - legend = n; - } - } - - return new Object[] { numRows, numColumns, legend, dataNode }; - } - - protected String getXMLNodeValue(final Node n) { - return n.getChildNodes().item(0).getNodeValue(); - } - - protected double getDataAverage(final Node dataNode, final int col, final int numRows) { - double value = 0; - final double dummy = 0; - int numRowsUsed = 0; - for (int row = 0; row < numRows; row++) { - final Node data = dataNode.getChildNodes().item(numRows - 1 - row).getChildNodes().item(col + 1); - final Double currentDataAsDouble = Double.valueOf(getXMLNodeValue(data)); - if (!currentDataAsDouble.equals(Double.NaN)) { - numRowsUsed += 1; - value += currentDataAsDouble; - } - } - - if (numRowsUsed == 0) { - if (!Double.isInfinite(value) && !Double.isNaN(value)) { - return value; - } else { - s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows=0"); - return dummy; - } - } else { - if (!Double.isInfinite(value / numRowsUsed) && !Double.isNaN(value / numRowsUsed)) { - return value / numRowsUsed; - } else { - s_logger.warn("Found an invalid value (infinity/NaN) in getDataAverage(), numRows>0"); - return dummy; - } - } - - } - - private static PowerState convertToPowerState(final VmPowerState ps) { - final PowerState powerState = s_powerStatesTable.get(ps); - return powerState == null ? PowerState.PowerUnknown : powerState; - } - - protected HashMap getHostVmStateReport(final Connection conn) { - - // TODO : new VM sync model does not require a cluster-scope report, we need to optimize - // the report accordingly - final HashMap vmStates = new HashMap(); - Map vm_map = null; for (int i = 0; i < 2; i++) { try { - vm_map = VM.getAllRecords(conn); //USE THIS TO GET ALL VMS FROM A CLUSTER - break; - } catch (final Throwable e) { - s_logger.warn("Unable to get vms", e); - } - try { - Thread.sleep(1000); - } catch (final InterruptedException ex) { - - } - } - - if (vm_map == null) { - return vmStates; - } - for (final VM.Record record : vm_map.values()) { - if (record.isControlDomain || record.isASnapshot || record.isATemplate) { - continue; // Skip DOM0 - } - - final VmPowerState ps = record.powerState; - final Host host = record.residentOn; - String host_uuid = null; - if (!isRefNull(host)) { - try { - host_uuid = host.getUuid(conn); - } catch (final BadServerResponse e) { - s_logger.error("Failed to get host uuid for host " + host.toWireString(), e); - } catch (final XenAPIException e) { - s_logger.error("Failed to get host uuid for host " + host.toWireString(), e); - } catch (final XmlRpcException e) { - s_logger.error("Failed to get host uuid for host " + host.toWireString(), e); + final Set vdis = sr.getVDIs(conn); + for (final VDI vdi : vdis) { + vdi.forget(conn); } - if (host_uuid.equalsIgnoreCase(_host.uuid)) { - vmStates.put( - record.nameLabel, - new HostVmStateReportEntry(convertToPowerState(ps), host_uuid) - ); + Set pbds = sr.getPBDs(conn); + for (final PBD pbd : pbds) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(logX(pbd, "Unplugging pbd")); + } + + // if (pbd.getCurrentlyAttached(conn)) { + pbd.unplug(conn); + // } + + pbd.destroy(conn); } - } - } - return vmStates; - } + pbds = sr.getPBDs(conn); - protected PowerState getVmState(final Connection conn, final String vmName) { - int retry = 3; - while (retry-- > 0) { - try { - final Set vms = VM.getByNameLabel(conn, vmName); - for (final VM vm : vms) { - return convertToPowerState(vm.getPowerState(conn)); + if (pbds.size() == 0) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(logX(sr, "Forgetting")); + } + + sr.forget(conn); + + return; } - } catch (final BadServerResponse e) { - // There is a race condition within xenserver such that if a vm is - // deleted and we - // happen to ask for it, it throws this stupid response. So - // if this happens, - // we take a nap and try again which then avoids the race - // condition because - // the vm's information is now cleaned up by xenserver. The error - // is as follows - // com.xensource.xenapi.Types$BadServerResponse - // [HANDLE_INVALID, VM, - // 3dde93f9-c1df-55a7-2cde-55e1dce431ab] - s_logger.info("Unable to get a vm PowerState due to " + e.toString() + ". We are retrying. Count: " + retry); - try { - Thread.sleep(3000); - } catch (final InterruptedException ex) { - } - } catch (final XenAPIException e) { - final String msg = "Unable to get a vm PowerState due to " + e.toString(); - s_logger.warn(msg, e); - break; - } catch (final XmlRpcException e) { - final String msg = "Unable to get a vm PowerState due to " + e.getMessage(); - s_logger.warn(msg, e); - break; - } - } + if (s_logger.isDebugEnabled()) { + s_logger.debug(logX(sr, "There is still one or more PBDs attached.")); - return PowerState.PowerOff; - } - - protected CheckVirtualMachineAnswer execute(final CheckVirtualMachineCommand cmd) { - final Connection conn = getConnection(); - final String vmName = cmd.getVmName(); - final PowerState powerState = getVmState(conn, vmName); - final Integer vncPort = null; - if (powerState == PowerState.PowerOn) { - s_logger.debug("3. The VM " + vmName + " is in Running state"); - } - - return new CheckVirtualMachineAnswer(cmd, powerState, vncPort); - } - - protected PrepareForMigrationAnswer execute(final PrepareForMigrationCommand cmd) { - final Connection conn = getConnection(); - - final VirtualMachineTO vm = cmd.getVirtualMachine(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Preparing host for migrating " + vm); - } - - final NicTO[] nics = vm.getNics(); - try { - prepareISO(conn, vm.getName()); - - for (final NicTO nic : nics) { - getNetwork(conn, nic); - } - s_logger.debug("4. The VM " + vm.getName() + " is in Migrating state"); - - return new PrepareForMigrationAnswer(cmd); - } catch (final Exception e) { - s_logger.warn("Catch Exception " + e.getClass().getName() + " prepare for migration failed due to " + e.toString(), e); - return new PrepareForMigrationAnswer(cmd, e); - } - } - - String upgradeSnapshot(final Connection conn, final String templatePath, final String snapshotPath) { - final String results = callHostPluginAsync(conn, "vmopspremium", "upgrade_snapshot", 2 * 60 * 60, "templatePath", templatePath, "snapshotPath", snapshotPath); - - if (results == null || results.isEmpty()) { - final String msg = "upgrade_snapshot return null"; - s_logger.warn(msg); - throw new CloudRuntimeException(msg); - } - final String[] tmp = results.split("#"); - final String status = tmp[0]; - if (status.equals("0")) { - return results; - } else { - s_logger.warn(results); - throw new CloudRuntimeException(results); - } - } - - String createTemplateFromSnapshot(final Connection conn, final String templatePath, final String snapshotPath, final int wait) { - final String tmpltLocalDir = UUID.randomUUID().toString(); - final String results = - callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, - "tmpltLocalDir", tmpltLocalDir); - String errMsg = null; - if (results == null || results.isEmpty()) { - errMsg = "create_privatetemplate_from_snapshot return null"; - } else { - final String[] tmp = results.split("#"); - final String status = tmp[0]; - if (status.equals("0")) { - return results; - } else { - errMsg = "create_privatetemplate_from_snapshot failed due to " + tmp[1]; - } - } - final String source = "cloud_mount/" + tmpltLocalDir; - killCopyProcess(conn, source); - s_logger.warn(errMsg); - throw new CloudRuntimeException(errMsg); - } - - boolean killCopyProcess(final Connection conn, final String nameLabel) { - final String results = callHostPluginAsync(conn, "vmops", "kill_copy_process", 60, "namelabel", nameLabel); - String errMsg = null; - if (results == null || results.equals("false")) { - errMsg = "kill_copy_process failed"; - s_logger.warn(errMsg); - return false; - } else { - return true; - } - } - - void destroyVDIbyNameLabel(final Connection conn, final String nameLabel) { - try { - final Set vdis = VDI.getByNameLabel(conn, nameLabel); - if (vdis.size() != 1) { - s_logger.warn("destoryVDIbyNameLabel failed due to there are " + vdis.size() + " VDIs with name " + nameLabel); - return; - } - for (final VDI vdi : vdis) { - try { - vdi.destroy(conn); - } catch (final Exception e) { - final String msg = "Failed to destroy VDI : " + nameLabel + "due to " + e.toString() + "\n Force deleting VDI using system 'rm' command"; - s_logger.warn(msg); - try { - final String srUUID = vdi.getSR(conn).getUuid(conn); - final String vdiUUID = vdi.getUuid(conn); - final String vdifile = "/var/run/sr-mount/" + srUUID + "/" + vdiUUID + ".vhd"; - final String results = callHostPluginAsync(conn, "vmopspremium", "remove_corrupt_vdi", 10, "vdifile", vdifile); - } catch (final Exception e2) { - s_logger.warn(e2); + if (s_logger.isTraceEnabled()) { + for (final PBD pbd : pbds) { + s_logger.trace(logX(pbd, " Still attached")); + } } } + } catch (final XenAPIException e) { + s_logger.debug(logX(sr, "Catch XenAPIException: " + e.toString())); + } catch (final XmlRpcException e) { + s_logger.debug(logX(sr, "Catch Exception: " + e.getMessage())); } - } catch (final Exception e) { } - } - String copy_vhd_from_secondarystorage(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 { - errMsg = tmp[1]; - } - } - final String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1); - if (killCopyProcess(conn, source)) { - destroyVDIbyNameLabel(conn, nameLabel); - } - s_logger.warn(errMsg); - throw new CloudRuntimeException(errMsg); - } - - public PrimaryStorageDownloadAnswer execute(final PrimaryStorageDownloadCommand cmd) { - final String tmplturl = cmd.getUrl(); - final String poolName = cmd.getPoolUuid(); - final int wait = cmd.getWait(); - try { - final URI uri = new URI(tmplturl); - final String tmplpath = uri.getHost() + ":" + uri.getPath(); - final Connection conn = getConnection(); - SR poolsr = null; - final Set srs = SR.getByNameLabel(conn, poolName); - if (srs.size() != 1) { - final String msg = "There are " + srs.size() + " SRs with same name: " + poolName; - s_logger.warn(msg); - return new PrimaryStorageDownloadAnswer(msg); - } else { - poolsr = srs.iterator().next(); - } - final String pUuid = poolsr.getUuid(conn); - final boolean isISCSI = IsISCSI(poolsr.getType(conn)); - final String uuid = copy_vhd_from_secondarystorage(conn, tmplpath, pUuid, wait); - final VDI tmpl = getVDIbyUuid(conn, uuid); - final VDI snapshotvdi = tmpl.snapshot(conn, new HashMap()); - final String snapshotUuid = snapshotvdi.getUuid(conn); - snapshotvdi.setNameLabel(conn, "Template " + cmd.getName()); - final String parentuuid = getVhdParent(conn, pUuid, snapshotUuid, isISCSI); - final VDI parent = getVDIbyUuid(conn, parentuuid); - final Long phySize = parent.getPhysicalUtilisation(conn); - tmpl.destroy(conn); - poolsr.scan(conn); - try { - Thread.sleep(5000); - } catch (final Exception e) { - } - return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize); - } catch (final Exception e) { - final String msg = "Catch Exception " + e.getClass().getName() + " on host:" + _host.uuid + " for template: " + tmplturl + " due to " + e.toString(); - s_logger.warn(msg, e); - return new PrimaryStorageDownloadAnswer(msg); - } + s_logger.warn(logX(sr, "Unable to remove SR")); } protected String removeSRSync(final Connection conn, final SR sr) { @@ -2877,292 +4297,95 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } - protected void removeSR(final Connection conn, final SR sr) { - if (sr == null) { - return; - } + public String revertToSnapshot(final Connection conn, final VM vmSnapshot, final String vmName, final String oldVmUuid, final Boolean snapshotMemory, final String hostUUID) + throws XenAPIException, XmlRpcException { - if (s_logger.isDebugEnabled()) { - s_logger.debug(logX(sr, "Removing SR")); - } - - for (int i = 0; i < 2; i++) { - try { - final Set vdis = sr.getVDIs(conn); - for (final VDI vdi : vdis) { - vdi.forget(conn); - } - - Set pbds = sr.getPBDs(conn); - for (final PBD pbd : pbds) { - if (s_logger.isDebugEnabled()) { - s_logger.debug(logX(pbd, "Unplugging pbd")); - } - - // if (pbd.getCurrentlyAttached(conn)) { - pbd.unplug(conn); - //} - - pbd.destroy(conn); - } - - pbds = sr.getPBDs(conn); - - if (pbds.size() == 0) { - if (s_logger.isDebugEnabled()) { - s_logger.debug(logX(sr, "Forgetting")); - } - - sr.forget(conn); - - return; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug(logX(sr, "There is still one or more PBDs attached.")); - - if (s_logger.isTraceEnabled()) { - for (final PBD pbd : pbds) { - s_logger.trace(logX(pbd, " Still attached")); - } - } - } - } catch (final XenAPIException e) { - s_logger.debug(logX(sr, "Catch XenAPIException: " + e.toString())); - } catch (final XmlRpcException e) { - s_logger.debug(logX(sr, "Catch Exception: " + e.getMessage())); + 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(logX(sr, "Unable to remove SR")); + s_logger.warn(errMsg); + throw new CloudRuntimeException(errMsg); } - protected MigrateAnswer execute(final MigrateCommand cmd) { - final Connection conn = getConnection(); - final String vmName = cmd.getVmName(); + public void scaleVM(final Connection conn, final VM vm, final VirtualMachineTO vmSpec, final Host host) throws XenAPIException, XmlRpcException { - try { - final Set vms = VM.getByNameLabel(conn, vmName); - - final String ipaddr = cmd.getDestinationIp(); - - final Set hosts = Host.getAll(conn); - Host dsthost = null; - if(hosts != null) { - for (final Host host : hosts) { - if (host.getAddress(conn).equals(ipaddr)) { - dsthost = host; - break; - } - } - } - if (dsthost == null) { - final String msg = "Migration failed due to unable to find host " + ipaddr + " in XenServer pool " + _host.pool; - s_logger.warn(msg); - return new MigrateAnswer(cmd, false, msg, null); - } - for (final VM vm : vms) { - final Set vbds = vm.getVBDs(conn); - for (final VBD vbd : vbds) { - final VBD.Record vbdRec = vbd.getRecord(conn); - if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) { - vbd.eject(conn); - break; - } - } - migrateVM(conn, dsthost, vm, vmName); - vm.setAffinity(conn, dsthost); - } - return new MigrateAnswer(cmd, true, "migration succeeded", null); - } catch (final Exception e) { - s_logger.warn(e.getMessage(), e); - return new MigrateAnswer(cmd, false, e.getMessage(), null); + 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()); - protected Pair getControlDomain(final Connection conn) throws XenAPIException, XmlRpcException { - final Host host = Host.getByUuid(conn, _host.uuid); - Set vms = null; - vms = host.getResidentVMs(conn); - for (final VM vm : vms) { - if (vm.getIsControlDomain(conn)) { - return new Pair(vm, vm.getRecord(conn)); + 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; } - } - throw new CloudRuntimeException("Com'on no control domain? What the crap?!#@!##$@"); - } - - protected void umountSnapshotDir(final Connection conn, final Long dcId) { - try { - callHostPlugin(conn, "vmopsSnapshot", "unmountSnapshotsDir", "dcId", dcId.toString()); - } catch (final Exception e) { - s_logger.debug("Failed to umount snapshot dir",e); - } - } - - protected ReadyAnswer execute(final ReadyCommand cmd) { - final Connection conn = getConnection(); - final Long dcId = cmd.getDataCenterId(); - // Ignore the result of the callHostPlugin. Even if unmounting the - // snapshots dir fails, let Ready command - // succeed. - umountSnapshotDir(conn, dcId); - - setupLinkLocalNetwork(conn); - // try to destroy CD-ROM device for all system VMs on this host - try { - final Host host = Host.getByUuid(conn, _host.uuid); - final Set vms = host.getResidentVMs(conn); - for (final VM vm : vms) { - destroyPatchVbd(conn, vm.getNameLabel(conn)); + 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()); } - } catch (final Exception e) { + // vm.addToVCPUsParamsLive(conn, "weight", + // Integer.toString(cpuWeight)); + callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", Integer.toString(cpuWeight), "vmname", vmSpec.getName()); } - try { - final boolean result = cleanupHaltedVms(conn); - if (!result) { - return new ReadyAnswer(cmd, "Unable to cleanup halted vms"); - } - } catch (final XenAPIException e) { - s_logger.warn("Unable to cleanup halted vms", e); - return new ReadyAnswer(cmd, "Unable to cleanup halted vms"); - } catch (final XmlRpcException e) { - s_logger.warn("Unable to cleanup halted vms", e); - return new ReadyAnswer(cmd, "Unable to cleanup halted vms"); - } - - return new ReadyAnswer(cmd); - } - - protected String getVncUrl(final Connection conn, final VM vm) { - VM.Record record; - Console c; - try { - record = vm.getRecord(conn); - final Set consoles = record.consoles; - - if (consoles.isEmpty()) { - s_logger.warn("There are no Consoles available to the vm : " + record.nameDescription); - return null; - } - final Iterator i = consoles.iterator(); - while (i.hasNext()) { - c = i.next(); - if (c.getProtocol(conn) == Types.ConsoleProtocol.RFB) { - return c.getLocation(conn); - } - } - } catch (final XenAPIException e) { - final String msg = "Unable to get console url due to " + e.toString(); - s_logger.warn(msg, e); - return null; - } catch (final XmlRpcException e) { - final String msg = "Unable to get console url due to " + e.getMessage(); - s_logger.warn(msg, e); - return null; - } - return null; } @Override - public RebootAnswer execute(final RebootCommand cmd) { - final Connection conn = getConnection(); - s_logger.debug("7. The VM " + cmd.getVmName() + " is in Starting state"); - try { - Set vms = null; - try { - vms = VM.getByNameLabel(conn, cmd.getVmName()); - } catch (final XenAPIException e0) { - s_logger.debug("getByNameLabel failed " + e0.toString()); - return new RebootAnswer(cmd, "getByNameLabel failed " + e0.toString(), false); - } catch (final Exception e0) { - s_logger.debug("getByNameLabel failed " + e0.getMessage()); - return new RebootAnswer(cmd, "getByNameLabel failed", false); - } - for (final VM vm : vms) { - try { - rebootVM(conn, vm, vm.getNameLabel(conn)); - } catch (final Exception e) { - final String msg = e.toString(); - s_logger.warn(msg, e); - return new RebootAnswer(cmd, msg, false); - } - } - return new RebootAnswer(cmd, "reboot succeeded", true); - } finally { - s_logger.debug("8. The VM " + cmd.getVmName() + " is in Running state"); - } + public void setAgentControl(final IAgentControl agentControl) { + _agentControl = agentControl; } - protected Answer execute(final RebootRouterCommand cmd) { - final Connection conn = getConnection(); - final RebootAnswer answer = execute((RebootCommand)cmd); - if (answer.getResult()) { - final String cnct = connect(conn, cmd.getVmName(), cmd.getPrivateIpAddress()); - networkUsage(conn, cmd.getPrivateIpAddress(), "create", null); - if (cnct == null) { - return answer; - } else { - return new Answer(cmd, false, cnct); - } - } - return answer; + public void setCanBridgeFirewall(final boolean canBridgeFirewall) { + _canBridgeFirewall = canBridgeFirewall; } - protected void startvmfailhandle(final Connection conn, final VM vm, final List> mounts) { - if (vm != null) { - try { + @Override + public void setConfigParams(final Map params) { + } - if (vm.getPowerState(conn) == VmPowerState.RUNNING) { - try { - vm.hardShutdown(conn); - } catch (final Exception e) { - final String msg = "VM hardshutdown failed due to " + e.toString(); - s_logger.warn(msg, e); - } - } - if (vm.getPowerState(conn) == VmPowerState.HALTED) { - try { - vm.destroy(conn); - } catch (final Exception e) { - final String msg = "VM destroy failed due to " + e.toString(); - s_logger.warn(msg, e); - } - } - } catch (final Exception e) { - final String msg = "VM getPowerState failed due to " + e.toString(); - s_logger.warn(msg, e); - } - } - if (mounts != null) { - for (final Ternary mount : mounts) { - final VDI vdi = mount.second(); - Set vbds = null; - try { - vbds = vdi.getVBDs(conn); - } catch (final Exception e) { - final String msg = "VDI getVBDS failed due to " + e.toString(); - s_logger.warn(msg, e); - continue; - } - for (final VBD vbd : vbds) { - try { - vbd.unplug(conn); - vbd.destroy(conn); - } catch (final Exception e) { - final String msg = "VBD destroy failed due to " + e.toString(); - s_logger.warn(msg, e); - } - } - } + public boolean setIptables(final Connection conn) { + final String result = callHostPlugin(conn, "vmops", "setIptables"); + if (result == null || result.isEmpty()) { + return false; } + return true; + } + + public void setIsOvs(final boolean isOvs) { + _isOvs = isOvs; } /** * WARN: static-min <= dynamic-min <= dynamic-max <= static-max - * @see XcpServerResource#setMemory(com.xensource.xenapi.Connection, com.xensource.xenapi.VM, long, long) + * + * @see XcpServerResource#setMemory(com.xensource.xenapi.Connection, + * com.xensource.xenapi.VM, long, long) * @param conn * @param vm * @param minMemsize @@ -3174,1182 +4397,66 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vm.setMemoryLimits(conn, mem_128m, maxMemsize, minMemsize, maxMemsize); } - /** - * When Dynamic Memory Control (DMC) is enabled - - * xenserver allows scaling the guest memory while the guest is running - * - * By default this is disallowed, override the specific xenserver resource - * if this is enabled - */ - protected boolean isDmcEnabled(final Connection conn, final Host host) throws XenAPIException, XmlRpcException { - return false; + @Override + public void setName(final String name) { } - protected void waitForTask(final Connection c, final Task task, final long pollInterval, final long timeout) throws XenAPIException, XmlRpcException, TimeoutException { - final long beginTime = System.currentTimeMillis(); - if (s_logger.isTraceEnabled()) { - s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout + - "ms timeout"); - } - while (task.getStatus(c) == Types.TaskStatusType.PENDING) { - try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") is pending, sleeping for " + pollInterval + "ms"); - } - Thread.sleep(pollInterval); - } catch (final InterruptedException e) { + protected void setNicDevIdIfCorrectVifIsNotNull(final Connection conn, final IpAddressTO ip, final VIF correctVif) throws InternalErrorException, BadServerResponse, + XenAPIException, XmlRpcException { + if (correctVif == null) { + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); } - if (System.currentTimeMillis() - beginTime > timeout) { - final String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString(); - s_logger.warn(msg); - task.cancel(c); - task.destroy(c); - throw new TimeoutException(msg); - } - } - } - - protected 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; } 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); + ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); } } - void rebootVM(final Connection conn, final VM vm, final String vmName) throws Exception { - Task task = null; - try { - task = vm.cleanRebootAsync(conn); - try { - //poll every 1 seconds , timeout after 10 minutes - waitForTask(conn, task, 1000, 10 * 60 * 1000); - checkForSuccess(conn, task); - } catch (final Types.HandleInvalid e) { - if (vm.getPowerState(conn) == VmPowerState.RUNNING) { - task = null; - return; - } - throw new CloudRuntimeException("Reboot VM catch HandleInvalid and VM is not in RUNNING state"); - } - } catch (final XenAPIException e) { - s_logger.debug("Unable to Clean Reboot VM(" + vmName + ") on host(" + _host.uuid + ") due to " + e.toString() + ", try hard reboot"); - try { - vm.hardReboot(conn); - } catch (final Exception e1) { - final String msg = "Unable to hard Reboot VM(" + vmName + ") on host(" + _host.uuid + ") due to " + e.toString(); - s_logger.warn(msg, e1); - throw new CloudRuntimeException(msg); - } - } finally { - if (task != null) { - try { - task.destroy(conn); - } catch (final Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e1.toString()); - } - } - } - } - - void forceShutdownVM(final Connection conn, final VM vm) { - try { - final Long domId = vm.getDomid(conn); - callHostPlugin(conn, "vmopspremium", "forceShutdownVM", "domId", domId.toString()); - vm.powerStateReset(conn); - vm.destroy(conn); - } catch (final Exception e) { - final String msg = "forceShutdown failed due to " + e.toString(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg); - } - } - - void shutdownVM(final Connection conn, final VM vm, final String vmName) throws XmlRpcException { - Task task = null; - try { - task = vm.cleanShutdownAsync(conn); - try { - //poll every 1 seconds , timeout after 10 minutes - waitForTask(conn, task, 1000, 10 * 60 * 1000); - checkForSuccess(conn, task); - } catch (final TimeoutException e) { - if (vm.getPowerState(conn) == VmPowerState.HALTED) { - task = null; - return; - } - throw new CloudRuntimeException("Shutdown VM catch HandleInvalid and VM is not in HALTED state"); - } - } catch (final XenAPIException e) { - s_logger.debug("Unable to cleanShutdown VM(" + vmName + ") on host(" + _host.uuid + ") due to " + e.toString()); - try { - VmPowerState state = vm.getPowerState(conn); - if (state == VmPowerState.RUNNING) { - try { - vm.hardShutdown(conn); - } catch (final Exception e1) { - s_logger.debug("Unable to hardShutdown VM(" + vmName + ") on host(" + _host.uuid + ") due to " + e.toString()); - state = vm.getPowerState(conn); - if (state == VmPowerState.RUNNING) { - forceShutdownVM(conn, vm); - } - return; - } - } else if (state == VmPowerState.HALTED) { - return; - } else { - final String msg = "After cleanShutdown the VM status is " + state.toString() + ", that is not expected"; - s_logger.warn(msg); - throw new CloudRuntimeException(msg); - } - } catch (final Exception e1) { - final String msg = "Unable to hardShutdown VM(" + vmName + ") on host(" + _host.uuid + ") due to " + e.toString(); - s_logger.warn(msg, e1); - throw new CloudRuntimeException(msg); - } - } finally { - if (task != null) { - try { - task.destroy(conn); - } catch (final Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e1.toString()); - } - } - } - } - - void startVM(final Connection conn, final Host host, final VM vm, final String vmName) throws Exception { - Task task = null; - try { - task = vm.startOnAsync(conn, host, false, true); - try { - //poll every 1 seconds , timeout after 10 minutes - waitForTask(conn, task, 1000, 10 * 60 * 1000); - checkForSuccess(conn, task); - } catch (final Types.HandleInvalid e) { - if (vm.getPowerState(conn) == VmPowerState.RUNNING) { - s_logger.debug("VM " + vmName + " is in Running status"); - task = null; - return; - } - throw new CloudRuntimeException("Start VM " + vmName + " catch HandleInvalid and VM is not in RUNNING state"); - } catch (final TimeoutException e) { - if (vm.getPowerState(conn) == VmPowerState.RUNNING) { - s_logger.debug("VM " + vmName + " is in Running status"); - task = null; - return; - } - throw new CloudRuntimeException("Start VM " + vmName + " catch BadAsyncResult and VM is not in RUNNING state"); - } - } catch (final XenAPIException e) { - final String msg = "Unable to start VM(" + vmName + ") on host(" + _host.uuid + ") due to " + e.toString(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg); - } finally { - if (task != null) { - try { - task.destroy(conn); - } catch (final Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e1.toString()); - } - } - } - } - - private void migrateVM(final Connection conn, final Host destHost, final VM vm, final String vmName) throws Exception { - Task task = null; - try { - final Map other = new HashMap(); - other.put("live", "true"); - task = vm.poolMigrateAsync(conn, destHost, other); - try { - // poll every 1 seconds - final long timeout = _migratewait * 1000L; - waitForTask(conn, task, 1000, timeout); - checkForSuccess(conn, task); - } catch (final Types.HandleInvalid e) { - if (vm.getResidentOn(conn).equals(destHost)) { - task = null; - return; - } - throw new CloudRuntimeException("migrate VM catch HandleInvalid and VM is not running on dest host"); - } - } catch (final XenAPIException e) { - final String msg = "Unable to migrate VM(" + vmName + ") from host(" + _host.uuid + ")"; - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg); - } finally { - if (task != null) { - try { - task.destroy(conn); - } catch (final Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e1.toString()); - } - } - } - } - - 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; - } - 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.uuid + ") due to " + e.toString()); - } - } - } - } - - 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 { - for (int i = 0; i < params.length; i += 2) { - args.put(params[i], params[i + 1]); - } - if (s_logger.isTraceEnabled()) { - s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); - } - final Host host = Host.getByUuid(conn, _host.uuid); - 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); - } - 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 { - task.destroy(conn); - } catch (final Exception e1) { - s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + ") due to " + e1.toString()); - } - } - } - return null; - } - @Override - public StopAnswer execute(final StopCommand cmd) { - final String vmName = cmd.getVmName(); - String platformstring = null; - try { - final Connection conn = getConnection(); - final Set vms = VM.getByNameLabel(conn, vmName); - // 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.RUNNING) { - continue; - } - if (isRefNull(vmr.residentOn)) { - continue; - } - if (vmr.residentOn.getUuid(conn).equals(_host.uuid)) { - continue; - } - iter.remove(); - } - - if (vms.size() == 0) { - return new StopAnswer(cmd, "VM does not exist", true); - } - for (final VM vm : vms) { - final VM.Record vmr = vm.getRecord(conn); - platformstring = StringUtils.mapToString(vmr.platform); - if (vmr.isControlDomain) { - final String msg = "Tring to Shutdown control domain"; - s_logger.warn(msg); - return new StopAnswer(cmd, msg, false); - } - - if (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid)) { - final String msg = "Stop Vm " + vmName + " failed due to this vm is not running on this host: " + _host.uuid + " but host:" + vmr.residentOn.getUuid(conn); - s_logger.warn(msg); - return new StopAnswer(cmd, msg, platformstring, false); - } - - if (cmd.checkBeforeCleanup() && vmr.powerState == VmPowerState.RUNNING) { - final String msg = "Vm " + vmName + " is running on host and checkBeforeCleanup flag is set, so bailing out"; - s_logger.debug(msg); - return new StopAnswer(cmd, msg, false); - } - - s_logger.debug("9. The VM " + vmName + " is in Stopping state"); - - try { - if (vmr.powerState == VmPowerState.RUNNING) { - /* when stop a vm, set affinity to current xenserver */ - vm.setAffinity(conn, vm.getResidentOn(conn)); - - if (_canBridgeFirewall) { - final String result = callHostPlugin(conn, "vmops", "destroy_network_rules_for_vm", "vmName", cmd.getVmName()); - if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { - s_logger.warn("Failed to remove network rules for vm " + cmd.getVmName()); - } else { - s_logger.info("Removed network rules for vm " + cmd.getVmName()); - } - } - shutdownVM(conn, vm, vmName); - } - } catch (final Exception e) { - final String msg = "Catch exception " + e.getClass().getName() + " when stop VM:" + cmd.getVmName() + " due to " + e.toString(); - s_logger.debug(msg); - return new StopAnswer(cmd, msg, platformstring, false); - } finally { - - try { - if (vm.getPowerState(conn) == VmPowerState.HALTED) { - Set vGPUs = null; - // Get updated GPU details - try { - vGPUs = vm.getVGPUs(conn); - } catch (final XenAPIException e2) { - s_logger.debug("VM " + vmName + " does not have GPU support."); - } - if (vGPUs != null && !vGPUs.isEmpty()) { - final HashMap> groupDetails = getGPUGroupDetails(conn); - cmd.setGpuDevice(new GPUDeviceTO(null, null, groupDetails)); - } - - final Set vifs = vm.getVIFs(conn); - final List networks = new ArrayList(); - for (final VIF vif : vifs) { - networks.add(vif.getNetwork(conn)); - } - vm.destroy(conn); - final SR sr = getISOSRbyVmName(conn, cmd.getVmName()); - removeSR(conn, sr); - // Disable any VLAN networks that aren't used - // anymore - for (final Network network : networks) { - try { - if (network.getNameLabel(conn).startsWith("VLAN")) { - disableVlanNetwork(conn, network); - } - } catch (final Exception e) { - // network might be destroyed by other host - } - } - return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", platformstring, true); - } - } catch (final Exception e) { - final String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.getMessage(); - s_logger.warn(msg, e); - } finally { - s_logger.debug("10. The VM " + vmName + " is in Stopped state"); - } - } - } - - } catch (final Exception e) { - final String msg = "Stop Vm " + vmName + " fail due to " + e.toString(); - s_logger.warn(msg, e); - return new StopAnswer(cmd, msg, platformstring, false); - } - return new StopAnswer(cmd, "Stop VM failed", platformstring, false); + public void setRunLevel(final int level) { } - private List getVdis(final Connection conn, final VM vm) { - final List vdis = new ArrayList(); - try { - final Set vbds = vm.getVBDs(conn); - for (final VBD vbd : vbds) { - vdis.add(vbd.getVDI(conn)); - } - } catch (final XenAPIException e) { - final String msg = "getVdis can not get VPD due to " + e.toString(); - s_logger.warn(msg, e); - } catch (final XmlRpcException e) { - final String msg = "getVdis can not get VPD due to " + e.getMessage(); - s_logger.warn(msg, e); + public String setupHeartbeatSr(final Connection conn, final SR sr, final boolean force) throws XenAPIException, XmlRpcException { + final SR.Record srRec = sr.getRecord(conn); + final String srUuid = srRec.uuid; + if (!srRec.shared || !SRType.LVMOHBA.equals(srRec.type) && !SRType.LVMOISCSI.equals(srRec.type) && !SRType.NFS.equals(srRec.type)) { + return srUuid; } - return vdis; - } - - protected 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; - } + String result = null; + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Set tags = host.getTags(conn); + if (force || !tags.contains("cloud-heartbeat-" + srUuid)) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to connect to " + ipAddress + " attempt " + i + " of " + _retry); + s_logger.debug("Setting up the heartbeat sr for host " + _host.getIp() + " and sr " + srUuid); } - if (pingdomr(conn, ipAddress, Integer.toString(port))) { - return null; - } - try { - Thread.sleep(_sleep); - } catch (final InterruptedException e) { - } - } - final String msg = "Timeout, Unable to logon to " + ipAddress; - s_logger.debug(msg); - - return msg; - } - - protected String connect(final Connection conn, final String vmname, final String ipAddress) { - return connect(conn, vmname, ipAddress, 3922); - } - - protected boolean isDeviceUsed(final Connection conn, final VM vm, final Long deviceId) { - // Figure out the disk number to attach the VM to - - String msg = null; - try { - final Set allowedVBDDevices = vm.getAllowedVBDDevices(conn); - if (allowedVBDDevices.contains(deviceId.toString())) { - return false; - } - return true; - } catch (final XmlRpcException e) { - msg = "Catch XmlRpcException due to: " + e.getMessage(); - s_logger.warn(msg, e); - } catch (final XenAPIException e) { - msg = "Catch XenAPIException due to: " + e.toString(); - s_logger.warn(msg, e); - } - throw new CloudRuntimeException("When check deviceId " + msg); - } - - protected String getUnusedDeviceNum(final Connection conn, final VM vm) { - // Figure out the disk number to attach the VM to - try { - final Set allowedVBDDevices = vm.getAllowedVBDDevices(conn); - if (allowedVBDDevices.size() == 0) { - throw new CloudRuntimeException("Could not find an available slot in VM with name: " + vm.getNameLabel(conn) + " to attach a new disk."); - } - return allowedVBDDevices.iterator().next(); - } catch (final XmlRpcException e) { - final String msg = "Catch XmlRpcException due to: " + e.getMessage(); - s_logger.warn(msg, e); - } catch (final XenAPIException e) { - final String msg = "Catch XenAPIException due to: " + e.toString(); - s_logger.warn(msg, e); - } - throw new CloudRuntimeException("Could not find an available slot in VM with name to attach a new disk."); - } - - protected String callHostPlugin(final Connection conn, final String plugin, final String cmd, final String... params) { - final Map args = new HashMap(); - String msg; - try { - for (int i = 0; i < params.length; i += 2) { - args.put(params[i], params[i + 1]); - } - - if (s_logger.isTraceEnabled()) { - s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); - } - final Host host = Host.getByUuid(conn, _host.uuid); - 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); - } - throw new CloudRuntimeException(msg); - } - - protected String getArgsString(final Map args) { - final StringBuilder argString = new StringBuilder(); - for (final Map.Entry arg : args.entrySet()) { - argString.append(arg.getKey() + ": " + arg.getValue() + ", "); - } - return argString.toString(); - } - - protected boolean setIptables(final Connection conn) { - final String result = callHostPlugin(conn, "vmops", "setIptables"); - if (result == null || result.isEmpty()) { - return false; - } - return true; - } - - protected XsLocalNetwork getManagementNetwork(final Connection conn) throws XmlRpcException, XenAPIException { - PIF mgmtPif = null; - PIF.Record mgmtPifRec = null; - final Host host = Host.getByUuid(conn, _host.uuid); - final Set hostPifs = host.getPIFs(conn); - for (final PIF pif : hostPifs) { - final PIF.Record rec = pif.getRecord(conn); - if (rec.management) { - if (rec.VLAN != null && rec.VLAN != -1) { - final String msg = - new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) - .append("; pif=") - .append(rec.uuid) - .append("; vlan=") - .append(rec.VLAN) - .toString(); - s_logger.warn(msg); - throw new CloudRuntimeException(msg); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Management network is on pif=" + rec.uuid); - } - mgmtPif = pif; - mgmtPifRec = rec; - break; - } - } - if (mgmtPif == null) { - final String msg = "Unable to find management network for " + _host.uuid; - s_logger.warn(msg); - throw new CloudRuntimeException(msg); - } - final Bond bond = mgmtPifRec.bondSlaveOf; - if (!isRefNull(bond)) { - final String msg = - "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.uuid + - "), please move management interface to bond!"; - s_logger.warn(msg); - throw new CloudRuntimeException(msg); - } - final Network nk = mgmtPifRec.network; - final Network.Record nkRec = nk.getRecord(conn); - return new XsLocalNetwork(nk, nkRec, mgmtPif, mgmtPifRec); - } - - protected VIF getCorrectVif(final Connection conn, final VM router, final Network network) throws XmlRpcException, XenAPIException { - final Set routerVIFs = router.getVIFs(conn); - for (final VIF vif : routerVIFs) { - final Network vifNetwork = vif.getNetwork(conn); - if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) { - return vif; - } - } - - return null; - } - - protected VIF getCorrectVif(final Connection conn, final VM router, final IpAddressTO ip) throws XmlRpcException, XenAPIException { - final NicTO nic = new NicTO(); - nic.setType(ip.getTrafficType()); - nic.setName(ip.getNetworkName()); - if (ip.getBroadcastUri() == null) { - nic.setBroadcastType(BroadcastDomainType.Native); - } else { - final URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); - nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); - nic.setBroadcastUri(uri); - } - final Network network = getNetwork(conn, nic); - // Determine the correct VIF on DomR to associate/disassociate the - // IP address with - final Set routerVIFs = router.getVIFs(conn); - for (final VIF vif : routerVIFs) { - final Network vifNetwork = vif.getNetwork(conn); - if (vifNetwork.getUuid(conn).equals(network.getUuid(conn))) { - return vif; - } - } - return null; - } - - protected VIF getVifByMac(final Connection conn, final VM router, String mac) throws XmlRpcException, XenAPIException { - final Set routerVIFs = router.getVIFs(conn); - mac = mac.trim(); - for (final VIF vif : routerVIFs) { - final String lmac = vif.getMAC(conn); - if (lmac.trim().equals(mac)) { - return vif; - } - } - return null; - } - - protected String getLowestAvailableVIFDeviceNum(final Connection conn, final VM vm) { - String vmName = ""; - try { - vmName = vm.getNameLabel(conn); - final List usedDeviceNums = new ArrayList(); - final Set vifs = vm.getVIFs(conn); - final Iterator vifIter = vifs.iterator(); - while (vifIter.hasNext()) { - final VIF vif = vifIter.next(); - try { - final String deviceId = vif.getDevice(conn); - if(vm.getIsControlDomain(conn) || vif.getCurrentlyAttached(conn)) { - usedDeviceNums.add(Integer.valueOf(deviceId)); - } else { - s_logger.debug("Found unplugged VIF " + deviceId + " in VM " + vmName + " destroy it"); - vif.destroy(conn); - } - } catch (final NumberFormatException e) { - final String msg = "Obtained an invalid value for an allocated VIF device number for VM: " + vmName; - s_logger.debug(msg, e); - throw new CloudRuntimeException(msg); + final Set pbds = sr.getPBDs(conn); + for (final PBD pbd : pbds) { + final PBD.Record pbdr = pbd.getRecord(conn); + if (!pbdr.currentlyAttached && pbdr.host.getUuid(conn).equals(_host.getUuid())) { + pbd.plug(conn); + break; } } - - for (Integer i = 0; i < _maxNics; i++) { - if (!usedDeviceNums.contains(i)) { - s_logger.debug("Lowest available Vif device number: " + i + " for VM: " + vmName); - return i.toString(); - } + result = callHostPluginThroughMaster(conn, "vmopspremium", "setup_heartbeat_sr", "host", _host.getUuid(), "sr", srUuid); + if (result == null || !result.split("#")[1].equals("0")) { + throw new CloudRuntimeException("Unable to setup heartbeat sr on SR " + srUuid + " due to " + result); } - } catch (final XmlRpcException e) { - final String msg = "Caught XmlRpcException: " + e.getMessage(); - s_logger.warn(msg, e); - } catch (final XenAPIException e) { - final String msg = "Caught XenAPIException: " + e.toString(); - s_logger.warn(msg, e); - } - throw new CloudRuntimeException("Could not find available VIF slot in VM with name: " + vmName); + if (!tags.contains("cloud-heartbeat-" + srUuid)) { + tags.add("cloud-heartbeat-" + srUuid); + host.setTags(conn, tags); + } + } + result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.getUuid(), "sr", srUuid, "add", "true"); + if (result == null || !result.split("#")[1].equals("0")) { + throw new CloudRuntimeException("Unable to setup heartbeat file entry on SR " + srUuid + " due to " + result); + } + return srUuid; } - protected VDI mount(final Connection conn, final StoragePoolType poolType, final String volumeFolder, final String volumePath) { - return getVDIbyUuid(conn, volumePath); - } - - /** - * getNetworkByName() retrieves what the server thinks is the actual - * network used by the XenServer host. This method should always be - * used to talk to retrieve a network by the name. The reason is - * because of the problems in using the name label as the way to find - * the Network. - * - * To see how we are working around these problems, take a look at - * enableVlanNetwork(). The following description assumes you have looked - * at the description on that method. - * - * In order to understand this, we have to see what type of networks are - * within a XenServer that's under CloudStack control. - * - * - Native Networks: these are networks that are untagged on the - * XenServer and are used to crate VLAN networks on. These are - * created by the user and is assumed to be one per cluster. - * - VLAN Networks: these are dynamically created by CloudStack and can - * have problems with duplicated names. - * - LinkLocal Networks: these are dynamically created by CloudStack and - * can also have problems with duplicated names but these don't have - * actual PIFs. - * - * In order to speed to retrieval of a network, we do the following: - * - We retrieve by the name. If only one network is retrieved, we - * assume we retrieved the right network. - * - If more than one network is retrieved, we check to see which one - * has the pif for the local host and use that. - * - If a pif is not found, then we look at the tags and find the - * one with the lowest timestamp. (See enableVlanNetwork()) - * - * @param conn Xapi connection - * @param name name of the network - * @return XsNic an object that contains network, network record, pif, and pif record. - * @throws XenAPIException - * @throws XmlRpcException - * - * @see CitrixResourceBase#enableVlanNetwork - */ - protected XsLocalNetwork getNetworkByName(final Connection conn, final String name) throws XenAPIException, XmlRpcException { - final Set networks = Network.getByNameLabel(conn, name); - if (networks.size() == 1) { - return new XsLocalNetwork(networks.iterator().next(), null, null, null); - } - - if (networks.size() == 0) { - return null; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found more than one network with the name " + name); - } - Network earliestNetwork = null; - Network.Record earliestNetworkRecord = null; - long earliestTimestamp = Long.MAX_VALUE; - int earliestRandom = Integer.MAX_VALUE; - for (final Network network : networks) { - final XsLocalNetwork nic = new XsLocalNetwork(network); - - if (nic.getPif(conn) != null) { - return nic; - } - - final Network.Record record = network.getRecord(conn); - if (record.tags != null) { - for (final String tag : record.tags) { - final Pair stamp = parseTimestamp(tag); - if (stamp == null) { - continue; - } - - if (stamp.first() < earliestTimestamp || stamp.first() == earliestTimestamp && stamp.second() < earliestRandom) { - earliestTimestamp = stamp.first(); - earliestRandom = stamp.second(); - earliestNetwork = network; - earliestNetworkRecord = record; - } - } - } - } - - return earliestNetwork != null ? new XsLocalNetwork(earliestNetwork, earliestNetworkRecord, null, null) : null; - } - - protected String generateTimeStamp() { - return new StringBuilder("CsCreateTime-").append(System.currentTimeMillis()).append("-").append(Rand.nextInt(Integer.MAX_VALUE)).toString(); - } - - protected Pair parseTimestamp(final String timeStampStr) { - final String[] tokens = timeStampStr.split("-"); - if (tokens.length != 3) { - s_logger.debug("timeStamp in network has wrong pattern: " + timeStampStr); - return null; - } - if (!tokens[0].equals("CsCreateTime")) { - s_logger.debug("timeStamp in network doesn't start with CsCreateTime: " + timeStampStr); - return null; - } - return new Pair(Long.parseLong(tokens[1]), Integer.parseInt(tokens[2])); - } - - /** - * enableVlanNetwork creates a Network object, Vlan object, and thereby - * a tagged PIF object in Xapi. - * - * In XenServer, VLAN is added by - * - Create a network, which is unique cluster wide. - * - Find the PIF that you want to create the VLAN on. - * - Create a VLAN using the network and the PIF. As a result of this - * operation, a tagged PIF object is also created. - * - * Here is a list of problems with clustered Xapi implementation that - * we are trying to circumvent. - * - There can be multiple Networks with the same name-label so searching - * using name-label is not unique. - * - There are no other ways to search for Networks other than listing - * all of them which is not efficient in our implementation because - * we can have over 4000 VLAN networks. - * - In a clustered situation, it's possible for both hosts to detect - * that the Network is missing and both creates it. This causes a - * lot of problems as one host may be using one Network and another - * may be using a different network for their VMs. This causes - * problems in migration because the VMs are logically attached - * to different networks in Xapi's database but in reality, they - * are attached to the same network. - * - * To work around these problems, we do the following. - * - * - When creating the VLAN network, we name it as VLAN-UUID of the - * Network it is created on-VLAN Tag. Because VLAN tags is unique with - * one particular network, this is a unique name-label to quickly - * retrieve the the VLAN network with when we need it again. - * - When we create the VLAN network, we add a timestamp and a random - * number as a tag into the network. Then instead of creating - * VLAN on that network, we actually retrieve the Network again - * and this time uses the VLAN network with lowest timestamp or - * lowest random number as the VLAN network. This allows VLAN creation - * to happen on multiple hosts concurrently but even if two VLAN - * networks were created with the same name, only one of them is used. - * - * One cavaet about this approach is that it relies on the timestamp to - * be relatively accurate among different hosts. - * - * @param conn Xapi Connection - * @param tag VLAN tag - * @param network network on this host to create the VLAN on. - * @return VLAN Network created. - * @throws XenAPIException - * @throws XmlRpcException - */ - protected Network enableVlanNetwork(final Connection conn, final long tag, final XsLocalNetwork network) throws XenAPIException, XmlRpcException { - Network vlanNetwork = null; - final String oldName = "VLAN" + Long.toString(tag); - final String newName = "VLAN-" + network.getNetworkRecord(conn).uuid + "-" + tag; - XsLocalNetwork vlanNic = getNetworkByName(conn, newName); - if (vlanNic == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Couldn't find vlan network with the new name so trying old name: " + oldName); - } - vlanNic = getNetworkByName(conn, oldName); - if (vlanNic != null) { - s_logger.info("Renaming VLAN with old name " + oldName + " to " + newName); - vlanNic.getNetwork().setNameLabel(conn, newName); - } - } - if (vlanNic == null) { // Can't find it, then create it. - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VLAN network for " + tag + " on host " + _host.ip); - } - final Network.Record nwr = new Network.Record(); - nwr.nameLabel = newName; - nwr.tags = new HashSet(); - nwr.tags.add(generateTimeStamp()); - vlanNetwork = Network.create(conn, nwr); - vlanNic = getNetworkByName(conn, newName); - if(vlanNic == null) { //Still vlanNic is null means we could not create it for some reason and no exception capture happened. - throw new CloudRuntimeException("Could not find/create vlan network with name: " + newName); - } - } - - final PIF nPif = network.getPif(conn); - final PIF.Record nPifr = network.getPifRecord(conn); - - vlanNetwork = vlanNic.getNetwork(); - if (vlanNic.getPif(conn) != null) { - return vlanNetwork; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating VLAN " + tag + " on host " + _host.ip + " on device " + nPifr.device); - } - final VLAN vlan = VLAN.create(conn, nPif, tag, vlanNetwork); - if (vlan != null) { - final VLAN.Record vlanr = vlan.getRecord(conn); - if (vlanr != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("VLAN is created for " + tag + ". The uuid is " + vlanr.uuid); - } - } - } - return vlanNetwork; - } - - protected void disableVlanNetwork(final Connection conn, final Network network) { - } - - protected SR getLocalLVMSR(final Connection conn) { - try { - final Map map = SR.getAllRecords(conn); - if(map != null && !map.isEmpty()) { - for (final Map.Entry entry : map.entrySet()) { - final SR.Record srRec = entry.getValue(); - if (SRType.LVM.equals(srRec.type)) { - final Set pbds = srRec.PBDs; - if (pbds == null) { - continue; - } - for (final PBD pbd : pbds) { - final Host host = pbd.getHost(conn); - if (!isRefNull(host) && host.getUuid(conn).equals(_host.uuid)) { - if (!pbd.getCurrentlyAttached(conn)) { - pbd.plug(conn); - } - final SR sr = entry.getKey(); - sr.scan(conn); - return sr; - } - } - } - } - } - } catch (final XenAPIException e) { - final String msg = "Unable to get local LVMSR in host:" + _host.uuid + e.toString(); - s_logger.warn(msg); - } catch (final XmlRpcException e) { - final String msg = "Unable to get local LVMSR in host:" + _host.uuid + e.getCause(); - s_logger.warn(msg); - } - return null; - } - - protected SR getLocalEXTSR(final Connection conn) { - try { - final Map map = SR.getAllRecords(conn); - if(map != null && !map.isEmpty()) { - for (final Map.Entry entry : map.entrySet()) { - final SR.Record srRec = entry.getValue(); - if (SRType.FILE.equals(srRec.type) || SRType.EXT.equals(srRec.type)) { - final Set pbds = srRec.PBDs; - if (pbds == null) { - continue; - } - for (final PBD pbd : pbds) { - final Host host = pbd.getHost(conn); - if (!isRefNull(host) && host.getUuid(conn).equals(_host.uuid)) { - if (!pbd.getCurrentlyAttached(conn)) { - pbd.plug(conn); - } - final SR sr = entry.getKey(); - sr.scan(conn); - return sr; - } - } - } - } - } - } catch (final XenAPIException e) { - final String msg = "Unable to get local EXTSR in host:" + _host.uuid + e.toString(); - s_logger.warn(msg); - } catch (final XmlRpcException e) { - final String msg = "Unable to get local EXTSR in host:" + _host.uuid + e.getCause(); - s_logger.warn(msg); - } - return null; - } - - protected StartupStorageCommand initializeLocalSR(final Connection conn) { - final SR lvmsr = getLocalLVMSR(conn); - if (lvmsr != null) { - try { - _host.localSRuuid = lvmsr.getUuid(conn); - - final String lvmuuid = lvmsr.getUuid(conn); - final long cap = lvmsr.getPhysicalSize(conn); - if (cap > 0) { - final long avail = cap - lvmsr.getPhysicalUtilisation(conn); - lvmsr.setNameLabel(conn, lvmuuid); - final String name = "Cloud Stack Local LVM Storage Pool for " + _host.uuid; - lvmsr.setNameDescription(conn, name); - final Host host = Host.getByUuid(conn, _host.uuid); - final String address = host.getAddress(conn); - final StoragePoolInfo pInfo = new StoragePoolInfo(lvmuuid, address, SRType.LVM.toString(), SRType.LVM.toString(), StoragePoolType.LVM, cap, avail); - final StartupStorageCommand cmd = new StartupStorageCommand(); - cmd.setPoolInfo(pInfo); - cmd.setGuid(_host.uuid); - cmd.setDataCenter(Long.toString(_dcId)); - cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); - return cmd; - } - } catch (final XenAPIException e) { - final String msg = "build local LVM info err in host:" + _host.uuid + e.toString(); - s_logger.warn(msg); - } catch (final XmlRpcException e) { - final String msg = "build local LVM info err in host:" + _host.uuid + e.getMessage(); - s_logger.warn(msg); - } - } - - final SR extsr = getLocalEXTSR(conn); - if (extsr != null) { - try { - final String extuuid = extsr.getUuid(conn); - _host.localSRuuid = extuuid; - final long cap = extsr.getPhysicalSize(conn); - if (cap > 0) { - final long avail = cap - extsr.getPhysicalUtilisation(conn); - extsr.setNameLabel(conn, extuuid); - final String name = "Cloud Stack Local EXT Storage Pool for " + _host.uuid; - extsr.setNameDescription(conn, name); - final Host host = Host.getByUuid(conn, _host.uuid); - final String address = host.getAddress(conn); - final StoragePoolInfo pInfo = new StoragePoolInfo(extuuid, address, SRType.EXT.toString(), SRType.EXT.toString(), StoragePoolType.EXT, cap, avail); - final StartupStorageCommand cmd = new StartupStorageCommand(); - cmd.setPoolInfo(pInfo); - cmd.setGuid(_host.uuid); - cmd.setDataCenter(Long.toString(_dcId)); - cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); - return cmd; - } - } catch (final XenAPIException e) { - final String msg = "build local EXT info err in host:" + _host.uuid + e.toString(); - s_logger.warn(msg); - } catch (final XmlRpcException e) { - final String msg = "build local EXT info err in host:" + _host.uuid + e.getMessage(); - s_logger.warn(msg); - } - } - return null; - } - - @Override - public PingCommand getCurrentStatus(final long id) { - try { - if (!pingXAPI()) { - Thread.sleep(1000); - if (!pingXAPI()) { - s_logger.warn("can not ping xenserver " + _host.uuid); - return null; - } - } - final Connection conn = getConnection(); - if (!_canBridgeFirewall && !_isOvs) { - return new PingRoutingCommand(getType(), id, getHostVmStateReport(conn)); - } else if (_isOvs) { - final List> ovsStates = ovsFullSyncStates(); - return new PingRoutingWithOvsCommand(getType(), id, getHostVmStateReport(conn), ovsStates); - } else { - final HashMap> nwGrpStates = syncNetworkGroups(conn, id); - return new PingRoutingWithNwGroupsCommand(getType(), id, getHostVmStateReport(conn), nwGrpStates); - } - } catch (final Exception e) { - s_logger.warn("Unable to get current status", e); - return null; - } - } - - private HashMap> syncNetworkGroups(final Connection conn, final long id) { - final HashMap> states = new HashMap>(); - - final String result = callHostPlugin(conn, "vmops", "get_rule_logs_for_vms", "host_uuid", _host.uuid); - s_logger.trace("syncNetworkGroups: id=" + id + " got: " + result); - 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; - } - //output = ','.join([vmName, vmID, vmIP, domID, signature, seqno]) - try { - states.put(log[0], new Pair(Long.parseLong(log[1]), Long.parseLong(log[5]))); - } catch (final NumberFormatException nfe) { - states.put(log[0], new Pair(-1L, -1L)); - } - } - return states; - } - - @Override - public Type getType() { - return com.cloud.host.Host.Type.Routing; - } - - protected boolean getHostInfo(final Connection conn) throws IllegalArgumentException { - try { - final Host myself = Host.getByUuid(conn, _host.uuid); - Set hcs = null; - for (int i = 0; i < 10; i++) { - hcs = myself.getHostCPUs(conn); - if(hcs != null) { - _host.cpus = hcs.size(); - if (_host.cpus > 0) { - break; - } - } - Thread.sleep(5000); - } - if (_host.cpus <= 0) { - throw new CloudRuntimeException("Cannot get the numbers of cpu from XenServer host " + _host.ip); - } - final Map cpuInfo = myself.getCpuInfo(conn); - if (cpuInfo.get("socket_count") != null) { - _host.cpuSockets = Integer.parseInt(cpuInfo.get("socket_count")); - } - // would hcs be null we would have thrown an exception on condition (_host.cpus <= 0) by now - for (final HostCpu hc : hcs) { - _host.speed = hc.getSpeed(conn).intValue(); - break; - } - final Host.Record hr = myself.getRecord(conn); - _host.productVersion = CitrixHelper.getProductVersion(hr); - - final XsLocalNetwork privateNic = getManagementNetwork(conn); - _privateNetworkName = privateNic.getNetworkRecord(conn).nameLabel; - _host.privatePif = privateNic.getPifRecord(conn).uuid; - _host.privateNetwork = privateNic.getNetworkRecord(conn).uuid; - _host.systemvmisouuid = null; - - XsLocalNetwork guestNic = null; - if (_guestNetworkName != null && !_guestNetworkName.equals(_privateNetworkName)) { - guestNic = getNetworkByName(conn, _guestNetworkName); - if (guestNic == null) { - s_logger.warn("Unable to find guest network " + _guestNetworkName); - throw new IllegalArgumentException("Unable to find guest network " + _guestNetworkName + " for host " + _host.ip); - } - } else { - guestNic = privateNic; - _guestNetworkName = _privateNetworkName; - } - _host.guestNetwork = guestNic.getNetworkRecord(conn).uuid; - _host.guestPif = guestNic.getPifRecord(conn).uuid; - - XsLocalNetwork publicNic = null; - if (_publicNetworkName != null && !_publicNetworkName.equals(_guestNetworkName)) { - publicNic = getNetworkByName(conn, _publicNetworkName); - if (publicNic == null) { - s_logger.warn("Unable to find public network " + _publicNetworkName + " for host " + _host.ip); - throw new IllegalArgumentException("Unable to find public network " + _publicNetworkName + " for host " + _host.ip); - } - } else { - publicNic = guestNic; - _publicNetworkName = _guestNetworkName; - } - _host.publicPif = publicNic.getPifRecord(conn).uuid; - _host.publicNetwork = publicNic.getNetworkRecord(conn).uuid; - if (_storageNetworkName1 == null) { - _storageNetworkName1 = _guestNetworkName; - } - XsLocalNetwork storageNic1 = null; - storageNic1 = getNetworkByName(conn, _storageNetworkName1); - if (storageNic1 == null) { - s_logger.warn("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.ip); - throw new IllegalArgumentException("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.ip); - } else { - _host.storageNetwork1 = storageNic1.getNetworkRecord(conn).uuid; - _host.storagePif1 = storageNic1.getPifRecord(conn).uuid; - } - - XsLocalNetwork storageNic2 = null; - if (_storageNetworkName2 != null) { - storageNic2 = getNetworkByName(conn, _storageNetworkName2); - if(storageNic2 != null) { - _host.storagePif2 = storageNic2.getPifRecord(conn).uuid; - } - } - - s_logger.info("XenServer Version is " + _host.productVersion + " for host " + _host.ip); - s_logger.info("Private Network is " + _privateNetworkName + " for host " + _host.ip); - s_logger.info("Guest Network is " + _guestNetworkName + " for host " + _host.ip); - s_logger.info("Public Network is " + _publicNetworkName + " for host " + _host.ip); - - return true; - } catch (final XenAPIException e) { - s_logger.warn("Unable to get host information for " + _host.ip, e); - return false; - } catch (final Exception e) { - s_logger.warn("Unable to get host information for " + _host.ip, e); - return false; - } - } - - protected void plugDom0Vif(final Connection conn, final VIF dom0Vif) throws XmlRpcException, XenAPIException { - if (dom0Vif != null) { - dom0Vif.plug(conn); - } - } - - private void setupLinkLocalNetwork(final Connection conn) { + public void setupLinkLocalNetwork(final Connection conn) { try { final Network.Record rec = new Network.Record(); final Set networks = Network.getByNameLabel(conn, _linkLocalPrivateNetworkName); @@ -4416,7 +4523,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe final String brName = linkLocal.getBridge(conn); callHostPlugin(conn, "vmops", "setLinkLocalIP", "brName", brName); - _host.linkLocalNetwork = linkLocal.getUuid(conn); + _host.setLinkLocalNetwork(linkLocal.getUuid(conn)); } catch (final XenAPIException e) { s_logger.warn("Unable to create local link network", e); @@ -4427,265 +4534,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected boolean transferManagementNetwork(final Connection conn, final Host host, final PIF src, final PIF.Record spr, final PIF dest) throws XmlRpcException, XenAPIException { - dest.reconfigureIp(conn, spr.ipConfigurationMode, spr.IP, spr.netmask, spr.gateway, spr.DNS); - Host.managementReconfigure(conn, dest); - String hostUuid = null; - final int count = 0; - while (count < 10) { - try { - Thread.sleep(10000); - hostUuid = host.getUuid(conn); - if (hostUuid != null) { - break; - } - } catch (final XmlRpcException e) { - s_logger.debug("Waiting for host to come back: " + e.getMessage()); - } catch (final XenAPIException e) { - s_logger.debug("Waiting for host to come back: " + e.getMessage()); - } catch (final InterruptedException e) { - s_logger.debug("Gotta run"); - return false; - } - } - if (hostUuid == null) { - s_logger.warn("Unable to transfer the management network from " + spr.uuid); - return false; - } - - src.reconfigureIp(conn, Types.IpConfigurationMode.NONE, null, null, null, null); - return true; - } - - @Override - public StartupCommand[] initialize() throws IllegalArgumentException { - final Connection conn = getConnection(); - if (!getHostInfo(conn)) { - s_logger.warn("Unable to get host information for " + _host.ip); - return null; - } - final StartupRoutingCommand cmd = new StartupRoutingCommand(); - fillHostInfo(conn, cmd); - cmd.setHypervisorType(HypervisorType.XenServer); - cmd.setCluster(_cluster); - cmd.setPoolSync(false); - - try { - final Pool pool = Pool.getByUuid(conn, _host.pool); - final Pool.Record poolr = pool.getRecord(conn); - poolr.master.getRecord(conn); - } catch (final Throwable e) { - s_logger.warn("Check for master failed, failing the FULL Cluster sync command"); - } - final StartupStorageCommand sscmd = initializeLocalSR(conn); - if (sscmd != null) { - return new StartupCommand[] {cmd, sscmd}; - } - return new StartupCommand[] {cmd}; - } - - private void cleanupTemplateSR(final Connection conn) { - Set pbds = null; - try { - final Host host = Host.getByUuid(conn, _host.uuid); - 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; - } - final String type = srRec.type; - if (srRec.shared) { - continue; - } - if (SRType.NFS.equals(type) || SRType.ISO.equals(type) && srRec.nameDescription.contains("template")) { - try { - pbd.unplug(conn); - pbd.destroy(conn); - sr.forget(conn); - } catch (final Exception e) { - s_logger.warn("forget SR catch Exception due to ", e); - } - } - } - } - - protected boolean launchHeartBeat(final Connection conn) { - final String result = callHostPluginPremium(conn, "heartbeat", - "host", _host.uuid, - "timeout", Integer.toString(_heartbeatTimeout), - "interval", Integer.toString(_heartbeatInterval)); - if (result == null || !result.contains("> DONE <")) { - s_logger.warn("Unable to launch the heartbeat process on " + _host.ip); - return false; - } - return true; - } - - protected SetupAnswer execute(final SetupCommand cmd) { - final Connection conn = getConnection(); - try { - final Map poolRecs = Pool.getAllRecords(conn); - if (poolRecs.size() != 1) { - throw new CloudRuntimeException("There are " + poolRecs.size() + " pool for host :" + _host.uuid); - } - final Host master = poolRecs.values().iterator().next().master; - setupServer(conn, master); - final Host host = Host.getByUuid(conn, _host.uuid); - setupServer(conn, host); - - if (!setIptables(conn)) { - s_logger.warn("set xenserver Iptable failed"); - return null; - } - - if (_securityGroupEnabled) { - _canBridgeFirewall = can_bridge_firewall(conn); - if (!_canBridgeFirewall) { - final String msg = "Failed to configure brige firewall"; - s_logger.warn(msg); - s_logger.warn("Check host " + _host.ip +" for CSP is installed or not and check network mode for bridge"); - return new SetupAnswer(cmd, msg); - } - - } - - - final boolean r = launchHeartBeat(conn); - if (!r) { - return null; - } - cleanupTemplateSR(conn); - try { - if (cmd.useMultipath()) { - // the config value is set to true - host.addToOtherConfig(conn, "multipathing", "true"); - host.addToOtherConfig(conn, "multipathhandle", "dmp"); - } - - } catch (final Types.MapDuplicateKey e) { - s_logger.debug("multipath is already set"); - } - - if (cmd.needSetup() ) { - final String result = callHostPlugin(conn, "vmops", "setup_iscsi", "uuid", _host.uuid); - - if (!result.contains("> DONE <")) { - s_logger.warn("Unable to setup iscsi: " + result); - return new SetupAnswer(cmd, result); - } - - Pair mgmtPif = null; - final Set hostPifs = host.getPIFs(conn); - for (final PIF pif : hostPifs) { - final PIF.Record rec = pif.getRecord(conn); - if (rec.management) { - if (rec.VLAN != null && rec.VLAN != -1) { - final String msg = - new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) - .append("; pif=") - .append(rec.uuid) - .append("; vlan=") - .append(rec.VLAN) - .toString(); - s_logger.warn(msg); - return new SetupAnswer(cmd, msg); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Management network is on pif=" + rec.uuid); - } - mgmtPif = new Pair(pif, rec); - break; - } - } - - if (mgmtPif == null) { - final String msg = "Unable to find management network for " + _host.uuid; - s_logger.warn(msg); - return new SetupAnswer(cmd, msg); - } - - final Map networks = Network.getAllRecords(conn); - if(networks == null) { - final String msg = "Unable to setup as there are no networks in the host: " + _host.uuid; - s_logger.warn(msg); - return new SetupAnswer(cmd, msg); - } - for (final Network.Record network : networks.values()) { - if (network.nameLabel.equals("cloud-private")) { - for (final PIF pif : network.PIFs) { - final PIF.Record pr = pif.getRecord(conn); - if (_host.uuid.equals(pr.host.getUuid(conn))) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found a network called cloud-private. host=" + _host.uuid + "; Network=" + network.uuid + "; pif=" + pr.uuid); - } - if (pr.VLAN != null && pr.VLAN != -1) { - final String msg = - new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) - .append(" ; pif=") - .append(pr.uuid) - .toString(); - s_logger.warn(msg); - return new SetupAnswer(cmd, msg); - } - if (!pr.management && pr.bondMasterOf != null && pr.bondMasterOf.size() > 0) { - if (pr.bondMasterOf.size() > 1) { - final String msg = - new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) - .append("; pif=") - .append(pr.uuid) - .toString(); - s_logger.warn(msg); - return new SetupAnswer(cmd, msg); - } - final Bond bond = pr.bondMasterOf.iterator().next(); - final Set slaves = bond.getSlaves(conn); - for (final PIF slave : slaves) { - final PIF.Record spr = slave.getRecord(conn); - if (spr.management) { - if (!transferManagementNetwork(conn, host, slave, spr, pif)) { - final String msg = - new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + - _host.uuid).toString(); - s_logger.warn(msg); - return new SetupAnswer(cmd, msg); - } - break; - } - } - } - } - } - } - } - } - return new SetupAnswer(cmd, false); - - } catch (final XmlRpcException e) { - s_logger.warn("Unable to setup", e); - return new SetupAnswer(cmd, e.getMessage()); - } catch (final XenAPIException e) { - s_logger.warn("Unable to setup", e); - return new SetupAnswer(cmd, e.getMessage()); - } catch (final Exception e) { - s_logger.warn("Unable to setup", e); - return new SetupAnswer(cmd, e.getMessage()); - } - } - /* return : if setup is needed */ - protected boolean setupServer(final Connection conn, final Host host) { + public boolean setupServer(final Connection conn, final Host host) { final String packageVersion = CitrixResourceBase.class.getPackage().getImplementationVersion(); final String version = this.getClass().getName() + "-" + (packageVersion == null ? Long.toString(System.currentTimeMillis()) : packageVersion); @@ -4732,8 +4582,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe final Properties props = PropertiesUtil.loadFromFile(file); for (final Map.Entry entry : props.entrySet()) { - final String k = (String)entry.getKey(); - final String v = (String)entry.getValue(); + final String k = (String) entry.getKey(); + final String v = (String) entry.getValue(); assert k != null && k.length() > 0 && v != null && v.length() > 0 : "Problems with " + k + "=" + v; @@ -4803,2084 +4653,86 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected CheckNetworkAnswer execute(final CheckNetworkCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Checking if network name setup is done on the resource"); - } - - final List infoList = cmd.getPhysicalNetworkInfoList(); - + public synchronized Network setupvSwitchNetwork(final Connection conn) { try { - boolean errorout = false; - String msg = ""; - for (final PhysicalNetworkSetupInfo info : infoList) { - if (!isNetworkSetupByName(info.getGuestNetworkName())) { - msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " + - info.getGuestNetworkName(); - errorout = true; - break; - } - if (!isNetworkSetupByName(info.getPrivateNetworkName())) { - msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " + - info.getPrivateNetworkName(); - errorout = true; - break; - } - if (!isNetworkSetupByName(info.getPublicNetworkName())) { - msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " + - info.getPublicNetworkName(); - errorout = true; - break; - } - /*if(!isNetworkSetupByName(info.getStorageNetworkName())){ - msg = "For Physical Network id:"+ info.getPhysicalNetworkId() + ", Storage Network is not configured on the backend by name " + info.getStorageNetworkName(); - errorout = true; - break; - }*/ - } - if (errorout) { - s_logger.error(msg); - return new CheckNetworkAnswer(cmd, false, msg); - } else { - return new CheckNetworkAnswer(cmd, true, "Network Setup check by names is done"); - } + 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); + } + return _host.getVswitchNetwork(); + } catch (final BadServerResponse e) { + s_logger.error("Failed to setup vswitch network", e); } catch (final XenAPIException e) { - final String msg = "CheckNetworkCommand failed with XenAPIException:" + e.toString() + " host:" + _host.uuid; - s_logger.warn(msg, e); - return new CheckNetworkAnswer(cmd, false, msg); - } catch (final Exception e) { - final String msg = "CheckNetworkCommand failed with Exception:" + e.getMessage() + " host:" + _host.uuid; - s_logger.warn(msg, e); - return new CheckNetworkAnswer(cmd, false, msg); + s_logger.error("Failed to setup vswitch network", e); + } catch (final XmlRpcException e) { + s_logger.error("Failed to setup vswitch network", e); } - } - protected boolean isNetworkSetupByName(final String nameTag) throws XenAPIException, XmlRpcException { - if (nameTag != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Looking for network setup by name " + nameTag); - } - final Connection conn = getConnection(); - final XsLocalNetwork network = getNetworkByName(conn, nameTag); - if (network == null) { - return false; - } - } - return true; - } - - protected List getPatchFiles() { return null; } - protected SR getSRByNameLabelandHost(final Connection conn, final String name) throws BadServerResponse, XenAPIException, XmlRpcException { - final Set srs = SR.getByNameLabel(conn, name); - SR ressr = null; - for (final SR sr : srs) { - Set pbds; - pbds = sr.getPBDs(conn); - for (final PBD pbd : pbds) { - final PBD.Record pbdr = pbd.getRecord(conn); - if (pbdr.host != null && pbdr.host.getUuid(conn).equals(_host.uuid)) { - if (!pbdr.currentlyAttached) { - pbd.plug(conn); - } - ressr = sr; - break; - } - } - } - return ressr; - } - - protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) { - final Connection conn = getConnection(); + public void shutdownVM(final Connection conn, final VM vm, final String vmName) throws XmlRpcException { + Task task = null; try { - final Set srs = SR.getByNameLabel(conn, cmd.getStorageId()); - if (srs.size() != 1) { - final String msg = "There are " + srs.size() + " storageid: " + cmd.getStorageId(); - s_logger.warn(msg); - return new GetStorageStatsAnswer(cmd, msg); + task = vm.cleanShutdownAsync(conn); + try { + // poll every 1 seconds , timeout after 10 minutes + waitForTask(conn, task, 1000, 10 * 60 * 1000); + checkForSuccess(conn, task); + } catch (final TimeoutException e) { + if (vm.getPowerState(conn) == VmPowerState.HALTED) { + task = null; + return; + } + throw new CloudRuntimeException("Shutdown VM catch HandleInvalid and VM is not in HALTED state"); } - final SR sr = srs.iterator().next(); - sr.scan(conn); - final long capacity = sr.getPhysicalSize(conn); - final long used = sr.getPhysicalUtilisation(conn); - return new GetStorageStatsAnswer(cmd, capacity, used); } catch (final XenAPIException e) { - final String msg = "GetStorageStats Exception:" + e.toString() + "host:" + _host.uuid + "storageid: " + cmd.getStorageId(); - s_logger.warn(msg); - return new GetStorageStatsAnswer(cmd, msg); - } catch (final XmlRpcException e) { - final String msg = "GetStorageStats Exception:" + e.getMessage() + "host:" + _host.uuid + "storageid: " + cmd.getStorageId(); - s_logger.warn(msg); - return new GetStorageStatsAnswer(cmd, msg); - } - } - - private void pbdPlug(final Connection conn, final PBD pbd, final String uuid) { - try { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Plugging in PBD " + uuid + " for " + _host); - } - pbd.plug(conn); - } catch (final Exception e) { - final String msg = "PBD " + uuid + " is not attached! and PBD plug failed due to " + e.toString() + ". Please check this PBD in " + _host; - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg); - } - } - - protected boolean checkSR(final Connection conn, final SR sr) { - try { - 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.uuid; - s_logger.warn(msg); - return false; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Checking " + srr.nameLabel + " or SR " + srr.uuid + " on " + _host); - } - 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); - } - } - - final Host host = Host.getByUuid(conn, _host.uuid); - 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); + s_logger.debug("Unable to cleanShutdown VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString()); + try { + VmPowerState state = vm.getPowerState(conn); + if (state == VmPowerState.RUNNING) { + try { + vm.hardShutdown(conn); + } catch (final Exception e1) { + s_logger.debug("Unable to hardShutdown VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString()); + state = vm.getPowerState(conn); + if (state == VmPowerState.RUNNING) { + forceShutdownVM(conn, vm); } - found = true; - break; + return; } - } - 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)); - } - } else { - for (final PBD pbd : pbds) { - final PBD.Record pbdr = pbd.getRecord(conn); - if (!pbdr.currentlyAttached) { - pbdPlug(conn, pbd, pbdr.uuid); - } - } - } - - } catch (final Exception e) { - final String msg = "checkSR failed host:" + _host + " due to " + e.toString(); - s_logger.warn(msg, e); - return false; - } - return true; - } - - protected Answer execute(final CreateStoragePoolCommand cmd) { - final Connection conn = getConnection(); - final StorageFilerTO pool = cmd.getPool(); - try { - if (pool.getType() == StoragePoolType.NetworkFilesystem) { - getNfsSR(conn, Long.toString(pool.getId()), pool.getUuid(), pool.getHost(), pool.getPath(), pool.toString()); - } else if (pool.getType() == StoragePoolType.IscsiLUN) { - getIscsiSR(conn, pool.getUuid(), pool.getHost(), pool.getPath(), null, null, false); - } else if (pool.getType() == StoragePoolType.PreSetup) { - } else { - return new Answer(cmd, false, "The pool type: " + pool.getType().name() + " is not supported."); - } - return new Answer(cmd, true, "success"); - } catch (final Exception e) { - final String msg = - "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + - pool.getHost() + pool.getPath(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } - - } - - protected String callHostPluginThroughMaster(final Connection conn, final String plugin, final String cmd, final String... params) { - final Map args = new HashMap(); - - try { - final Map poolRecs = Pool.getAllRecords(conn); - if (poolRecs.size() != 1) { - throw new CloudRuntimeException("There are " + poolRecs.size() + " pool for host :" + _host.uuid); - } - 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 (s_logger.isTraceEnabled()) { - s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); - } - final String result = master.callPlugin(conn, plugin, cmd, args); - if (s_logger.isTraceEnabled()) { - s_logger.trace("callHostPlugin Result: " + result); - } - 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; - } - - protected String callHostPluginPremium(final Connection conn, final String cmd, final String... params) { - return callHostPlugin(conn, "vmopspremium", cmd, params); - } - - protected String setupHeartbeatSr(final Connection conn, final SR sr, final boolean force) throws XenAPIException, XmlRpcException { - final SR.Record srRec = sr.getRecord(conn); - final String srUuid = srRec.uuid; - if (!srRec.shared || !SRType.LVMOHBA.equals(srRec.type) && !SRType.LVMOISCSI.equals(srRec.type) && !SRType.NFS.equals(srRec.type)) { - return srUuid; - } - String result = null; - final Host host = Host.getByUuid(conn, _host.uuid); - final Set tags = host.getTags(conn); - if (force || !tags.contains("cloud-heartbeat-" + srUuid)) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Setting up the heartbeat sr for host " + _host.ip + " and sr " + srUuid); - } - final Set pbds = sr.getPBDs(conn); - for (final PBD pbd : pbds) { - final PBD.Record pbdr = pbd.getRecord(conn); - if (!pbdr.currentlyAttached && pbdr.host.getUuid(conn).equals(_host.uuid)) { - pbd.plug(conn); - break; - } - } - result = callHostPluginThroughMaster(conn, "vmopspremium", "setup_heartbeat_sr", "host", _host.uuid, "sr", srUuid); - if (result == null || !result.split("#")[1].equals("0")) { - throw new CloudRuntimeException("Unable to setup heartbeat sr on SR " + srUuid + " due to " + result); - } - - if (!tags.contains("cloud-heartbeat-" + srUuid)) { - tags.add("cloud-heartbeat-" + srUuid); - host.setTags(conn, tags); - } - } - result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.uuid, "sr", srUuid, "add", "true"); - if (result == null || !result.split("#")[1].equals("0")) { - throw new CloudRuntimeException("Unable to setup heartbeat file entry on SR " + srUuid + " due to " + result); - } - return srUuid; - } - - protected Answer execute(final ModifyStoragePoolCommand cmd) { - final Connection conn = getConnection(); - final StorageFilerTO pool = cmd.getPool(); - final boolean add = cmd.getAdd(); - if (add) { - try { - final SR sr = getStorageRepository(conn, pool.getUuid()); - setupHeartbeatSr(conn, sr, false); - final long capacity = sr.getPhysicalSize(conn); - final long available = capacity - sr.getPhysicalUtilisation(conn); - if (capacity == -1) { - final String msg = "Pool capacity is -1! pool: " + pool.getHost() + pool.getPath(); - s_logger.warn(msg); - return new Answer(cmd, false, msg); - } - final Map tInfo = new HashMap(); - final ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo); - return answer; - } catch (final XenAPIException e) { - final String msg = "ModifyStoragePoolCommand add XenAPIException:" + e.toString() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } catch (final Exception e) { - final String msg = "ModifyStoragePoolCommand add XenAPIException:" + e.getMessage() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } - } else { - try { - final SR sr = getStorageRepository(conn, pool.getUuid()); - final String srUuid = sr.getUuid(conn); - final String result = callHostPluginPremium(conn, "setup_heartbeat_file", "host", _host.uuid, "sr", srUuid, "add", "false"); - if (result == null || !result.split("#")[1].equals("0")) { - throw new CloudRuntimeException("Unable to remove heartbeat file entry for SR " + srUuid + " due to " + result); - } - return new Answer(cmd, true, "seccuss"); - } catch (final XenAPIException e) { - final String msg = "ModifyStoragePoolCommand remove XenAPIException:" + e.toString() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } catch (final Exception e) { - final String msg = "ModifyStoragePoolCommand remove XenAPIException:" + e.getMessage() + " host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } - } - - } - - protected boolean can_bridge_firewall(final Connection conn) { - return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.uuid, "instance", _instance)); - } - - private Answer execute(final OvsSetupBridgeCommand cmd) { - final Connection conn = getConnection(); - findOrCreateTunnelNetwork(conn, cmd.getBridgeName()); - configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getHostId(), cmd.getBridgeName()); - s_logger.debug("OVS Bridge configured"); - return new Answer(cmd, true, null); - } - - private Answer execute(final OvsDestroyBridgeCommand cmd) { - try { - final Connection conn = getConnection(); - final Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName()); - cleanUpTmpDomVif(conn, nw); - destroyTunnelNetwork(conn, nw, cmd.getHostId()); - s_logger.debug("OVS Bridge destroyed"); - return new Answer(cmd, true, null); - } catch (final Exception e) { - s_logger.warn("caught execption when destroying ovs bridge", e); - return new Answer(cmd, false, e.getMessage()); - } - } - - private Answer execute(final OvsDestroyTunnelCommand cmd) { - final Connection conn = getConnection(); - try { - final Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName()); - if (nw == null) { - s_logger.warn("Unable to find tunnel network for GRE key:" + cmd.getBridgeName()); - return new Answer(cmd, false, "No network found"); - } - - final String bridge = nw.getBridge(conn); - final String result = callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", cmd.getInPortName()); - - 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 execption when destroy ovs tunnel", e); - return new Answer(cmd, false, e.getMessage()); - } - } - - public Answer execute(final OvsVpcPhysicalTopologyConfigCommand cmd) { - final Connection conn = getConnection(); - try { - final Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName()); - final String bridgeName = nw.getBridge(conn); - final long sequenceNo = cmd.getSequenceNumber(); - final String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", - bridgeName, "config", cmd.getVpcConfigInJson(), "host-id", ((Long)cmd.getHostId()).toString(), - "seq-no", Long.toString(sequenceNo)); - if (result.startsWith("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 Answer execute(final OvsVpcRoutingPolicyConfigCommand cmd) { - final Connection conn = getConnection(); - try { - final Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName()); - final String bridgeName = nw.getBridge(conn); - final long sequenceNo = cmd.getSequenceNumber(); - - final String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_routing_policies", "bridge", - bridgeName, "host-id", ((Long)cmd.getHostId()).toString(), "config", - cmd.getVpcConfigInJson(), "seq-no", Long.toString(sequenceNo)); - if (result.startsWith("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 policies", e); - return new Answer(cmd, false, e.getMessage()); - } - } - - private Answer execute(final UpdateHostPasswordCommand cmd) { - _password.add(cmd.getNewPassword()); - return new Answer(cmd, true, null); - } - - private OvsCreateTunnelAnswer execute(final OvsCreateTunnelCommand cmd) { - final Connection conn = getConnection(); - String bridge = "unknown"; - try { - final Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkName()); - if (nw == null) { - s_logger.debug("Error during bridge setup"); - return new OvsCreateTunnelAnswer(cmd, false, "Cannot create network", bridge); - } - - configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getNetworkName()); - bridge = nw.getBridge(conn); - final String result = - callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), - "key", cmd.getKey().toString(), "from", - cmd.getFrom().toString(), "to", cmd.getTo().toString(), "cloudstack-network-id", - cmd.getNetworkUuid()); - final String[] res = result.split(":"); - if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) { - return new OvsCreateTunnelAnswer(cmd, true, result, res[1], 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 Answer execute(final OvsDeleteFlowCommand cmd) { - _isOvs = true; - - final Connection conn = getConnection(); - try { - final Network nw = setupvSwitchNetwork(conn); - final String bridge = nw.getBridge(conn); - final String result = callHostPlugin(conn, "ovsgre", "ovs_delete_flow", "bridge", bridge, "vmName", cmd.getVmName()); - - if (result.equalsIgnoreCase("SUCCESS")) { - return new Answer(cmd, true, "success to delete flows for " + cmd.getVmName()); - } else { - return new Answer(cmd, false, result); - } - } catch (final BadServerResponse e) { - s_logger.error("Failed to delete flow", e); - } catch (final XenAPIException e) { - s_logger.error("Failed to delete flow", e); - } catch (final XmlRpcException e) { - s_logger.error("Failed to delete flow", e); - } - return new Answer(cmd, false, "failed to delete flow for " + cmd.getVmName()); - } - - private List> ovsFullSyncStates() { - final Connection conn = getConnection(); - final String result = callHostPlugin(conn, "ovsgre", "ovs_get_vm_log", "host_uuid", _host.uuid); - final String[] logs = result != null ? result.split(";") : new String[0]; - final List> states = new ArrayList>(); - for (final String log : logs) { - final String[] info = log.split(","); - if (info.length != 5) { - s_logger.warn("Wrong element number in ovs log(" + log + ")"); - continue; - } - - //','.join([bridge, vmName, vmId, seqno, tag]) - try { - states.add(new Pair(info[0], Long.parseLong(info[3]))); - } catch (final NumberFormatException nfe) { - states.add(new Pair(info[0], -1L)); - } - } - return states; - } - - private OvsSetTagAndFlowAnswer execute(final OvsSetTagAndFlowCommand cmd) { - _isOvs = true; - - final Connection conn = getConnection(); - try { - final Network nw = setupvSwitchNetwork(conn); - final String bridge = nw.getBridge(conn); - - /*If VM is domainRouter, this will try to set flow and tag on its - * none guest network nic. don't worry, it will fail silently at host - * plugin side - */ - final String result = - callHostPlugin(conn, "ovsgre", "ovs_set_tag_and_flow", "bridge", bridge, "vmName", cmd.getVmName(), "tag", cmd.getTag(), "vlans", cmd.getVlans(), - "seqno", cmd.getSeqNo()); - s_logger.debug("set flow for " + cmd.getVmName() + " " + result); - - if (result.equalsIgnoreCase("SUCCESS")) { - return new OvsSetTagAndFlowAnswer(cmd, true, result); - } else { - return new OvsSetTagAndFlowAnswer(cmd, false, result); - } - } catch (final BadServerResponse e) { - s_logger.error("Failed to set tag and flow", e); - } catch (final XenAPIException e) { - s_logger.error("Failed to set tag and flow", e); - } catch (final XmlRpcException e) { - s_logger.error("Failed to set tag and flow", e); - } - - return new OvsSetTagAndFlowAnswer(cmd, false, "EXCEPTION"); - } - - private OvsFetchInterfaceAnswer execute(final OvsFetchInterfaceCommand cmd) { - - String label = cmd.getLabel(); - //FIXME: this is a tricky to pass the network checking in XCP. I temporary get default label from Host. - if (is_xcp()) { - label = getLabel(); - } - s_logger.debug("Will look for network with name-label:" + label + " on host " + _host.ip); - final Connection conn = getConnection(); - try { - final XsLocalNetwork nw = getNetworkByName(conn, label); - if(nw == null) { - throw new CloudRuntimeException("Unable to locate the network with name-label: " + label + " on host: " + _host.ip); - } - s_logger.debug("Network object:" + nw.getNetwork().getUuid(conn)); - final PIF pif = nw.getPif(conn); - final PIF.Record pifRec = pif.getRecord(conn); - s_logger.debug("PIF object:" + pifRec.uuid + "(" + pifRec.device + ")"); - return new OvsFetchInterfaceAnswer(cmd, true, "Interface " + pifRec.device + " retrieved successfully", pifRec.IP, pifRec.netmask, pifRec.MAC); - } catch (final BadServerResponse e) { - s_logger.error("An error occurred while fetching the interface for " + label + " on host " + _host.ip, e); - return new OvsFetchInterfaceAnswer(cmd, false, "EXCEPTION:" + e.getMessage()); - } catch (final XenAPIException e) { - s_logger.error("An error occurred while fetching the interface for " + label + " on host " + _host.ip, e); - return new OvsFetchInterfaceAnswer(cmd, false, "EXCEPTION:" + e.getMessage()); - } catch (final XmlRpcException e) { - s_logger.error("An error occurred while fetching the interface for " + label + " on host " + _host.ip, e); - return new OvsFetchInterfaceAnswer(cmd, false, "EXCEPTION:" + e.getMessage()); - } - } - - private OvsCreateGreTunnelAnswer execute(final OvsCreateGreTunnelCommand cmd) { - _isOvs = true; - - final Connection conn = getConnection(); - String bridge = "unkonwn"; - try { - final Network nw = setupvSwitchNetwork(conn); - bridge = nw.getBridge(conn); - - final String result = - callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", cmd.getRemoteIp(), "greKey", cmd.getKey(), "from", - Long.toString(cmd.getFrom()), "to", Long.toString(cmd.getTo())); - final String[] res = result.split(":"); - if (res.length != 2 || res.length == 2 && res[1].equalsIgnoreCase("[]")) { - return new OvsCreateGreTunnelAnswer(cmd, false, result, _host.ip, bridge); - } else { - return new OvsCreateGreTunnelAnswer(cmd, true, result, _host.ip, bridge, Integer.parseInt(res[1])); - } - } catch (final BadServerResponse e) { - s_logger.error("An error occurred while creating a GRE tunnel to " + cmd.getRemoteIp() + " on host " + _host.ip, e); - } catch (final XenAPIException e) { - s_logger.error("An error occurred while creating a GRE tunnel to " + cmd.getRemoteIp() + " on host " + _host.ip, e); - } catch (final XmlRpcException e) { - s_logger.error("An error occurred while creating a GRE tunnel to " + cmd.getRemoteIp() + " on host " + _host.ip, e); - } - - return new OvsCreateGreTunnelAnswer(cmd, false, "EXCEPTION", _host.ip, bridge); - } - - private Answer execute(final SecurityGroupRulesCmd cmd) { - final Connection conn = getConnection(); - if (s_logger.isTraceEnabled()) { - s_logger.trace("Sending network rules command to " + _host.ip); - } - - if (!_canBridgeFirewall) { - s_logger.warn("Host " + _host.ip + " cannot do bridge firewalling"); - return new SecurityGroupRuleAnswer(cmd, false, "Host " + _host.ip + " cannot do bridge firewalling", - SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); - } - - final String result = - callHostPlugin(conn, "vmops", "network_rules", "vmName", cmd.getVmName(), "vmIP", cmd.getGuestIp(), "vmMAC", cmd.getGuestMac(), "vmID", - Long.toString(cmd.getVmId()), "signature", cmd.getSignature(), "seqno", Long.toString(cmd.getSeqNum()), "deflated", "true", "rules", - cmd.compressStringifiedRules(), "secIps", cmd.getSecIpsString()); - - if (result == null || result.isEmpty() || !Boolean.parseBoolean(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.info("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 Answer execute(final DeleteStoragePoolCommand cmd) { - final Connection conn = getConnection(); - final StorageFilerTO poolTO = cmd.getPool(); - try { - final SR sr = getStorageRepository(conn, poolTO.getUuid()); - removeSR(conn, sr); - final Answer answer = new Answer(cmd, true, "success"); - return answer; - } catch (final Exception e) { - final String msg = "DeleteStoragePoolCommand XenAPIException:" + e.getMessage() + " host:" + _host.uuid + " pool: " + poolTO.getHost() + poolTO.getPath(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } - - } - - public Connection getConnection() { - return ConnPool.connect(_host.uuid, _host.pool, _host.ip, _username, _password, _wait); - } - - - protected void fillHostInfo(final Connection conn, final StartupRoutingCommand cmd) { - final StringBuilder caps = new StringBuilder(); - try { - - final Host host = Host.getByUuid(conn, _host.uuid); - final Host.Record hr = host.getRecord(conn); - - Map details = cmd.getHostDetails(); - if (details == null) { - details = new HashMap(); - } - - String productBrand = hr.softwareVersion.get("product_brand"); - if (productBrand == null) { - productBrand = hr.softwareVersion.get("platform_name"); - } - details.put("product_brand", productBrand); - details.put("product_version", _host.productVersion); - if (hr.softwareVersion.get("product_version_text_short") != null) { - details.put("product_version_text_short", hr.softwareVersion.get("product_version_text_short")); - cmd.setHypervisorVersion(hr.softwareVersion.get("product_version_text_short")); - - cmd.setHypervisorVersion(_host.productVersion); - } - if (_privateNetworkName != null) { - details.put("private.network.device", _privateNetworkName); - } - - cmd.setHostDetails(details); - cmd.setName(hr.nameLabel); - cmd.setGuid(_host.uuid); - cmd.setPool(_host.pool); - cmd.setDataCenter(Long.toString(_dcId)); - for (final String cap : hr.capabilities) { - if (cap.length() > 0) { - caps.append(cap).append(" , "); - } - } - if (caps.length() > 0) { - caps.delete(caps.length() - 3, caps.length()); - } - cmd.setCaps(caps.toString()); - - cmd.setSpeed(_host.speed); - cmd.setCpuSockets(_host.cpuSockets); - cmd.setCpus(_host.cpus); - - final HostMetrics hm = host.getMetrics(conn); - - long ram = 0; - long dom0Ram = 0; - ram = hm.getMemoryTotal(conn); - final Set vms = host.getResidentVMs(conn); - for (final VM vm : vms) { - if (vm.getIsControlDomain(conn)) { - dom0Ram = vm.getMemoryStaticMax(conn); - break; - } - } - - ram = (long)((ram - dom0Ram - _xsMemoryUsed) * _xsVirtualizationFactor); - cmd.setMemory(ram); - cmd.setDom0MinMemory(dom0Ram); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Total Ram: " + ram + " dom0 Ram: " + dom0Ram); - } - - PIF pif = PIF.getByUuid(conn, _host.privatePif); - PIF.Record pifr = pif.getRecord(conn); - if (pifr.IP != null && pifr.IP.length() > 0) { - cmd.setPrivateIpAddress(pifr.IP); - cmd.setPrivateMacAddress(pifr.MAC); - cmd.setPrivateNetmask(pifr.netmask); - } else { - cmd.setPrivateIpAddress(_host.ip); - cmd.setPrivateMacAddress(pifr.MAC); - cmd.setPrivateNetmask("255.255.255.0"); - } - - pif = PIF.getByUuid(conn, _host.publicPif); - pifr = pif.getRecord(conn); - if (pifr.IP != null && pifr.IP.length() > 0) { - cmd.setPublicIpAddress(pifr.IP); - cmd.setPublicMacAddress(pifr.MAC); - cmd.setPublicNetmask(pifr.netmask); - } - - if (_host.storagePif1 != null) { - pif = PIF.getByUuid(conn, _host.storagePif1); - pifr = pif.getRecord(conn); - if (pifr.IP != null && pifr.IP.length() > 0) { - cmd.setStorageIpAddress(pifr.IP); - cmd.setStorageMacAddress(pifr.MAC); - cmd.setStorageNetmask(pifr.netmask); - } - } - - if (_host.storagePif2 != null) { - pif = PIF.getByUuid(conn, _host.storagePif2); - pifr = pif.getRecord(conn); - if (pifr.IP != null && pifr.IP.length() > 0) { - cmd.setStorageIpAddressDeux(pifr.IP); - cmd.setStorageMacAddressDeux(pifr.MAC); - cmd.setStorageNetmaskDeux(pifr.netmask); - } - } - - final Map configs = hr.otherConfig; - cmd.setIqn(configs.get("iscsi_iqn")); - - cmd.setPod(_pod); - cmd.setVersion(CitrixResourceBase.class.getPackage().getImplementationVersion()); - - } catch (final XmlRpcException e) { - throw new CloudRuntimeException("XML RPC Exception" + e.getMessage(), e); - } catch (final XenAPIException e) { - throw new CloudRuntimeException("XenAPIException" + e.toString(), e); - } - } - - public CitrixResourceBase() { - } - - @Override - public boolean configure(final String name, final Map params) throws ConfigurationException { - _name = name; - - try { - _dcId = Long.parseLong((String)params.get("zone")); - } catch (final NumberFormatException e) { - throw new ConfigurationException("Unable to get the zone " + params.get("zone")); - } - - _host.uuid = (String)params.get("guid"); - - _name = _host.uuid; - _host.ip = (String)params.get("ipaddress"); - - _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"; - } - - _storageNetworkName1 = (String)params.get("storage.network.device1"); - _storageNetworkName2 = (String)params.get("storage.network.device2"); - - _heartbeatTimeout = NumbersUtil.parseInt((String)params.get("xenserver.heartbeat.timeout"), 120); - _heartbeatInterval = NumbersUtil.parseInt((String)params.get("xenserver.heartbeat.interval"), 60); - - String value = (String)params.get("wait"); - _wait = NumbersUtil.parseInt(value, 600); - - value = (String)params.get("migratewait"); - _migratewait = NumbersUtil.parseInt(value, 3600); - - _maxNics = NumbersUtil.parseInt((String)params.get("xenserver.nics.max"), 7); - - if (_pod == null) { - throw new ConfigurationException("Unable to get the pod"); - } - - if (_host.ip == null) { - throw new ConfigurationException("Unable to get the host address"); - } - - if (_username == null) { - throw new ConfigurationException("Unable to get the username"); - } - - if (_password.peek() == null) { - throw new ConfigurationException("Unable to get the password"); - } - - if (_host.uuid == null) { - throw new ConfigurationException("Unable to get the uuid"); - } - - CheckXenHostInfo(); - - storageHandler = getStorageHandler(); - - _vrResource = new VirtualRoutingResource(this); - if (!_vrResource.configure(name, params)) { - throw new ConfigurationException("Unable to configure VirtualRoutingResource"); - } - return true; - } - - protected StorageSubsystemCommandHandler getStorageHandler() { - final XenServerStorageProcessor processor = new XenServerStorageProcessor(this); - return new StorageSubsystemCommandHandlerBase(processor); - } - - private void CheckXenHostInfo() throws ConfigurationException { - final Connection conn = ConnPool.getConnect(_host.ip, _username, _password); - if( conn == null ) { - throw new ConfigurationException("Can not create connection to " + _host.ip); - } - try { - Host.Record hostRec = null; - try { - final Host host = Host.getByUuid(conn, _host.uuid); - hostRec = host.getRecord(conn); - final Pool.Record poolRec = Pool.getAllRecords(conn).values().iterator().next(); - _host.pool = poolRec.uuid; - - } catch (final Exception e) { - throw new ConfigurationException("Can not get host information from " + _host.ip); - } - if (!hostRec.address.equals(_host.ip)) { - final String msg = "Host " + _host.ip + " seems be reinstalled, please remove this host and readd"; - s_logger.error(msg); - throw new ConfigurationException(msg); - } - } finally { - try { - Session.logout(conn); - } catch (final Exception e) { - } - } - } - - - public CreateAnswer execute(final CreateCommand cmd) { - final Connection conn = getConnection(); - final StorageFilerTO pool = cmd.getPool(); - final DiskProfile dskch = cmd.getDiskCharacteristics(); - VDI vdi = null; - try { - final SR poolSr = getStorageRepository(conn, pool.getUuid()); - if (cmd.getTemplateUrl() != null) { - VDI tmpltvdi = null; - - tmpltvdi = getVDIbyUuid(conn, cmd.getTemplateUrl()); - vdi = tmpltvdi.createClone(conn, new HashMap()); - vdi.setNameLabel(conn, dskch.getName()); - } else { - final VDI.Record vdir = new VDI.Record(); - vdir.nameLabel = dskch.getName(); - vdir.SR = poolSr; - vdir.type = Types.VdiType.USER; - - vdir.virtualSize = dskch.getSize(); - vdi = VDI.create(conn, vdir); - } - - VDI.Record vdir; - vdir = vdi.getRecord(conn); - s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid); - - final VolumeTO vol = - new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); - return new CreateAnswer(cmd, vol); - } catch (final Exception e) { - s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: " + dskch, e); - return new CreateAnswer(cmd, e); - } - } - - public Answer execute(final ResizeVolumeCommand cmd) { - final Connection conn = getConnection(); - final String volid = cmd.getPath(); - final long newSize = cmd.getNewSize(); - - try { - final VDI vdi = getVDIbyUuid(conn, volid); - vdi.resize(conn, newSize); - return new ResizeVolumeAnswer(cmd, true, "success", newSize); - } catch (final Exception e) { - s_logger.warn("Unable to resize volume", e); - final String error = "failed to resize volume:" + e; - return new ResizeVolumeAnswer(cmd, false, error); - } - } - - protected SR getISOSRbyVmName(final Connection conn, final String vmName) { - try { - final Set srs = SR.getByNameLabel(conn, vmName + "-ISO"); - if (srs.size() == 0) { - return null; - } else if (srs.size() == 1) { - return srs.iterator().next(); - } else { - final String msg = "getIsoSRbyVmName failed due to there are more than 1 SR having same Label"; - s_logger.warn(msg); - } - } catch (final XenAPIException e) { - final String msg = "getIsoSRbyVmName failed due to " + e.toString(); - s_logger.warn(msg, e); - } catch (final Exception e) { - final String msg = "getIsoSRbyVmName failed due to " + e.getMessage(); - s_logger.warn(msg, e); - } - return null; - } - - protected SR createNfsSRbyURI(final Connection conn, final URI uri, final boolean shared) { - try { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating a " + (shared ? "shared SR for " : "not shared SR for ") + uri); - } - - final Map deviceConfig = new HashMap(); - String path = uri.getPath(); - path = path.replace("//", "/"); - deviceConfig.put("server", uri.getHost()); - deviceConfig.put("serverpath", path); - final String name = UUID.nameUUIDFromBytes(new String(uri.getHost() + path).getBytes()).toString(); - if (!shared) { - final Set srs = SR.getByNameLabel(conn, name); - for (final SR sr : srs) { - final SR.Record record = sr.getRecord(conn); - if (SRType.NFS.equals(record.type) && record.contentType.equals("user") && !record.shared) { - removeSRSync(conn, sr); - } - } - } - - final Host host = Host.getByUuid(conn, _host.uuid); - final Map smConfig = new HashMap(); - smConfig.put("nosubdir", "true"); - final SR sr = SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, smConfig); - - if (!checkSR(conn, sr)) { - throw new Exception("no attached PBD"); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug(logX(sr, "Created a SR; UUID is " + sr.getUuid(conn) + " device config is " + deviceConfig)); - } - sr.scan(conn); - return sr; - } catch (final XenAPIException e) { - final String msg = "Can not create second storage SR mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.toString(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } catch (final Exception e) { - final String msg = "Can not create second storage SR mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.getMessage(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } - } - - protected SR createIsoSRbyURI(final Connection conn, final URI uri, final String vmName, final boolean shared) { - try { - final Map deviceConfig = new HashMap(); - String path = uri.getPath(); - path = path.replace("//", "/"); - deviceConfig.put("location", uri.getHost() + ":" + path); - final Host host = Host.getByUuid(conn, _host.uuid); - final SR sr = SR.create(conn, host, deviceConfig, new Long(0), uri.getHost() + path, "iso", "iso", "iso", shared, new HashMap()); - sr.setNameLabel(conn, vmName + "-ISO"); - sr.setNameDescription(conn, deviceConfig.get("location")); - - sr.scan(conn); - return sr; - } catch (final XenAPIException e) { - final String msg = "createIsoSRbyURI failed! mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.toString(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } catch (final Exception e) { - final String msg = "createIsoSRbyURI failed! mountpoint: " + uri.getHost() + uri.getPath() + " due to " + e.getMessage(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } - } - - protected VDI getVDIbyLocationandSR(final Connection conn, final String loc, final SR sr) { - try { - final Set vdis = sr.getVDIs(conn); - for (final VDI vdi : vdis) { - if (vdi.getLocation(conn).startsWith(loc)) { - return vdi; - } - } - - final String msg = "can not getVDIbyLocationandSR " + loc; - s_logger.warn(msg); - return null; - } catch (final XenAPIException e) { - final String msg = "getVDIbyLocationandSR exception " + loc + " due to " + e.toString(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } catch (final Exception e) { - final String msg = "getVDIbyLocationandSR exception " + loc + " due to " + e.getMessage(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } - - } - - protected VDI getVDIbyUuid(final Connection conn, final String uuid) { - return getVDIbyUuid(conn, uuid, true); - } - - protected VDI getVDIbyUuid(final Connection conn, final String uuid, final boolean throwExceptionIfNotFound) { - try { - return VDI.getByUuid(conn, uuid); - } catch (final Exception e) { - if (throwExceptionIfNotFound) { - final String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString(); - - s_logger.debug(msg); - - throw new CloudRuntimeException(msg, e); - } - - return null; - } - } - - protected SR getIscsiSR(final Connection conn, final String srNameLabel, final String target, String path, final String chapInitiatorUsername, final String chapInitiatorPassword, - final boolean ignoreIntroduceException) { - synchronized (srNameLabel.intern()) { - final Map deviceConfig = new HashMap(); - try { - if (path.endsWith("/")) { - path = path.substring(0, path.length() - 1); - } - - final String tmp[] = path.split("/"); - if (tmp.length != 3) { - final String msg = "Wrong iscsi path " + path + " it should be /targetIQN/LUN"; + } else if (state == VmPowerState.HALTED) { + return; + } else { + final String msg = "After cleanShutdown the VM status is " + state.toString() + ", that is not expected"; s_logger.warn(msg); throw new CloudRuntimeException(msg); } - final String targetiqn = tmp[1].trim(); - final String lunid = tmp[2].trim(); - String scsiid = ""; - - final Set srs = SR.getByNameLabel(conn, srNameLabel); - for (final SR sr : srs) { - if (!SRType.LVMOISCSI.equals(sr.getType(conn))) { - continue; - } - final Set pbds = sr.getPBDs(conn); - if (pbds.isEmpty()) { - continue; - } - final PBD pbd = pbds.iterator().next(); - final Map dc = pbd.getDeviceConfig(conn); - if (dc == null) { - continue; - } - if (dc.get("target") == null) { - continue; - } - if (dc.get("targetIQN") == null) { - continue; - } - if (dc.get("lunid") == null) { - continue; - } - if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) { - throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + dc.get("targetIQN") + - ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.uuid); - } - } - deviceConfig.put("target", target); - deviceConfig.put("targetIQN", targetiqn); - - if (StringUtils.isNotBlank(chapInitiatorUsername) && StringUtils.isNotBlank(chapInitiatorPassword)) { - deviceConfig.put("chapuser", chapInitiatorUsername); - deviceConfig.put("chappassword", chapInitiatorPassword); - } - - final Host host = Host.getByUuid(conn, _host.uuid); - final Map smConfig = new HashMap(); - final String type = SRType.LVMOISCSI.toString(); - SR sr = null; - try { - sr = SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, type, "user", true, smConfig); - } catch (final XenAPIException e) { - final String errmsg = e.toString(); - if (errmsg.contains("SR_BACKEND_FAILURE_107")) { - final String lun[] = errmsg.split(""); - boolean found = false; - for (int i = 1; i < lun.length; i++) { - final int blunindex = lun[i].indexOf("") + 7; - final int elunindex = lun[i].indexOf(""); - String ilun = lun[i].substring(blunindex, elunindex); - ilun = ilun.trim(); - if (ilun.equals(lunid)) { - final int bscsiindex = lun[i].indexOf("") + 8; - final int escsiindex = lun[i].indexOf(""); - scsiid = lun[i].substring(bscsiindex, escsiindex); - scsiid = scsiid.trim(); - found = true; - break; - } - } - if (!found) { - final String msg = "can not find LUN " + lunid + " in " + errmsg; - s_logger.warn(msg); - throw new CloudRuntimeException(msg); - } - } else { - final String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.toString(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } - } - deviceConfig.put("SCSIid", scsiid); - - final String result = SR.probe(conn, host, deviceConfig, type, smConfig); - String pooluuid = null; - if (result.indexOf("") != -1) { - pooluuid = result.substring(result.indexOf("") + 6, result.indexOf("")).trim(); - } - - if (pooluuid == null || pooluuid.length() != 36) { - sr = SR.create(conn, host, deviceConfig, new Long(0), srNameLabel, srNameLabel, type, "user", true, smConfig); - } else { - try { - sr = SR.introduce(conn, pooluuid, srNameLabel, srNameLabel, type, "user", true, smConfig); - } catch (final XenAPIException ex) { - if (ignoreIntroduceException) { - return sr; - } - - throw ex; - } - - final Set setHosts = Host.getAll(conn); - if(setHosts == null) { - final String msg = "Unable to create Iscsi SR " + deviceConfig + " due to hosts not available."; - s_logger.warn(msg); - throw new CloudRuntimeException(msg); - } - for (final Host currentHost : setHosts) { - final PBD.Record rec = new PBD.Record(); - - rec.deviceConfig = deviceConfig; - rec.host = currentHost; - rec.SR = sr; - - final PBD pbd = PBD.create(conn, rec); - - pbd.plug(conn); - } - } - sr.scan(conn); - return sr; - } catch (final XenAPIException e) { - final String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.toString(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); - } catch (final Exception e) { - final String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.getMessage(); - s_logger.warn(msg, e); - throw new CloudRuntimeException(msg, e); + } catch (final Exception e1) { + final String msg = "Unable to hardShutdown VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString(); + s_logger.warn(msg, e1); + throw new CloudRuntimeException(msg); } - } - } - - protected SR getNfsSR(final Connection conn, final String poolid, final String uuid, final String server, String serverpath, final String pooldesc) { - final Map deviceConfig = new HashMap(); - try { - serverpath = serverpath.replace("//", "/"); - final Set srs = SR.getAll(conn); - if(srs != null && !srs.isEmpty()) { - for (final SR sr : srs) { - if (!SRType.NFS.equals(sr.getType(conn))) { - continue; - } - - final Set pbds = sr.getPBDs(conn); - if (pbds.isEmpty()) { - continue; - } - - final PBD pbd = pbds.iterator().next(); - - final Map dc = pbd.getDeviceConfig(conn); - - if (dc == null) { - continue; - } - - if (dc.get("server") == null) { - continue; - } - - if (dc.get("serverpath") == null) { - continue; - } - - if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { - throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath") + - " for pool " + uuid + " on host:" + _host.uuid); - } - - } - } - deviceConfig.put("server", server); - deviceConfig.put("serverpath", serverpath); - final Host host = Host.getByUuid(conn, _host.uuid); - final Map smConfig = new HashMap(); - smConfig.put("nosubdir", "true"); - final SR sr = SR.create(conn, host, deviceConfig, new Long(0), uuid, poolid, SRType.NFS.toString(), "user", true, smConfig); - sr.scan(conn); - return sr; - } catch (final XenAPIException e) { - throw new CloudRuntimeException("Unable to create NFS SR " + pooldesc, e); - } catch (final XmlRpcException e) { - throw new CloudRuntimeException("Unable to create NFS SR " + pooldesc, e); - } - } - - public Answer execute(final DestroyCommand cmd) { - final Connection conn = getConnection(); - final VolumeTO vol = cmd.getVolume(); - // Look up the VDI - final String volumeUUID = vol.getPath(); - VDI vdi = null; - try { - vdi = getVDIbyUuid(conn, volumeUUID); - } catch (final Exception e) { - return new Answer(cmd, true, "Success"); - } - Set vbds = null; - try { - vbds = vdi.getVBDs(conn); - } catch (final Exception e) { - final String msg = "VDI getVBDS for " + volumeUUID + " failed due to " + e.toString(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } - for (final VBD vbd : vbds) { - try { - vbd.unplug(conn); - vbd.destroy(conn); - } catch (final Exception e) { - final String msg = "VM destroy for " + volumeUUID + " failed due to " + e.toString(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } - } - try { - final Set snapshots = vdi.getSnapshots(conn); - for (final VDI snapshot : snapshots) { - snapshot.destroy(conn); - } - vdi.destroy(conn); - } catch (final Exception e) { - final String msg = "VDI destroy for " + volumeUUID + " failed due to " + e.toString(); - s_logger.warn(msg, e); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd, true, "Success"); - } - - protected VDI createVdi(final SR sr, final String vdiNameLabel, final Long volumeSize) throws Types.XenAPIException, XmlRpcException { - final Connection conn = getConnection(); - - final VDI.Record vdir = new VDI.Record(); - - vdir.nameLabel = vdiNameLabel; - vdir.SR = sr; - vdir.type = Types.VdiType.USER; - - final long totalSrSpace = sr.getPhysicalSize(conn); - final long unavailableSrSpace = sr.getPhysicalUtilisation(conn); - final long availableSrSpace = totalSrSpace - unavailableSrSpace; - - if (availableSrSpace < volumeSize) { - throw new CloudRuntimeException("Available space for SR cannot be less than " + volumeSize + "."); - } - - vdir.virtualSize = volumeSize; - - return VDI.create(conn, vdir); - } - - protected void handleSrAndVdiDetach(final String iqn, final Connection conn) throws Exception { - final SR sr = getStorageRepository(conn, iqn); - - removeSR(conn, sr); - } - - protected AttachVolumeAnswer execute(final AttachVolumeCommand cmd) { - final Connection conn = getConnection(); - final boolean attach = cmd.getAttach(); - final String vmName = cmd.getVmName(); - final String vdiNameLabel = vmName + "-DATA"; - final Long deviceId = cmd.getDeviceId(); - - String errorMsg; - if (attach) { - errorMsg = "Failed to attach volume"; - } else { - errorMsg = "Failed to detach volume"; - } - - try { - VDI vdi = null; - - if (cmd.getAttach() && cmd.isManaged()) { - final SR sr = getIscsiSR(conn, cmd.get_iScsiName(), cmd.getStorageHost(), cmd.get_iScsiName(), cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), true); - - vdi = getVDIbyUuid(conn, cmd.getVolumePath(), false); - - if (vdi == null) { - vdi = createVdi(sr, vdiNameLabel, cmd.getVolumeSize()); - } - } else { - vdi = getVDIbyUuid(conn, cmd.getVolumePath()); - } - - // Look up the VM - final VM vm = getVM(conn, vmName); - if (attach) { - // Figure out the disk number to attach the VM to - String diskNumber = null; - if (deviceId != null) { - if (deviceId.longValue() == 3) { - final String msg = "Device 3 is reserved for CD-ROM, choose other device"; - return new AttachVolumeAnswer(cmd, msg); - } - if (isDeviceUsed(conn, vm, deviceId)) { - final String msg = "Device " + deviceId + " is used in VM " + vmName; - return new AttachVolumeAnswer(cmd, msg); - } - diskNumber = deviceId.toString(); - } else { - diskNumber = getUnusedDeviceNum(conn, vm); - } - // Create a new VBD - final VBD.Record vbdr = new VBD.Record(); - vbdr.VM = vm; - vbdr.VDI = vdi; - vbdr.bootable = false; - vbdr.userdevice = diskNumber; - vbdr.mode = Types.VbdMode.RW; - vbdr.type = Types.VbdType.DISK; - vbdr.unpluggable = true; - final VBD vbd = VBD.create(conn, vbdr); - - // Attach the VBD to the VM - vbd.plug(conn); - - // Update the VDI's label to include the VM name - vdi.setNameLabel(conn, vdiNameLabel); - - return new AttachVolumeAnswer(cmd, Long.parseLong(diskNumber), vdi.getUuid(conn)); - } else { - // Look up all VBDs for this VDI - final Set vbds = vdi.getVBDs(conn); - - // Detach each VBD from its VM, and then destroy it - for (final VBD vbd : vbds) { - final VBD.Record vbdr = vbd.getRecord(conn); - - if (vbdr.currentlyAttached) { - vbd.unplug(conn); - } - - vbd.destroy(conn); - } - - // Update the VDI's label to be "detached" - vdi.setNameLabel(conn, "detached"); - - if (cmd.isManaged()) { - handleSrAndVdiDetach(cmd.get_iScsiName(), conn); - } - - return new AttachVolumeAnswer(cmd); - } - } catch (final XenAPIException e) { - final String msg = errorMsg + " for uuid: " + cmd.getVolumePath() + " due to " + e.toString(); - s_logger.warn(msg, e); - return new AttachVolumeAnswer(cmd, msg); - } catch (final Exception e) { - final String msg = errorMsg + " for uuid: " + cmd.getVolumePath() + " due to " + e.getMessage(); - s_logger.warn(msg, e); - return new AttachVolumeAnswer(cmd, msg); - } - - } - - protected void umount(final Connection conn, final VDI vdi) { - - } - - private long getVMSnapshotChainSize(final Connection conn, final VolumeObjectTO volumeTo, final String vmName) throws BadServerResponse, XenAPIException, XmlRpcException { - final Set allvolumeVDIs = VDI.getByNameLabel(conn, volumeTo.getName()); - long size = 0; - for (final VDI vdi : allvolumeVDIs) { - try { - if (vdi.getIsASnapshot(conn) && vdi.getSmConfig(conn).get("vhd-parent") != null) { - final String parentUuid = vdi.getSmConfig(conn).get("vhd-parent"); - final VDI parentVDI = VDI.getByUuid(conn, parentUuid); - // add size of snapshot vdi node, usually this only contains meta data - size = size + vdi.getPhysicalUtilisation(conn); - // add size of snapshot vdi parent, this contains data - if (!isRefNull(parentVDI)) { - size = size + parentVDI.getPhysicalUtilisation(conn).longValue(); - } - } - } catch (final Exception e) { - s_logger.debug("Exception occurs when calculate snapshot capacity for volumes: due to " + e.toString()); - continue; - } - } - if (volumeTo.getVolumeType() == Volume.Type.ROOT) { - final Map allVMs = VM.getAllRecords(conn); - // add size of memory snapshot vdi - if (allVMs != null && allVMs.size() > 0) { - for (final VM vmr : allVMs.keySet()) { - try { - final String vName = vmr.getNameLabel(conn); - if (vName != null && vName.contains(vmName) && vmr.getIsASnapshot(conn)) { - final VDI memoryVDI = vmr.getSuspendVDI(conn); - if (!isRefNull(memoryVDI)) { - size = size + memoryVDI.getPhysicalUtilisation(conn); - final VDI pMemoryVDI = memoryVDI.getParent(conn); - if (!isRefNull(pMemoryVDI)) { - size = size + pMemoryVDI.getPhysicalUtilisation(conn); - } - } - } - } catch (final Exception e) { - s_logger.debug("Exception occurs when calculate snapshot capacity for memory: due to " + e.toString()); - continue; - } - } - } - } - return size; - } - - protected Answer execute(final CreateVMSnapshotCommand cmd) { - final String vmName = cmd.getVmName(); - final String vmSnapshotName = cmd.getTarget().getSnapshotName(); - final List listVolumeTo = cmd.getVolumeTOs(); - VmPowerState vmState = VmPowerState.HALTED; - final String guestOSType = cmd.getGuestOSType(); - final String platformEmulator = cmd.getPlatformEmulator(); - - final boolean snapshotMemory = cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory; - final long timeout = cmd.getWait(); - - final Connection conn = getConnection(); - VM vm = null; - VM vmSnapshot = null; - boolean success = false; - - try { - // check if VM snapshot already exists - final Set vmSnapshots = VM.getByNameLabel(conn, cmd.getTarget().getSnapshotName()); - if (vmSnapshots.size() > 0) { - return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), cmd.getVolumeTOs()); - } - - // check if there is already a task for this VM snapshot - Task task = null; - Set tasks = Task.getByNameLabel(conn, "Async.VM.snapshot"); - if(tasks == null) { - tasks = new LinkedHashSet<>(); - } - final Set tasksByName = Task.getByNameLabel(conn, "Async.VM.checkpoint"); - if(tasksByName != null) { - tasks.addAll(tasksByName); - } - for (final Task taskItem : tasks) { - if (taskItem.getOtherConfig(conn).containsKey("CS_VM_SNAPSHOT_KEY")) { - final String vmSnapshotTaskName = taskItem.getOtherConfig(conn).get("CS_VM_SNAPSHOT_KEY"); - if (vmSnapshotTaskName != null && vmSnapshotTaskName.equals(cmd.getTarget().getSnapshotName())) { - task = taskItem; - } - } - } - - // create a new task if there is no existing task for this VM snapshot - if (task == null) { - try { - vm = getVM(conn, vmName); - vmState = vm.getPowerState(conn); - } catch (final Exception e) { - if (!snapshotMemory) { - vm = createWorkingVM(conn, vmName, guestOSType, platformEmulator, listVolumeTo); - } - } - - if (vm == null) { - return new CreateVMSnapshotAnswer(cmd, false, "Creating VM Snapshot Failed due to can not find vm: " + vmName); - } - - // call Xenserver API - if (!snapshotMemory) { - task = vm.snapshotAsync(conn, vmSnapshotName); - } else { - final Set vbds = vm.getVBDs(conn); - final Pool pool = Pool.getByUuid(conn, _host.pool); - for (final VBD vbd : vbds) { - final VBD.Record vbdr = vbd.getRecord(conn); - if (vbdr.userdevice.equals("0")) { - final VDI vdi = vbdr.VDI; - final SR sr = vdi.getSR(conn); - // store memory image on the same SR with ROOT volume - pool.setSuspendImageSR(conn, sr); - } - } - task = vm.checkpointAsync(conn, vmSnapshotName); - } - task.addToOtherConfig(conn, "CS_VM_SNAPSHOT_KEY", vmSnapshotName); - } - - waitForTask(conn, task, 1000, timeout * 1000); - checkForSuccess(conn, task); - final String result = task.getResult(conn); - - // extract VM snapshot ref from result - final String ref = result.substring("".length(), result.length() - "".length()); - vmSnapshot = Types.toVM(ref); - try { - Thread.sleep(5000); - } catch (final InterruptedException ex) { - - } - // calculate used capacity for this VM snapshot - for (final VolumeObjectTO volumeTo : cmd.getVolumeTOs()) { - final long size = getVMSnapshotChainSize(conn, volumeTo, cmd.getVmName()); - volumeTo.setSize(size); - } - - success = true; - return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), cmd.getVolumeTOs()); - } catch (final Exception e) { - String msg = ""; - if (e instanceof Types.BadAsyncResult) { - final String licenseKeyWord = "LICENCE_RESTRICTION"; - final Types.BadAsyncResult errorResult = (Types.BadAsyncResult)e; - if (errorResult.shortDescription != null && errorResult.shortDescription.contains(licenseKeyWord)) { - msg = licenseKeyWord; - } - } else { - msg = e.toString(); - } - s_logger.warn("Creating VM Snapshot " + cmd.getTarget().getSnapshotName() + " failed due to: " + msg, e); - return new CreateVMSnapshotAnswer(cmd, false, msg); } finally { - try { - if (!success) { - if (vmSnapshot != null) { - s_logger.debug("Delete exsisting VM Snapshot " + vmSnapshotName + " after making VolumeTO failed"); - final Set vbds = vmSnapshot.getVBDs(conn); - for (final VBD vbd : vbds) { - final VBD.Record vbdr = vbd.getRecord(conn); - if (vbdr.type == Types.VbdType.DISK) { - final VDI vdi = vbdr.VDI; - vdi.destroy(conn); - } - } - vmSnapshot.destroy(conn); - } - } - if (vmState == VmPowerState.HALTED) { - if (vm != null) { - vm.destroy(conn); - } - } - } catch (final Exception e2) { - s_logger.error("delete snapshot error due to " + e2.getMessage()); - } - } - } - - private VM createWorkingVM(final Connection conn, final String vmName, final String guestOSType, final String platformEmulator, final List listVolumeTo) throws BadServerResponse, - Types.VmBadPowerState, Types.SrFull, - Types.OperationNotAllowed, XenAPIException, XmlRpcException { - //below is redundant but keeping for consistency and code readabilty - final String guestOsTypeName = platformEmulator; - if (guestOsTypeName == null) { - final String msg = - " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM"; - s_logger.warn(msg); - throw new CloudRuntimeException(msg); - } - final VM template = getVM(conn, guestOsTypeName); - final VM vm = template.createClone(conn, vmName); - vm.setIsATemplate(conn, false); - final Map vdiMap = new HashMap(); - for (final VolumeObjectTO volume : listVolumeTo) { - final String vdiUuid = volume.getPath(); - try { - final VDI vdi = VDI.getByUuid(conn, vdiUuid); - vdiMap.put(vdi, volume); - } catch (final Types.UuidInvalid e) { - s_logger.warn("Unable to find vdi by uuid: " + vdiUuid + ", skip it"); - } - } - for (final Map.Entryentry : vdiMap.entrySet()) { - final VDI vdi = entry.getKey(); - final VolumeObjectTO volumeTO = entry.getValue(); - final VBD.Record vbdr = new VBD.Record(); - vbdr.VM = vm; - vbdr.VDI = vdi; - if (volumeTO.getVolumeType() == Volume.Type.ROOT) { - vbdr.bootable = true; - vbdr.unpluggable = false; - } else { - vbdr.bootable = false; - vbdr.unpluggable = true; - } - vbdr.userdevice = Long.toString(volumeTO.getDeviceId()); - vbdr.mode = Types.VbdMode.RW; - vbdr.type = Types.VbdType.DISK; - VBD.create(conn, vbdr); - } - return vm; - } - - protected Answer execute(final DeleteVMSnapshotCommand cmd) { - final String snapshotName = cmd.getTarget().getSnapshotName(); - final Connection conn = getConnection(); - - try { - final List vdiList = new ArrayList(); - final Set snapshots = VM.getByNameLabel(conn, snapshotName); - if (snapshots.size() == 0) { - s_logger.warn("VM snapshot with name " + snapshotName + " does not exist, assume it is already deleted"); - return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs()); - } - final VM snapshot = snapshots.iterator().next(); - final Set vbds = snapshot.getVBDs(conn); - for (final VBD vbd : vbds) { - if (vbd.getType(conn) == Types.VbdType.DISK) { - final VDI vdi = vbd.getVDI(conn); - vdiList.add(vdi); - } - } - if (cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory) { - vdiList.add(snapshot.getSuspendVDI(conn)); - } - snapshot.destroy(conn); - for (final VDI vdi : vdiList) { - vdi.destroy(conn); - } - - try { - Thread.sleep(5000); - } catch (final InterruptedException ex) { - - } - // re-calculate used capacify for this VM snapshot - for (final VolumeObjectTO volumeTo : cmd.getVolumeTOs()) { - final long size = getVMSnapshotChainSize(conn, volumeTo, cmd.getVmName()); - volumeTo.setSize(size); - } - - return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs()); - } catch (final Exception e) { - s_logger.warn("Catch Exception: " + e.getClass().toString() + " due to " + e.toString(), e); - return new DeleteVMSnapshotAnswer(cmd, false, e.getMessage()); - } - } - - protected Answer execute(final AttachIsoCommand cmd) { - final Connection conn = getConnection(); - final boolean attach = cmd.isAttach(); - final String vmName = cmd.getVmName(); - final String isoURL = cmd.getIsoPath(); - - String errorMsg; - if (attach) { - errorMsg = "Failed to attach ISO"; - } else { - errorMsg = "Failed to detach ISO"; - } - try { - if (attach) { - VBD isoVBD = null; - - // Find the VM - final VM vm = getVM(conn, vmName); - - // Find the ISO VDI - final VDI isoVDI = getIsoVDIByURL(conn, vmName, isoURL); - - // Find the VM's CD-ROM VBD - final Set vbds = vm.getVBDs(conn); - for (final VBD vbd : vbds) { - final String userDevice = vbd.getUserdevice(conn); - final Types.VbdType type = vbd.getType(conn); - - if (userDevice.equals("3") && type == Types.VbdType.CD) { - isoVBD = vbd; - break; - } - } - - if (isoVBD == null) { - throw new CloudRuntimeException("Unable to find CD-ROM VBD for VM: " + vmName); - } else { - // If an ISO is already inserted, eject it - if (isoVBD.getEmpty(conn) == false) { - isoVBD.eject(conn); - } - - // Insert the new ISO - isoVBD.insert(conn, isoVDI); - } - - return new Answer(cmd); - } else { - // Find the VM - final VM vm = getVM(conn, vmName); - final String vmUUID = vm.getUuid(conn); - - // Find the ISO VDI - final VDI isoVDI = getIsoVDIByURL(conn, vmName, isoURL); - - final SR sr = isoVDI.getSR(conn); - - // Look up all VBDs for this VDI - final Set vbds = isoVDI.getVBDs(conn); - - // Iterate through VBDs, and if the VBD belongs the VM, eject - // the ISO from it - for (final VBD vbd : vbds) { - final VM vbdVM = vbd.getVM(conn); - final String vbdVmUUID = vbdVM.getUuid(conn); - - if (vbdVmUUID.equals(vmUUID)) { - // If an ISO is already inserted, eject it - if (!vbd.getEmpty(conn)) { - vbd.eject(conn); - } - - break; - } - } - - if (!sr.getNameLabel(conn).startsWith("XenServer Tools")) { - removeSR(conn, sr); - } - - return new Answer(cmd); - } - } catch (final XenAPIException e) { - s_logger.warn(errorMsg + ": " + e.toString(), e); - return new Answer(cmd, false, e.toString()); - } catch (final Exception e) { - s_logger.warn(errorMsg + ": " + e.toString(), e); - return new Answer(cmd, false, e.getMessage()); - } - } - - boolean IsISCSI(final String type) { - return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type); - } - - protected Answer execute(final UpgradeSnapshotCommand cmd) { - - final String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); - final String backedUpSnapshotUuid = cmd.getSnapshotUuid(); - final Long volumeId = cmd.getVolumeId(); - final Long accountId = cmd.getAccountId(); - final Long templateId = cmd.getTemplateId(); - final Long tmpltAcountId = cmd.getTmpltAccountId(); - final String version = cmd.getVersion(); - - if (!version.equals("2.1")) { - return new Answer(cmd, true, "success"); - } - try { - final Connection conn = getConnection(); - final URI uri = new URI(secondaryStorageUrl); - final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); - final String snapshotPath = secondaryStorageMountPath + "/snapshots/" + accountId + "/" + volumeId + "/" + backedUpSnapshotUuid + ".vhd"; - final String templatePath = secondaryStorageMountPath + "/template/tmpl/" + tmpltAcountId + "/" + templateId; - upgradeSnapshot(conn, templatePath, snapshotPath); - return new Answer(cmd, true, "success"); - } catch (final Exception e) { - final String details = "upgrading snapshot " + backedUpSnapshotUuid + " failed due to " + e.toString(); - s_logger.error(details, e); - - } - return new Answer(cmd, false, "failure"); - } - - private boolean destroySnapshotOnPrimaryStorageExceptThis(final Connection conn, final String volumeUuid, final String avoidSnapshotUuid) { - try { - final VDI volume = getVDIbyUuid(conn, volumeUuid); - if (volume == null) { - throw new InternalErrorException("Could not destroy snapshot on volume " + volumeUuid + " due to can not find it"); - } - final Set snapshots = volume.getSnapshots(conn); - for (final VDI snapshot : snapshots) { + if (task != null) { try { - if (!snapshot.getUuid(conn).equals(avoidSnapshotUuid)) { - snapshot.destroy(conn); - } - } catch (final Exception e) { - final String msg = "Destroying snapshot: " + snapshot + " on primary storage failed due to " + e.toString(); - s_logger.warn(msg, e); + task.destroy(conn); + } catch (final Exception e1) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString()); } } - s_logger.debug("Successfully destroyed snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid); - return true; - } catch (final XenAPIException e) { - final String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString(); - s_logger.error(msg, e); - } catch (final Exception e) { - final String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString(); - s_logger.warn(msg, e); } - - return false; - } - - protected VM getVM(final Connection conn, final String vmName) { - // Look up VMs with the specified name - Set vms; - try { - vms = VM.getByNameLabel(conn, vmName); - } catch (final XenAPIException e) { - throw new CloudRuntimeException("Unable to get " + vmName + ": " + e.toString(), e); - } catch (final Exception e) { - throw new CloudRuntimeException("Unable to get " + vmName + ": " + e.getMessage(), e); - } - - // If there are no VMs, throw an exception - if (vms.size() == 0) { - throw new CloudRuntimeException("VM with name: " + vmName + " does not exist."); - } - - // If there is more than one VM, print a warning - if (vms.size() > 1) { - s_logger.warn("Found " + vms.size() + " VMs with name: " + vmName); - } - - // Return the first VM in the set - return vms.iterator().next(); - } - - protected VDI getIsoVDIByURL(final Connection conn, final String vmName, final String isoURL) { - SR isoSR = null; - String mountpoint = null; - if (isoURL.startsWith("xs-tools")) { - try { - final Set vdis = VDI.getByNameLabel(conn, isoURL); - if (vdis.isEmpty()) { - throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL); - } - return vdis.iterator().next(); - - } catch (final XenAPIException e) { - throw new CloudRuntimeException("Unable to get pv iso: " + isoURL + " due to " + e.toString()); - } catch (final Exception e) { - throw new CloudRuntimeException("Unable to get pv iso: " + isoURL + " due to " + e.toString()); - } - } - - final int index = isoURL.lastIndexOf("/"); - mountpoint = isoURL.substring(0, index); - - URI uri; - try { - uri = new URI(mountpoint); - } catch (final URISyntaxException e) { - throw new CloudRuntimeException("isoURL is wrong: " + isoURL); - } - isoSR = getISOSRbyVmName(conn, vmName); - if (isoSR == null) { - isoSR = createIsoSRbyURI(conn, uri, vmName, false); - } - - final String isoName = isoURL.substring(index + 1); - - final VDI isoVDI = getVDIbyLocationandSR(conn, isoName, isoSR); - - if (isoVDI != null) { - return isoVDI; - } else { - throw new CloudRuntimeException("Could not find ISO with URL: " + isoURL); - } - } - - protected SR getStorageRepository(final Connection conn, final String srNameLabel) { - Set srs; - try { - srs = SR.getByNameLabel(conn, srNameLabel); - } catch (final XenAPIException e) { - throw new CloudRuntimeException("Unable to get SR " + srNameLabel + " due to " + e.toString(), e); - } catch (final Exception e) { - throw new CloudRuntimeException("Unable to get SR " + srNameLabel + " due to " + e.getMessage(), e); - } - - if (srs.size() > 1) { - throw new CloudRuntimeException("More than one storage repository was found for pool with uuid: " + srNameLabel); - } else if (srs.size() == 1) { - final SR sr = srs.iterator().next(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("SR retrieved for " + srNameLabel); - } - - if (checkSR(conn, sr)) { - return sr; - } - throw new CloudRuntimeException("SR check failed for storage pool: " + srNameLabel + "on host:" + _host.uuid); - } else { - throw new CloudRuntimeException("Can not see storage pool: " + srNameLabel + " from on host:" + _host.uuid); - } - } - - 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 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)); - 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 boolean createSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String newFolder) { - final String result = callHostPlugin(conn, "vmopsSnapshot", "create_secondary_storage_folder", "remoteMountPath", remoteMountPath, "newFolder", newFolder); - return result != null; - } - - protected boolean deleteSecondaryStorageFolder(final Connection conn, final String remoteMountPath, final String folder) { - final String details = callHostPlugin(conn, "vmopsSnapshot", "delete_secondary_storage_folder", "remoteMountPath", remoteMountPath, "folder", folder); - return details != null && details.equals("1"); - } - - protected boolean postCreatePrivateTemplate(final Connection conn, final String templatePath, final String tmpltFilename, final String templateName, String templateDescription, - String checksum, final long size, final long virtualSize, final long templateId) { - - if (templateDescription == null) { - templateDescription = ""; - } - - if (checksum == null) { - checksum = ""; - } - - final String result = - callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", - templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), - "templateId", String.valueOf(templateId)); - - boolean success = false; - if (result != null && !result.isEmpty()) { - // Else, command threw an exception which has already been logged. - - if (result.equalsIgnoreCase("1")) { - s_logger.debug("Successfully created template.properties file on secondary storage for " + tmpltFilename); - success = true; - } else { - s_logger.warn("Could not create template.properties file on secondary storage for " + tmpltFilename + " for templateId: " + templateId); - } - } - - return success; - } - - protected String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) { - final String parentUuid = - callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", - isISCSI.toString()); - - if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) { - s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid); - // errString is already logged. - return null; - } - return parentUuid; - } - - protected String deleteSnapshotBackup(final Connection conn, final Long dcId, final Long accountId, final Long volumeId, final String secondaryStorageMountPath, final String backupUUID) { - - // If anybody modifies the formatting below again, I'll skin them - final String result = - callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), - "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath); - - return result; } @Override @@ -6888,453 +4740,201 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return true; } + public void startVM(final Connection conn, final Host host, final VM vm, final String vmName) throws Exception { + Task task = null; + try { + task = vm.startOnAsync(conn, host, false, true); + try { + // poll every 1 seconds , timeout after 10 minutes + waitForTask(conn, task, 1000, 10 * 60 * 1000); + checkForSuccess(conn, task); + } catch (final Types.HandleInvalid e) { + if (vm.getPowerState(conn) == VmPowerState.RUNNING) { + s_logger.debug("VM " + vmName + " is in Running status"); + task = null; + return; + } + throw new CloudRuntimeException("Start VM " + vmName + " catch HandleInvalid and VM is not in RUNNING state"); + } catch (final TimeoutException e) { + if (vm.getPowerState(conn) == VmPowerState.RUNNING) { + s_logger.debug("VM " + vmName + " is in Running status"); + task = null; + return; + } + throw new CloudRuntimeException("Start VM " + vmName + " catch BadAsyncResult and VM is not in RUNNING state"); + } + } catch (final XenAPIException e) { + final String msg = "Unable to start VM(" + vmName + ") on host(" + _host.getUuid() + ") due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg); + } finally { + if (task != null) { + try { + task.destroy(conn); + } catch (final Exception e1) { + s_logger.debug("unable to destroy task(" + task.toString() + ") on host(" + _host.getUuid() + ") due to " + e1.toString()); + } + } + } + } + + protected void startvmfailhandle(final Connection conn, final VM vm, final List> mounts) { + if (vm != null) { + try { + + if (vm.getPowerState(conn) == VmPowerState.RUNNING) { + try { + vm.hardShutdown(conn); + } catch (final Exception e) { + final String msg = "VM hardshutdown failed due to " + e.toString(); + s_logger.warn(msg, e); + } + } + if (vm.getPowerState(conn) == VmPowerState.HALTED) { + try { + vm.destroy(conn); + } catch (final Exception e) { + final String msg = "VM destroy failed due to " + e.toString(); + s_logger.warn(msg, e); + } + } + } catch (final Exception e) { + final String msg = "VM getPowerState failed due to " + e.toString(); + s_logger.warn(msg, e); + } + } + if (mounts != null) { + for (final Ternary mount : mounts) { + final VDI vdi = mount.second(); + Set vbds = null; + try { + vbds = vdi.getVBDs(conn); + } catch (final Exception e) { + final String msg = "VDI getVBDS failed due to " + e.toString(); + s_logger.warn(msg, e); + continue; + } + for (final VBD vbd : vbds) { + try { + vbd.unplug(conn); + vbd.destroy(conn); + } catch (final Exception e) { + final String msg = "VBD destroy failed due to " + e.toString(); + s_logger.warn(msg, e); + } + } + } + } + } + @Override public boolean stop() { disconnected(); return true; } - @Override - public String getName() { - return _name; - } + private HashMap> syncNetworkGroups(final Connection conn, final long id) { + final HashMap> states = new HashMap>(); - @Override - public IAgentControl getAgentControl() { - return _agentControl; - } - - @Override - public void setAgentControl(final IAgentControl agentControl) { - _agentControl = agentControl; - } - - private Answer execute(final CleanupNetworkRulesCmd cmd) { - if (!_canBridgeFirewall) { - return new Answer(cmd, true, null); - } - final Connection conn = getConnection(); - final String result = callHostPlugin(conn, "vmops", "cleanup_rules", "instance", _instance); - final int numCleaned = Integer.parseInt(result); - if (result == null || result.isEmpty() || numCleaned < 0) { - s_logger.warn("Failed to cleanup rules for host " + _host.ip); - return new Answer(cmd, false, result); - } - if (numCleaned > 0) { - s_logger.info("Cleaned up rules for " + result + " vms on host " + _host.ip); - } - return new Answer(cmd, true, result); - } - - /** - * XsNic represents a network and the host's specific PIF. - */ - protected class XsLocalNetwork { - private final Network _n; - private Network.Record _nr; - private PIF _p; - private PIF.Record _pr; - - public XsLocalNetwork(final Network n) { - this(n, null, null, null); - } - - public XsLocalNetwork(final Network n, final Network.Record nr, final PIF p, final PIF.Record pr) { - _n = n; - _nr = nr; - _p = p; - _pr = pr; - } - - public Network getNetwork() { - return _n; - } - - public Network.Record getNetworkRecord(final Connection conn) throws XenAPIException, XmlRpcException { - if (_nr == null) { - _nr = _n.getRecord(conn); + final String result = callHostPlugin(conn, "vmops", "get_rule_logs_for_vms", "host_uuid", _host.getUuid()); + s_logger.trace("syncNetworkGroups: id=" + id + " got: " + result); + 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; + } + // output = ','.join([vmName, vmID, vmIP, domID, signature, seqno]) + try { + states.put(log[0], new Pair(Long.parseLong(log[1]), Long.parseLong(log[5]))); + } catch (final NumberFormatException nfe) { + states.put(log[0], new Pair(-1L, -1L)); } - - return _nr; } + return states; + } - public PIF getPif(final Connection conn) throws XenAPIException, XmlRpcException { - if (_p == null) { - final Network.Record nr = getNetworkRecord(conn); - for (final PIF pif : nr.PIFs) { - final PIF.Record pr = pif.getRecord(conn); - if (_host.uuid.equals(pr.host.getUuid(conn))) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found a network called " + nr.nameLabel + " on host=" + _host.ip + "; Network=" + nr.uuid + "; pif=" + pr.uuid); - } - _p = pif; - _pr = pr; - break; - } + public boolean transferManagementNetwork(final Connection conn, final Host host, final PIF src, final PIF.Record spr, final PIF dest) throws XmlRpcException, XenAPIException { + dest.reconfigureIp(conn, spr.ipConfigurationMode, spr.IP, spr.netmask, spr.gateway, spr.DNS); + Host.managementReconfigure(conn, dest); + String hostUuid = null; + final int count = 0; + while (count < 10) { + try { + Thread.sleep(10000); + hostUuid = host.getUuid(conn); + if (hostUuid != null) { + break; } - } - return _p; - } - - public PIF.Record getPifRecord(final Connection conn) throws XenAPIException, XmlRpcException { - if (_pr == null) { - final PIF p = getPif(conn); - if (_pr == null) { - _pr = p.getRecord(conn); - } - } - return _pr; - } - } - - // A list of UUIDs that are gathered from the XenServer when - // the resource first connects to XenServer. These UUIDs do - // not change over time. - protected class XsHost { - public String systemvmisouuid; - public String uuid; - public String ip; - public String publicNetwork; - public String privateNetwork; - public String linkLocalNetwork; - public Network vswitchNetwork; - public String storageNetwork1; - public String guestNetwork; - public String guestPif; - public String publicPif; - public String privatePif; - public String storagePif1; - public String storagePif2; - public String pool; - public int speed; - public Integer cpuSockets; - public int cpus; - public String productVersion; - public String localSRuuid; - - @Override - public String toString() { - return new StringBuilder("XS[").append(uuid).append("-").append(ip).append("]").toString(); - } - } - - - protected String getGuestOsType(final String stdType, String platformEmulator, final boolean bootFromCD) { - if (platformEmulator == null) { - s_logger.debug("no guest OS type, start it as HVM guest"); - platformEmulator = "Other install media"; - } - return platformEmulator; - } - - private Answer execute(final NetworkRulesSystemVmCommand cmd) { - boolean success = true; - final Connection conn = getConnection(); - if (cmd.getType() != VirtualMachine.Type.User) { - final String result = callHostPlugin(conn, "vmops", "default_network_rules_systemvm", "vmName", cmd.getVmName()); - if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { - success = false; + } catch (final XmlRpcException e) { + s_logger.debug("Waiting for host to come back: " + e.getMessage()); + } catch (final XenAPIException e) { + s_logger.debug("Waiting for host to come back: " + e.getMessage()); + } catch (final InterruptedException e) { + s_logger.debug("Gotta run"); + return false; } } - - return new Answer(cmd, success, ""); - } - - private Answer execute(final NetworkRulesVmSecondaryIpCommand cmd) { - boolean success = true; - final Connection conn = getConnection(); - - final String result = - callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", cmd.getVmName(), "vmMac", cmd.getVmMac(), "vmSecIp", cmd.getVmSecIp(), "action", - cmd.getAction()); - if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { - success = false; + if (hostUuid == null) { + s_logger.warn("Unable to transfer the management network from " + spr.uuid); + return false; } - return new Answer(cmd, success, ""); + src.reconfigureIp(conn, Types.IpConfigurationMode.NONE, null, null, null, null); + return true; } - protected ClusterVMMetaDataSyncAnswer execute(final ClusterVMMetaDataSyncCommand cmd) { - final Connection conn = getConnection(); - //check if this is master - Pool pool; + protected void umount(final Connection conn, final VDI vdi) { + + } + + public void umountSnapshotDir(final Connection conn, final Long dcId) { try { - pool = Pool.getByUuid(conn, _host.pool); - final Pool.Record poolr = pool.getRecord(conn); - final Host.Record hostr = poolr.master.getRecord(conn); - if (!_host.uuid.equals(hostr.uuid)) { - return new ClusterVMMetaDataSyncAnswer(cmd.getClusterId(), null); - } - } catch (final Throwable e) { - s_logger.warn("Check for master failed, failing the Cluster sync VMMetaData command"); - return new ClusterVMMetaDataSyncAnswer(cmd.getClusterId(), null); + callHostPlugin(conn, "vmopsSnapshot", "unmountSnapshotsDir", "dcId", dcId.toString()); + } catch (final Exception e) { + s_logger.debug("Failed to umount snapshot dir", e); } - final HashMap vmMetadatum = clusterVMMetaDataSync(conn); - return new ClusterVMMetaDataSyncAnswer(cmd.getClusterId(), vmMetadatum); } - protected 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.uuid + " due to to " + e.toString(); - s_logger.warn(msg, e); + public String upgradeSnapshot(final Connection conn, final String templatePath, final String snapshotPath) { + final String results = callHostPluginAsync(conn, "vmopspremium", "upgrade_snapshot", 2 * 60 * 60, "templatePath", templatePath, "snapshotPath", snapshotPath); + + if (results == null || results.isEmpty()) { + final String msg = "upgrade_snapshot return null"; + s_logger.warn(msg); throw new CloudRuntimeException(msg); } - return vmMetaDatum; - } - - /** - * @param cmd - * @return - */ - private UnPlugNicAnswer execute(final UnPlugNicCommand cmd) { - final Connection conn = getConnection(); - final String vmName = cmd.getVmName(); - try { - final Set vms = VM.getByNameLabel(conn, vmName); - if (vms == null || vms.isEmpty()) { - return new UnPlugNicAnswer(cmd, false, "Can not find VM " + vmName); - } - final VM vm = vms.iterator().next(); - final NicTO nic = cmd.getNic(); - final String mac = nic.getMac(); - final VIF vif = getVifByMac(conn, vm, mac); - if (vif != null) { - vif.unplug(conn); - final Network network = vif.getNetwork(conn); - vif.destroy(conn); - try { - if (network.getNameLabel(conn).startsWith("VLAN")) { - disableVlanNetwork(conn, network); - } - } catch (final Exception e) { - } - } - return new UnPlugNicAnswer(cmd, true, "success"); - } catch (final Exception e) { - final String msg = " UnPlug Nic failed due to " + e.toString(); - s_logger.warn(msg, e); - return new UnPlugNicAnswer(cmd, false, msg); - } - } - - /** - * @param cmd - * @return - */ - private PlugNicAnswer execute(final PlugNicCommand cmd) { - final Connection conn = getConnection(); - final String vmName = cmd.getVmName(); - try { - final Set vms = VM.getByNameLabel(conn, vmName); - if (vms == null || vms.isEmpty()) { - return new PlugNicAnswer(cmd, false, "Can not find VM " + vmName); - } - final VM vm = vms.iterator().next(); - final NicTO nic = cmd.getNic(); - - String mac = nic.getMac(); - final Set routerVIFs = vm.getVIFs(conn); - mac = mac.trim(); - - int counter = 0; - for (final VIF vif : routerVIFs) { - final String lmac = vif.getMAC(conn); - if (lmac.trim().equals(mac)) { - counter++; - } - } - // We allow 2 routers with the same mac. It's needed for the redundant vpc routers. - // [FIXME] Find a way to identify the type of the router or if it's redundant. - if (counter > 2) { - final String msg = " Plug Nic failed due to a VIF with the same mac " + nic.getMac() + " exists in more than 2 routers."; - s_logger.error(msg); - return new PlugNicAnswer(cmd, false, msg); - } - - // Wilder Rodrigues - replaced this code with the code above. - // VIF vif = getVifByMac(conn, vm, nic.getMac()); - // if (vif != null) { - // final String msg = " Plug Nic failed due to a VIF with the same mac " + nic.getMac() + " exists"; - // s_logger.warn(msg); - // return new PlugNicAnswer(cmd, false, msg); - // } - - final String deviceId = getLowestAvailableVIFDeviceNum(conn, vm); - nic.setDeviceId(Integer.parseInt(deviceId)); - final VIF vif = createVif(conn, vmName, vm, null, nic); - // vif = createVif(conn, vmName, vm, null, nic); - vif.plug(conn); - return new PlugNicAnswer(cmd, true, "success"); - } catch (final Exception e) { - final String msg = " Plug Nic failed due to " + e.toString(); - s_logger.error(msg, e); - return new PlugNicAnswer(cmd, false, msg); - } - } - - /** - * @param cmd - * @return - */ - private ExecutionResult prepareNetworkElementCommand(final SetupGuestNetworkCommand cmd) { - final Connection conn = getConnection(); - final NicTO nic = cmd.getNic(); - final String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - try { - final Set vms = VM.getByNameLabel(conn, domrName); - if (vms == null || vms.isEmpty()) { - return new ExecutionResult(false, "Can not find VM " + domrName); - } - final VM vm = vms.iterator().next(); - final String mac = nic.getMac(); - VIF domrVif = null; - for (final VIF vif : vm.getVIFs(conn)) { - final String lmac = vif.getMAC(conn); - if (lmac.equals(mac)) { - domrVif = vif; - //Do not break it! We have 2 routers. - //break; - } - } - if (domrVif == null) { - return new ExecutionResult(false, "Can not find vif with mac " + mac + " for VM " + domrName); - } - - nic.setDeviceId(Integer.valueOf(domrVif.getDevice(conn))); - } catch (final Exception e) { - final String msg = "Creating guest network failed due to " + e.toString(); - s_logger.warn(msg, e); - return new ExecutionResult(false, msg); - } - return new ExecutionResult(true, null); - } - - protected ExecutionResult prepareNetworkElementCommand(final IpAssocVpcCommand cmd) { - final Connection conn = getConnection(); - final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - try { - final IpAddressTO[] ips = cmd.getIpAddresses(); - for (final IpAddressTO ip : ips) { - - final VM router = getVM(conn, routerName); - - final VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress()); - setNicDevIdIfCorrectVifIsNotNull(conn, ip, correctVif); - } - } catch (final Exception e) { - s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - return new ExecutionResult(false, e.getMessage()); - } - - return new ExecutionResult(true, null); - } - - protected void setNicDevIdIfCorrectVifIsNotNull(final Connection conn, final IpAddressTO ip, final VIF correctVif) throws InternalErrorException, BadServerResponse, XenAPIException, - XmlRpcException { - if (correctVif == null) { - if (ip.isAdd()) { - throw new InternalErrorException("Failed to find DomR VIF to associate IP with."); - } else { - s_logger.debug("VIF to deassociate IP with does not exist, return success"); - } + final String[] tmp = results.split("#"); + final String status = tmp[0]; + if (status.equals("0")) { + return results; } else { - ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); + s_logger.warn(results); + throw new CloudRuntimeException(results); } } - protected ExecutionResult prepareNetworkElementCommand(final SetSourceNatCommand cmd) { - final Connection conn = getConnection(); - final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - final IpAddressTO pubIp = cmd.getIpAddress(); - try { - final VM router = getVM(conn, routerName); - - final VIF correctVif = getCorrectVif(conn, router, pubIp); - - pubIp.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); - - } catch (final Exception e) { - final String msg = "Ip SNAT failure due to " + e.toString(); - s_logger.error(msg, e); - return new ExecutionResult(false, msg); + public void waitForTask(final Connection c, final Task task, final long pollInterval, final long timeout) throws XenAPIException, XmlRpcException, TimeoutException { + final long beginTime = System.currentTimeMillis(); + if (s_logger.isTraceEnabled()) { + s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout + + "ms timeout"); } - return new ExecutionResult(true, null); - } - - protected ExecutionResult prepareNetworkElementCommand(final SetNetworkACLCommand cmd) { - final Connection conn = getConnection(); - final String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - - try { - final VM router = getVM(conn, routerName); - - final NicTO nic = cmd.getNic(); - if(nic != null) { - final VIF vif = getVifByMac(conn, router, nic.getMac()); - if(vif == null) { - final String msg = "Prepare SetNetworkACL failed due to VIF is null for : " + nic.getMac() +" with routername: " + routerName; - s_logger.error(msg); - return new ExecutionResult(false, msg); + while (task.getStatus(c) == Types.TaskStatusType.PENDING) { + try { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") is pending, sleeping for " + pollInterval + "ms"); } - nic.setDeviceId(Integer.valueOf(vif.getDevice(conn))); - } else { - final String msg = "Prepare SetNetworkACL failed due to nic is null for : " + routerName; - s_logger.error(msg); - return new ExecutionResult(false, msg); + Thread.sleep(pollInterval); + } catch (final InterruptedException e) { + } + if (System.currentTimeMillis() - beginTime > timeout) { + final String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString(); + s_logger.warn(msg); + task.cancel(c); + task.destroy(c); + throw new TimeoutException(msg); } - } catch (final Exception e) { - final String msg = "Prepare SetNetworkACL failed due to " + e.toString(); - s_logger.error(msg, e); - return new ExecutionResult(false, msg); } - return new ExecutionResult(true, null); } - - @Override - public void setName(final String name) { - } - - @Override - public void setConfigParams(final Map params) { - } - - @Override - public Map getConfigParams() { - return null; - } - - @Override - public int getRunLevel() { - return 0; - } - - @Override - public void setRunLevel(final int level) { - } - - private boolean is_xcp() { - final Connection conn = getConnection(); - final String result = callHostPlugin(conn, "ovstunnel", "is_xcp"); - if (result.equals("XCP")) { - return true; - } - return false; - } - - private String getLabel() { - final Connection conn = getConnection(); - final String result = callHostPlugin(conn, "ovstunnel", "getLabel"); - return result; - } -} +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java index 1a6de1f2daa..540044e5d04 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpOssResource.java @@ -27,15 +27,6 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.SR; -import com.xensource.xenapi.Types; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VBD; -import com.xensource.xenapi.VDI; -import com.xensource.xenapi.VM; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.NetworkUsageAnswer; @@ -49,6 +40,14 @@ import com.cloud.resource.ServerResource; import com.cloud.storage.Storage; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; @Local(value = ServerResource.class) public class XcpOssResource extends CitrixResourceBase { @@ -57,55 +56,55 @@ public class XcpOssResource extends CitrixResourceBase { @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xcposs/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xcposs/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } @Override - protected void fillHostInfo(Connection conn, StartupRoutingCommand cmd) { + protected void fillHostInfo(final Connection conn, final StartupRoutingCommand cmd) { super.fillHostInfo(conn, cmd); cmd.setCaps(cmd.getCapabilities() + " , hvm"); } @Override - protected boolean launchHeartBeat(Connection conn) { + public boolean launchHeartBeat(final Connection conn) { return true; } @Override - protected StartupStorageCommand initializeLocalSR(Connection conn) { - SR extsr = getLocalEXTSR(conn); + protected StartupStorageCommand initializeLocalSR(final Connection conn) { + final SR extsr = getLocalEXTSR(conn); if (extsr != null) { try { - String extuuid = extsr.getUuid(conn); - _host.localSRuuid = extuuid; - long cap = extsr.getPhysicalSize(conn); + final String extuuid = extsr.getUuid(conn); + _host.setLocalSRuuid(extuuid); + final long cap = extsr.getPhysicalSize(conn); if (cap > 0) { - long avail = cap - extsr.getPhysicalUtilisation(conn); - String name = "Cloud Stack Local EXT Storage Pool for " + _host.uuid; + final long avail = cap - extsr.getPhysicalUtilisation(conn); + final String name = "Cloud Stack Local EXT Storage Pool for " + _host.getUuid(); extsr.setNameDescription(conn, name); - Host host = Host.getByUuid(conn, _host.uuid); - String address = host.getAddress(conn); - StoragePoolInfo pInfo = new StoragePoolInfo(extsr.getNameLabel(conn), address, SRType.EXT.toString(), SRType.EXT.toString(), Storage.StoragePoolType.EXT, cap, avail); - StartupStorageCommand cmd = new StartupStorageCommand(); + final Host host = Host.getByUuid(conn, _host.getUuid()); + final String address = host.getAddress(conn); + final StoragePoolInfo pInfo = new StoragePoolInfo(extsr.getNameLabel(conn), address, SRType.EXT.toString(), SRType.EXT.toString(), Storage.StoragePoolType.EXT, cap, avail); + final StartupStorageCommand cmd = new StartupStorageCommand(); cmd.setPoolInfo(pInfo); - cmd.setGuid(_host.uuid); + cmd.setGuid(_host.getUuid()); cmd.setDataCenter(Long.toString(_dcId)); cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); return cmd; } - } catch (XenAPIException e) { - String msg = "build local EXT info err in host:" + _host.uuid + e.toString(); + } catch (final XenAPIException e) { + final String msg = "build local EXT info err in host:" + _host.getUuid() + e.toString(); s_logger.warn(msg); - } catch (XmlRpcException e) { - String msg = "build local EXT info err in host:" + _host.uuid + e.getMessage(); + } catch (final XmlRpcException e) { + final String msg = "build local EXT info err in host:" + _host.getUuid() + e.getMessage(); s_logger.warn(msg); } } @@ -113,7 +112,7 @@ public class XcpOssResource extends CitrixResourceBase { } @Override - protected String getGuestOsType(String stdType, String platformEmulator, boolean bootFromCD) { + protected String getGuestOsType(final String stdType, final String platformEmulator, final boolean bootFromCD) { if (stdType.equalsIgnoreCase("Debian GNU/Linux 6(64-bit)")) { return "Debian Squeeze 6.0 (64-bit)"; } else if (stdType.equalsIgnoreCase("CentOS 5.6 (64-bit)")) { @@ -124,21 +123,21 @@ public class XcpOssResource extends CitrixResourceBase { } @Override - protected synchronized VBD createPatchVbd(Connection conn, String vmName, VM vm) throws XmlRpcException, XenAPIException { - if (_host.localSRuuid != null) { + public synchronized VBD createPatchVbd(final Connection conn, final String vmName, final VM vm) throws XmlRpcException, XenAPIException { + if (_host.getLocalSRuuid() != null) { //create an iso vdi on it - String result = callHostPlugin(conn, "vmops", "createISOVHD", "uuid", _host.localSRuuid); + final String result = callHostPlugin(conn, "vmops", "createISOVHD", "uuid", _host.getLocalSRuuid()); if (result == null || result.equalsIgnoreCase("Failed")) { throw new CloudRuntimeException("can not create systemvm vdi"); } - Set vdis = VDI.getByNameLabel(conn, "systemvm-vdi"); + final Set vdis = VDI.getByNameLabel(conn, "systemvm-vdi"); if (vdis.size() != 1) { throw new CloudRuntimeException("can not find systemvmiso"); } - VDI systemvmVDI = vdis.iterator().next(); + final VDI systemvmVDI = vdis.iterator().next(); - VBD.Record cdromVBDR = new VBD.Record(); + final VBD.Record cdromVBDR = new VBD.Record(); cdromVBDR.VM = vm; cdromVBDR.empty = false; cdromVBDR.bootable = false; @@ -146,32 +145,32 @@ public class XcpOssResource extends CitrixResourceBase { cdromVBDR.mode = Types.VbdMode.RO; cdromVBDR.type = Types.VbdType.DISK; cdromVBDR.VDI = systemvmVDI; - VBD cdromVBD = VBD.create(conn, cdromVBDR); + final VBD cdromVBD = VBD.create(conn, cdromVBDR); return cdromVBD; } else { throw new CloudRuntimeException("can not find local sr"); } } - protected NetworkUsageAnswer execute(NetworkUsageCommand cmd) { + protected NetworkUsageAnswer execute(final NetworkUsageCommand cmd) { try { - Connection conn = getConnection(); + final Connection conn = getConnection(); if (cmd.getOption() != null && cmd.getOption().equals("create")) { - String result = networkUsage(conn, cmd.getPrivateIP(), "create", null); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); + final String result = networkUsage(conn, cmd.getPrivateIP(), "create", null); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); return answer; } - long[] stats = getNetworkStats(conn, cmd.getPrivateIP()); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); + final long[] stats = getNetworkStats(conn, cmd.getPrivateIP()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); return answer; - } catch (Exception ex) { + } catch (final Exception ex) { s_logger.warn("Failed to get network usage stats due to ", ex); return new NetworkUsageAnswer(cmd, ex); } } @Override - public Answer executeRequest(Command cmd) { + public Answer executeRequest(final Command cmd) { if (cmd instanceof NetworkUsageCommand) { return execute((NetworkUsageCommand) cmd); } else { @@ -180,18 +179,18 @@ public class XcpOssResource extends CitrixResourceBase { } @Override - public StopAnswer execute(StopCommand cmd) { - StopAnswer answer = super.execute(cmd); - String vmName = cmd.getVmName(); + public StopAnswer execute(final StopCommand cmd) { + final StopAnswer answer = super.execute(cmd); + final String vmName = cmd.getVmName(); if (vmName.startsWith("v-")) { - Connection conn = getConnection(); + final Connection conn = getConnection(); callHostPlugin(conn, "vmops", "setDNATRule", "add", "false"); } return answer; } @Override - protected void setMemory(Connection conn, VM vm, long minMemsize, long maxMemsize) throws XmlRpcException, XenAPIException { + protected void setMemory(final Connection conn, final VM vm, final long minMemsize, final long maxMemsize) throws XmlRpcException, XenAPIException { vm.setMemoryLimits(conn, mem_32m, maxMemsize, minMemsize, maxMemsize); } } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java index 782a530d2e0..4b2936eb720 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XcpServerResource.java @@ -25,11 +25,6 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VM; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.NetworkUsageAnswer; @@ -37,19 +32,22 @@ import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VM; @Local(value = ServerResource.class) public class XcpServerResource extends CitrixResourceBase { private final static Logger s_logger = Logger.getLogger(XcpServerResource.class); private static final long mem_32m = 33554432L; - private String version; public XcpServerResource() { super(); } @Override - public Answer executeRequest(Command cmd) { + public Answer executeRequest(final Command cmd) { if (cmd instanceof NetworkUsageCommand) { return execute((NetworkUsageCommand)cmd); } else { @@ -59,29 +57,29 @@ public class XcpServerResource extends CitrixResourceBase { @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xcpserver/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xcpserver/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } - protected NetworkUsageAnswer execute(NetworkUsageCommand cmd) { + protected NetworkUsageAnswer execute(final NetworkUsageCommand cmd) { try { - Connection conn = getConnection(); + final Connection conn = getConnection(); if (cmd.getOption() != null && cmd.getOption().equals("create")) { - String result = networkUsage(conn, cmd.getPrivateIP(), "create", null); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); + final String result = networkUsage(conn, cmd.getPrivateIP(), "create", null); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); return answer; } - long[] stats = getNetworkStats(conn, cmd.getPrivateIP()); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); + final long[] stats = getNetworkStats(conn, cmd.getPrivateIP()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); return answer; - } catch (Exception ex) { + } catch (final Exception ex) { s_logger.warn("Failed to get network usage stats due to ", ex); return new NetworkUsageAnswer(cmd, ex); } @@ -137,17 +135,17 @@ public class XcpServerResource extends CitrixResourceBase { cf: https://wiki.xenserver.org/index.php?title=XCP_FAQ_Dynamic_Memory_Control */ @Override - protected void setMemory(Connection conn, VM vm, long minMemsize, long maxMemsize) throws XmlRpcException, XenAPIException { + protected void setMemory(final Connection conn, final VM vm, final long minMemsize, final long maxMemsize) throws XmlRpcException, XenAPIException { //setMemoryLimits(staticMin, staticMax, dynamicMin, dynamicMax) if (s_logger.isDebugEnabled()) { s_logger.debug("Memory Limits for VM [" + vm.getNameLabel(conn) + "[staticMin:" + mem_32m + ", staticMax:" + maxMemsize + ", dynamicMin: " + minMemsize + - ", dynamicMax:" + maxMemsize + "]]"); + ", dynamicMax:" + maxMemsize + "]]"); } vm.setMemoryLimits(conn, mem_32m, maxMemsize, minMemsize, maxMemsize); } @Override - protected boolean isDmcEnabled(Connection conn, Host host) { + public boolean isDmcEnabled(final Connection conn, final Host host) { //Dynamic Memory Control (DMC) is a technology provided by Xen Cloud Platform (XCP), starting from the 0.5 release //For the supported XCPs dmc is default enabled, XCP 1.0.0, 1.1.0, 1.4.x, 1.5 beta, 1.6.x; return true; diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java index eeeb9590986..11435283a23 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56FP1Resource.java @@ -18,33 +18,22 @@ package com.cloud.hypervisor.xenserver.resource; import java.io.File; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import javax.ejb.Local; -import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VBD; -import com.xensource.xenapi.VDI; -import com.xensource.xenapi.VM; - -import com.cloud.agent.api.FenceAnswer; -import com.cloud.agent.api.FenceCommand; import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types.XenAPIException; @Local(value = ServerResource.class) public class XenServer56FP1Resource extends XenServer56Resource { - private static final long mem_128m = 134217728L; - private static final Logger s_logger = Logger.getLogger(XenServer56FP1Resource.class); public XenServer56FP1Resource() { super(); @@ -52,63 +41,17 @@ public class XenServer56FP1Resource extends XenServer56Resource { @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } - @Override - protected FenceAnswer execute(FenceCommand cmd) { - Connection conn = getConnection(); - try { - Boolean alive = check_heartbeat(cmd.getHostGuid()); - if ( alive == null ) { - s_logger.debug("Failed to check heartbeat, so unable to fence"); - return new FenceAnswer(cmd, false, "Failed to check heartbeat, so unable to fence"); - } - if ( alive ) { - s_logger.debug("Heart beat is still going so unable to fence"); - return new FenceAnswer(cmd, false, "Heartbeat is still going on unable to fence"); - } - Set vms = VM.getByNameLabel(conn, cmd.getVmName()); - for (VM vm : vms) { - Set vdis = new HashSet(); - Set vbds = vm.getVBDs(conn); - for (VBD vbd : vbds) { - VDI vdi = vbd.getVDI(conn); - if (!isRefNull(vdi)) { - vdis.add(vdi); - } - } - s_logger.info("Fence command for VM " + cmd.getVmName()); - vm.powerStateReset(conn); - vm.destroy(conn); - for (VDI vdi : vdis) { - Map smConfig = vdi.getSmConfig(conn); - for (String key : smConfig.keySet()) { - if (key.startsWith("host_")) { - vdi.removeFromSmConfig(conn, key); - break; - } - } - } - } - return new FenceAnswer(cmd); - } catch (XmlRpcException e) { - s_logger.warn("Unable to fence", e); - return new FenceAnswer(cmd, false, e.getMessage()); - } catch (XenAPIException e) { - s_logger.warn("Unable to fence", e); - return new FenceAnswer(cmd, false, e.getMessage()); - } - } - /** * When Dynamic Memory Control (DMC) is enabled - * xenserver allows scaling the guest memory while the guest is running @@ -117,9 +60,9 @@ public class XenServer56FP1Resource extends XenServer56Resource { * When false, scaling is allowed hence DMC is enabled */ @Override - protected boolean isDmcEnabled(Connection conn, Host host) throws XenAPIException, XmlRpcException { - Map hostParams = host.getLicenseParams(conn); - Boolean isDmcEnabled = hostParams.get("restrict_dmc").equalsIgnoreCase("false"); + public boolean isDmcEnabled(final Connection conn, final Host host) throws XenAPIException, XmlRpcException { + final Map hostParams = host.getLicenseParams(conn); + final Boolean isDmcEnabled = hostParams.get("restrict_dmc").equalsIgnoreCase("false"); return isDmcEnabled; } } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java index eec972e6b64..3a30dae8347 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56Resource.java @@ -19,13 +19,20 @@ package com.cloud.hypervisor.xenserver.resource; import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.Set; import javax.ejb.Local; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.StartupCommand; +import com.cloud.hypervisor.xenserver.resource.wrapper.CitrixRequestWrapper; +import com.cloud.resource.ServerResource; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; +import com.cloud.utils.ssh.SSHCmdHelper; import com.xensource.xenapi.Connection; import com.xensource.xenapi.Host; import com.xensource.xenapi.Network; @@ -33,98 +40,81 @@ import com.xensource.xenapi.PIF; import com.xensource.xenapi.Types.IpConfigurationMode; import com.xensource.xenapi.Types.XenAPIException; import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.CheckOnHostAnswer; -import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.FenceAnswer; -import com.cloud.agent.api.FenceCommand; -import com.cloud.agent.api.NetworkUsageAnswer; -import com.cloud.agent.api.NetworkUsageCommand; -import com.cloud.agent.api.StartupCommand; -import com.cloud.resource.ServerResource; -import com.cloud.utils.ExecutionResult; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.script.Script; -import com.cloud.utils.ssh.SSHCmdHelper; @Local(value = ServerResource.class) public class XenServer56Resource extends CitrixResourceBase { private final static Logger s_logger = Logger.getLogger(XenServer56Resource.class); @Override - public Answer executeRequest(Command cmd) { - if (cmd instanceof FenceCommand) { - return execute((FenceCommand)cmd); - } else if (cmd instanceof NetworkUsageCommand) { - return execute((NetworkUsageCommand)cmd); - } else { + public Answer executeRequest(final Command cmd) { + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + try { + return wrapper.execute(cmd, this); + } catch (final Exception e) { return super.executeRequest(cmd); } } - @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xenserver56/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xenserver56/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } @Override - protected void disableVlanNetwork(Connection conn, Network network) { + public void disableVlanNetwork(final Connection conn, final Network network) { try { - Network.Record networkr = network.getRecord(conn); + final Network.Record networkr = network.getRecord(conn); if (!networkr.nameLabel.startsWith("VLAN")) { return; } - String bridge = networkr.bridge.trim(); - for (PIF pif : networkr.PIFs) { - PIF.Record pifr = pif.getRecord(conn); - if (!pifr.host.getUuid(conn).equalsIgnoreCase(_host.uuid)) { + final String bridge = networkr.bridge.trim(); + for (final PIF pif : networkr.PIFs) { + final PIF.Record pifr = pif.getRecord(conn); + if (!pifr.host.getUuid(conn).equalsIgnoreCase(_host.getUuid())) { continue; } - VLAN vlan = pifr.VLANMasterOf; + final VLAN vlan = pifr.VLANMasterOf; if (vlan != null) { - String vlannum = pifr.VLAN.toString(); - String device = pifr.device.trim(); + final String vlannum = pifr.VLAN.toString(); + final String device = pifr.device.trim(); if (vlannum.equals("-1")) { return; } try { vlan.destroy(conn); - Host host = Host.getByUuid(conn, _host.uuid); + final Host host = Host.getByUuid(conn, _host.getUuid()); host.forgetDataSourceArchives(conn, "pif_" + bridge + "_tx"); host.forgetDataSourceArchives(conn, "pif_" + bridge + "_rx"); host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_tx"); host.forgetDataSourceArchives(conn, "pif_" + device + "." + vlannum + "_rx"); - } catch (XenAPIException e) { - s_logger.trace("Catch " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.uuid + " due to " + e.toString()); + } catch (final XenAPIException e) { + s_logger.trace("Catch " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.getUuid() + " due to " + e.toString()); } } return; } - } catch (XenAPIException e) { - String msg = "Unable to disable VLAN network due to " + e.toString(); + } catch (final XenAPIException e) { + final String msg = "Unable to disable VLAN network due to " + e.toString(); s_logger.warn(msg, e); - } catch (Exception e) { - String msg = "Unable to disable VLAN network due to " + e.getMessage(); + } catch (final Exception e) { + final String msg = "Unable to disable VLAN network due to " + e.getMessage(); s_logger.warn(msg, e); } } @Override - protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { + public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif) { String args = ""; if (option.equals("get")) { args += "-g"; @@ -143,90 +133,22 @@ public class XenServer56Resource extends CitrixResourceBase { return executeInVR(privateIpAddress, "netusage.sh", args).getDetails(); } - protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { - try { - Connection conn = getConnection(); - String option = cmd.getOption(); - String publicIp = cmd.getGatewayIP(); - - String args = " -l " + publicIp + " "; - if (option.equals("get")) { - args += "-g"; - } else if (option.equals("create")) { - args += "-c"; - String vpcCIDR = cmd.getVpcCIDR(); - args += " -v " + vpcCIDR; - } else if (option.equals("reset")) { - args += "-r"; - } else if (option.equals("vpn")) { - args += "-n"; - } else if (option.equals("remove")) { - args += "-d"; - } else { - return new NetworkUsageAnswer(cmd, "success", 0L, 0L); - } - - ExecutionResult result = executeInVR(cmd.getPrivateIP(), "vpc_netusage.sh", args); - String detail = result.getDetails(); - if (!result.isSuccess()) { - throw new Exception(" vpc network usage plugin call failed "); - } - if (option.equals("get") || option.equals("vpn")) { - long[] stats = new long[2]; - if (detail != null) { - String[] splitResult = detail.split(":"); - int i = 0; - while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); - } - return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); - } - } - return new NetworkUsageAnswer(cmd, "success", 0L, 0L); - } catch (Exception ex) { - s_logger.warn("Failed to get network usage stats due to ", ex); - return new NetworkUsageAnswer(cmd, ex); - } - } - - protected NetworkUsageAnswer execute(NetworkUsageCommand cmd) { - if (cmd.isForVpc()) { - return VPCNetworkUsage(cmd); - } - try { - Connection conn = getConnection(); - if (cmd.getOption() != null && cmd.getOption().equals("create")) { - String result = networkUsage(conn, cmd.getPrivateIP(), "create", null); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, result, 0L, 0L); - return answer; - } - long[] stats = getNetworkStats(conn, cmd.getPrivateIP()); - NetworkUsageAnswer answer = new NetworkUsageAnswer(cmd, "", stats[0], stats[1]); - return answer; - } catch (Exception ex) { - s_logger.warn("Failed to get network usage stats due to ", ex); - return new NetworkUsageAnswer(cmd, ex); - } - } - - protected Boolean check_heartbeat(String hostuuid) { - com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.ip, 22); + public Boolean checkHeartbeat(final String hostuuid) { + final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22); try { sshConnection.connect(null, 60000, 60000); if (!sshConnection.authenticateWithPassword(_username, _password.peek())) { throw new CloudRuntimeException("Unable to authenticate"); } - String shcmd = "/opt/cloud/bin/check_heartbeat.sh " + hostuuid + " " - + Integer.toString(_heartbeatInterval * 2); + final String shcmd = "/opt/cloud/bin/check_heartbeat.sh " + hostuuid + " " + Integer.toString(_heartbeatInterval * 2); if (!SSHCmdHelper.sshExecuteCmd(sshConnection, shcmd)) { s_logger.debug("Heart beat is gone so dead."); return false; } s_logger.debug("Heart beat is still going"); return true; - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("health check failed due to catch exception " + e.toString()); return null; } finally { @@ -234,41 +156,12 @@ public class XenServer56Resource extends CitrixResourceBase { } } - protected FenceAnswer execute(FenceCommand cmd) { - Connection conn = getConnection(); - try { - Boolean alive = check_heartbeat(cmd.getHostGuid()); - if ( alive == null ) { - s_logger.debug("Failed to check heartbeat, so unable to fence"); - return new FenceAnswer(cmd, false, "Failed to check heartbeat, so unable to fence"); - } - if ( alive ) { - s_logger.debug("Heart beat is still going so unable to fence"); - return new FenceAnswer(cmd, false, "Heartbeat is still going on unable to fence"); - } - Set vms = VM.getByNameLabel(conn, cmd.getVmName()); - for (VM vm : vms) { - s_logger.info("Fence command for VM " + cmd.getVmName()); - vm.powerStateReset(conn); - vm.destroy(conn); - } - return new FenceAnswer(cmd); - } catch (XmlRpcException e) { - s_logger.warn("Unable to fence", e); - return new FenceAnswer(cmd, false, e.getMessage()); - } catch (XenAPIException e) { - s_logger.warn("Unable to fence", e); - return new FenceAnswer(cmd, false, e.getMessage()); - } - } - - @Override - protected boolean transferManagementNetwork(Connection conn, Host host, PIF src, PIF.Record spr, PIF dest) throws XmlRpcException, XenAPIException { + public boolean transferManagementNetwork(final Connection conn, final Host host, final PIF src, final PIF.Record spr, final PIF dest) throws XmlRpcException, XenAPIException { dest.reconfigureIp(conn, spr.ipConfigurationMode, spr.IP, spr.netmask, spr.gateway, spr.DNS); Host.managementReconfigure(conn, dest); String hostUuid = null; - int count = 0; + final int count = 0; while (count < 10) { try { Thread.sleep(10000); @@ -276,11 +169,11 @@ public class XenServer56Resource extends CitrixResourceBase { if (hostUuid != null) { break; } - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { s_logger.debug("Waiting for host to come back: " + e.getMessage()); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.debug("Waiting for host to come back: " + e.getMessage()); - } catch (InterruptedException e) { + } catch (final InterruptedException e) { s_logger.debug("Gotta run"); return false; } @@ -297,30 +190,11 @@ public class XenServer56Resource extends CitrixResourceBase { @Override public StartupCommand[] initialize() { pingXAPI(); - StartupCommand[] cmds = super.initialize(); + final StartupCommand[] cmds = super.initialize(); return cmds; } - - @Override - protected CheckOnHostAnswer execute(CheckOnHostCommand cmd) { - Boolean alive = check_heartbeat(cmd.getHost().getGuid()); - String msg = ""; - if (alive == null) { - msg = " cannot determine "; - } else if ( alive == true) { - msg = "Heart beat is still going"; - } else { - msg = "Heart beat is gone so dead."; - } - s_logger.debug(msg); - return new CheckOnHostAnswer(cmd, alive, msg); - - } - - public XenServer56Resource() { super(); } - -} +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java index c0d6f004e3b..37748178fbb 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer56SP2Resource.java @@ -22,15 +22,12 @@ import java.util.List; import javax.ejb.Local; -import org.apache.log4j.Logger; - import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; @Local(value = ServerResource.class) public class XenServer56SP2Resource extends XenServer56FP1Resource { - private static final Logger s_logger = Logger.getLogger(XenServer56SP2Resource.class); public XenServer56SP2Resource() { super(); @@ -40,13 +37,13 @@ public class XenServer56SP2Resource extends XenServer56FP1Resource { @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java index 037ded32321..c6e5d82af06 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer600Resource.java @@ -22,29 +22,22 @@ import java.util.List; import javax.ejb.Local; -import org.apache.log4j.Logger; - import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; @Local(value = ServerResource.class) public class XenServer600Resource extends XenServer56SP2Resource { - private static final Logger s_logger = Logger.getLogger(XenServer600Resource.class); - - public XenServer600Resource() { - super(); - } @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xenserver60/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xenserver60/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java index 2283477eac3..e71a97db2b6 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer610Resource.java @@ -24,23 +24,10 @@ import java.util.Set; import javax.ejb.Local; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.SR; -import com.xensource.xenapi.Task; -import com.xensource.xenapi.Types; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VBD; -import com.xensource.xenapi.VDI; -import com.xensource.xenapi.VIF; -import com.xensource.xenapi.VM; - -import org.apache.cloudstack.storage.to.VolumeObjectTO; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.MigrateWithStorageAnswer; @@ -62,6 +49,17 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.resource.ServerResource; import com.cloud.storage.Volume; import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Task; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VM; @Local(value = ServerResource.class) public class XenServer610Resource extends XenServer600Resource { @@ -72,7 +70,7 @@ public class XenServer610Resource extends XenServer600Resource { } @Override - public Answer executeRequest(Command cmd) { + public Answer executeRequest(final Command cmd) { if (cmd instanceof MigrateWithStorageCommand) { return execute((MigrateWithStorageCommand)cmd); } else if (cmd instanceof MigrateWithStorageReceiveCommand) { @@ -88,34 +86,34 @@ public class XenServer610Resource extends XenServer600Resource { } } - private List getUpdatedVolumePathsOfMigratedVm(Connection connection, VM migratedVm, DiskTO[] volumes) throws CloudRuntimeException { - List volumeToList = new ArrayList(); + private List getUpdatedVolumePathsOfMigratedVm(final Connection connection, final VM migratedVm, final DiskTO[] volumes) throws CloudRuntimeException { + final List volumeToList = new ArrayList(); try { // Volume paths would have changed. Return that information. - Set vbds = migratedVm.getVBDs(connection); - Map deviceIdToVdiMap = new HashMap(); + final Set vbds = migratedVm.getVBDs(connection); + final Map deviceIdToVdiMap = new HashMap(); // get vdi:vbdr to a map - for (VBD vbd : vbds) { - VBD.Record vbdr = vbd.getRecord(connection); + for (final VBD vbd : vbds) { + final VBD.Record vbdr = vbd.getRecord(connection); if (vbdr.type == Types.VbdType.DISK) { - VDI vdi = vbdr.VDI; + final VDI vdi = vbdr.VDI; deviceIdToVdiMap.put(vbdr.userdevice, vdi); } } - for (DiskTO volumeTo : volumes) { + for (final DiskTO volumeTo : volumes) { if (volumeTo.getType() != Volume.Type.ISO) { - VolumeObjectTO vol = (VolumeObjectTO)volumeTo.getData(); - Long deviceId = volumeTo.getDiskSeq(); - VDI vdi = deviceIdToVdiMap.get(deviceId.toString()); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VolumeObjectTO vol = (VolumeObjectTO)volumeTo.getData(); + final Long deviceId = volumeTo.getDiskSeq(); + final VDI vdi = deviceIdToVdiMap.get(deviceId.toString()); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(vdi.getUuid(connection)); newVol.setId(vol.getId()); volumeToList.add(newVol); } } - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("Unable to get the updated VDI paths of the migrated vm " + e.toString(), e); throw new CloudRuntimeException("Unable to get the updated VDI paths of the migrated vm " + e.toString(), e); } @@ -123,10 +121,10 @@ public class XenServer610Resource extends XenServer600Resource { return volumeToList; } - protected MigrateWithStorageAnswer execute(MigrateWithStorageCommand cmd) { - Connection connection = getConnection(); - VirtualMachineTO vmSpec = cmd.getVirtualMachine(); - Map volumeToFiler = cmd.getVolumeToFiler(); + protected MigrateWithStorageAnswer execute(final MigrateWithStorageCommand cmd) { + final Connection connection = getConnection(); + final VirtualMachineTO vmSpec = cmd.getVirtualMachine(); + final Map volumeToFiler = cmd.getVolumeToFiler(); final String vmName = vmSpec.getName(); Task task = null; @@ -134,24 +132,24 @@ public class XenServer610Resource extends XenServer600Resource { prepareISO(connection, vmSpec.getName()); // Get the list of networks and recreate VLAN, if required. - for (NicTO nicTo : vmSpec.getNics()) { + for (final NicTO nicTo : vmSpec.getNics()) { getNetwork(connection, nicTo); } - Map other = new HashMap(); + final Map other = new HashMap(); other.put("live", "true"); - Network networkForSm = getNativeNetworkForTraffic(connection, TrafficType.Storage, null).getNetwork(); - Host host = Host.getByUuid(connection, _host.uuid); - Map token = host.migrateReceive(connection, networkForSm, other); + final Network networkForSm = getNativeNetworkForTraffic(connection, TrafficType.Storage, null).getNetwork(); + final Host host = Host.getByUuid(connection, _host.getUuid()); + final Map token = host.migrateReceive(connection, networkForSm, other); // Get the vm to migrate. - Set vms = VM.getByNameLabel(connection, vmSpec.getName()); - VM vmToMigrate = vms.iterator().next(); + final Set vms = VM.getByNameLabel(connection, vmSpec.getName()); + final VM vmToMigrate = vms.iterator().next(); // Create the vif map. The vm stays in the same cluster so we have to pass an empty vif map. - Map vifMap = new HashMap(); - Map vdiMap = new HashMap(); - for (Map.Entry entry : volumeToFiler.entrySet()) { + final Map vifMap = new HashMap(); + final Map vdiMap = new HashMap(); + for (final Map.Entry entry : volumeToFiler.entrySet()) { vdiMap.put(getVDIbyUuid(connection, entry.getKey().getPath()), getStorageRepository(connection, entry.getValue().getUuid())); } @@ -159,10 +157,10 @@ public class XenServer610Resource extends XenServer600Resource { task = vmToMigrate.assertCanMigrateAsync(connection, token, true, vdiMap, vifMap, other); try { // poll every 1 seconds - long timeout = (_migratewait) * 1000L; + final long timeout = _migratewait * 1000L; waitForTask(connection, task, 1000, timeout); checkForSuccess(connection, task); - } catch (Types.HandleInvalid e) { + } catch (final Types.HandleInvalid e) { s_logger.error("Error while checking if vm " + vmName + " can be migrated to the destination host " + host, e); throw new CloudRuntimeException("Error while checking if vm " + vmName + " can be migrated to the " + "destination host " + host, e); } @@ -171,90 +169,89 @@ public class XenServer610Resource extends XenServer600Resource { task = vmToMigrate.migrateSendAsync(connection, token, true, vdiMap, vifMap, other); try { // poll every 1 seconds. - long timeout = (_migratewait) * 1000L; + final long timeout = _migratewait * 1000L; waitForTask(connection, task, 1000, timeout); checkForSuccess(connection, task); - } catch (Types.HandleInvalid e) { + } catch (final Types.HandleInvalid e) { s_logger.error("Error while migrating vm " + vmName + " to the destination host " + host, e); throw new CloudRuntimeException("Error while migrating vm " + vmName + " to the destination host " + host, e); } // Volume paths would have changed. Return that information. - List volumeToList = getUpdatedVolumePathsOfMigratedVm(connection, vmToMigrate, vmSpec.getDisks()); + final List volumeToList = getUpdatedVolumePathsOfMigratedVm(connection, vmToMigrate, vmSpec.getDisks()); vmToMigrate.setAffinity(connection, host); return new MigrateWithStorageAnswer(cmd, volumeToList); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("Catch Exception " + e.getClass().getName() + ". Storage motion failed due to " + e.toString(), e); return new MigrateWithStorageAnswer(cmd, e); } finally { if (task != null) { try { task.destroy(connection); - } catch (Exception e) { - s_logger.debug("Unable to destroy task " + task.toString() + " on host " + _host.uuid + " due to " + e.toString()); + } catch (final Exception e) { + s_logger.debug("Unable to destroy task " + task.toString() + " on host " + _host.getUuid() + " due to " + e.toString()); } } } } - protected MigrateWithStorageReceiveAnswer execute(MigrateWithStorageReceiveCommand cmd) { - Connection connection = getConnection(); - VirtualMachineTO vmSpec = cmd.getVirtualMachine(); - Map volumeToFiler = cmd.getVolumeToFiler(); + protected MigrateWithStorageReceiveAnswer execute(final MigrateWithStorageReceiveCommand cmd) { + final Connection connection = getConnection(); + final VirtualMachineTO vmSpec = cmd.getVirtualMachine(); + final Map volumeToFiler = cmd.getVolumeToFiler(); try { // Get a map of all the SRs to which the vdis will be migrated. - Map volumeToSr = new HashMap(); - for (Map.Entry entry : volumeToFiler.entrySet()) { - SR sr = getStorageRepository(connection, entry.getValue().getUuid()); + final Map volumeToSr = new HashMap(); + for (final Map.Entry entry : volumeToFiler.entrySet()) { + final SR sr = getStorageRepository(connection, entry.getValue().getUuid()); volumeToSr.put(entry.getKey(), sr); } // Get the list of networks to which the vifs will attach. - Map nicToNetwork = new HashMap(); - for (NicTO nicTo : vmSpec.getNics()) { - Network network = getNetwork(connection, nicTo); + final Map nicToNetwork = new HashMap(); + for (final NicTO nicTo : vmSpec.getNics()) { + final Network network = getNetwork(connection, nicTo); nicToNetwork.put(nicTo, network); } - Map other = new HashMap(); + final Map other = new HashMap(); other.put("live", "true"); - Network network = getNativeNetworkForTraffic(connection, TrafficType.Storage, null).getNetwork(); - Host host = Host.getByUuid(connection, _host.uuid); - Map token = host.migrateReceive(connection, network, other); + final Network network = getNativeNetworkForTraffic(connection, TrafficType.Storage, null).getNetwork(); + final Host host = Host.getByUuid(connection, _host.getUuid()); + final Map token = host.migrateReceive(connection, network, other); return new MigrateWithStorageReceiveAnswer(cmd, volumeToSr, nicToNetwork, token); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { s_logger.error("Migration of vm " + vmSpec.getName() + " with storage failed due to " + e.toString(), e); return new MigrateWithStorageReceiveAnswer(cmd, e); - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("Migration of vm " + vmSpec.getName() + " with storage failed due to " + e.toString(), e); return new MigrateWithStorageReceiveAnswer(cmd, e); } } - protected MigrateWithStorageSendAnswer execute(MigrateWithStorageSendCommand cmd) { - Connection connection = getConnection(); - VirtualMachineTO vmSpec = cmd.getVirtualMachine(); - Map volumeToSr = cmd.getVolumeToSr(); - Map nicToNetwork = cmd.getNicToNetwork(); - Map token = cmd.getToken(); + protected MigrateWithStorageSendAnswer execute(final MigrateWithStorageSendCommand cmd) { + final Connection connection = getConnection(); + final VirtualMachineTO vmSpec = cmd.getVirtualMachine(); + final Map volumeToSr = cmd.getVolumeToSr(); + final Map nicToNetwork = cmd.getNicToNetwork(); + final Map token = cmd.getToken(); final String vmName = vmSpec.getName(); - Set volumeToSet = null; - boolean migrated = false; + final Set volumeToSet = null; Task task = null; try { - Set vms = VM.getByNameLabel(connection, vmSpec.getName()); - VM vmToMigrate = vms.iterator().next(); - Map other = new HashMap(); + final Set vms = VM.getByNameLabel(connection, vmSpec.getName()); + final VM vmToMigrate = vms.iterator().next(); + final Map other = new HashMap(); other.put("live", "true"); // Create the vdi map which tells what volumes of the vm need to go on which sr on the destination. - Map vdiMap = new HashMap(); - for (Map.Entry entry : volumeToSr.entrySet()) { + final Map vdiMap = new HashMap(); + for (final Map.Entry entry : volumeToSr.entrySet()) { if (entry.getValue() instanceof SR) { - SR sr = (SR)entry.getValue(); - VDI vdi = getVDIbyUuid(connection, entry.getKey().getPath()); + final SR sr = (SR)entry.getValue(); + final VDI vdi = getVDIbyUuid(connection, entry.getKey().getPath()); vdiMap.put(vdi, sr); } else { throw new CloudRuntimeException("The object " + entry.getValue() + " passed is not of type SR."); @@ -262,11 +259,11 @@ public class XenServer610Resource extends XenServer600Resource { } // Create the vif map. - Map vifMap = new HashMap(); - for (Map.Entry entry : nicToNetwork.entrySet()) { + final Map vifMap = new HashMap(); + for (final Map.Entry entry : nicToNetwork.entrySet()) { if (entry.getValue() instanceof Network) { - Network network = (Network)entry.getValue(); - VIF vif = getVifByMac(connection, vmToMigrate, entry.getKey().getMac()); + final Network network = (Network)entry.getValue(); + final VIF vif = getVifByMac(connection, vmToMigrate, entry.getKey().getMac()); vifMap.put(vif, network); } else { throw new CloudRuntimeException("The object " + entry.getValue() + " passed is not of type Network."); @@ -277,10 +274,10 @@ public class XenServer610Resource extends XenServer600Resource { task = vmToMigrate.assertCanMigrateAsync(connection, token, true, vdiMap, vifMap, other); try { // poll every 1 seconds. - long timeout = (_migratewait) * 1000L; + final long timeout = _migratewait * 1000L; waitForTask(connection, task, 1000, timeout); checkForSuccess(connection, task); - } catch (Types.HandleInvalid e) { + } catch (final Types.HandleInvalid e) { s_logger.error("Error while checking if vm " + vmName + " can be migrated.", e); throw new CloudRuntimeException("Error while checking if vm " + vmName + " can be migrated.", e); } @@ -289,41 +286,40 @@ public class XenServer610Resource extends XenServer600Resource { task = vmToMigrate.migrateSendAsync(connection, token, true, vdiMap, vifMap, other); try { // poll every 1 seconds. - long timeout = (_migratewait) * 1000L; + final long timeout = _migratewait * 1000L; waitForTask(connection, task, 1000, timeout); checkForSuccess(connection, task); - } catch (Types.HandleInvalid e) { + } catch (final Types.HandleInvalid e) { s_logger.error("Error while migrating vm " + vmName, e); throw new CloudRuntimeException("Error while migrating vm " + vmName, e); } - migrated = true; return new MigrateWithStorageSendAnswer(cmd, volumeToSet); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { s_logger.error("Migration of vm " + vmName + " with storage failed due to " + e.toString(), e); return new MigrateWithStorageSendAnswer(cmd, e); - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("Migration of vm " + vmName + " with storage failed due to " + e.toString(), e); return new MigrateWithStorageSendAnswer(cmd, e); } finally { if (task != null) { try { task.destroy(connection); - } catch (Exception e) { - s_logger.debug("Unable to destroy task " + task.toString() + " on host " + _host.uuid + " due to " + e.toString()); + } catch (final Exception e) { + s_logger.debug("Unable to destroy task " + task.toString() + " on host " + _host.getUuid() + " due to " + e.toString()); } } } } - protected MigrateWithStorageCompleteAnswer execute(MigrateWithStorageCompleteCommand cmd) { - Connection connection = getConnection(); - VirtualMachineTO vmSpec = cmd.getVirtualMachine(); + protected MigrateWithStorageCompleteAnswer execute(final MigrateWithStorageCompleteCommand cmd) { + final Connection connection = getConnection(); + final VirtualMachineTO vmSpec = cmd.getVirtualMachine(); try { - Host host = Host.getByUuid(connection, _host.uuid); - Set vms = VM.getByNameLabel(connection, vmSpec.getName()); - VM migratedVm = vms.iterator().next(); + final Host host = Host.getByUuid(connection, _host.getUuid()); + final Set vms = VM.getByNameLabel(connection, vmSpec.getName()); + final VM migratedVm = vms.iterator().next(); // Check the vm is present on the new host. if (migratedVm == null) { @@ -331,47 +327,47 @@ public class XenServer610Resource extends XenServer600Resource { } // Volume paths would have changed. Return that information. - List volumeToSet = getUpdatedVolumePathsOfMigratedVm(connection, migratedVm, vmSpec.getDisks()); + final List volumeToSet = getUpdatedVolumePathsOfMigratedVm(connection, migratedVm, vmSpec.getDisks()); migratedVm.setAffinity(connection, host); return new MigrateWithStorageCompleteAnswer(cmd, volumeToSet); - } catch (CloudRuntimeException e) { + } catch (final CloudRuntimeException e) { s_logger.error("Migration of vm " + vmSpec.getName() + " with storage failed due to " + e.toString(), e); return new MigrateWithStorageCompleteAnswer(cmd, e); - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("Migration of vm " + vmSpec.getName() + " with storage failed due to " + e.toString(), e); return new MigrateWithStorageCompleteAnswer(cmd, e); } } - protected MigrateVolumeAnswer execute(MigrateVolumeCommand cmd) { - Connection connection = getConnection(); - String volumeUUID = cmd.getVolumePath(); - StorageFilerTO poolTO = cmd.getPool(); + protected MigrateVolumeAnswer execute(final MigrateVolumeCommand cmd) { + final Connection connection = getConnection(); + final String volumeUUID = cmd.getVolumePath(); + final StorageFilerTO poolTO = cmd.getPool(); try { - SR destinationPool = getStorageRepository(connection, poolTO.getUuid()); - VDI srcVolume = getVDIbyUuid(connection, volumeUUID); - Map other = new HashMap(); + final SR destinationPool = getStorageRepository(connection, poolTO.getUuid()); + final VDI srcVolume = getVDIbyUuid(connection, volumeUUID); + final Map other = new HashMap(); other.put("live", "true"); // Live migrate the vdi across pool. - Task task = srcVolume.poolMigrateAsync(connection, destinationPool, other); - long timeout = (_migratewait) * 1000L; + final Task task = srcVolume.poolMigrateAsync(connection, destinationPool, other); + final long timeout = _migratewait * 1000L; waitForTask(connection, task, 1000, timeout); checkForSuccess(connection, task); - VDI dvdi = Types.toVDI(task, connection); + final VDI dvdi = Types.toVDI(task, connection); return new MigrateVolumeAnswer(cmd, true, null, dvdi.getUuid(connection)); - } catch (Exception e) { - String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString(); s_logger.error(msg, e); return new MigrateVolumeAnswer(cmd, false, msg, null); } } @Override - protected void plugDom0Vif(Connection conn, VIF dom0Vif) throws XmlRpcException, XenAPIException { + protected void plugDom0Vif(final Connection conn, final VIF dom0Vif) throws XmlRpcException, XenAPIException { // do nothing. In xenserver 6.1 and beyond this step isn't needed. } } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java index ecc30895232..858fc154957 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620Resource.java @@ -20,18 +20,16 @@ import java.util.Set; import javax.ejb.Local; +import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs; import org.apache.log4j.Logger; +import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.resource.ServerResource; import com.xensource.xenapi.Connection; import com.xensource.xenapi.Host; import com.xensource.xenapi.HostPatch; import com.xensource.xenapi.PoolPatch; -import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs; - -import com.cloud.agent.api.StartupRoutingCommand; -import com.cloud.resource.ServerResource; - @Local(value = ServerResource.class) public class XenServer620Resource extends XenServer610Resource { private static final Logger s_logger = Logger.getLogger(XenServer620Resource.class); @@ -40,34 +38,33 @@ public class XenServer620Resource extends XenServer610Resource { super(); } - - protected boolean hostHasHotFix(Connection conn, String hotFixUuid) { + protected boolean hostHasHotFix(final Connection conn, final String hotFixUuid) { try { - Host host = Host.getByUuid(conn, _host.uuid); - Host.Record re = host.getRecord(conn); - Set patches = re.patches; - PoolPatch poolPatch = PoolPatch.getByUuid(conn, hotFixUuid); - for(HostPatch patch : patches) { - PoolPatch pp = patch.getPoolPatch(conn); + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Host.Record re = host.getRecord(conn); + final Set patches = re.patches; + final PoolPatch poolPatch = PoolPatch.getByUuid(conn, hotFixUuid); + for(final HostPatch patch : patches) { + final PoolPatch pp = patch.getPoolPatch(conn); if (pp.equals(poolPatch) && patch.getApplied(conn)) { return true; } } - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("can't get patches information for hotFix: " + hotFixUuid); } return false; } @Override - protected void fillHostInfo(Connection conn, StartupRoutingCommand cmd) { + protected void fillHostInfo(final Connection conn, final StartupRoutingCommand cmd) { super.fillHostInfo(conn, cmd); - Map details = cmd.getHostDetails(); - Boolean hotFix62ESP1004 = hostHasHotFix(conn, XenserverConfigs.XSHotFix62ESP1004); + final Map details = cmd.getHostDetails(); + final Boolean hotFix62ESP1004 = hostHasHotFix(conn, XenserverConfigs.XSHotFix62ESP1004); if( hotFix62ESP1004 != null && hotFix62ESP1004 ) { details.put(XenserverConfigs.XS620HotFix , XenserverConfigs.XSHotFix62ESP1004); } else { - Boolean hotFix62ESP1 = hostHasHotFix(conn, XenserverConfigs.XSHotFix62ESP1); + final Boolean hotFix62ESP1 = hostHasHotFix(conn, XenserverConfigs.XSHotFix62ESP1); if( hotFix62ESP1 != null && hotFix62ESP1 ) { details.put(XenserverConfigs.XS620HotFix , XenserverConfigs.XSHotFix62ESP1); } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java index 5553553d49a..0704e8e4b62 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer620SP1Resource.java @@ -28,6 +28,15 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.GetGPUStatsAnswer; +import com.cloud.agent.api.GetGPUStatsCommand; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.agent.api.VgpuTypesInfo; +import com.cloud.agent.api.to.GPUDeviceTO; +import com.cloud.resource.ServerResource; import com.xensource.xenapi.Connection; import com.xensource.xenapi.GPUGroup; import com.xensource.xenapi.Host; @@ -38,16 +47,6 @@ import com.xensource.xenapi.VGPUType; import com.xensource.xenapi.VGPUType.Record; import com.xensource.xenapi.VM; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.GetGPUStatsAnswer; -import com.cloud.agent.api.GetGPUStatsCommand; -import com.cloud.agent.api.StartCommand; -import com.cloud.agent.api.StartupRoutingCommand; -import com.cloud.agent.api.VgpuTypesInfo; -import com.cloud.agent.api.to.GPUDeviceTO; -import com.cloud.resource.ServerResource; - @Local(value=ServerResource.class) public class XenServer620SP1Resource extends XenServer620Resource { private static final Logger s_logger = Logger.getLogger(XenServer620SP1Resource.class); @@ -57,8 +56,8 @@ public class XenServer620SP1Resource extends XenServer620Resource { } @Override - public Answer executeRequest(Command cmd) { - Class clazz = cmd.getClass(); + public Answer executeRequest(final Command cmd) { + final Class clazz = cmd.getClass(); if (clazz == GetGPUStatsCommand.class) { return execute((GetGPUStatsCommand) cmd); } else { @@ -66,28 +65,28 @@ public class XenServer620SP1Resource extends XenServer620Resource { } } - protected GetGPUStatsAnswer execute(GetGPUStatsCommand cmd) { - Connection conn = getConnection(); + protected GetGPUStatsAnswer execute(final GetGPUStatsCommand cmd) { + final Connection conn = getConnection(); HashMap> groupDetails = new HashMap>(); try { groupDetails = getGPUGroupDetails(conn); - } catch (Exception e) { - String msg = "Unable to get GPU stats" + e.toString(); + } catch (final Exception e) { + final String msg = "Unable to get GPU stats" + e.toString(); s_logger.warn(msg, e); } return new GetGPUStatsAnswer(cmd, groupDetails); } @Override - protected void fillHostInfo(Connection conn, StartupRoutingCommand cmd) { + protected void fillHostInfo(final Connection conn, final StartupRoutingCommand cmd) { super.fillHostInfo(conn, cmd); try { - HashMap> groupDetails = getGPUGroupDetails(conn); + final HashMap> groupDetails = getGPUGroupDetails(conn); cmd.setGpuGroupDetails(groupDetails); if (groupDetails != null && !groupDetails.isEmpty()) { cmd.setHostTags("GPU"); } - } catch (Exception e) { + } catch (final Exception e) { if (s_logger.isDebugEnabled()) { s_logger.debug("Error while getting GPU device info from host " + cmd.getName(), e); } @@ -95,26 +94,26 @@ public class XenServer620SP1Resource extends XenServer620Resource { } @Override - protected HashMap> getGPUGroupDetails(Connection conn) throws XenAPIException, XmlRpcException { - HashMap> groupDetails = new HashMap>(); - Host host = Host.getByUuid(conn, _host.uuid); - Set pgpus = host.getPGPUs(conn); - Iterator iter = pgpus.iterator(); + public HashMap> getGPUGroupDetails(final Connection conn) throws XenAPIException, XmlRpcException { + final HashMap> groupDetails = new HashMap>(); + final Host host = Host.getByUuid(conn, _host.getUuid()); + final Set pgpus = host.getPGPUs(conn); + final Iterator iter = pgpus.iterator(); while (iter.hasNext()) { - PGPU pgpu = iter.next(); - GPUGroup gpuGroup = pgpu.getGPUGroup(conn); - Set enabledVGPUTypes = gpuGroup.getEnabledVGPUTypes(conn); - String groupName = gpuGroup.getNameLabel(conn); + final PGPU pgpu = iter.next(); + final GPUGroup gpuGroup = pgpu.getGPUGroup(conn); + final Set enabledVGPUTypes = gpuGroup.getEnabledVGPUTypes(conn); + final String groupName = gpuGroup.getNameLabel(conn); HashMap gpuCapacity = new HashMap(); if (groupDetails.get(groupName) != null) { gpuCapacity = groupDetails.get(groupName); } // Get remaining capacity of all the enabled VGPU in a PGPU if(enabledVGPUTypes != null) { - Iterator it = enabledVGPUTypes.iterator(); + final Iterator it = enabledVGPUTypes.iterator(); while (it.hasNext()) { - VGPUType type = it.next(); - Record record = type.getRecord(conn); + final VGPUType type = it.next(); + final Record record = type.getRecord(conn); Long remainingCapacity = pgpu.getRemainingCapacity(conn, type); Long maxCapacity = pgpu.getSupportedVGPUMaxCapacities(conn).get(type); VgpuTypesInfo entry; @@ -125,7 +124,7 @@ public class XenServer620SP1Resource extends XenServer620Resource { entry.setMaxVmCapacity(maxCapacity); gpuCapacity.put(record.modelName, entry); } else { - VgpuTypesInfo vgpuTypeRecord = new VgpuTypesInfo(null, record.modelName, record.framebufferSize, record.maxHeads, + final VgpuTypesInfo vgpuTypeRecord = new VgpuTypesInfo(null, record.modelName, record.framebufferSize, record.maxHeads, record.maxResolutionX, record.maxResolutionY, maxCapacity, remainingCapacity, maxCapacity); gpuCapacity.put(record.modelName, vgpuTypeRecord); } @@ -137,27 +136,27 @@ public class XenServer620SP1Resource extends XenServer620Resource { } @Override - protected void createVGPU(Connection conn, StartCommand cmd, VM vm, GPUDeviceTO gpuDevice) throws XenAPIException, XmlRpcException { + public void createVGPU(final Connection conn, final StartCommand cmd, final VM vm, final GPUDeviceTO gpuDevice) throws XenAPIException, XmlRpcException { if (s_logger.isDebugEnabled()) { s_logger.debug("Creating VGPU of VGPU type [ " + gpuDevice.getVgpuType() + " ] in gpu group" + gpuDevice.getGpuGroup() + " for VM " + cmd.getVirtualMachine().getName()); } - Set groups = GPUGroup.getByNameLabel(conn, gpuDevice.getGpuGroup()); + final Set groups = GPUGroup.getByNameLabel(conn, gpuDevice.getGpuGroup()); assert groups.size() == 1 : "Should only have 1 group but found " + groups.size(); - GPUGroup gpuGroup = groups.iterator().next(); + final GPUGroup gpuGroup = groups.iterator().next(); - Set vgpuTypes = gpuGroup.getEnabledVGPUTypes(conn); - Iterator iter = vgpuTypes.iterator(); + final Set vgpuTypes = gpuGroup.getEnabledVGPUTypes(conn); + final Iterator iter = vgpuTypes.iterator(); VGPUType vgpuType = null; while (iter.hasNext()) { - VGPUType entry = iter.next(); + final VGPUType entry = iter.next(); if (entry.getModelName(conn).equals(gpuDevice.getVgpuType())) { vgpuType = entry; } } - String device = "0"; // Only allow device = "0" for now, as XenServer supports just a single vGPU per VM. - Map other_config = new HashMap(); + final String device = "0"; // Only allow device = "0" for now, as XenServer supports just a single vGPU per VM. + final Map other_config = new HashMap(); VGPU.create(conn, vm, gpuGroup, device, other_config, vgpuType); if (s_logger.isDebugEnabled()) { @@ -166,5 +165,4 @@ public class XenServer620SP1Resource extends XenServer620Resource { // Calculate and set remaining GPU capacity in the host. cmd.getVirtualMachine().getGpuDevice().setGroupDetails(getGPUGroupDetails(conn)); } - -} +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer650Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer650Resource.java index 4fa82a80680..98796eb0435 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer650Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServer650Resource.java @@ -18,32 +18,28 @@ */ package com.cloud.hypervisor.xenserver.resource; -import com.cloud.resource.ServerResource; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.script.Script; -import org.apache.log4j.Logger; - -import javax.ejb.Local; import java.io.File; import java.util.ArrayList; import java.util.List; +import javax.ejb.Local; + +import com.cloud.resource.ServerResource; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; + @Local(value=ServerResource.class) public class XenServer650Resource extends Xenserver625Resource { - private static final Logger s_logger = Logger.getLogger(XenServer650Resource.class); - - public XenServer650Resource() { - super(); - } + @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xenserver65/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xenserver65/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java index 10a97a21c12..0cf40f58d63 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java @@ -92,7 +92,7 @@ public class XenServerStorageProcessor implements StorageProcessor { protected CitrixResourceBase hypervisorResource; protected String BaseMountPointOnHost = "/var/run/cloud_mount"; - public XenServerStorageProcessor(CitrixResourceBase resource) { + public XenServerStorageProcessor(final CitrixResourceBase resource) { hypervisorResource = resource; } @@ -104,39 +104,39 @@ public class XenServerStorageProcessor implements StorageProcessor { // detach the new SR // if we needed to perform an attach to the source SR, detach from it @Override - public SnapshotAndCopyAnswer snapshotAndCopy(SnapshotAndCopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); + public SnapshotAndCopyAnswer snapshotAndCopy(final SnapshotAndCopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); try { SR sourceSr = null; - Map sourceDetails = cmd.getSourceDetails(); + final Map sourceDetails = cmd.getSourceDetails(); if (sourceDetails != null && sourceDetails.keySet().size() > 0) { - String iScsiName = sourceDetails.get(DiskTO.IQN); - String storageHost = sourceDetails.get(DiskTO.STORAGE_HOST); - String chapInitiatorUsername = sourceDetails.get(DiskTO.CHAP_INITIATOR_USERNAME); - String chapInitiatorSecret = sourceDetails.get(DiskTO.CHAP_INITIATOR_SECRET); + final String iScsiName = sourceDetails.get(DiskTO.IQN); + final String storageHost = sourceDetails.get(DiskTO.STORAGE_HOST); + final String chapInitiatorUsername = sourceDetails.get(DiskTO.CHAP_INITIATOR_USERNAME); + final String chapInitiatorSecret = sourceDetails.get(DiskTO.CHAP_INITIATOR_SECRET); sourceSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false); } - VDI vdiToSnapshot = VDI.getByUuid(conn, cmd.getUuidOfSourceVdi()); + final VDI vdiToSnapshot = VDI.getByUuid(conn, cmd.getUuidOfSourceVdi()); - VDI vdiSnapshot = vdiToSnapshot.snapshot(conn, new HashMap()); + final VDI vdiSnapshot = vdiToSnapshot.snapshot(conn, new HashMap()); - Map destDetails = cmd.getDestDetails(); + final Map destDetails = cmd.getDestDetails(); - String iScsiName = destDetails.get(DiskTO.IQN); - String storageHost = destDetails.get(DiskTO.STORAGE_HOST); - String chapInitiatorUsername = destDetails.get(DiskTO.CHAP_INITIATOR_USERNAME); - String chapInitiatorSecret = destDetails.get(DiskTO.CHAP_INITIATOR_SECRET); + final String iScsiName = destDetails.get(DiskTO.IQN); + final String storageHost = destDetails.get(DiskTO.STORAGE_HOST); + final String chapInitiatorUsername = destDetails.get(DiskTO.CHAP_INITIATOR_USERNAME); + final String chapInitiatorSecret = destDetails.get(DiskTO.CHAP_INITIATOR_SECRET); - SR newSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false); + final SR newSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false); - VDI vdiCopy = vdiSnapshot.copy(conn, newSr); + final VDI vdiCopy = vdiSnapshot.copy(conn, newSr); - String vdiUuid = vdiCopy.getUuid(conn); + final String vdiUuid = vdiCopy.getUuid(conn); vdiSnapshot.destroy(conn); @@ -146,13 +146,13 @@ public class XenServerStorageProcessor implements StorageProcessor { hypervisorResource.removeSR(conn, newSr); - SnapshotAndCopyAnswer snapshotAndCopyAnswer = new SnapshotAndCopyAnswer(); + final SnapshotAndCopyAnswer snapshotAndCopyAnswer = new SnapshotAndCopyAnswer(); snapshotAndCopyAnswer.setPath(vdiUuid); return snapshotAndCopyAnswer; } - catch (Exception ex) { + catch (final Exception ex) { s_logger.warn("Failed to take and copy snapshot: " + ex.toString(), ex); return new SnapshotAndCopyAnswer(ex.getMessage()); @@ -160,40 +160,40 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public AttachAnswer attachIso(AttachCommand cmd) { - DiskTO disk = cmd.getDisk(); - DataTO data = disk.getData(); - DataStoreTO store = data.getDataStore(); + public AttachAnswer attachIso(final AttachCommand cmd) { + final DiskTO disk = cmd.getDisk(); + final DataTO data = disk.getData(); + final DataStoreTO store = data.getDataStore(); String isoURL = null; if (store == null) { - TemplateObjectTO iso = (TemplateObjectTO) disk.getData(); + final TemplateObjectTO iso = (TemplateObjectTO) disk.getData(); isoURL = iso.getName(); } else { if (!(store instanceof NfsTO)) { s_logger.debug("Can't attach a iso which is not created on nfs: "); return new AttachAnswer("Can't attach a iso which is not created on nfs: "); } - NfsTO nfsStore = (NfsTO) store; + final NfsTO nfsStore = (NfsTO) store; isoURL = nfsStore.getUrl() + nfsStore.getPathSeparator() + data.getPath(); } - String vmName = cmd.getVmName(); + final String vmName = cmd.getVmName(); try { - Connection conn = hypervisorResource.getConnection(); + final Connection conn = hypervisorResource.getConnection(); VBD isoVBD = null; // Find the VM - VM vm = hypervisorResource.getVM(conn, vmName); + final VM vm = hypervisorResource.getVM(conn, vmName); // Find the ISO VDI - VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, vmName, isoURL); + final VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, vmName, isoURL); // Find the VM's CD-ROM VBD - Set vbds = vm.getVBDs(conn); - for (VBD vbd : vbds) { - String userDevice = vbd.getUserdevice(conn); - Types.VbdType type = vbd.getType(conn); + final Set vbds = vm.getVBDs(conn); + for (final VBD vbd : vbds) { + final String userDevice = vbd.getUserdevice(conn); + final Types.VbdType type = vbd.getType(conn); if (userDevice.equals("3") && type == Types.VbdType.CD) { isoVBD = vbd; @@ -215,39 +215,39 @@ public class XenServerStorageProcessor implements StorageProcessor { return new AttachAnswer(disk); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.warn("Failed to attach iso" + ": " + e.toString(), e); return new AttachAnswer(e.toString()); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("Failed to attach iso" + ": " + e.toString(), e); return new AttachAnswer(e.toString()); } } @Override - public AttachAnswer attachVolume(AttachCommand cmd) { - DiskTO disk = cmd.getDisk(); - DataTO data = disk.getData(); + public AttachAnswer attachVolume(final AttachCommand cmd) { + final DiskTO disk = cmd.getDisk(); + final DataTO data = disk.getData(); try { - String vmName = cmd.getVmName(); - String vdiNameLabel = vmName + "-DATA"; + final String vmName = cmd.getVmName(); + final String vdiNameLabel = vmName + "-DATA"; - Connection conn = this.hypervisorResource.getConnection(); + final Connection conn = hypervisorResource.getConnection(); VM vm = null; boolean vmNotRunning = true; try { - vm = this.hypervisorResource.getVM(conn, vmName); + vm = hypervisorResource.getVM(conn, vmName); - VM.Record vmr = vm.getRecord(conn); + final VM.Record vmr = vm.getRecord(conn); vmNotRunning = vmr.powerState != VmPowerState.RUNNING; - } catch (CloudRuntimeException ex) { + } catch (final CloudRuntimeException ex) { } - Map details = disk.getDetails(); - boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); + final Map details = disk.getDetails(); + final boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); // if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here) // this should probably never actually happen @@ -261,7 +261,7 @@ public class XenServerStorageProcessor implements StorageProcessor { vdi = hypervisorResource.prepareManagedStorage(conn, details, data.getPath(), vdiNameLabel); if (vmNotRunning) { - DiskTO newDisk = new DiskTO(disk.getData(), disk.getDiskSeq(), vdi.getUuid(conn), disk.getType()); + final DiskTO newDisk = new DiskTO(disk.getData(), disk.getDiskSeq(), vdi.getUuid(conn), disk.getType()); return new AttachAnswer(newDisk); } @@ -271,17 +271,17 @@ public class XenServerStorageProcessor implements StorageProcessor { // Figure out the disk number to attach the VM to String diskNumber = null; - Long deviceId = disk.getDiskSeq(); + final Long deviceId = disk.getDiskSeq(); if (deviceId != null) { if (deviceId.longValue() == 3) { - String msg = "Device 3 is reserved for CD-ROM, choose other device"; + final String msg = "Device 3 is reserved for CD-ROM, choose other device"; return new AttachAnswer(msg); } if (hypervisorResource.isDeviceUsed(conn, vm, deviceId)) { - String msg = "Device " + deviceId + " is used in VM " + vmName; + final String msg = "Device " + deviceId + " is used in VM " + vmName; return new AttachAnswer(msg); } @@ -291,7 +291,7 @@ public class XenServerStorageProcessor implements StorageProcessor { diskNumber = hypervisorResource.getUnusedDeviceNum(conn, vm); } - VBD.Record vbdr = new VBD.Record(); + final VBD.Record vbdr = new VBD.Record(); vbdr.VM = vm; vbdr.VDI = vdi; @@ -301,66 +301,66 @@ public class XenServerStorageProcessor implements StorageProcessor { vbdr.type = Types.VbdType.DISK; vbdr.unpluggable = true; - VBD vbd = VBD.create(conn, vbdr); + final VBD vbd = VBD.create(conn, vbdr); // Attach the VBD to the VM try { vbd.plug(conn); - } catch (Exception e) { + } catch (final Exception e) { vbd.destroy(conn); throw e; } // Update the VDI's label to include the VM name vdi.setNameLabel(conn, vdiNameLabel); - DiskTO newDisk = new DiskTO(disk.getData(), Long.parseLong(diskNumber), vdi.getUuid(conn), disk.getType()); + final DiskTO newDisk = new DiskTO(disk.getData(), Long.parseLong(diskNumber), vdi.getUuid(conn), disk.getType()); return new AttachAnswer(newDisk); - } catch (Exception e) { - String msg = "Failed to attach volume" + " for uuid: " + data.getPath() + " due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Failed to attach volume" + " for uuid: " + data.getPath() + " due to " + e.toString(); s_logger.warn(msg, e); return new AttachAnswer(msg); } } @Override - public Answer dettachIso(DettachCommand cmd) { - DiskTO disk = cmd.getDisk(); - DataTO data = disk.getData(); - DataStoreTO store = data.getDataStore(); + public Answer dettachIso(final DettachCommand cmd) { + final DiskTO disk = cmd.getDisk(); + final DataTO data = disk.getData(); + final DataStoreTO store = data.getDataStore(); String isoURL = null; if (store == null) { - TemplateObjectTO iso = (TemplateObjectTO) disk.getData(); + final TemplateObjectTO iso = (TemplateObjectTO) disk.getData(); isoURL = iso.getName(); } else { if (!(store instanceof NfsTO)) { s_logger.debug("Can't attach a iso which is not created on nfs: "); return new AttachAnswer("Can't attach a iso which is not created on nfs: "); } - NfsTO nfsStore = (NfsTO) store; + final NfsTO nfsStore = (NfsTO) store; isoURL = nfsStore.getUrl() + nfsStore.getPathSeparator() + data.getPath(); } try { - Connection conn = hypervisorResource.getConnection(); + final Connection conn = hypervisorResource.getConnection(); // Find the VM - VM vm = hypervisorResource.getVM(conn, cmd.getVmName()); - String vmUUID = vm.getUuid(conn); + final VM vm = hypervisorResource.getVM(conn, cmd.getVmName()); + final String vmUUID = vm.getUuid(conn); // Find the ISO VDI - VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, cmd.getVmName(), isoURL); + final VDI isoVDI = hypervisorResource.getIsoVDIByURL(conn, cmd.getVmName(), isoURL); - SR sr = isoVDI.getSR(conn); + final SR sr = isoVDI.getSR(conn); // Look up all VBDs for this VDI - Set vbds = isoVDI.getVBDs(conn); + final Set vbds = isoVDI.getVBDs(conn); // Iterate through VBDs, and if the VBD belongs the VM, eject // the ISO from it - for (VBD vbd : vbds) { - VM vbdVM = vbd.getVM(conn); - String vbdVmUUID = vbdVM.getUuid(conn); + for (final VBD vbd : vbds) { + final VM vbdVM = vbd.getVM(conn); + final String vbdVmUUID = vbdVM.getUuid(conn); if (vbdVmUUID.equals(vmUUID)) { // If an ISO is already inserted, eject it @@ -376,37 +376,37 @@ public class XenServerStorageProcessor implements StorageProcessor { } return new DettachAnswer(disk); - } catch (XenAPIException e) { - String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + " due to " + e.toString(); + } catch (final XenAPIException e) { + final String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + " due to " + e.toString(); s_logger.warn(msg, e); return new DettachAnswer(msg); - } catch (Exception e) { - String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + " due to " + e.getMessage(); + } catch (final Exception e) { + final String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + " due to " + e.getMessage(); s_logger.warn(msg, e); return new DettachAnswer(msg); } } @Override - public Answer dettachVolume(DettachCommand cmd) { - DiskTO disk = cmd.getDisk(); - DataTO data = disk.getData(); + public Answer dettachVolume(final DettachCommand cmd) { + final DiskTO disk = cmd.getDisk(); + final DataTO data = disk.getData(); try { - Connection conn = this.hypervisorResource.getConnection(); + final Connection conn = hypervisorResource.getConnection(); - String vmName = cmd.getVmName(); + final String vmName = cmd.getVmName(); VM vm = null; boolean vmNotRunning = true; try { - vm = this.hypervisorResource.getVM(conn, vmName); + vm = hypervisorResource.getVM(conn, vmName); - VM.Record vmr = vm.getRecord(conn); + final VM.Record vmr = vm.getRecord(conn); vmNotRunning = vmr.powerState != VmPowerState.RUNNING; - } catch (CloudRuntimeException ex) { + } catch (final CloudRuntimeException ex) { } // if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here) @@ -416,14 +416,14 @@ public class XenServerStorageProcessor implements StorageProcessor { } if (!vmNotRunning) { - VDI vdi = this.hypervisorResource.mount(conn, null, null, data.getPath()); + final VDI vdi = hypervisorResource.mount(conn, null, null, data.getPath()); // Look up all VBDs for this VDI - Set vbds = vdi.getVBDs(conn); + final Set vbds = vdi.getVBDs(conn); // Detach each VBD from its VM, and then destroy it - for (VBD vbd : vbds) { - VBD.Record vbdr = vbd.getRecord(conn); + for (final VBD vbd : vbds) { + final VBD.Record vbdr = vbd.getRecord(conn); if (vbdr.currentlyAttached) { vbd.unplug(conn); @@ -435,7 +435,7 @@ public class XenServerStorageProcessor implements StorageProcessor { // Update the VDI's label to be "detached" vdi.setNameLabel(conn, "detached"); - this.hypervisorResource.umount(conn, vdi); + hypervisorResource.umount(conn, vdi); } if (cmd.isManaged()) { @@ -443,83 +443,83 @@ public class XenServerStorageProcessor implements StorageProcessor { } return new DettachAnswer(disk); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("Failed dettach volume: " + data.getPath()); return new DettachAnswer("Failed dettach volume: " + data.getPath() + ", due to " + e.toString()); } } - protected SR getSRByNameLabel(Connection conn, String nameLabel) throws BadServerResponse, XenAPIException, XmlRpcException { - Set srs = SR.getByNameLabel(conn, nameLabel); + protected SR getSRByNameLabel(final Connection conn, final String nameLabel) throws BadServerResponse, XenAPIException, XmlRpcException { + final Set srs = SR.getByNameLabel(conn, nameLabel); if (srs.size() != 1) { throw new CloudRuntimeException("storage uuid: " + nameLabel + " is not unique"); } - SR poolsr = srs.iterator().next(); + final SR poolsr = srs.iterator().next(); return poolsr; } - protected VDI createVdi(Connection conn, String vdiName, SR sr, long size) throws BadServerResponse, XenAPIException, XmlRpcException { - VDI.Record vdir = new VDI.Record(); + protected VDI createVdi(final Connection conn, final String vdiName, final SR sr, final long size) throws BadServerResponse, XenAPIException, XmlRpcException { + final VDI.Record vdir = new VDI.Record(); vdir.nameLabel = vdiName; vdir.SR = sr; vdir.type = Types.VdiType.USER; vdir.virtualSize = size; - VDI vdi = VDI.create(conn, vdir); + final VDI vdi = VDI.create(conn, vdir); return vdi; } - protected void deleteVDI(Connection conn, VDI vdi) throws BadServerResponse, XenAPIException, XmlRpcException { + protected void deleteVDI(final Connection conn, final VDI vdi) throws BadServerResponse, XenAPIException, XmlRpcException { vdi.destroy(conn); } @Override - public Answer createSnapshot(CreateObjectCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - SnapshotObjectTO snapshotTO = (SnapshotObjectTO) cmd.getData(); - long snapshotId = snapshotTO.getId(); - String snapshotName = snapshotTO.getName(); + public Answer createSnapshot(final CreateObjectCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) cmd.getData(); + final long snapshotId = snapshotTO.getId(); + final String snapshotName = snapshotTO.getName(); String details = "create snapshot operation Failed for snapshotId: " + snapshotId; String snapshotUUID = null; try { - String volumeUUID = snapshotTO.getVolume().getPath(); - VDI volume = VDI.getByUuid(conn, volumeUUID); + final String volumeUUID = snapshotTO.getVolume().getPath(); + final VDI volume = VDI.getByUuid(conn, volumeUUID); - VDI snapshot = volume.snapshot(conn, new HashMap()); + final VDI snapshot = volume.snapshot(conn, new HashMap()); if (snapshotName != null) { snapshot.setNameLabel(conn, snapshotName); } snapshotUUID = snapshot.getUuid(conn); - String preSnapshotUUID = snapshotTO.getParentSnapshotPath(); + final String preSnapshotUUID = snapshotTO.getParentSnapshotPath(); //check if it is a empty snapshot if (preSnapshotUUID != null) { - SR sr = volume.getSR(conn); - String srUUID = sr.getUuid(conn); - String type = sr.getType(conn); - Boolean isISCSI = IsISCSI(type); - String snapshotParentUUID = getVhdParent(conn, srUUID, snapshotUUID, isISCSI); + final SR sr = volume.getSR(conn); + final String srUUID = sr.getUuid(conn); + final String type = sr.getType(conn); + final Boolean isISCSI = IsISCSI(type); + final String snapshotParentUUID = getVhdParent(conn, srUUID, snapshotUUID, isISCSI); try { - String preSnapshotParentUUID = getVhdParent(conn, srUUID, preSnapshotUUID, isISCSI); + final String preSnapshotParentUUID = getVhdParent(conn, srUUID, preSnapshotUUID, isISCSI); if (snapshotParentUUID != null && snapshotParentUUID.equals(preSnapshotParentUUID)) { // this is empty snapshot, remove it snapshot.destroy(conn); snapshotUUID = preSnapshotUUID; } - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to get parent snapshot", e); } } - SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + final SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); newSnapshot.setPath(snapshotUUID); return new CreateObjectAnswer(newSnapshot); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { details += ", reason: " + e.toString(); s_logger.warn(details, e); - } catch (Exception e) { + } catch (final Exception e) { details += ", reason: " + e.toString(); s_logger.warn(details, e); } @@ -528,47 +528,47 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer deleteVolume(DeleteCommand cmd) { - DataTO volume = cmd.getData(); - Connection conn = hypervisorResource.getConnection(); + public Answer deleteVolume(final DeleteCommand cmd) { + final DataTO volume = cmd.getData(); + final Connection conn = hypervisorResource.getConnection(); String errorMsg = null; try { - VDI vdi = VDI.getByUuid(conn, volume.getPath()); + final VDI vdi = VDI.getByUuid(conn, volume.getPath()); deleteVDI(conn, vdi); return new Answer(null); - } catch (BadServerResponse e) { + } catch (final BadServerResponse e) { s_logger.debug("Failed to delete volume", e); errorMsg = e.toString(); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.debug("Failed to delete volume", e); errorMsg = e.toString(); - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { s_logger.debug("Failed to delete volume", e); errorMsg = e.toString(); } return new Answer(null, false, errorMsg); } - protected SR getNfsSR(Connection conn, StorageFilerTO pool) { - Map deviceConfig = new HashMap(); + protected SR getNfsSR(final Connection conn, final StorageFilerTO pool) { + final Map deviceConfig = new HashMap(); try { - String server = pool.getHost(); + final String server = pool.getHost(); String serverpath = pool.getPath(); serverpath = serverpath.replace("//", "/"); - Set srs = SR.getAll(conn); - for (SR sr : srs) { + final Set srs = SR.getAll(conn); + for (final SR sr : srs) { if (!SRType.NFS.equals(sr.getType(conn))) { continue; } - Set pbds = sr.getPBDs(conn); + final Set pbds = sr.getPBDs(conn); if (pbds.isEmpty()) { continue; } - PBD pbd = pbds.iterator().next(); + final PBD pbd = pbds.iterator().next(); - Map dc = pbd.getDeviceConfig(conn); + final Map dc = pbd.getDeviceConfig(conn); if (dc == null) { continue; @@ -584,27 +584,27 @@ public class XenServerStorageProcessor implements StorageProcessor { if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath") + - " for pool " + pool.getUuid() + "on host:" + hypervisorResource.getHost().uuid); + " for pool " + pool.getUuid() + "on host:" + hypervisorResource.getHost().getUuid()); } } deviceConfig.put("server", server); deviceConfig.put("serverpath", serverpath); - Host host = Host.getByUuid(conn, hypervisorResource.getHost().uuid); - Map smConfig = new HashMap(); + final Host host = Host.getByUuid(conn, hypervisorResource.getHost().getUuid()); + final Map smConfig = new HashMap(); smConfig.put("nosubdir", "true"); - SR sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, smConfig); + final SR sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, smConfig); sr.scan(conn); return sr; - } catch (XenAPIException e) { + } catch (final XenAPIException e) { throw new CloudRuntimeException("Unable to create NFS SR " + pool.toString(), e); - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { throw new CloudRuntimeException("Unable to create NFS SR " + pool.toString(), e); } } - protected Answer directDownloadHttpTemplate(CopyCommand cmd, DecodedDataObject srcObj, DecodedDataObject destObj) { - Connection conn = hypervisorResource.getConnection(); + protected Answer directDownloadHttpTemplate(final CopyCommand cmd, final DecodedDataObject srcObj, final DecodedDataObject destObj) { + final Connection conn = hypervisorResource.getConnection(); SR poolsr = null; VDI vdi = null; boolean result = false; @@ -617,53 +617,53 @@ public class XenServerStorageProcessor implements StorageProcessor { if (vdi == null) { throw new CloudRuntimeException("can't find volume: " + destObj.getPath()); } - String destStoreUuid = destObj.getStore().getUuid(); - Set srs = SR.getByNameLabel(conn, destStoreUuid); + final String destStoreUuid = destObj.getStore().getUuid(); + final Set srs = SR.getByNameLabel(conn, destStoreUuid); if (srs.size() != 1) { throw new CloudRuntimeException("storage uuid: " + destStoreUuid + " is not unique"); } poolsr = srs.iterator().next(); - VDI.Record vdir = vdi.getRecord(conn); - String vdiLocation = vdir.location; + final VDI.Record vdir = vdi.getRecord(conn); + final String vdiLocation = vdir.location; String pbdLocation = null; if (destObj.getStore().getScheme().equalsIgnoreCase(DataStoreProtocol.NFS.toString())) { pbdLocation = "/run/sr-mount/" + poolsr.getUuid(conn); } else { - Set pbds = poolsr.getPBDs(conn); + final Set pbds = poolsr.getPBDs(conn); if (pbds.size() != 1) { throw new CloudRuntimeException("Don't how to handle multiple pbds:" + pbds.size() + " for sr: " + poolsr.getUuid(conn)); } - PBD pbd = pbds.iterator().next(); - Map deviceCfg = pbd.getDeviceConfig(conn); + final PBD pbd = pbds.iterator().next(); + final Map deviceCfg = pbd.getDeviceConfig(conn); pbdLocation = deviceCfg.get("location"); } if (pbdLocation == null) { throw new CloudRuntimeException("Can't get pbd location"); } - String vdiPath = pbdLocation + "/" + vdiLocation + ".vhd"; + final String vdiPath = pbdLocation + "/" + vdiLocation + ".vhd"; //download a url into vdipath //downloadHttpToLocalFile(vdiPath, template.getPath()); hypervisorResource.callHostPlugin(conn, "storagePlugin", "downloadTemplateFromUrl", "destPath", vdiPath, "srcUrl", srcObj.getPath()); result = true; //return new CopyCmdAnswer(cmd, vdi.getUuid(conn)); - } catch (BadServerResponse e) { + } catch (final BadServerResponse e) { s_logger.debug("Failed to download template", e); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.debug("Failed to download template", e); - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { s_logger.debug("Failed to download template", e); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to download template", e); } finally { if (!result && vdi != null) { try { vdi.destroy(conn); - } catch (BadServerResponse e) { + } catch (final BadServerResponse e) { s_logger.debug("Failed to cleanup newly created vdi"); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.debug("Failed to cleanup newly created vdi"); - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { s_logger.debug("Failed to cleanup newly created vdi"); } } @@ -671,61 +671,61 @@ public class XenServerStorageProcessor implements StorageProcessor { return new Answer(cmd, false, "Failed to download template"); } - protected Answer execute(AttachPrimaryDataStoreCmd cmd) { - String dataStoreUri = cmd.getDataStore(); - Connection conn = hypervisorResource.getConnection(); + protected Answer execute(final AttachPrimaryDataStoreCmd cmd) { + final String dataStoreUri = cmd.getDataStore(); + final Connection conn = hypervisorResource.getConnection(); try { - DecodedDataObject obj = Decoder.decode(dataStoreUri); + final DecodedDataObject obj = Decoder.decode(dataStoreUri); - DecodedDataStore store = obj.getStore(); + final DecodedDataStore store = obj.getStore(); - SR sr = hypervisorResource.getStorageRepository(conn, store.getUuid()); + final SR sr = hypervisorResource.getStorageRepository(conn, store.getUuid()); hypervisorResource.setupHeartbeatSr(conn, sr, false); - long capacity = sr.getPhysicalSize(conn); - long available = capacity - sr.getPhysicalUtilisation(conn); + final long capacity = sr.getPhysicalSize(conn); + final long available = capacity - sr.getPhysicalUtilisation(conn); if (capacity == -1) { - String msg = "Pool capacity is -1! pool: "; + final String msg = "Pool capacity is -1! pool: "; s_logger.warn(msg); return new Answer(cmd, false, msg); } - AttachPrimaryDataStoreAnswer answer = new AttachPrimaryDataStoreAnswer(cmd); + final AttachPrimaryDataStoreAnswer answer = new AttachPrimaryDataStoreAnswer(cmd); answer.setCapacity(capacity); answer.setUuid(sr.getUuid(conn)); answer.setAvailable(available); return answer; - } catch (XenAPIException e) { - String msg = "AttachPrimaryDataStoreCmd add XenAPIException:" + e.toString(); + } catch (final XenAPIException e) { + final String msg = "AttachPrimaryDataStoreCmd add XenAPIException:" + e.toString(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); - } catch (Exception e) { - String msg = "AttachPrimaryDataStoreCmd failed:" + e.getMessage(); + } catch (final Exception e) { + final String msg = "AttachPrimaryDataStoreCmd failed:" + e.getMessage(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); } } - protected boolean IsISCSI(String type) { + protected boolean IsISCSI(final String type) { return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type); } - private String copy_vhd_from_secondarystorage(Connection conn, String mountpoint, String sruuid, int wait) { - String nameLabel = "cloud-" + UUID.randomUUID().toString(); - String results = + private String copy_vhd_from_secondarystorage(final Connection conn, final String mountpoint, final String sruuid, final int wait) { + final String nameLabel = "cloud-" + UUID.randomUUID().toString(); + final String results = hypervisorResource.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 { - String[] tmp = results.split("#"); - String status = tmp[0]; + final String[] tmp = results.split("#"); + final String status = tmp[0]; if (status.equals("0")) { return tmp[1]; } else { errMsg = tmp[1]; } } - String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1); + final String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1); if (hypervisorResource.killCopyProcess(conn, source)) { destroyVDIbyNameLabel(conn, nameLabel); } @@ -733,35 +733,35 @@ public class XenServerStorageProcessor implements StorageProcessor { throw new CloudRuntimeException(errMsg); } - private void destroyVDIbyNameLabel(Connection conn, String nameLabel) { + private void destroyVDIbyNameLabel(final Connection conn, final String nameLabel) { try { - Set vdis = VDI.getByNameLabel(conn, nameLabel); + final Set vdis = VDI.getByNameLabel(conn, nameLabel); if (vdis.size() != 1) { s_logger.warn("destoryVDIbyNameLabel failed due to there are " + vdis.size() + " VDIs with name " + nameLabel); return; } - for (VDI vdi : vdis) { + for (final VDI vdi : vdis) { try { vdi.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { } } - } catch (Exception e) { + } catch (final Exception e) { } } - protected VDI getVDIbyUuid(Connection conn, String uuid) { + protected VDI getVDIbyUuid(final Connection conn, final String uuid) { try { return VDI.getByUuid(conn, uuid); - } catch (Exception e) { - String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString(); s_logger.debug(msg); throw new CloudRuntimeException(msg, e); } } - protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { - String parentUuid = + protected String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) { + final String parentUuid = hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString()); @@ -774,20 +774,20 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { - DataTO srcDataTo = cmd.getSrcTO(); - DataTO destDataTo = cmd.getDestTO(); - int wait = cmd.getWait(); - DataStoreTO srcDataStoreTo = srcDataTo.getDataStore(); + public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) { + final DataTO srcDataTo = cmd.getSrcTO(); + final DataTO destDataTo = cmd.getDestTO(); + final int wait = cmd.getWait(); + final DataStoreTO srcDataStoreTo = srcDataTo.getDataStore(); try { - if ((srcDataStoreTo instanceof NfsTO) && (srcDataTo.getObjectType() == DataObjectType.TEMPLATE)) { - NfsTO srcImageStore = (NfsTO) srcDataStoreTo; - TemplateObjectTO srcTemplateObjectTo = (TemplateObjectTO) srcDataTo; - String storeUrl = srcImageStore.getUrl(); - URI uri = new URI(storeUrl); - String tmplPath = uri.getHost() + ":" + uri.getPath() + "/" + srcDataTo.getPath(); - DataStoreTO destDataStoreTo = destDataTo.getDataStore(); + if (srcDataStoreTo instanceof NfsTO && srcDataTo.getObjectType() == DataObjectType.TEMPLATE) { + final NfsTO srcImageStore = (NfsTO) srcDataStoreTo; + final TemplateObjectTO srcTemplateObjectTo = (TemplateObjectTO) srcDataTo; + final String storeUrl = srcImageStore.getUrl(); + final URI uri = new URI(storeUrl); + final String tmplPath = uri.getHost() + ":" + uri.getPath() + "/" + srcDataTo.getPath(); + final DataStoreTO destDataStoreTo = destDataTo.getDataStore(); boolean managed = false; String storageHost = null; @@ -798,9 +798,9 @@ public class XenServerStorageProcessor implements StorageProcessor { String chapInitiatorSecret = null; if (destDataStoreTo instanceof PrimaryDataStoreTO) { - PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destDataStoreTo; + final PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destDataStoreTo; - Map details = destPrimaryDataStoreTo.getDetails(); + final Map details = destPrimaryDataStoreTo.getDetails(); if (details != null) { managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED)); @@ -816,12 +816,12 @@ public class XenServerStorageProcessor implements StorageProcessor { } } - Connection conn = hypervisorResource.getConnection(); + final Connection conn = hypervisorResource.getConnection(); final SR sr; if (managed) { - Map details = new HashMap(); + final Map details = new HashMap(); details.put(DiskTO.STORAGE_HOST, storageHost); details.put(DiskTO.IQN, managedStoragePoolName); @@ -831,11 +831,11 @@ public class XenServerStorageProcessor implements StorageProcessor { sr = hypervisorResource.prepareManagedSr(conn, details); } else { - String srName = destDataStoreTo.getUuid(); - Set srs = SR.getByNameLabel(conn, srName); + final String srName = destDataStoreTo.getUuid(); + final Set srs = SR.getByNameLabel(conn, srName); if (srs.size() != 1) { - String msg = "There are " + srs.size() + " SRs with same name: " + srName; + final String msg = "There are " + srs.size() + " SRs with same name: " + srName; s_logger.warn(msg); @@ -845,19 +845,19 @@ public class XenServerStorageProcessor implements StorageProcessor { } } - String srUuid = sr.getUuid(conn); - String tmplUuid = copy_vhd_from_secondarystorage(conn, tmplPath, srUuid, wait); - VDI tmplVdi = getVDIbyUuid(conn, tmplUuid); + final String srUuid = sr.getUuid(conn); + final String tmplUuid = copy_vhd_from_secondarystorage(conn, tmplPath, srUuid, wait); + final VDI tmplVdi = getVDIbyUuid(conn, tmplUuid); final String uuidToReturn; - Long physicalSize = tmplVdi.getPhysicalUtilisation(conn); + final Long physicalSize = tmplVdi.getPhysicalUtilisation(conn); if (managed) { uuidToReturn = tmplUuid; tmplVdi.setNameLabel(conn, managedStoragePoolRootVolumeName); } else { - VDI snapshotVdi = tmplVdi.snapshot(conn, new HashMap()); + final VDI snapshotVdi = tmplVdi.snapshot(conn, new HashMap()); uuidToReturn = snapshotVdi.getUuid(conn); @@ -870,10 +870,10 @@ public class XenServerStorageProcessor implements StorageProcessor { try { Thread.sleep(5000); - } catch (InterruptedException e) { + } catch (final InterruptedException e) { } - TemplateObjectTO newVol = new TemplateObjectTO(); + final TemplateObjectTO newVol = new TemplateObjectTO(); newVol.setUuid(uuidToReturn); newVol.setPath(uuidToReturn); @@ -884,8 +884,8 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CopyCmdAnswer(newVol); } - } catch (Exception e) { - String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString(); s_logger.warn(msg, e); @@ -896,13 +896,13 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer createVolume(CreateObjectCommand cmd) { - DataTO data = cmd.getData(); - VolumeObjectTO volume = (VolumeObjectTO) data; + public Answer createVolume(final CreateObjectCommand cmd) { + final DataTO data = cmd.getData(); + final VolumeObjectTO volume = (VolumeObjectTO) data; try { - Connection conn = hypervisorResource.getConnection(); - SR poolSr = hypervisorResource.getStorageRepository(conn, data.getDataStore().getUuid()); + final Connection conn = hypervisorResource.getConnection(); + final SR poolSr = hypervisorResource.getStorageRepository(conn, data.getDataStore().getUuid()); VDI.Record vdir = new VDI.Record(); vdir.nameLabel = volume.getName(); vdir.SR = poolSr; @@ -913,24 +913,24 @@ public class XenServerStorageProcessor implements StorageProcessor { vdi = VDI.create(conn, vdir); vdir = vdi.getRecord(conn); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setName(vdir.nameLabel); newVol.setSize(vdir.virtualSize); newVol.setPath(vdir.uuid); return new CreateObjectAnswer(newVol); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("create volume failed: " + e.toString()); return new CreateObjectAnswer(e.toString()); } } @Override - public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - VolumeObjectTO volume = (VolumeObjectTO) destData; + public Answer cloneVolumeFromBaseTemplate(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final DataTO srcData = cmd.getSrcTO(); + final DataTO destData = cmd.getDestTO(); + final VolumeObjectTO volume = (VolumeObjectTO) destData; VDI vdi = null; try { VDI tmpltvdi = null; @@ -943,43 +943,43 @@ public class XenServerStorageProcessor implements StorageProcessor { vdir = vdi.getRecord(conn); s_logger.debug("Succesfully created VDI: Uuid = " + vdir.uuid); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setName(vdir.nameLabel); newVol.setSize(vdir.virtualSize); newVol.setPath(vdir.uuid); return new CopyCmdAnswer(newVol); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("Unable to create volume; Pool=" + destData + "; Disk: ", e); return new CopyCmdAnswer(e.toString()); } } @Override - public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - int wait = cmd.getWait(); - VolumeObjectTO srcVolume = (VolumeObjectTO) srcData; - VolumeObjectTO destVolume = (VolumeObjectTO) destData; - DataStoreTO srcStore = srcVolume.getDataStore(); + public Answer copyVolumeFromImageCacheToPrimary(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final DataTO srcData = cmd.getSrcTO(); + final DataTO destData = cmd.getDestTO(); + final int wait = cmd.getWait(); + final VolumeObjectTO srcVolume = (VolumeObjectTO) srcData; + final VolumeObjectTO destVolume = (VolumeObjectTO) destData; + final DataStoreTO srcStore = srcVolume.getDataStore(); if (srcStore instanceof NfsTO) { - NfsTO nfsStore = (NfsTO) srcStore; + final NfsTO nfsStore = (NfsTO) srcStore; try { - SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, destVolume.getDataStore().getUuid()); - String srUuid = primaryStoragePool.getUuid(conn); - URI uri = new URI(nfsStore.getUrl()); - String volumePath = uri.getHost() + ":" + uri.getPath() + nfsStore.getPathSeparator() + srcVolume.getPath(); - String uuid = copy_vhd_from_secondarystorage(conn, volumePath, srUuid, wait); - VolumeObjectTO newVol = new VolumeObjectTO(); + final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, destVolume.getDataStore().getUuid()); + final String srUuid = primaryStoragePool.getUuid(conn); + final URI uri = new URI(nfsStore.getUrl()); + final String volumePath = uri.getHost() + ":" + uri.getPath() + nfsStore.getPathSeparator() + srcVolume.getPath(); + final String uuid = copy_vhd_from_secondarystorage(conn, volumePath, srUuid, wait); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(uuid); newVol.setSize(srcVolume.getSize()); return new CopyCmdAnswer(newVol); - } catch (Exception e) { - String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString(); s_logger.warn(msg, e); return new CopyCmdAnswer(e.toString()); } @@ -990,18 +990,18 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - VolumeObjectTO srcVolume = (VolumeObjectTO) cmd.getSrcTO(); - VolumeObjectTO destVolume = (VolumeObjectTO) cmd.getDestTO(); - int wait = cmd.getWait(); - DataStoreTO destStore = destVolume.getDataStore(); + public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final VolumeObjectTO srcVolume = (VolumeObjectTO) cmd.getSrcTO(); + final VolumeObjectTO destVolume = (VolumeObjectTO) cmd.getDestTO(); + final int wait = cmd.getWait(); + final DataStoreTO destStore = destVolume.getDataStore(); if (destStore instanceof NfsTO) { SR secondaryStorage = null; try { - NfsTO nfsStore = (NfsTO) destStore; - URI uri = new URI(nfsStore.getUrl()); + final NfsTO nfsStore = (NfsTO) destStore; + final URI uri = new URI(nfsStore.getUrl()); // Create the volume folder if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) { throw new InternalErrorException("Failed to create the volume folder."); @@ -1010,16 +1010,16 @@ public class XenServerStorageProcessor implements StorageProcessor { // Create a SR for the volume UUID folder secondaryStorage = hypervisorResource.createNfsSRbyURI(conn, new URI(nfsStore.getUrl() + nfsStore.getPathSeparator() + destVolume.getPath()), false); // Look up the volume on the source primary storage pool - VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath()); + final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath()); // Copy the volume to secondary storage - VDI destVdi = hypervisorResource.cloudVDIcopy(conn, srcVdi, secondaryStorage, wait); - String destVolumeUUID = destVdi.getUuid(conn); + final VDI destVdi = hypervisorResource.cloudVDIcopy(conn, srcVdi, secondaryStorage, wait); + final String destVolumeUUID = destVdi.getUuid(conn); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(destVolume.getPath() + nfsStore.getPathSeparator() + destVolumeUUID + ".vhd"); newVol.setSize(srcVolume.getSize()); return new CopyCmdAnswer(newVol); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to copy volume to secondary: " + e.toString()); return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString()); } finally { @@ -1029,7 +1029,7 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CopyCmdAnswer("unsupported protocol"); } - boolean swiftUpload(Connection conn, SwiftTO swift, String container, String ldir, String lfilename, Boolean isISCSI, int wait) { + boolean swiftUpload(final Connection conn, final SwiftTO swift, final String container, final String ldir, final String lfilename, final Boolean isISCSI, final int wait) { String result = null; try { result = @@ -1038,23 +1038,23 @@ public class XenServerStorageProcessor implements StorageProcessor { if (result != null && result.equals("true")) { return true; } - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("swift upload failed due to " + e.toString(), e); } return false; } - protected String deleteSnapshotBackup(Connection conn, String localMountPoint, String path, String secondaryStorageMountPath, String backupUUID) { + protected String deleteSnapshotBackup(final Connection conn, final String localMountPoint, final String path, final String secondaryStorageMountPath, final String backupUUID) { // If anybody modifies the formatting below again, I'll skin them - String result = + final String result = hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath, "localMountPoint", localMountPoint); return result; } - public String swiftBackupSnapshot(Connection conn, SwiftTO swift, String srUuid, String snapshotUuid, String container, Boolean isISCSI, int wait) { + public String swiftBackupSnapshot(final Connection conn, final SwiftTO swift, final String srUuid, final String snapshotUuid, final String container, final Boolean isISCSI, final int wait) { String lfilename; String ldir; if (isISCSI) { @@ -1069,7 +1069,7 @@ public class XenServerStorageProcessor implements StorageProcessor { } protected String backupSnapshotToS3(final Connection connection, final S3TO s3, final String srUuid, final String folder, final String snapshotUuid, - final Boolean iSCSIFlag, final int wait) { + final Boolean iSCSIFlag, final int wait) { final String filename = iSCSIFlag ? "VHD-" + snapshotUuid : snapshotUuid + ".vhd"; final String dir = (iSCSIFlag ? "/dev/VG_XenStorage-" : "/var/run/sr-mount/") + srUuid; @@ -1090,7 +1090,7 @@ public class XenServerStorageProcessor implements StorageProcessor { } return null; - } catch (Exception e) { + } catch (final Exception e) { s_logger.error(String.format("S3 upload failed of snapshot %1$s due to %2$s.", snapshotUuid, e.toString()), e); } @@ -1098,8 +1098,8 @@ public class XenServerStorageProcessor implements StorageProcessor { } - protected Long getSnapshotSize(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI, int wait) { - String physicalSize = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "getSnapshotSize", wait, + protected Long getSnapshotSize(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI, final int wait) { + final String physicalSize = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "getSnapshotSize", wait, "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString()); if (physicalSize == null || physicalSize.isEmpty()) { return (long) 0; @@ -1108,8 +1108,8 @@ public class XenServerStorageProcessor implements StorageProcessor { } } - protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, String localMountPoint, String path, String secondaryStorageMountPath, - String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait) { + protected String backupSnapshot(final Connection conn, final String primaryStorageSRUuid, final String localMountPoint, final String path, final String secondaryStorageMountPath, + final String snapshotUuid, String prevBackupUuid, final Boolean isISCSI, final int wait) { String backupSnapshotUuid = null; if (prevBackupUuid == null) { @@ -1118,8 +1118,8 @@ public class XenServerStorageProcessor implements StorageProcessor { // Each argument is put in a separate line for readability. // Using more lines does not harm the environment. - String backupUuid = UUID.randomUUID().toString(); - String results = + final String backupUuid = UUID.randomUUID().toString(); + final String results = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait, "primaryStorageSRUuid", primaryStorageSRUuid, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath, "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString(), "localMountPoint", localMountPoint); @@ -1130,8 +1130,8 @@ public class XenServerStorageProcessor implements StorageProcessor { secondaryStorageMountPath + " due to null"; } else { - String[] tmp = results.split("#"); - String status = tmp[0]; + final String[] tmp = results.split("#"); + final String status = tmp[0]; backupSnapshotUuid = tmp[1]; // status == "1" if and only if backupSnapshotUuid != null // So we don't rely on status value but return backupSnapshotUuid as an @@ -1145,45 +1145,45 @@ public class XenServerStorageProcessor implements StorageProcessor { secondaryStorageMountPath + " due to " + tmp[1]; } } - String source = backupUuid + ".vhd"; + final String source = backupUuid + ".vhd"; hypervisorResource.killCopyProcess(conn, source); s_logger.warn(errMsg); throw new CloudRuntimeException(errMsg); } - protected boolean destroySnapshotOnPrimaryStorageExceptThis(Connection conn, String volumeUuid, String avoidSnapshotUuid) { + protected boolean destroySnapshotOnPrimaryStorageExceptThis(final Connection conn, final String volumeUuid, final String avoidSnapshotUuid) { try { - VDI volume = getVDIbyUuid(conn, volumeUuid); + final VDI volume = getVDIbyUuid(conn, volumeUuid); if (volume == null) { throw new InternalErrorException("Could not destroy snapshot on volume " + volumeUuid + " due to can not find it"); } - Set snapshots = volume.getSnapshots(conn); - for (VDI snapshot : snapshots) { + final Set snapshots = volume.getSnapshots(conn); + for (final VDI snapshot : snapshots) { try { if (!snapshot.getUuid(conn).equals(avoidSnapshotUuid)) { snapshot.destroy(conn); } - } catch (Exception e) { - String msg = "Destroying snapshot: " + snapshot + " on primary storage failed due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Destroying snapshot: " + snapshot + " on primary storage failed due to " + e.toString(); s_logger.warn(msg, e); } } s_logger.debug("Successfully destroyed snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid); return true; - } catch (XenAPIException e) { - String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString(); + } catch (final XenAPIException e) { + final String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString(); s_logger.error(msg, e); - } catch (Exception e) { - String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot " + avoidSnapshotUuid + " failed due to " + e.toString(); s_logger.warn(msg, e); } return false; } - private boolean destroySnapshotOnPrimaryStorage(Connection conn, String lastSnapshotUuid) { + private boolean destroySnapshotOnPrimaryStorage(final Connection conn, final String lastSnapshotUuid) { try { - VDI snapshot = getVDIbyUuid(conn, lastSnapshotUuid); + final VDI snapshot = getVDIbyUuid(conn, lastSnapshotUuid); if (snapshot == null) { // since this is just used to cleanup leftover bad snapshots, no need to throw exception s_logger.warn("Could not destroy snapshot " + lastSnapshotUuid + " due to can not find it"); @@ -1191,24 +1191,24 @@ public class XenServerStorageProcessor implements StorageProcessor { } snapshot.destroy(conn); return true; - } catch (XenAPIException e) { - String msg = "Destroying snapshot: " + lastSnapshotUuid + " failed due to " + e.toString(); + } catch (final XenAPIException e) { + final String msg = "Destroying snapshot: " + lastSnapshotUuid + " failed due to " + e.toString(); s_logger.error(msg, e); - } catch (Exception e) { - String msg = "Destroying snapshot: " + lastSnapshotUuid + " failed due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Destroying snapshot: " + lastSnapshotUuid + " failed due to " + e.toString(); s_logger.warn(msg, e); } return false; } @Override - public Answer backupSnapshot(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - DataTO srcData = cmd.getSrcTO(); - DataTO cacheData = cmd.getCacheTO(); - DataTO destData = cmd.getDestTO(); - int wait = cmd.getWait(); - String primaryStorageNameLabel = srcData.getDataStore().getUuid(); + public Answer backupSnapshot(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final DataTO srcData = cmd.getSrcTO(); + final DataTO cacheData = cmd.getCacheTO(); + final DataTO destData = cmd.getDestTO(); + final int wait = cmd.getWait(); + final String primaryStorageNameLabel = srcData.getDataStore().getUuid(); String secondaryStorageUrl = null; NfsTO cacheStore = null; String destPath = null; @@ -1222,58 +1222,58 @@ public class XenServerStorageProcessor implements StorageProcessor { destPath = destData.getPath(); } - SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData; - SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData; - String snapshotUuid = snapshotTO.getPath(); - String volumeUuid = snapshotTO.getVolume().getPath(); + final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData; + final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData; + final String snapshotUuid = snapshotTO.getPath(); + final String volumeUuid = snapshotTO.getVolume().getPath(); - String prevBackupUuid = snapshotOnImage.getParentSnapshotPath(); - String prevSnapshotUuid = snapshotTO.getParentSnapshotPath(); + final String prevBackupUuid = snapshotOnImage.getParentSnapshotPath(); + final String prevSnapshotUuid = snapshotTO.getParentSnapshotPath(); // By default assume failure String details = null; String snapshotBackupUuid = null; Long physicalSize = null; - Map options = cmd.getOptions(); + final Map options = cmd.getOptions(); boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot")); boolean result = false; try { - SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); + final SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); if (primaryStorageSR == null) { throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel); } - String psUuid = primaryStorageSR.getUuid(conn); - Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn)); + final String psUuid = primaryStorageSR.getUuid(conn); + final Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn)); - VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid); + final VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid); String snapshotPaUuid = null; if (prevSnapshotUuid != null && !fullbackup) { try { snapshotPaUuid = getVhdParent(conn, psUuid, snapshotUuid, isISCSI); if (snapshotPaUuid != null) { - String snashotPaPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI); - String prevSnashotPaUuid = getVhdParent(conn, psUuid, prevSnapshotUuid, isISCSI); + final String snashotPaPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI); + final String prevSnashotPaUuid = getVhdParent(conn, psUuid, prevSnapshotUuid, isISCSI); if (snashotPaPaPaUuid != null && prevSnashotPaUuid != null && prevSnashotPaUuid.equals(snashotPaPaPaUuid)) { fullbackup = false; } else { fullbackup = true; } } - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to get parent snapshots, take full snapshot", e); fullbackup = true; } } - URI uri = new URI(secondaryStorageUrl); - String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); - DataStoreTO destStore = destData.getDataStore(); - String folder = destPath; + final URI uri = new URI(secondaryStorageUrl); + final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); + final DataStoreTO destStore = destData.getDataStore(); + final String folder = destPath; String finalPath = null; - String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString(); + final String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString(); if (fullbackup) { // the first snapshot is always a full snapshot @@ -1282,25 +1282,25 @@ public class XenServerStorageProcessor implements StorageProcessor { s_logger.warn(details); return new CopyCmdAnswer(details); } - String snapshotMountpoint = secondaryStorageUrl + "/" + folder; + final String snapshotMountpoint = secondaryStorageUrl + "/" + folder; SR snapshotSr = null; try { snapshotSr = hypervisorResource.createNfsSRbyURI(conn, new URI(snapshotMountpoint), false); - VDI backedVdi = hypervisorResource.cloudVDIcopy(conn, snapshotVdi, snapshotSr, wait); + final VDI backedVdi = hypervisorResource.cloudVDIcopy(conn, snapshotVdi, snapshotSr, wait); snapshotBackupUuid = backedVdi.getUuid(conn); - String primarySRuuid = snapshotSr.getUuid(conn); + final String primarySRuuid = snapshotSr.getUuid(conn); physicalSize = getSnapshotSize(conn, primarySRuuid, snapshotBackupUuid, isISCSI, wait); if (destStore instanceof SwiftTO) { try { - String container = "S-" + snapshotTO.getVolume().getVolumeId().toString(); - String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO) destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait); - String swiftPath = container + File.separator + destSnapshotName; + final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString(); + final String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO) destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait); + final String swiftPath = container + File.separator + destSnapshotName; finalPath = swiftPath; } finally { try { deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to delete snapshot on cache storages", e); } } @@ -1314,7 +1314,7 @@ public class XenServerStorageProcessor implements StorageProcessor { } finally { try { deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to delete snapshot on cache storages", e); } } @@ -1329,9 +1329,9 @@ public class XenServerStorageProcessor implements StorageProcessor { } } } else { - String primaryStorageSRUuid = primaryStorageSR.getUuid(conn); + final String primaryStorageSRUuid = primaryStorageSR.getUuid(conn); if (destStore instanceof SwiftTO) { - String container = "S-" + snapshotTO.getVolume().getVolumeId().toString(); + final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString(); snapshotBackupUuid = swiftBackupSnapshot(conn, (SwiftTO) destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait); @@ -1342,10 +1342,10 @@ public class XenServerStorageProcessor implements StorageProcessor { throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed"); } } else { - String results = + final String results = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait); - String[] tmp = results.split("#"); + final String[] tmp = results.split("#"); snapshotBackupUuid = tmp[1]; physicalSize = Long.parseLong(tmp[2]); finalPath = folder + cacheStore.getPathSeparator() + snapshotBackupUuid; @@ -1354,7 +1354,7 @@ public class XenServerStorageProcessor implements StorageProcessor { // delete primary snapshots with only the last one left destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid); - SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + final SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); newSnapshot.setPath(finalPath); newSnapshot.setPhysicalSize(physicalSize); if (fullbackup) { @@ -1364,10 +1364,10 @@ public class XenServerStorageProcessor implements StorageProcessor { } result = true; return new CopyCmdAnswer(newSnapshot); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { details = "BackupSnapshot Failed due to " + e.toString(); s_logger.warn(details, e); - } catch (Exception e) { + } catch (final Exception e) { details = "BackupSnapshot Failed due to " + e.getMessage(); s_logger.warn(details, e); } finally { @@ -1375,7 +1375,7 @@ public class XenServerStorageProcessor implements StorageProcessor { // remove last bad primary snapshot when exception happens try { destroySnapshotOnPrimaryStorage(conn, snapshotUuid); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("clean up snapshot failed", e); } } @@ -1385,17 +1385,17 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer createTemplateFromVolume(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - VolumeObjectTO volume = (VolumeObjectTO) cmd.getSrcTO(); - TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO(); - NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore(); - int wait = cmd.getWait(); + public Answer createTemplateFromVolume(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final VolumeObjectTO volume = (VolumeObjectTO) cmd.getSrcTO(); + final TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO(); + final NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore(); + final int wait = cmd.getWait(); - String secondaryStoragePoolURL = destStore.getUrl(); - String volumeUUID = volume.getPath(); + final String secondaryStoragePoolURL = destStore.getUrl(); + final String volumeUUID = volume.getPath(); - String userSpecifiedName = template.getName(); + final String userSpecifiedName = template.getName(); String details = null; SR tmpltSR = null; @@ -1403,7 +1403,7 @@ public class XenServerStorageProcessor implements StorageProcessor { String secondaryStorageMountPath = null; String installPath = null; try { - URI uri = new URI(secondaryStoragePoolURL); + final URI uri = new URI(secondaryStoragePoolURL); secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); installPath = template.getPath(); if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) { @@ -1412,25 +1412,25 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CopyCmdAnswer(details); } - VDI vol = getVDIbyUuid(conn, volumeUUID); + final VDI vol = getVDIbyUuid(conn, volumeUUID); // create template SR - URI tmpltURI = new URI(secondaryStoragePoolURL + "/" + installPath); + final URI tmpltURI = new URI(secondaryStoragePoolURL + "/" + installPath); tmpltSR = hypervisorResource.createNfsSRbyURI(conn, tmpltURI, false); // copy volume to template SR - VDI tmpltVDI = hypervisorResource.cloudVDIcopy(conn, vol, tmpltSR, wait); + final VDI tmpltVDI = hypervisorResource.cloudVDIcopy(conn, vol, tmpltSR, wait); // scan makes XenServer pick up VDI physicalSize tmpltSR.scan(conn); if (userSpecifiedName != null) { tmpltVDI.setNameLabel(conn, userSpecifiedName); } - String tmpltUUID = tmpltVDI.getUuid(conn); - String tmpltFilename = tmpltUUID + ".vhd"; - long virtualSize = tmpltVDI.getVirtualSize(conn); - long physicalSize = tmpltVDI.getPhysicalUtilisation(conn); + final String tmpltUUID = tmpltVDI.getUuid(conn); + final String tmpltFilename = tmpltUUID + ".vhd"; + final long virtualSize = tmpltVDI.getVirtualSize(conn); + final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn); // create the template.properties file - String templatePath = secondaryStorageMountPath + "/" + installPath; + final String templatePath = secondaryStorageMountPath + "/" + installPath; result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, template.getId()); @@ -1440,15 +1440,15 @@ public class XenServerStorageProcessor implements StorageProcessor { installPath = installPath + "/" + tmpltFilename; hypervisorResource.removeSR(conn, tmpltSR); tmpltSR = null; - TemplateObjectTO newTemplate = new TemplateObjectTO(); + final TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(installPath); newTemplate.setFormat(ImageFormat.VHD); newTemplate.setSize(virtualSize); newTemplate.setPhysicalSize(physicalSize); newTemplate.setName(tmpltUUID); - CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate); + final CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate); return answer; - } catch (Exception e) { + } catch (final Exception e) { if (tmpltSR != null) { hypervisorResource.removeSR(conn, tmpltSR); } @@ -1462,17 +1462,17 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer createTemplateFromSnapshot(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); + public Answer createTemplateFromSnapshot(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); - SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO)cmd.getSrcTO(); - TemplateObjectTO templateObjTO = (TemplateObjectTO)cmd.getDestTO(); + final SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO)cmd.getSrcTO(); + final TemplateObjectTO templateObjTO = (TemplateObjectTO)cmd.getDestTO(); if (!(snapshotObjTO.getDataStore() instanceof PrimaryDataStoreTO) || !(templateObjTO.getDataStore() instanceof NfsTO)) { return null; } - String userSpecifiedTemplateName = templateObjTO.getName(); + final String userSpecifiedTemplateName = templateObjTO.getName(); NfsTO destStore = null; URI destUri = null; @@ -1481,7 +1481,7 @@ public class XenServerStorageProcessor implements StorageProcessor { destStore = (NfsTO)templateObjTO.getDataStore(); destUri = new URI(destStore.getUrl()); - } catch (Exception ex) { + } catch (final Exception ex) { s_logger.debug("Invalid URI", ex); return new CopyCmdAnswer("Invalid URI: " + ex.toString()); @@ -1490,37 +1490,37 @@ public class XenServerStorageProcessor implements StorageProcessor { SR srcSr = null; SR destSr = null; - String destDir = templateObjTO.getPath(); + final String destDir = templateObjTO.getPath(); VDI destVdi = null; boolean result = false; try { - Map srcDetails = cmd.getOptions(); + final Map srcDetails = cmd.getOptions(); - String iScsiName = srcDetails.get(DiskTO.IQN); - String storageHost = srcDetails.get(DiskTO.STORAGE_HOST); - String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME); - String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET); + final String iScsiName = srcDetails.get(DiskTO.IQN); + final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST); + final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME); + final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET); srcSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true); - String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); + final String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); if (!hypervisorResource.createSecondaryStorageFolder(conn, destNfsPath, destDir)) { - String details = " Failed to create folder " + destDir + " in secondary storage"; + final String details = " Failed to create folder " + destDir + " in secondary storage"; s_logger.warn(details); return new CopyCmdAnswer(details); } - URI templateUri = new URI(destStore.getUrl() + "/" + destDir); + final URI templateUri = new URI(destStore.getUrl() + "/" + destDir); destSr = hypervisorResource.createNfsSRbyURI(conn, templateUri, false); // there should only be one VDI in this SR - VDI srcVdi = srcSr.getVDIs(conn).iterator().next(); + final VDI srcVdi = srcSr.getVDIs(conn).iterator().next(); destVdi = srcVdi.copy(conn, destSr); @@ -1531,10 +1531,10 @@ public class XenServerStorageProcessor implements StorageProcessor { destVdi.setNameLabel(conn, userSpecifiedTemplateName); } - String templateUuid = destVdi.getUuid(conn); - String templateFilename = templateUuid + ".vhd"; - long virtualSize = destVdi.getVirtualSize(conn); - long physicalSize = destVdi.getPhysicalUtilisation(conn); + final String templateUuid = destVdi.getUuid(conn); + final String templateFilename = templateUuid + ".vhd"; + final long virtualSize = destVdi.getVirtualSize(conn); + final long physicalSize = destVdi.getPhysicalUtilisation(conn); // create the template.properties file String templatePath = destNfsPath + "/" + destDir; @@ -1548,7 +1548,7 @@ public class XenServerStorageProcessor implements StorageProcessor { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + templateUri); } - TemplateObjectTO newTemplate = new TemplateObjectTO(); + final TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(destDir + "/" + templateFilename); newTemplate.setFormat(Storage.ImageFormat.VHD); @@ -1560,7 +1560,7 @@ public class XenServerStorageProcessor implements StorageProcessor { result = true; return new CopyCmdAnswer(newTemplate); - } catch (Exception ex) { + } catch (final Exception ex) { s_logger.error("Failed to create a template from a snapshot", ex); return new CopyCmdAnswer("Failed to create a template from a snapshot: " + ex.toString()); @@ -1569,7 +1569,7 @@ public class XenServerStorageProcessor implements StorageProcessor { if (destVdi != null) { try { destVdi.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Cleaned up leftover VDI on destination storage due to failure: ", e); } } @@ -1586,12 +1586,12 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer createVolumeFromSnapshot(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - DataTO srcData = cmd.getSrcTO(); - SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData; - DataTO destData = cmd.getDestTO(); - DataStoreTO imageStore = srcData.getDataStore(); + public Answer createVolumeFromSnapshot(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final DataTO srcData = cmd.getSrcTO(); + final SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData; + final DataTO destData = cmd.getDestTO(); + final DataStoreTO imageStore = srcData.getDataStore(); if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof PrimaryDataStoreTO) { return createVolumeFromSnapshot2(cmd); @@ -1601,10 +1601,10 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CopyCmdAnswer("unsupported protocol"); } - NfsTO nfsImageStore = (NfsTO) imageStore; - String primaryStorageNameLabel = destData.getDataStore().getUuid(); - String secondaryStorageUrl = nfsImageStore.getUrl(); - int wait = cmd.getWait(); + final NfsTO nfsImageStore = (NfsTO) imageStore; + final String primaryStorageNameLabel = destData.getDataStore().getUuid(); + final String secondaryStorageUrl = nfsImageStore.getUrl(); + final int wait = cmd.getWait(); boolean result = false; // Generic error message. String details = null; @@ -1615,34 +1615,34 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CopyCmdAnswer(details); } try { - SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); + final SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); if (primaryStorageSR == null) { throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel); } // Get the absolute path of the snapshot on the secondary storage. String snapshotInstallPath = snapshot.getPath(); - int index = snapshotInstallPath.lastIndexOf(nfsImageStore.getPathSeparator()); - String snapshotName = snapshotInstallPath.substring(index + 1); + final int index = snapshotInstallPath.lastIndexOf(nfsImageStore.getPathSeparator()); + final String snapshotName = snapshotInstallPath.substring(index + 1); if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) { snapshotInstallPath = snapshotInstallPath + ".vhd"; } - URI snapshotURI = new URI(secondaryStorageUrl + nfsImageStore.getPathSeparator() + snapshotInstallPath); - String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath(); - String srUuid = primaryStorageSR.getUuid(conn); + final URI snapshotURI = new URI(secondaryStorageUrl + nfsImageStore.getPathSeparator() + snapshotInstallPath); + final String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath(); + final String srUuid = primaryStorageSR.getUuid(conn); volumeUUID = copy_vhd_from_secondarystorage(conn, snapshotPath, srUuid, wait); result = true; - VDI volume = VDI.getByUuid(conn, volumeUUID); - VDI.Record vdir = volume.getRecord(conn); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VDI volume = VDI.getByUuid(conn, volumeUUID); + final VDI.Record vdir = volume.getRecord(conn); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(volumeUUID); newVol.setSize(vdir.virtualSize); return new CopyCmdAnswer(newVol); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { details += " due to " + e.toString(); s_logger.warn(details, e); - } catch (Exception e) { + } catch (final Exception e) { details += " due to " + e.getMessage(); s_logger.warn(details, e); } @@ -1655,34 +1655,34 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CopyCmdAnswer(details); } - protected Answer createVolumeFromSnapshot2(CopyCommand cmd) { + protected Answer createVolumeFromSnapshot2(final CopyCommand cmd) { try { - Connection conn = hypervisorResource.getConnection(); + final Connection conn = hypervisorResource.getConnection(); - Map srcOptions = cmd.getOptions(); + final Map srcOptions = cmd.getOptions(); - String src_iScsiName = srcOptions.get(DiskTO.IQN); - String srcStorageHost = srcOptions.get(DiskTO.STORAGE_HOST); - String srcChapInitiatorUsername = srcOptions.get(DiskTO.CHAP_INITIATOR_USERNAME); - String srcChapInitiatorSecret = srcOptions.get(DiskTO.CHAP_INITIATOR_SECRET); + final String src_iScsiName = srcOptions.get(DiskTO.IQN); + final String srcStorageHost = srcOptions.get(DiskTO.STORAGE_HOST); + final String srcChapInitiatorUsername = srcOptions.get(DiskTO.CHAP_INITIATOR_USERNAME); + final String srcChapInitiatorSecret = srcOptions.get(DiskTO.CHAP_INITIATOR_SECRET); - SR srcSr = hypervisorResource.getIscsiSR(conn, src_iScsiName, srcStorageHost, src_iScsiName, srcChapInitiatorUsername, srcChapInitiatorSecret, false); + final SR srcSr = hypervisorResource.getIscsiSR(conn, src_iScsiName, srcStorageHost, src_iScsiName, srcChapInitiatorUsername, srcChapInitiatorSecret, false); - Map destOptions = cmd.getOptions2(); + final Map destOptions = cmd.getOptions2(); - String dest_iScsiName = destOptions.get(DiskTO.IQN); - String destStorageHost = destOptions.get(DiskTO.STORAGE_HOST); - String destChapInitiatorUsername = destOptions.get(DiskTO.CHAP_INITIATOR_USERNAME); - String destChapInitiatorSecret = destOptions.get(DiskTO.CHAP_INITIATOR_SECRET); + final String dest_iScsiName = destOptions.get(DiskTO.IQN); + final String destStorageHost = destOptions.get(DiskTO.STORAGE_HOST); + final String destChapInitiatorUsername = destOptions.get(DiskTO.CHAP_INITIATOR_USERNAME); + final String destChapInitiatorSecret = destOptions.get(DiskTO.CHAP_INITIATOR_SECRET); - SR destSr = hypervisorResource.getIscsiSR(conn, dest_iScsiName, destStorageHost, dest_iScsiName, destChapInitiatorUsername, destChapInitiatorSecret, false); + final SR destSr = hypervisorResource.getIscsiSR(conn, dest_iScsiName, destStorageHost, dest_iScsiName, destChapInitiatorUsername, destChapInitiatorSecret, false); // there should only be one VDI in this SR - VDI srcVdi = srcSr.getVDIs(conn).iterator().next(); + final VDI srcVdi = srcSr.getVDIs(conn).iterator().next(); - VDI vdiCopy = srcVdi.copy(conn, destSr); + final VDI vdiCopy = srcVdi.copy(conn, destSr); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setSize(vdiCopy.getVirtualSize(conn)); newVol.setPath(vdiCopy.getUuid(conn)); @@ -1693,7 +1693,7 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CopyCmdAnswer(newVol); } - catch (Exception ex) { + catch (final Exception ex) { s_logger.warn("Failed to copy snapshot to volume: " + ex.toString(), ex); return new CopyCmdAnswer(ex.getMessage()); @@ -1701,25 +1701,25 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer deleteSnapshot(DeleteCommand cmd) { - SnapshotObjectTO snapshot = (SnapshotObjectTO) cmd.getData(); - DataStoreTO store = snapshot.getDataStore(); + public Answer deleteSnapshot(final DeleteCommand cmd) { + final SnapshotObjectTO snapshot = (SnapshotObjectTO) cmd.getData(); + final DataStoreTO store = snapshot.getDataStore(); if (store.getRole() == DataStoreRole.Primary) { - Connection conn = hypervisorResource.getConnection(); - VDI snapshotVdi = getVDIbyUuid(conn, snapshot.getPath()); + final Connection conn = hypervisorResource.getConnection(); + final VDI snapshotVdi = getVDIbyUuid(conn, snapshot.getPath()); if (snapshotVdi == null) { return new Answer(null); } String errMsg = null; try { deleteVDI(conn, snapshotVdi); - } catch (BadServerResponse e) { + } catch (final BadServerResponse e) { s_logger.debug("delete snapshot failed:" + e.toString()); errMsg = e.toString(); - } catch (XenAPIException e) { + } catch (final XenAPIException e) { s_logger.debug("delete snapshot failed:" + e.toString()); errMsg = e.toString(); - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { s_logger.debug("delete snapshot failed:" + e.toString()); errMsg = e.toString(); } @@ -1729,28 +1729,28 @@ public class XenServerStorageProcessor implements StorageProcessor { } @Override - public Answer introduceObject(IntroduceObjectCmd cmd) { + public Answer introduceObject(final IntroduceObjectCmd cmd) { try { - Connection conn = hypervisorResource.getConnection(); - DataStoreTO store = cmd.getDataTO().getDataStore(); - SR poolSr = hypervisorResource.getStorageRepository(conn, store.getUuid()); + final Connection conn = hypervisorResource.getConnection(); + final DataStoreTO store = cmd.getDataTO().getDataStore(); + final SR poolSr = hypervisorResource.getStorageRepository(conn, store.getUuid()); poolSr.scan(conn); return new IntroduceObjectAnswer(cmd.getDataTO()); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to introduce object", e); return new Answer(cmd, false, e.toString()); } } @Override - public Answer forgetObject(ForgetObjectCmd cmd) { + public Answer forgetObject(final ForgetObjectCmd cmd) { try { - Connection conn = hypervisorResource.getConnection(); - DataTO data = cmd.getDataTO(); - VDI vdi = VDI.getByUuid(conn, data.getPath()); + final Connection conn = hypervisorResource.getConnection(); + final DataTO data = cmd.getDataTO(); + final VDI vdi = VDI.getByUuid(conn, data.getPath()); vdi.forget(conn); return new IntroduceObjectAnswer(cmd.getDataTO()); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to introduce object", e); return new Answer(cmd, false, e.toString()); } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java index c10844e0f67..6a782874fa7 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625Resource.java @@ -24,22 +24,20 @@ import java.util.List; import javax.ejb.Local; +import org.apache.cloudstack.hypervisor.xenserver.XenServerResourceNewBase; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Types; -import com.xensource.xenapi.VM; - -import org.apache.cloudstack.hypervisor.xenserver.XenServerResourceNewBase; - import com.cloud.resource.ServerResource; import com.cloud.storage.resource.StorageSubsystemCommandHandler; import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; import com.cloud.utils.ssh.SSHCmdHelper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.VM; @Local(value=ServerResource.class) public class Xenserver625Resource extends XenServerResourceNewBase { @@ -51,49 +49,48 @@ public class Xenserver625Resource extends XenServerResourceNewBase { @Override protected List getPatchFiles() { - List files = new ArrayList(); - String patch = "scripts/vm/hypervisor/xenserver/xenserver62/patch"; - String patchfilePath = Script.findScript("", patch); + final List files = new ArrayList(); + final String patch = "scripts/vm/hypervisor/xenserver/xenserver62/patch"; + final String patchfilePath = Script.findScript("", patch); if (patchfilePath == null) { throw new CloudRuntimeException("Unable to find patch file " + patch); } - File file = new File(patchfilePath); + final File file = new File(patchfilePath); files.add(file); return files; } @Override - protected StorageSubsystemCommandHandler getStorageHandler() { - XenServerStorageProcessor processor = new Xenserver625StorageProcessor(this); + protected StorageSubsystemCommandHandler buildStorageHandler() { + final XenServerStorageProcessor processor = new Xenserver625StorageProcessor(this); return new StorageSubsystemCommandHandlerBase(processor); } @Override - protected void umountSnapshotDir(Connection conn, Long dcId) { - + public void umountSnapshotDir(final Connection conn, final Long dcId) { } @Override - protected boolean setupServer(Connection conn,Host host) { - com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.ip, 22); + public boolean setupServer(final Connection conn,final Host host) { + final com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_host.getIp(), 22); try { sshConnection.connect(null, 60000, 60000); if (!sshConnection.authenticateWithPassword(_username, _password.peek())) { throw new CloudRuntimeException("Unable to authenticate"); } - String cmd = "rm -f /opt/xensource/sm/hostvmstats.py " + - "/opt/xensource/bin/copy_vhd_to_secondarystorage.sh " + - "/opt/xensource/bin/copy_vhd_from_secondarystorage.sh " + - "/opt/xensource/bin/create_privatetemplate_from_snapshot.sh " + - "/opt/xensource/bin/vhd-util " + - "/opt/cloud/bin/copy_vhd_to_secondarystorage.sh " + - "/opt/cloud/bin/copy_vhd_from_secondarystorage.sh " + - "/opt/cloud/bin/create_privatetemplate_from_snapshot.sh " + - "/opt/cloud/bin/vhd-util"; + final String cmd = "rm -f /opt/xensource/sm/hostvmstats.py " + + "/opt/xensource/bin/copy_vhd_to_secondarystorage.sh " + + "/opt/xensource/bin/copy_vhd_from_secondarystorage.sh " + + "/opt/xensource/bin/create_privatetemplate_from_snapshot.sh " + + "/opt/xensource/bin/vhd-util " + + "/opt/cloud/bin/copy_vhd_to_secondarystorage.sh " + + "/opt/cloud/bin/copy_vhd_from_secondarystorage.sh " + + "/opt/cloud/bin/create_privatetemplate_from_snapshot.sh " + + "/opt/cloud/bin/vhd-util"; SSHCmdHelper.sshExecuteCmd(sshConnection, cmd); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Catch exception " + e.toString(), e); } finally { sshConnection.close(); @@ -102,11 +99,11 @@ public class Xenserver625Resource extends XenServerResourceNewBase { } @Override - protected String revertToSnapshot(Connection conn, VM vmSnapshot, - String vmName, String oldVmUuid, Boolean snapshotMemory, String hostUUID) - throws Types.XenAPIException, XmlRpcException { + public String revertToSnapshot(final Connection conn, final VM vmSnapshot, + final String vmName, final String oldVmUuid, final Boolean snapshotMemory, final String hostUUID) + throws Types.XenAPIException, XmlRpcException { - String results = callHostPluginAsync(conn, "vmopsSnapshot", + 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); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java index c4f2dc916ea..37c311a6759 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java @@ -62,20 +62,20 @@ import com.xensource.xenapi.VDI; public class Xenserver625StorageProcessor extends XenServerStorageProcessor { private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class); - public Xenserver625StorageProcessor(CitrixResourceBase resource) { + public Xenserver625StorageProcessor(final CitrixResourceBase resource) { super(resource); } - protected boolean mountNfs(Connection conn, String remoteDir, String localDir) { + protected boolean mountNfs(final Connection conn, final String remoteDir, String localDir) { if (localDir == null) { localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remoteDir.getBytes()); } - String results = hypervisorResource.callHostPluginAsync(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", 100 * 1000, - "localDir", localDir, "remoteDir", remoteDir); + final String results = hypervisorResource.callHostPluginAsync(conn, "cloud-plugin-storage", "mountNfsSecondaryStorage", 100 * 1000, "localDir", localDir, "remoteDir", + remoteDir); if (results == null || results.isEmpty()) { - String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir; + final String errMsg = "Could not mount secondary storage " + remoteDir + " on host " + localDir; s_logger.warn(errMsg); @@ -85,8 +85,8 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { return true; } - protected boolean makeDirectory(Connection conn, String path) { - String result = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "makeDirectory", "path", path); + protected boolean makeDirectory(final Connection conn, final String path) { + final String result = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "makeDirectory", "path", path); if (result == null || result.isEmpty()) { return false; @@ -95,27 +95,27 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { return true; } - protected SR createFileSR(Connection conn, String path) { + protected SR createFileSR(final Connection conn, final String path) { SR sr = null; PBD pbd = null; try { - String srname = hypervisorResource.getHost().uuid + path.trim(); + final String srname = hypervisorResource.getHost().getUuid() + path.trim(); - Set srs = SR.getByNameLabel(conn, srname); + final Set srs = SR.getByNameLabel(conn, srname); if (srs != null && !srs.isEmpty()) { return srs.iterator().next(); } - Map smConfig = new HashMap(); + final Map smConfig = new HashMap(); - Host host = Host.getByUuid(conn, hypervisorResource.getHost().uuid); - String uuid = UUID.randomUUID().toString(); + final Host host = Host.getByUuid(conn, hypervisorResource.getHost().getUuid()); + final String uuid = UUID.randomUUID().toString(); sr = SR.introduce(conn, uuid, srname, srname, "file", "file", false, smConfig); - PBD.Record record = new PBD.Record(); + final PBD.Record record = new PBD.Record(); record.host = host; record.SR = sr; @@ -131,12 +131,12 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { sr.scan(conn); return sr; - } catch (Exception ex) { + } catch (final Exception ex) { try { if (pbd != null) { pbd.destroy(conn); } - } catch (Exception e1) { + } catch (final Exception e1) { s_logger.debug("Failed to destroy PBD", ex); } @@ -144,11 +144,11 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (sr != null) { sr.forget(conn); } - } catch (Exception e2) { + } catch (final Exception e2) { s_logger.error("Failed to forget SR", ex); } - String msg = "createFileSR failed! due to the following: " + ex.toString(); + final String msg = "createFileSR failed! due to the following: " + ex.toString(); s_logger.warn(msg, ex); @@ -156,52 +156,52 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } } - protected SR createFileSr(Connection conn, String remotePath, String dir) { - String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remotePath.getBytes()); + protected SR createFileSr(final Connection conn, final String remotePath, final String dir) { + final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(remotePath.getBytes()); mountNfs(conn, remotePath, localDir); - SR sr = createFileSR(conn, localDir + "/" + dir); + final SR sr = createFileSR(conn, localDir + "/" + dir); return sr; } @Override - public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - int wait = cmd.getWait(); - DataStoreTO srcStore = srcData.getDataStore(); - Connection conn = hypervisorResource.getConnection(); + public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) { + final DataTO srcData = cmd.getSrcTO(); + final DataTO destData = cmd.getDestTO(); + final int wait = cmd.getWait(); + final DataStoreTO srcStore = srcData.getDataStore(); + final Connection conn = hypervisorResource.getConnection(); SR srcSr = null; Task task = null; try { - if ((srcStore instanceof NfsTO) && (srcData.getObjectType() == DataObjectType.TEMPLATE)) { - NfsTO srcImageStore = (NfsTO)srcStore; - TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData; - String storeUrl = srcImageStore.getUrl(); - URI uri = new URI(storeUrl); + if (srcStore instanceof NfsTO && srcData.getObjectType() == DataObjectType.TEMPLATE) { + final NfsTO srcImageStore = (NfsTO) srcStore; + final TemplateObjectTO srcTemplate = (TemplateObjectTO) srcData; + final String storeUrl = srcImageStore.getUrl(); + final URI uri = new URI(storeUrl); String volumePath = srcData.getPath(); volumePath = StringUtils.stripEnd(volumePath, "/"); - String[] splits = volumePath.split("/"); + final String[] splits = volumePath.split("/"); String volumeDirectory = volumePath; if (splits.length > 4) { - //"template/tmpl/dcid/templateId/templatename" - int index = volumePath.lastIndexOf("/"); + // "template/tmpl/dcid/templateId/templatename" + final int index = volumePath.lastIndexOf("/"); volumeDirectory = volumePath.substring(0, index); } srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory); - Set setVdis = srcSr.getVDIs(conn); + final Set setVdis = srcSr.getVDIs(conn); if (setVdis.size() != 1) { return new CopyCmdAnswer("Can't find template VDI under: " + uri.getHost() + ":" + uri.getPath() + "/" + volumeDirectory); } - VDI srcVdi = setVdis.iterator().next(); + final VDI srcVdi = setVdis.iterator().next(); boolean managed = false; String storageHost = null; @@ -211,7 +211,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { String chapInitiatorUsername = null; String chapInitiatorSecret = null; - PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore(); + final PrimaryDataStoreTO destStore = (PrimaryDataStoreTO) destData.getDataStore(); Map details = destStore.getDetails(); @@ -240,13 +240,12 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { details.put(DiskTO.CHAP_INITIATOR_SECRET, chapInitiatorSecret); destSr = hypervisorResource.prepareManagedSr(conn, details); - } - else { - String srName = destStore.getUuid(); - Set srs = SR.getByNameLabel(conn, srName); + } else { + final String srName = destStore.getUuid(); + final Set srs = SR.getByNameLabel(conn, srName); if (srs.size() != 1) { - String msg = "There are " + srs.size() + " SRs with same name: " + srName; + final String msg = "There are " + srs.size() + " SRs with same name: " + srName; s_logger.warn(msg); @@ -262,17 +261,17 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { hypervisorResource.waitForTask(conn, task, 1000, wait * 1000); hypervisorResource.checkForSuccess(conn, task); - VDI tmplVdi = Types.toVDI(task, conn); + final VDI tmplVdi = Types.toVDI(task, conn); final String uuidToReturn; - Long physicalSize = tmplVdi.getPhysicalUtilisation(conn); + final Long physicalSize = tmplVdi.getPhysicalUtilisation(conn); if (managed) { uuidToReturn = tmplVdi.getUuid(conn); tmplVdi.setNameLabel(conn, managedStoragePoolRootVolumeName); } else { - VDI snapshotVdi = tmplVdi.snapshot(conn, new HashMap()); + final VDI snapshotVdi = tmplVdi.snapshot(conn, new HashMap()); uuidToReturn = snapshotVdi.getUuid(conn); @@ -283,12 +282,12 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { destSr.scan(conn); - try{ + try { Thread.sleep(5000); - } catch (Exception e) { + } catch (final Exception e) { } - TemplateObjectTO newVol = new TemplateObjectTO(); + final TemplateObjectTO newVol = new TemplateObjectTO(); newVol.setUuid(uuidToReturn); newVol.setPath(uuidToReturn); @@ -299,8 +298,8 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { return new CopyCmdAnswer(newVol); } - } catch (Exception e) { - String msg = "Catch Exception " + e.getClass().getName() + " for template due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Catch Exception " + e.getClass().getName() + " for template due to " + e.toString(); s_logger.warn(msg, e); @@ -309,7 +308,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (task != null) { try { task.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("unable to destroy task (" + task.toWireString() + ") due to " + e.toString()); } } @@ -322,7 +321,8 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { return new CopyCmdAnswer("not implemented yet"); } - protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, String localMountPoint, String path, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, String prevSnapshotUuid, Boolean isISCSI, int wait) { + protected String backupSnapshot(final Connection conn, final String primaryStorageSRUuid, final String localMountPoint, final String path, + final String secondaryStorageMountPath, final String snapshotUuid, String prevBackupUuid, final String prevSnapshotUuid, final Boolean isISCSI, int wait) { boolean filesrcreated = false; // boolean copied = false; @@ -331,12 +331,12 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } SR ssSR = null; - String remoteDir = secondaryStorageMountPath; + final String remoteDir = secondaryStorageMountPath; try { ssSR = createFileSr(conn, remoteDir, path); filesrcreated = true; - VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid); + final VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid); if (wait == 0) { wait = 2 * 60 * 60; } @@ -345,7 +345,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { try { VDI previousSnapshotVdi = null; if (prevSnapshotUuid != null) { - previousSnapshotVdi = VDI.getByUuid(conn,prevSnapshotUuid); + previousSnapshotVdi = VDI.getByUuid(conn, prevSnapshotUuid); } task = snapshotvdi.copyAsync(conn, ssSR, previousSnapshotVdi, null); // poll every 1 seconds , @@ -357,15 +357,15 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (task != null) { try { task.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString()); } } } - String result = dvdi.getUuid(conn).concat("#").concat(dvdi.getPhysicalUtilisation(conn).toString()); + final String result = dvdi.getUuid(conn).concat("#").concat(dvdi.getPhysicalUtilisation(conn).toString()); return result; - } catch (Exception e) { - String msg = "Exception in backupsnapshot stage due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Exception in backupsnapshot stage due to " + e.toString(); s_logger.debug(msg); throw new CloudRuntimeException(msg, e); } finally { @@ -373,16 +373,16 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (filesrcreated && ssSR != null) { hypervisorResource.removeSR(conn, ssSR); } - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Exception in backupsnapshot cleanup stage due to " + e.toString()); } } } @Override - protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { - String parentUuid = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, - "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString()); + protected String getVhdParent(final Connection conn, final String primaryStorageSRUuid, final String snapshotUuid, final Boolean isISCSI) { + final String parentUuid = hypervisorResource.callHostPlugin(conn, "cloud-plugin-storage", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", + snapshotUuid, "isISCSI", isISCSI.toString()); if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) { s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid); @@ -393,64 +393,64 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } @Override - public Answer backupSnapshot(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - DataTO srcData = cmd.getSrcTO(); - DataTO cacheData = cmd.getCacheTO(); - DataTO destData = cmd.getDestTO(); - int wait = cmd.getWait(); - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcData.getDataStore(); - String primaryStorageNameLabel = primaryStore.getUuid(); + public Answer backupSnapshot(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final DataTO srcData = cmd.getSrcTO(); + final DataTO cacheData = cmd.getCacheTO(); + final DataTO destData = cmd.getDestTO(); + final int wait = cmd.getWait(); + final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) srcData.getDataStore(); + final String primaryStorageNameLabel = primaryStore.getUuid(); String secondaryStorageUrl = null; NfsTO cacheStore = null; String destPath = null; if (cacheData != null) { - cacheStore = (NfsTO)cacheData.getDataStore(); + cacheStore = (NfsTO) cacheData.getDataStore(); secondaryStorageUrl = cacheStore.getUrl(); destPath = cacheData.getPath(); } else { - cacheStore = (NfsTO)destData.getDataStore(); + cacheStore = (NfsTO) destData.getDataStore(); secondaryStorageUrl = cacheStore.getUrl(); destPath = destData.getPath(); } - SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData; - SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData; - String snapshotUuid = snapshotTO.getPath(); + final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData; + final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData; + final String snapshotUuid = snapshotTO.getPath(); - String prevBackupUuid = snapshotOnImage.getParentSnapshotPath(); - String prevSnapshotUuid = snapshotTO.getParentSnapshotPath(); - Map options = cmd.getOptions(); + final String prevBackupUuid = snapshotOnImage.getParentSnapshotPath(); + final String prevSnapshotUuid = snapshotTO.getParentSnapshotPath(); + final Map options = cmd.getOptions(); // By default assume failure String details = null; String snapshotBackupUuid = null; - boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot")); + final boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot")); Long physicalSize = null; try { - SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); + final SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); if (primaryStorageSR == null) { throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel); } // String psUuid = primaryStorageSR.getUuid(conn); - Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn)); + final Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn)); - VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid); - String snapshotPaUuid = null; + final VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid); + final String snapshotPaUuid = null; - URI uri = new URI(secondaryStorageUrl); - String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); - DataStoreTO destStore = destData.getDataStore(); - String folder = destPath; + final URI uri = new URI(secondaryStorageUrl); + final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); + final DataStoreTO destStore = destData.getDataStore(); + final String folder = destPath; String finalPath = null; - String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString(); + final String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString(); if (fullbackup) { SR snapshotSr = null; Task task = null; try { - String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes()); + final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes()); mountNfs(conn, secondaryStorageMountPath, localDir); - boolean result = makeDirectory(conn, localDir + "/" + folder); + final boolean result = makeDirectory(conn, localDir + "/" + folder); if (!result) { details = " Filed to create folder " + folder + " in secondary storage"; s_logger.warn(details); @@ -463,21 +463,21 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { // poll every 1 seconds , hypervisorResource.waitForTask(conn, task, 1000, wait * 1000); hypervisorResource.checkForSuccess(conn, task); - VDI backedVdi = Types.toVDI(task, conn); + final VDI backedVdi = Types.toVDI(task, conn); snapshotBackupUuid = backedVdi.getUuid(conn); physicalSize = backedVdi.getPhysicalUtilisation(conn); - if( destStore instanceof SwiftTO) { + if (destStore instanceof SwiftTO) { try { - String container = "S-" + snapshotTO.getVolume().getVolumeId().toString(); - String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait); - String swiftPath = container + File.separator + destSnapshotName; + final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString(); + final String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO) destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait); + final String swiftPath = container + File.separator + destSnapshotName; finalPath = swiftPath; } finally { try { deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid); - } catch (Exception e) { - s_logger.debug("Failed to delete snapshot on cache storages" ,e); + } catch (final Exception e) { + s_logger.debug("Failed to delete snapshot on cache storages", e); } } @@ -490,11 +490,12 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } finally { try { deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid); - } catch (Exception e) { - s_logger.debug("Failed to delete snapshot on cache storages" ,e); + } catch (final Exception e) { + s_logger.debug("Failed to delete snapshot on cache storages", e); } } - // finalPath = folder + File.separator + snapshotBackupUuid; + // finalPath = folder + File.separator + + // snapshotBackupUuid; } else { finalPath = folder + File.separator + snapshotBackupUuid; } @@ -503,38 +504,39 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (task != null) { try { task.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString()); } } - if( snapshotSr != null) { + if (snapshotSr != null) { hypervisorResource.removeSR(conn, snapshotSr); } } } else { - String primaryStorageSRUuid = primaryStorageSR.getUuid(conn); - if( destStore instanceof SwiftTO ) { - String container = "S-" + snapshotTO.getVolume().getVolumeId().toString(); - snapshotBackupUuid = swiftBackupSnapshot(conn, (SwiftTO)destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait); + final String primaryStorageSRUuid = primaryStorageSR.getUuid(conn); + if (destStore instanceof SwiftTO) { + final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString(); + snapshotBackupUuid = swiftBackupSnapshot(conn, (SwiftTO) destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + + snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait); finalPath = container + File.separator + snapshotBackupUuid; - } else if (destStore instanceof S3TO ) { + } else if (destStore instanceof S3TO) { finalPath = backupSnapshotToS3(conn, (S3TO) destStore, primaryStorageSRUuid, folder, snapshotPaUuid, isISCSI, wait); if (finalPath == null) { throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed"); } } else { - String result = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, - secondaryStorageMountPath, snapshotUuid, prevBackupUuid, prevSnapshotUuid, isISCSI, wait); - String[] tmp = result.split("#"); + final String result = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, + prevSnapshotUuid, isISCSI, wait); + final String[] tmp = result.split("#"); snapshotBackupUuid = tmp[0]; physicalSize = Long.parseLong(tmp[1]); finalPath = folder + File.separator + snapshotBackupUuid; } } - String volumeUuid = snapshotTO.getVolume().getPath(); + final String volumeUuid = snapshotTO.getVolume().getPath(); destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid); - SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + final SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); newSnapshot.setPath(finalPath); newSnapshot.setPhysicalSize(physicalSize); if (fullbackup) { @@ -543,10 +545,10 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { newSnapshot.setParentSnapshotPath(prevBackupUuid); } return new CopyCmdAnswer(newSnapshot); - } catch (Types.XenAPIException e) { + } catch (final Types.XenAPIException e) { details = "BackupSnapshot Failed due to " + e.toString(); s_logger.warn(details, e); - } catch (Exception e) { + } catch (final Exception e) { details = "BackupSnapshot Failed due to " + e.getMessage(); s_logger.warn(details, e); } @@ -555,18 +557,17 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } @Override - public Answer createTemplateFromVolume(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO(); - TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO(); - NfsTO destStore = (NfsTO)cmd.getDestTO().getDataStore(); - int wait = cmd.getWait(); + public Answer createTemplateFromVolume(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final VolumeObjectTO volume = (VolumeObjectTO) cmd.getSrcTO(); + final TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO(); + final NfsTO destStore = (NfsTO) cmd.getDestTO().getDataStore(); + final int wait = cmd.getWait(); - String secondaryStoragePoolURL = destStore.getUrl(); - String volumeUUID = volume.getPath(); - - String userSpecifiedName = template.getName(); + final String secondaryStoragePoolURL = destStore.getUrl(); + final String volumeUUID = volume.getPath(); + final String userSpecifiedName = template.getName(); String details = null; SR tmpltSR = null; @@ -575,16 +576,16 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { String installPath = null; Task task = null; try { - URI uri = new URI(secondaryStoragePoolURL); + final URI uri = new URI(secondaryStoragePoolURL); secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); installPath = template.getPath(); - if( !hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) { + if (!hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) { details = " Filed to create folder " + installPath + " in secondary storage"; s_logger.warn(details); return new CopyCmdAnswer(details); } - VDI vol = getVDIbyUuid(conn, volumeUUID); + final VDI vol = getVDIbyUuid(conn, volumeUUID); // create template SR tmpltSR = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), installPath); @@ -593,39 +594,40 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { // poll every 1 seconds , hypervisorResource.waitForTask(conn, task, 1000, wait * 1000); hypervisorResource.checkForSuccess(conn, task); - VDI tmpltVDI = Types.toVDI(task, conn); + final VDI tmpltVDI = Types.toVDI(task, conn); // scan makes XenServer pick up VDI physicalSize tmpltSR.scan(conn); if (userSpecifiedName != null) { tmpltVDI.setNameLabel(conn, userSpecifiedName); } - String tmpltUUID = tmpltVDI.getUuid(conn); - String tmpltFilename = tmpltUUID + ".vhd"; - long virtualSize = tmpltVDI.getVirtualSize(conn); - long physicalSize = tmpltVDI.getPhysicalUtilisation(conn); + final String tmpltUUID = tmpltVDI.getUuid(conn); + final String tmpltFilename = tmpltUUID + ".vhd"; + final long virtualSize = tmpltVDI.getVirtualSize(conn); + final long physicalSize = tmpltVDI.getPhysicalUtilisation(conn); // create the template.properties file - String templatePath = secondaryStorageMountPath + "/" + installPath; - result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, template.getId()); + final String templatePath = secondaryStorageMountPath + "/" + installPath; + result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, + template.getId()); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); } installPath = installPath + "/" + tmpltFilename; hypervisorResource.removeSR(conn, tmpltSR); tmpltSR = null; - TemplateObjectTO newTemplate = new TemplateObjectTO(); + final TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(installPath); newTemplate.setFormat(Storage.ImageFormat.VHD); newTemplate.setSize(virtualSize); newTemplate.setPhysicalSize(physicalSize); newTemplate.setName(tmpltUUID); - CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate); + final CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate); return answer; - } catch (Exception e) { + } catch (final Exception e) { if (tmpltSR != null) { hypervisorResource.removeSR(conn, tmpltSR); } - if ( secondaryStorageMountPath != null) { + if (secondaryStorageMountPath != null) { hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath); } details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString(); @@ -634,15 +636,15 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (task != null) { try { task.destroy(conn); - } catch (Exception e) { - s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString()); + } catch (final Exception e) { + s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString()); } } } return new CopyCmdAnswer(details); } - protected String getSnapshotUuid(String snapshotPath) { + protected String getSnapshotUuid(final String snapshotPath) { int index = snapshotPath.lastIndexOf(File.separator); String snapshotUuid = snapshotPath.substring(index + 1); index = snapshotUuid.lastIndexOf("."); @@ -653,14 +655,14 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } @Override - public Answer createVolumeFromSnapshot(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - DataTO srcData = cmd.getSrcTO(); - SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData; - DataTO destData = cmd.getDestTO(); - PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); - VolumeObjectTO volume = (VolumeObjectTO)destData; - DataStoreTO imageStore = srcData.getDataStore(); + public Answer createVolumeFromSnapshot(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final DataTO srcData = cmd.getSrcTO(); + final SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData; + final DataTO destData = cmd.getDestTO(); + final PrimaryDataStoreTO pool = (PrimaryDataStoreTO) destData.getDataStore(); + final VolumeObjectTO volume = (VolumeObjectTO) destData; + final DataStoreTO imageStore = srcData.getDataStore(); if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof PrimaryDataStoreTO) { return createVolumeFromSnapshot2(cmd); @@ -670,10 +672,10 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { return new CopyCmdAnswer("unsupported protocol"); } - NfsTO nfsImageStore = (NfsTO)imageStore; - String primaryStorageNameLabel = pool.getUuid(); - String secondaryStorageUrl = nfsImageStore.getUrl(); - int wait = cmd.getWait(); + final NfsTO nfsImageStore = (NfsTO) imageStore; + final String primaryStorageNameLabel = pool.getUuid(); + final String secondaryStorageUrl = nfsImageStore.getUrl(); + final int wait = cmd.getWait(); boolean result = false; // Generic error message. String details = null; @@ -686,38 +688,38 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { SR srcSr = null; VDI destVdi = null; try { - SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); + final SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); if (primaryStorageSR == null) { throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel); } - String nameLabel = "cloud-" + UUID.randomUUID().toString(); + final String nameLabel = "cloud-" + UUID.randomUUID().toString(); destVdi = createVdi(conn, nameLabel, primaryStorageSR, volume.getSize()); volumeUUID = destVdi.getUuid(conn); - String snapshotInstallPath = snapshot.getPath(); - int index = snapshotInstallPath.lastIndexOf(File.separator); - String snapshotDirectory = snapshotInstallPath.substring(0, index); - String snapshotUuid = getSnapshotUuid(snapshotInstallPath); + final String snapshotInstallPath = snapshot.getPath(); + final int index = snapshotInstallPath.lastIndexOf(File.separator); + final String snapshotDirectory = snapshotInstallPath.substring(0, index); + final String snapshotUuid = getSnapshotUuid(snapshotInstallPath); - URI uri = new URI(secondaryStorageUrl); + final URI uri = new URI(secondaryStorageUrl); srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), snapshotDirectory); - String[] parents = snapshot.getParents(); - List snapshotChains = new ArrayList(); + final String[] parents = snapshot.getParents(); + final List snapshotChains = new ArrayList(); if (parents != null) { - for(int i = 0; i < parents.length; i++) { - String snChainPath = parents[i]; - String uuid = getSnapshotUuid(snChainPath); - VDI chain = VDI.getByUuid(conn, uuid); + for (int i = 0; i < parents.length; i++) { + final String snChainPath = parents[i]; + final String uuid = getSnapshotUuid(snChainPath); + final VDI chain = VDI.getByUuid(conn, uuid); snapshotChains.add(chain); } } - VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid); + final VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid); snapshotChains.add(snapshotVdi); - for(VDI snapChain : snapshotChains) { - Task task = snapChain.copyAsync(conn, null, null, destVdi); + for (final VDI snapChain : snapshotChains) { + final Task task = snapChain.copyAsync(conn, null, null, destVdi); // poll every 1 seconds , hypervisorResource.waitForTask(conn, task, 1000, wait * 1000); hypervisorResource.checkForSuccess(conn, task); @@ -726,15 +728,15 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { result = true; destVdi = VDI.getByUuid(conn, volumeUUID); - VDI.Record vdir = destVdi.getRecord(conn); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VDI.Record vdir = destVdi.getRecord(conn); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(volumeUUID); newVol.setSize(vdir.virtualSize); return new CopyCmdAnswer(newVol); - } catch (Types.XenAPIException e) { + } catch (final Types.XenAPIException e) { details += " due to " + e.toString(); s_logger.warn(details, e); - } catch (Exception e) { + } catch (final Exception e) { details += " due to " + e.getMessage(); s_logger.warn(details, e); } finally { @@ -744,7 +746,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (!result && destVdi != null) { try { destVdi.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("destroy dest vdi failed", e); } } @@ -759,19 +761,19 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } @Override - public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO(); - VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO(); - int wait = cmd.getWait(); - DataStoreTO destStore = destVolume.getDataStore(); + public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final VolumeObjectTO srcVolume = (VolumeObjectTO) cmd.getSrcTO(); + final VolumeObjectTO destVolume = (VolumeObjectTO) cmd.getDestTO(); + final int wait = cmd.getWait(); + final DataStoreTO destStore = destVolume.getDataStore(); if (destStore instanceof NfsTO) { SR secondaryStorage = null; Task task = null; try { - NfsTO nfsStore = (NfsTO)destStore; - URI uri = new URI(nfsStore.getUrl()); + final NfsTO nfsStore = (NfsTO) destStore; + final URI uri = new URI(nfsStore.getUrl()); // Create the volume folder if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) { throw new InternalErrorException("Failed to create the volume folder."); @@ -780,27 +782,27 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { // Create a SR for the volume UUID folder secondaryStorage = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath()); // Look up the volume on the source primary storage pool - VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath()); + final VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath()); // Copy the volume to secondary storage task = srcVdi.copyAsync(conn, secondaryStorage, null, null); // poll every 1 seconds , hypervisorResource.waitForTask(conn, task, 1000, wait * 1000); hypervisorResource.checkForSuccess(conn, task); - VDI destVdi = Types.toVDI(task, conn); - String destVolumeUUID = destVdi.getUuid(conn); + final VDI destVdi = Types.toVDI(task, conn); + final String destVolumeUUID = destVdi.getUuid(conn); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(destVolume.getPath() + File.separator + destVolumeUUID + ".vhd"); newVol.setSize(srcVolume.getSize()); return new CopyCmdAnswer(newVol); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Failed to copy volume to secondary: " + e.toString()); return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString()); } finally { if (task != null) { try { task.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString()); } } @@ -811,21 +813,21 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } @Override - public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - int wait = cmd.getWait(); - VolumeObjectTO srcVolume = (VolumeObjectTO)srcData; - VolumeObjectTO destVolume = (VolumeObjectTO)destData; - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destVolume.getDataStore(); - DataStoreTO srcStore = srcVolume.getDataStore(); + public Answer copyVolumeFromImageCacheToPrimary(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); + final DataTO srcData = cmd.getSrcTO(); + final DataTO destData = cmd.getDestTO(); + final int wait = cmd.getWait(); + final VolumeObjectTO srcVolume = (VolumeObjectTO) srcData; + final VolumeObjectTO destVolume = (VolumeObjectTO) destData; + final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) destVolume.getDataStore(); + final DataStoreTO srcStore = srcVolume.getDataStore(); if (srcStore instanceof NfsTO) { - NfsTO nfsStore = (NfsTO)srcStore; - String volumePath = srcVolume.getPath(); + final NfsTO nfsStore = (NfsTO) srcStore; + final String volumePath = srcVolume.getPath(); int index = volumePath.lastIndexOf("/"); - String volumeDirectory = volumePath.substring(0, index); + final String volumeDirectory = volumePath.substring(0, index); String volumeUuid = volumePath.substring(index + 1); index = volumeUuid.indexOf("."); if (index != -1) { @@ -834,33 +836,33 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { URI uri = null; try { uri = new URI(nfsStore.getUrl()); - } catch (Exception e) { + } catch (final Exception e) { return new CopyCmdAnswer(e.toString()); } - SR srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory); + final SR srcSr = createFileSr(conn, uri.getHost() + ":" + uri.getPath(), volumeDirectory); Task task = null; try { - SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid()); - VDI srcVdi = VDI.getByUuid(conn, volumeUuid); + final SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid()); + final VDI srcVdi = VDI.getByUuid(conn, volumeUuid); task = srcVdi.copyAsync(conn, primaryStoragePool, null, null); // poll every 1 seconds , hypervisorResource.waitForTask(conn, task, 1000, wait * 1000); hypervisorResource.checkForSuccess(conn, task); - VDI destVdi = Types.toVDI(task, conn); - VolumeObjectTO newVol = new VolumeObjectTO(); + final VDI destVdi = Types.toVDI(task, conn); + final VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(destVdi.getUuid(conn)); newVol.setSize(srcVolume.getSize()); return new CopyCmdAnswer(newVol); - } catch (Exception e) { - String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString(); + } catch (final Exception e) { + final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString(); s_logger.warn(msg, e); return new CopyCmdAnswer(e.toString()); } finally { if (task != null) { try { task.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.warn("unable to destroy task(" + task.toString() + ") due to " + e.toString()); } } @@ -875,23 +877,23 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } @Override - public Answer createTemplateFromSnapshot(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); + public Answer createTemplateFromSnapshot(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); + final DataTO srcData = cmd.getSrcTO(); + final DataTO destData = cmd.getDestTO(); if (srcData.getDataStore() instanceof PrimaryDataStoreTO && destData.getDataStore() instanceof NfsTO) { return createTemplateFromSnapshot2(cmd); } - int wait = cmd.getWait(); + final int wait = cmd.getWait(); - SnapshotObjectTO srcObj = (SnapshotObjectTO)srcData; - TemplateObjectTO destObj = (TemplateObjectTO)destData; + final SnapshotObjectTO srcObj = (SnapshotObjectTO) srcData; + final TemplateObjectTO destObj = (TemplateObjectTO) destData; - NfsTO srcStore = (NfsTO)srcObj.getDataStore(); - NfsTO destStore = (NfsTO)destObj.getDataStore(); + final NfsTO srcStore = (NfsTO) srcObj.getDataStore(); + final NfsTO destStore = (NfsTO) destObj.getDataStore(); URI srcUri = null; URI destUri = null; @@ -899,16 +901,16 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { try { srcUri = new URI(srcStore.getUrl()); destUri = new URI(destStore.getUrl()); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("incorrect url", e); return new CopyCmdAnswer("incorrect url" + e.toString()); } - String srcPath = srcObj.getPath(); - int index = srcPath.lastIndexOf("/"); - String srcDir = srcPath.substring(0, index); - String destDir = destObj.getPath(); + final String srcPath = srcObj.getPath(); + final int index = srcPath.lastIndexOf("/"); + final String srcDir = srcPath.substring(0, index); + final String destDir = destObj.getPath(); SR srcSr = null; SR destSr = null; @@ -920,42 +922,42 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { try { srcSr = createFileSr(conn, srcUri.getHost() + ":" + srcUri.getPath(), srcDir); - String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); - String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes()); + final String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); + final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes()); mountNfs(conn, destUri.getHost() + ":" + destUri.getPath(), localDir); makeDirectory(conn, localDir + "/" + destDir); destSr = createFileSR(conn, localDir + "/" + destDir); - String nameLabel = "cloud-" + UUID.randomUUID().toString(); + final String nameLabel = "cloud-" + UUID.randomUUID().toString(); - String[] parents = srcObj.getParents(); - List snapshotChains = new ArrayList(); + final String[] parents = srcObj.getParents(); + final List snapshotChains = new ArrayList(); if (parents != null) { for (int i = 0; i < parents.length; i++) { - String snChainPath = parents[i]; - String uuid = getSnapshotUuid(snChainPath); - VDI chain = VDI.getByUuid(conn, uuid); + final String snChainPath = parents[i]; + final String uuid = getSnapshotUuid(snChainPath); + final VDI chain = VDI.getByUuid(conn, uuid); snapshotChains.add(chain); } } - String snapshotUuid = getSnapshotUuid(srcPath); - VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid); + final String snapshotUuid = getSnapshotUuid(srcPath); + final VDI snapshotVdi = VDI.getByUuid(conn, snapshotUuid); snapshotChains.add(snapshotVdi); - long templateVirtualSize = snapshotChains.get(0).getVirtualSize(conn); + final long templateVirtualSize = snapshotChains.get(0).getVirtualSize(conn); destVdi = createVdi(conn, nameLabel, destSr, templateVirtualSize); - String destVdiUuid = destVdi.getUuid(conn); + final String destVdiUuid = destVdi.getUuid(conn); - for (VDI snapChain : snapshotChains) { - Task task = snapChain.copyAsync(conn, null, null, destVdi); + for (final VDI snapChain : snapshotChains) { + final Task task = snapChain.copyAsync(conn, null, null, destVdi); // poll every 1 seconds , hypervisorResource.waitForTask(conn, task, 1000, wait * 1000); hypervisorResource.checkForSuccess(conn, task); @@ -968,23 +970,22 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { // scan makes XenServer pick up VDI physicalSize destSr.scan(conn); - String templateUuid = destVdi.getUuid(conn); - String templateFilename = templateUuid + ".vhd"; - long virtualSize = destVdi.getVirtualSize(conn); - long physicalSize = destVdi.getPhysicalUtilisation(conn); + final String templateUuid = destVdi.getUuid(conn); + final String templateFilename = templateUuid + ".vhd"; + final long virtualSize = destVdi.getVirtualSize(conn); + final long physicalSize = destVdi.getPhysicalUtilisation(conn); String templatePath = destNfsPath + "/" + destDir; - templatePath = templatePath.replaceAll("//","/"); + templatePath = templatePath.replaceAll("//", "/"); - result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, - physicalSize, virtualSize, destObj.getId()); + result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, destObj.getId()); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); } - TemplateObjectTO newTemplate = new TemplateObjectTO(); + final TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(destDir + "/" + templateFilename); newTemplate.setFormat(Storage.ImageFormat.VHD); @@ -995,7 +996,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { result = true; return new CopyCmdAnswer(newTemplate); - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("Failed create template from snapshot", e); return new CopyCmdAnswer("Failed create template from snapshot " + e.toString()); @@ -1004,7 +1005,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (destVdi != null) { try { destVdi.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Clean up left over on dest storage failed: ", e); } } @@ -1020,11 +1021,11 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { } } - public Answer createTemplateFromSnapshot2(CopyCommand cmd) { - Connection conn = hypervisorResource.getConnection(); + public Answer createTemplateFromSnapshot2(final CopyCommand cmd) { + final Connection conn = hypervisorResource.getConnection(); - SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO)cmd.getSrcTO(); - TemplateObjectTO templateObjTO = (TemplateObjectTO)cmd.getDestTO(); + final SnapshotObjectTO snapshotObjTO = (SnapshotObjectTO) cmd.getSrcTO(); + final TemplateObjectTO templateObjTO = (TemplateObjectTO) cmd.getDestTO(); if (!(snapshotObjTO.getDataStore() instanceof PrimaryDataStoreTO) || !(templateObjTO.getDataStore() instanceof NfsTO)) { return null; @@ -1034,10 +1035,10 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { URI destUri = null; try { - destStore = (NfsTO)templateObjTO.getDataStore(); + destStore = (NfsTO) templateObjTO.getDataStore(); destUri = new URI(destStore.getUrl()); - } catch (Exception ex) { + } catch (final Exception ex) { s_logger.debug("Invalid URI", ex); return new CopyCmdAnswer("Invalid URI: " + ex.toString()); @@ -1046,23 +1047,23 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { SR srcSr = null; SR destSr = null; - String destDir = templateObjTO.getPath(); + final String destDir = templateObjTO.getPath(); VDI destVdi = null; boolean result = false; try { - Map srcDetails = cmd.getOptions(); + final Map srcDetails = cmd.getOptions(); - String iScsiName = srcDetails.get(DiskTO.IQN); - String storageHost = srcDetails.get(DiskTO.STORAGE_HOST); - String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME); - String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET); + final String iScsiName = srcDetails.get(DiskTO.IQN); + final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST); + final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME); + final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET); srcSr = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true); - String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); - String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes()); + final String destNfsPath = destUri.getHost() + ":" + destUri.getPath(); + final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(destNfsPath.getBytes()); mountNfs(conn, destNfsPath, localDir); makeDirectory(conn, localDir + "/" + destDir); @@ -1070,35 +1071,35 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { destSr = createFileSR(conn, localDir + "/" + destDir); // there should only be one VDI in this SR - VDI srcVdi = srcSr.getVDIs(conn).iterator().next(); + final VDI srcVdi = srcSr.getVDIs(conn).iterator().next(); destVdi = srcVdi.copy(conn, destSr); - String nameLabel = "cloud-" + UUID.randomUUID().toString(); + final String nameLabel = "cloud-" + UUID.randomUUID().toString(); destVdi.setNameLabel(conn, nameLabel); // scan makes XenServer pick up VDI physicalSize destSr.scan(conn); - String templateUuid = destVdi.getUuid(conn); - String templateFilename = templateUuid + ".vhd"; - long virtualSize = destVdi.getVirtualSize(conn); - long physicalSize = destVdi.getPhysicalUtilisation(conn); + final String templateUuid = destVdi.getUuid(conn); + final String templateFilename = templateUuid + ".vhd"; + final long virtualSize = destVdi.getVirtualSize(conn); + final long physicalSize = destVdi.getPhysicalUtilisation(conn); // create the template.properties file String templatePath = destNfsPath + "/" + destDir; templatePath = templatePath.replaceAll("//", "/"); - result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, - physicalSize, virtualSize, templateObjTO.getId()); + result = hypervisorResource.postCreatePrivateTemplate(conn, templatePath, templateFilename, templateUuid, nameLabel, null, physicalSize, virtualSize, + templateObjTO.getId()); if (!result) { throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir"); } - TemplateObjectTO newTemplate = new TemplateObjectTO(); + final TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(destDir + "/" + templateFilename); newTemplate.setFormat(Storage.ImageFormat.VHD); @@ -1110,19 +1111,22 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { result = true; return new CopyCmdAnswer(newTemplate); -// } catch (Exception ex) { -// s_logger.error("Failed to create a template from a snapshot", ex); -// -// return new CopyCmdAnswer("Failed to create a template from a snapshot: " + ex.toString()); - } catch (BadServerResponse e) { - s_logger.error("Failed to create a template from a snapshot due to incomprehensible server response", e); + // } catch (Exception ex) { + // s_logger.error("Failed to create a template from a snapshot", + // ex); + // + // return new + // CopyCmdAnswer("Failed to create a template from a snapshot: " + + // ex.toString()); + } catch (final BadServerResponse e) { + s_logger.error("Failed to create a template from a snapshot due to incomprehensible server response", e); - return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString()); - } catch (XenAPIException e) { - s_logger.error("Failed to create a template from a snapshot due to xenapi error", e); + return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString()); + } catch (final XenAPIException e) { + s_logger.error("Failed to create a template from a snapshot due to xenapi error", e); - return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString()); - } catch (XmlRpcException e) { + return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString()); + } catch (final XmlRpcException e) { s_logger.error("Failed to create a template from a snapshot due to rpc error", e); return new CopyCmdAnswer("Failed to create a template from a snapshot: " + e.toString()); @@ -1131,7 +1135,7 @@ public class Xenserver625StorageProcessor extends XenServerStorageProcessor { if (destVdi != null) { try { destVdi.destroy(conn); - } catch (Exception e) { + } catch (final Exception e) { s_logger.debug("Cleaned up leftover VDI on destination storage due to failure: ", e); } } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsHost.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsHost.java new file mode 100644 index 00000000000..e17a017e6f4 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsHost.java @@ -0,0 +1,212 @@ +// 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; + +import com.xensource.xenapi.Network; + +/** + * A list of UUIDs that are gathered from the XenServer when the resource first + * connects to XenServer. These UUIDs do not change over time. + */ +public class XsHost { + + private String systemvmisouuid; + private String uuid; + private String ip; + private String publicNetwork; + private String privateNetwork; + private String linkLocalNetwork; + private Network vswitchNetwork; + private String storageNetwork1; + private String guestNetwork; + private String guestPif; + private String publicPif; + private String privatePif; + private String storagePif1; + private String storagePif2; + private String pool; + private int speed; + private Integer cpuSockets; + private int cpus; + private String productVersion; + private String localSRuuid; + + public String getSystemvmisouuid() { + return systemvmisouuid; + } + + public void setSystemvmisouuid(final String systemvmisouuid) { + this.systemvmisouuid = systemvmisouuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(final String uuid) { + this.uuid = uuid; + } + + public String getIp() { + return ip; + } + + public void setIp(final String ip) { + this.ip = ip; + } + + public String getPublicNetwork() { + return publicNetwork; + } + + public void setPublicNetwork(final String publicNetwork) { + this.publicNetwork = publicNetwork; + } + + public String getPrivateNetwork() { + return privateNetwork; + } + + public void setPrivateNetwork(final String privateNetwork) { + this.privateNetwork = privateNetwork; + } + + public String getLinkLocalNetwork() { + return linkLocalNetwork; + } + + public void setLinkLocalNetwork(final String linkLocalNetwork) { + this.linkLocalNetwork = linkLocalNetwork; + } + + public Network getVswitchNetwork() { + return vswitchNetwork; + } + + public void setVswitchNetwork(final Network vswitchNetwork) { + this.vswitchNetwork = vswitchNetwork; + } + + public String getStorageNetwork1() { + return storageNetwork1; + } + + public void setStorageNetwork1(final String storageNetwork1) { + this.storageNetwork1 = storageNetwork1; + } + + public String getGuestNetwork() { + return guestNetwork; + } + + public void setGuestNetwork(final String guestNetwork) { + this.guestNetwork = guestNetwork; + } + + public String getGuestPif() { + return guestPif; + } + + public void setGuestPif(final String guestPif) { + this.guestPif = guestPif; + } + + public String getPublicPif() { + return publicPif; + } + + public void setPublicPif(final String publicPif) { + this.publicPif = publicPif; + } + + public String getPrivatePif() { + return privatePif; + } + + public void setPrivatePif(final String privatePif) { + this.privatePif = privatePif; + } + + public String getStoragePif1() { + return storagePif1; + } + + public void setStoragePif1(final String storagePif1) { + this.storagePif1 = storagePif1; + } + + public String getStoragePif2() { + return storagePif2; + } + + public void setStoragePif2(final String storagePif2) { + this.storagePif2 = storagePif2; + } + + public String getPool() { + return pool; + } + + public void setPool(final String pool) { + this.pool = pool; + } + + public int getSpeed() { + return speed; + } + + public void setSpeed(final int speed) { + this.speed = speed; + } + + public Integer getCpuSockets() { + return cpuSockets; + } + + public void setCpuSockets(final Integer cpuSockets) { + this.cpuSockets = cpuSockets; + } + + public int getCpus() { + return cpus; + } + + public void setCpus(final int cpus) { + this.cpus = cpus; + } + + public String getProductVersion() { + return productVersion; + } + + public void setProductVersion(final String productVersion) { + this.productVersion = productVersion; + } + + public String getLocalSRuuid() { + return localSRuuid; + } + + public void setLocalSRuuid(final String localSRuuid) { + this.localSRuuid = localSRuuid; + } + + @Override + public String toString() { + return new StringBuilder("XS[").append(uuid).append("-").append(ip).append("]").toString(); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsLocalNetwork.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsLocalNetwork.java new file mode 100644 index 00000000000..c7f4f8369ea --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XsLocalNetwork.java @@ -0,0 +1,91 @@ +// 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; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Types.XenAPIException; + +/** + * XsNic represents a network and the host's specific PIF. + */ +public class XsLocalNetwork { + + private static final Logger s_logger = Logger.getLogger(XsLocalNetwork.class); + + private final CitrixResourceBase _citrixResourceBase; + private final Network _n; + private Network.Record _nr; + private PIF _p; + private PIF.Record _pr; + + public XsLocalNetwork(final CitrixResourceBase citrixResourceBase, final Network n) { + this(citrixResourceBase, n, null, null, null); + } + + public XsLocalNetwork(final CitrixResourceBase citrixResourceBase, final Network n, final Network.Record nr, final PIF p, final PIF.Record pr) { + _citrixResourceBase = citrixResourceBase; + _n = n; + _nr = nr; + _p = p; + _pr = pr; + } + + public Network getNetwork() { + return _n; + } + + public Network.Record getNetworkRecord(final Connection conn) throws XenAPIException, XmlRpcException { + if (_nr == null) { + _nr = _n.getRecord(conn); + } + + return _nr; + } + + public PIF getPif(final Connection conn) throws XenAPIException, XmlRpcException { + if (_p == null) { + final Network.Record nr = getNetworkRecord(conn); + for (final PIF pif : nr.PIFs) { + final PIF.Record pr = pif.getRecord(conn); + if (_citrixResourceBase.getHost().getUuid().equals(pr.host.getUuid(conn))) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found a network called " + nr.nameLabel + " on host=" + _citrixResourceBase.getHost().getIp() + "; Network=" + nr.uuid + "; pif=" + pr.uuid); + } + _p = pif; + _pr = pr; + break; + } + } + } + return _p; + } + + public PIF.Record getPifRecord(final Connection conn) throws XenAPIException, XmlRpcException { + if (_pr == null) { + final PIF p = getPif(conn); + if (_pr == null) { + _pr = p.getRecord(conn); + } + } + return _pr; + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachIsoCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachIsoCommandWrapper.java new file mode 100644 index 00000000000..cc444c5a92d --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachIsoCommandWrapper.java @@ -0,0 +1,134 @@ +// +// 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.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachIsoCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; + +public final class CitrixAttachIsoCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixAttachIsoCommandWrapper.class); + + @Override + public Answer execute(final AttachIsoCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final boolean attach = command.isAttach(); + final String vmName = command.getVmName(); + final String isoURL = command.getIsoPath(); + + String errorMsg; + if (attach) { + errorMsg = "Failed to attach ISO"; + } else { + errorMsg = "Failed to detach ISO"; + } + try { + if (attach) { + VBD isoVBD = null; + + // Find the VM + final VM vm = citrixResourceBase.getVM(conn, vmName); + + // Find the ISO VDI + final VDI isoVDI = citrixResourceBase.getIsoVDIByURL(conn, vmName, isoURL); + + // Find the VM's CD-ROM VBD + final Set vbds = vm.getVBDs(conn); + for (final VBD vbd : vbds) { + final String userDevice = vbd.getUserdevice(conn); + final Types.VbdType type = vbd.getType(conn); + + if (userDevice.equals("3") && type == Types.VbdType.CD) { + isoVBD = vbd; + break; + } + } + + if (isoVBD == null) { + throw new CloudRuntimeException("Unable to find CD-ROM VBD for VM: " + vmName); + } else { + // If an ISO is already inserted, eject it + if (isoVBD.getEmpty(conn) == false) { + isoVBD.eject(conn); + } + + // Insert the new ISO + isoVBD.insert(conn, isoVDI); + } + + return new Answer(command); + } else { + // Find the VM + final VM vm = citrixResourceBase.getVM(conn, vmName); + final String vmUUID = vm.getUuid(conn); + + // Find the ISO VDI + final VDI isoVDI = citrixResourceBase.getIsoVDIByURL(conn, vmName, isoURL); + + final SR sr = isoVDI.getSR(conn); + + // Look up all VBDs for this VDI + final Set vbds = isoVDI.getVBDs(conn); + + // Iterate through VBDs, and if the VBD belongs the VM, eject + // the ISO from it + for (final VBD vbd : vbds) { + final VM vbdVM = vbd.getVM(conn); + final String vbdVmUUID = vbdVM.getUuid(conn); + + if (vbdVmUUID.equals(vmUUID)) { + // If an ISO is already inserted, eject it + if (!vbd.getEmpty(conn)) { + vbd.eject(conn); + } + + break; + } + } + + if (!sr.getNameLabel(conn).startsWith("XenServer Tools")) { + citrixResourceBase.removeSR(conn, sr); + } + + return new Answer(command); + } + } catch (final XenAPIException e) { + s_logger.warn(errorMsg + ": " + e.toString(), e); + return new Answer(command, false, e.toString()); + } catch (final Exception e) { + s_logger.warn(errorMsg + ": " + e.toString(), e); + return new Answer(command, false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachVolumeCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachVolumeCommandWrapper.java new file mode 100644 index 00000000000..01fd874e55c --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachVolumeCommandWrapper.java @@ -0,0 +1,144 @@ +// +// 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.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachVolumeAnswer; +import com.cloud.agent.api.AttachVolumeCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; + +public final class CitrixAttachVolumeCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixAttachVolumeCommandWrapper.class); + + @Override + public Answer execute(final AttachVolumeCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final boolean attach = command.getAttach(); + final String vmName = command.getVmName(); + final String vdiNameLabel = vmName + "-DATA"; + final Long deviceId = command.getDeviceId(); + + String errorMsg; + if (attach) { + errorMsg = "Failed to attach volume"; + } else { + errorMsg = "Failed to detach volume"; + } + + try { + VDI vdi = null; + + if (command.getAttach() && command.isManaged()) { + final SR sr = citrixResourceBase.getIscsiSR(conn, command.get_iScsiName(), command.getStorageHost(), command.get_iScsiName(), command.getChapInitiatorUsername(), + command.getChapInitiatorPassword(), true); + + vdi = citrixResourceBase.getVDIbyUuid(conn, command.getVolumePath(), false); + + if (vdi == null) { + vdi = citrixResourceBase.createVdi(sr, vdiNameLabel, command.getVolumeSize()); + } + } else { + vdi = citrixResourceBase.getVDIbyUuid(conn, command.getVolumePath()); + } + + // Look up the VM + final VM vm = citrixResourceBase.getVM(conn, vmName); + if (attach) { + // Figure out the disk number to attach the VM to + String diskNumber = null; + if (deviceId != null) { + if (deviceId.longValue() == 3) { + final String msg = "Device 3 is reserved for CD-ROM, choose other device"; + return new AttachVolumeAnswer(command, msg); + } + if (citrixResourceBase.isDeviceUsed(conn, vm, deviceId)) { + final String msg = "Device " + deviceId + " is used in VM " + vmName; + return new AttachVolumeAnswer(command, msg); + } + diskNumber = deviceId.toString(); + } else { + diskNumber = citrixResourceBase.getUnusedDeviceNum(conn, vm); + } + // Create a new VBD + final VBD.Record vbdr = new VBD.Record(); + vbdr.VM = vm; + vbdr.VDI = vdi; + vbdr.bootable = false; + vbdr.userdevice = diskNumber; + vbdr.mode = Types.VbdMode.RW; + vbdr.type = Types.VbdType.DISK; + vbdr.unpluggable = true; + final VBD vbd = VBD.create(conn, vbdr); + + // Attach the VBD to the VM + vbd.plug(conn); + + // Update the VDI's label to include the VM name + vdi.setNameLabel(conn, vdiNameLabel); + + return new AttachVolumeAnswer(command, Long.parseLong(diskNumber), vdi.getUuid(conn)); + } else { + // Look up all VBDs for this VDI + final Set vbds = vdi.getVBDs(conn); + + // Detach each VBD from its VM, and then destroy it + for (final VBD vbd : vbds) { + final VBD.Record vbdr = vbd.getRecord(conn); + + if (vbdr.currentlyAttached) { + vbd.unplug(conn); + } + + vbd.destroy(conn); + } + + // Update the VDI's label to be "detached" + vdi.setNameLabel(conn, "detached"); + + if (command.isManaged()) { + citrixResourceBase.handleSrAndVdiDetach(command.get_iScsiName(), conn); + } + + return new AttachVolumeAnswer(command); + } + } catch (final XenAPIException e) { + final String msg = errorMsg + " for uuid: " + command.getVolumePath() + " due to " + e.toString(); + s_logger.warn(msg, e); + return new AttachVolumeAnswer(command, msg); + } catch (final Exception e) { + final String msg = errorMsg + " for uuid: " + command.getVolumePath() + " due to " + e.getMessage(); + s_logger.warn(msg, e); + return new AttachVolumeAnswer(command, msg); + } + } +} \ 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 new file mode 100644 index 00000000000..bdf7c319a59 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckConsoleProxyLoadCommandWrapper.java @@ -0,0 +1,38 @@ +// +// 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 com.cloud.agent.api.Answer; +import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; + +public final class CitrixCheckConsoleProxyLoadCommandWrapper extends CommandWrapper { + + @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(); + + return executeProxyLoadScan(command, proxyVmId, proxyVmName, proxyManagementIp, cmdPort); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckHealthCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckHealthCommandWrapper.java new file mode 100644 index 00000000000..f77e3092ab7 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckHealthCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckHealthAnswer; +import com.cloud.agent.api.CheckHealthCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; + +public final class CitrixCheckHealthCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CheckHealthCommand command, final CitrixResourceBase citrixResourceBase) { + final boolean result = citrixResourceBase.pingXAPI(); + return new CheckHealthAnswer(command, result); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckNetworkCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckNetworkCommandWrapper.java new file mode 100644 index 00000000000..fb62fcebbc3 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckNetworkCommandWrapper.java @@ -0,0 +1,94 @@ +// +// 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.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckNetworkAnswer; +import com.cloud.agent.api.CheckNetworkCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.network.PhysicalNetworkSetupInfo; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixCheckNetworkCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixCheckNetworkCommandWrapper.class); + + @Override + public Answer execute(final CheckNetworkCommand command, final CitrixResourceBase citrixResourceBase) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Checking if network name setup is done on the resource"); + } + + final List infoList = command.getPhysicalNetworkInfoList(); + + try { + boolean errorout = false; + String msg = ""; + for (final PhysicalNetworkSetupInfo info : infoList) { + if (!citrixResourceBase.isNetworkSetupByName(info.getGuestNetworkName())) { + msg = + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " + + info.getGuestNetworkName(); + errorout = true; + break; + } + if (!citrixResourceBase.isNetworkSetupByName(info.getPrivateNetworkName())) { + msg = + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " + + info.getPrivateNetworkName(); + errorout = true; + break; + } + if (!citrixResourceBase.isNetworkSetupByName(info.getPublicNetworkName())) { + msg = + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " + + info.getPublicNetworkName(); + errorout = true; + break; + } + /*if(!isNetworkSetupByName(info.getStorageNetworkName())){ + msg = "For Physical Network id:"+ info.getPhysicalNetworkId() + ", Storage Network is not configured on the backend by name " + info.getStorageNetworkName(); + errorout = true; + break; + }*/ + } + if (errorout) { + s_logger.error(msg); + return new CheckNetworkAnswer(command, false, msg); + } else { + return new CheckNetworkAnswer(command, true, "Network Setup check by names is done"); + } + + } catch (final XenAPIException e) { + final String msg = "CheckNetworkCommand failed with XenAPIException:" + e.toString() + " host:" + citrixResourceBase.getHost().getUuid(); + s_logger.warn(msg, e); + return new CheckNetworkAnswer(command, false, msg); + } catch (final Exception e) { + final String msg = "CheckNetworkCommand failed with Exception:" + e.getMessage() + " host:" + citrixResourceBase.getHost().getUuid(); + s_logger.warn(msg, e); + return new CheckNetworkAnswer(command, false, msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckOnHostCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckOnHostCommandWrapper.java new file mode 100644 index 00000000000..aaee57b498e --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckOnHostCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckOnHostAnswer; +import com.cloud.agent.api.CheckOnHostCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; + +public final class CitrixCheckOnHostCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final CheckOnHostCommand command, final CitrixResourceBase citrixResourceBase) { + return new CheckOnHostAnswer(command, "Not Implmeneted"); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckSshCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckSshCommandWrapper.java new file mode 100644 index 00000000000..4437641d405 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckSshCommandWrapper.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.xenserver.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.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixCheckSshCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixCheckSshCommandWrapper.class); + + @Override + public Answer execute(final CheckSshCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + 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); + } + + try { + final String result = citrixResourceBase.connect(conn, command.getName(), privateIp, cmdPort); + if (result != null) { + return new CheckSshAnswer(command, "Can not ping System vm " + vmName + "due to:" + result); + } + //Do not destroy the disk here! It will stio the patching process. Please, don't! + //destroyPatchVbd(conn, vmName); + } catch (final Exception e) { + return new CheckSshAnswer(command, e); + } + + 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/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckVirtualMachineCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckVirtualMachineCommandWrapper.java new file mode 100644 index 00000000000..1ae20c1bcfb --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCheckVirtualMachineCommandWrapper.java @@ -0,0 +1,48 @@ +// +// 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 org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckVirtualMachineAnswer; +import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.vm.VirtualMachine.PowerState; +import com.xensource.xenapi.Connection; + +public final class CitrixCheckVirtualMachineCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixCheckVirtualMachineCommandWrapper.class); + + @Override + public Answer execute(final CheckVirtualMachineCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final String vmName = command.getVmName(); + final PowerState powerState = citrixResourceBase.getVmState(conn, vmName); + final Integer vncPort = null; + if (powerState == PowerState.PowerOn) { + s_logger.debug("3. The VM " + vmName + " is in Running state"); + } + + return new CheckVirtualMachineAnswer(command, powerState, vncPort); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCleanupNetworkRulesCmdWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCleanupNetworkRulesCmdWrapper.java new file mode 100644 index 00000000000..471c1e8a9eb --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCleanupNetworkRulesCmdWrapper.java @@ -0,0 +1,54 @@ +// +// 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 org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CleanupNetworkRulesCmd; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixCleanupNetworkRulesCmdWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixCleanupNetworkRulesCmdWrapper.class); + + @Override + public Answer execute(final CleanupNetworkRulesCmd command, final CitrixResourceBase citrixResourceBase) { + if (!citrixResourceBase.canBridgeFirewall()) { + return new Answer(command, true, null); + } + final Connection conn = citrixResourceBase.getConnection(); + + final String result = citrixResourceBase.callHostPlugin(conn, "vmops", "cleanup_rules", "instance", citrixResourceBase.getVMInstanceName()); + final int numCleaned = Integer.parseInt(result); + + if (result == null || result.isEmpty() || numCleaned < 0) { + s_logger.warn("Failed to cleanup rules for host " + citrixResourceBase.getHost().getIp()); + return new Answer(command, false, result); + } + + if (numCleaned > 0) { + s_logger.info("Cleaned up rules for " + result + " vms on host " + citrixResourceBase.getHost().getIp()); + } + return new Answer(command, true, result); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixClusterVMMetaDataSyncCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixClusterVMMetaDataSyncCommandWrapper.java new file mode 100644 index 00000000000..fb7384be75e --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixClusterVMMetaDataSyncCommandWrapper.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.xenserver.resource.wrapper; + +import java.util.HashMap; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ClusterVMMetaDataSyncAnswer; +import com.cloud.agent.api.ClusterVMMetaDataSyncCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Pool; + +public final class CitrixClusterVMMetaDataSyncCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixClusterVMMetaDataSyncCommandWrapper.class); + + @Override + public Answer execute(final ClusterVMMetaDataSyncCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + //check if this is master + try { + final Pool pool = Pool.getByUuid(conn, citrixResourceBase.getHost().getPool()); + final Pool.Record poolr = pool.getRecord(conn); + final Host.Record hostr = poolr.master.getRecord(conn); + if (!citrixResourceBase.getHost().getUuid().equals(hostr.uuid)) { + return new ClusterVMMetaDataSyncAnswer(command.getClusterId(), null); + } + } catch (final Throwable e) { + s_logger.warn("Check for master failed, failing the Cluster sync VMMetaData command"); + return new ClusterVMMetaDataSyncAnswer(command.getClusterId(), null); + } + final HashMap vmMetadatum = citrixResourceBase.clusterVMMetaDataSync(conn); + return new ClusterVMMetaDataSyncAnswer(command.getClusterId(), vmMetadatum); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateCommandWrapper.java new file mode 100644 index 00000000000..c58c5a9a87a --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateCommandWrapper.java @@ -0,0 +1,82 @@ +// +// 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.util.HashMap; + +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.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.vm.DiskProfile; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.VDI; + +public final class CitrixCreateCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixCreateCommandWrapper.class); + + @Override + public Answer execute(final CreateCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final StorageFilerTO pool = command.getPool(); + final DiskProfile dskch = command.getDiskCharacteristics(); + + VDI vdi = null; + try { + final SR poolSr = citrixResourceBase.getStorageRepository(conn, pool.getUuid()); + if (command.getTemplateUrl() != null) { + VDI tmpltvdi = null; + + tmpltvdi = citrixResourceBase.getVDIbyUuid(conn, command.getTemplateUrl()); + vdi = tmpltvdi.createClone(conn, new HashMap()); + vdi.setNameLabel(conn, dskch.getName()); + } else { + final VDI.Record vdir = new VDI.Record(); + vdir.nameLabel = dskch.getName(); + vdir.SR = poolSr; + vdir.type = Types.VdiType.USER; + + vdir.virtualSize = dskch.getSize(); + vdi = VDI.create(conn, vdir); + } + + VDI.Record vdir; + vdir = vdi.getRecord(conn); + + s_logger.debug("Succesfully created VDI for " + command + ". Uuid = " + vdir.uuid); + + final VolumeTO vol = + new VolumeTO(command.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); + + return new CreateAnswer(command, vol); + } catch (final Exception e) { + s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: " + dskch, e); + return new CreateAnswer(command, e); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateStoragePoolCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateStoragePoolCommandWrapper.java new file mode 100644 index 00000000000..f749abb04a9 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateStoragePoolCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.storage.Storage.StoragePoolType; +import com.xensource.xenapi.Connection; + +public final class CitrixCreateStoragePoolCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixCreateStoragePoolCommandWrapper.class); + + @Override + public Answer execute(final CreateStoragePoolCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final StorageFilerTO pool = command.getPool(); + try { + if (pool.getType() == StoragePoolType.NetworkFilesystem) { + citrixResourceBase.getNfsSR(conn, Long.toString(pool.getId()), pool.getUuid(), pool.getHost(), pool.getPath(), pool.toString()); + } else if (pool.getType() == StoragePoolType.IscsiLUN) { + citrixResourceBase.getIscsiSR(conn, pool.getUuid(), pool.getHost(), pool.getPath(), null, null, false); + } else if (pool.getType() == StoragePoolType.PreSetup) { + } else { + return new Answer(command, false, "The pool type: " + pool.getType().name() + " is not supported."); + } + return new Answer(command, true, "success"); + } catch (final Exception e) { + final String msg = "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + + citrixResourceBase.getHost().getUuid() + " pool: " + pool.getHost() + pool.getPath(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateVMSnapshotCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateVMSnapshotCommandWrapper.java new file mode 100644 index 00000000000..7ccf9279b04 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixCreateVMSnapshotCommandWrapper.java @@ -0,0 +1,188 @@ +// +// 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.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CreateVMSnapshotAnswer; +import com.cloud.agent.api.CreateVMSnapshotCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.vm.snapshot.VMSnapshot; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Pool; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Task; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.VmPowerState; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; + +public final class CitrixCreateVMSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixCreateVMSnapshotCommandWrapper.class); + + @Override + public Answer execute(final CreateVMSnapshotCommand command, final CitrixResourceBase citrixResourceBase) { + final String vmName = command.getVmName(); + final String vmSnapshotName = command.getTarget().getSnapshotName(); + final List listVolumeTo = command.getVolumeTOs(); + + VmPowerState vmState = VmPowerState.HALTED; + + final String guestOSType = command.getGuestOSType(); + final String platformEmulator = command.getPlatformEmulator(); + + final boolean snapshotMemory = command.getTarget().getType() == VMSnapshot.Type.DiskAndMemory; + final long timeout = command.getWait(); + + final Connection conn = citrixResourceBase.getConnection(); + VM vm = null; + VM vmSnapshot = null; + boolean success = false; + + try { + // check if VM snapshot already exists + final Set vmSnapshots = VM.getByNameLabel(conn, command.getTarget().getSnapshotName()); + if (vmSnapshots == null || vmSnapshots.size() > 0) { + return new CreateVMSnapshotAnswer(command, command.getTarget(), command.getVolumeTOs()); + } + + // check if there is already a task for this VM snapshot + Task task = null; + Set tasks = Task.getByNameLabel(conn, "Async.VM.snapshot"); + if(tasks == null) { + tasks = new LinkedHashSet<>(); + } + final Set tasksByName = Task.getByNameLabel(conn, "Async.VM.checkpoint"); + if(tasksByName != null) { + tasks.addAll(tasksByName); + } + for (final Task taskItem : tasks) { + if (taskItem.getOtherConfig(conn).containsKey("CS_VM_SNAPSHOT_KEY")) { + final String vmSnapshotTaskName = taskItem.getOtherConfig(conn).get("CS_VM_SNAPSHOT_KEY"); + if (vmSnapshotTaskName != null && vmSnapshotTaskName.equals(command.getTarget().getSnapshotName())) { + task = taskItem; + } + } + } + + // create a new task if there is no existing task for this VM snapshot + if (task == null) { + try { + vm = citrixResourceBase.getVM(conn, vmName); + vmState = vm.getPowerState(conn); + } catch (final Exception e) { + if (!snapshotMemory) { + vm = citrixResourceBase.createWorkingVM(conn, vmName, guestOSType, platformEmulator, listVolumeTo); + } + } + + if (vm == null) { + return new CreateVMSnapshotAnswer(command, false, "Creating VM Snapshot Failed due to can not find vm: " + vmName); + } + + // call Xenserver API + if (!snapshotMemory) { + task = vm.snapshotAsync(conn, vmSnapshotName); + } else { + final Set vbds = vm.getVBDs(conn); + final Pool pool = Pool.getByUuid(conn, citrixResourceBase.getHost().getPool()); + for (final VBD vbd : vbds) { + final VBD.Record vbdr = vbd.getRecord(conn); + if (vbdr.userdevice.equals("0")) { + final VDI vdi = vbdr.VDI; + final SR sr = vdi.getSR(conn); + // store memory image on the same SR with ROOT volume + pool.setSuspendImageSR(conn, sr); + } + } + task = vm.checkpointAsync(conn, vmSnapshotName); + } + task.addToOtherConfig(conn, "CS_VM_SNAPSHOT_KEY", vmSnapshotName); + } + + citrixResourceBase.waitForTask(conn, task, 1000, timeout * 1000); + citrixResourceBase.checkForSuccess(conn, task); + final String result = task.getResult(conn); + + // extract VM snapshot ref from result + final String ref = result.substring("".length(), result.length() - "".length()); + vmSnapshot = Types.toVM(ref); + try { + Thread.sleep(5000); + } catch (final InterruptedException ex) { + + } + // calculate used capacity for this VM snapshot + for (final VolumeObjectTO volumeTo : command.getVolumeTOs()) { + final long size = citrixResourceBase.getVMSnapshotChainSize(conn, volumeTo, command.getVmName()); + volumeTo.setSize(size); + } + + success = true; + return new CreateVMSnapshotAnswer(command, command.getTarget(), command.getVolumeTOs()); + } catch (final Exception e) { + String msg = ""; + if (e instanceof Types.BadAsyncResult) { + final String licenseKeyWord = "LICENCE_RESTRICTION"; + final Types.BadAsyncResult errorResult = (Types.BadAsyncResult)e; + if (errorResult.shortDescription != null && errorResult.shortDescription.contains(licenseKeyWord)) { + msg = licenseKeyWord; + } + } else { + msg = e.toString(); + } + s_logger.warn("Creating VM Snapshot " + command.getTarget().getSnapshotName() + " failed due to: " + msg, e); + return new CreateVMSnapshotAnswer(command, false, msg); + } finally { + try { + if (!success) { + if (vmSnapshot != null) { + s_logger.debug("Delete exsisting VM Snapshot " + vmSnapshotName + " after making VolumeTO failed"); + final Set vbds = vmSnapshot.getVBDs(conn); + for (final VBD vbd : vbds) { + final VBD.Record vbdr = vbd.getRecord(conn); + if (vbdr.type == Types.VbdType.DISK) { + final VDI vdi = vbdr.VDI; + vdi.destroy(conn); + } + } + vmSnapshot.destroy(conn); + } + } + if (vmState == VmPowerState.HALTED) { + if (vm != null) { + vm.destroy(conn); + } + } + } catch (final Exception e2) { + s_logger.error("delete snapshot error due to " + e2.getMessage()); + } + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDeleteStoragePoolCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDeleteStoragePoolCommandWrapper.java new file mode 100644 index 00000000000..e95a2729b68 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDeleteStoragePoolCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.DeleteStoragePoolCommand; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.SR; + +public final class CitrixDeleteStoragePoolCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixDeleteStoragePoolCommandWrapper.class); + + @Override + public Answer execute(final DeleteStoragePoolCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final StorageFilerTO poolTO = command.getPool(); + try { + final SR sr = citrixResourceBase.getStorageRepository(conn, poolTO.getUuid()); + citrixResourceBase.removeSR(conn, sr); + final Answer answer = new Answer(command, true, "success"); + return answer; + } catch (final Exception e) { + final String msg = "DeleteStoragePoolCommand XenAPIException:" + e.getMessage() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: " + poolTO.getHost() + + poolTO.getPath(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDeleteVMSnapshotCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDeleteVMSnapshotCommandWrapper.java new file mode 100644 index 00000000000..10f409176ff --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDeleteVMSnapshotCommandWrapper.java @@ -0,0 +1,90 @@ +// +// 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.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.DeleteVMSnapshotAnswer; +import com.cloud.agent.api.DeleteVMSnapshotCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.vm.snapshot.VMSnapshot; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; + +public final class CitrixDeleteVMSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixDeleteVMSnapshotCommandWrapper.class); + + @Override + public Answer execute(final DeleteVMSnapshotCommand command, final CitrixResourceBase citrixResourceBase) { + final String snapshotName = command.getTarget().getSnapshotName(); + final Connection conn = citrixResourceBase.getConnection(); + + try { + final List vdiList = new ArrayList(); + final Set snapshots = VM.getByNameLabel(conn, snapshotName); + if (snapshots == null || snapshots.size() == 0) { + s_logger.warn("VM snapshot with name " + snapshotName + " does not exist, assume it is already deleted"); + return new DeleteVMSnapshotAnswer(command, command.getVolumeTOs()); + } + final VM snapshot = snapshots.iterator().next(); + final Set vbds = snapshot.getVBDs(conn); + for (final VBD vbd : vbds) { + if (vbd.getType(conn) == Types.VbdType.DISK) { + final VDI vdi = vbd.getVDI(conn); + vdiList.add(vdi); + } + } + if (command.getTarget().getType() == VMSnapshot.Type.DiskAndMemory) { + vdiList.add(snapshot.getSuspendVDI(conn)); + } + snapshot.destroy(conn); + for (final VDI vdi : vdiList) { + vdi.destroy(conn); + } + + try { + Thread.sleep(5000); + } catch (final InterruptedException ex) { + + } + // re-calculate used capacify for this VM snapshot + for (final VolumeObjectTO volumeTo : command.getVolumeTOs()) { + final long size = citrixResourceBase.getVMSnapshotChainSize(conn, volumeTo, command.getVmName()); + volumeTo.setSize(size); + } + + return new DeleteVMSnapshotAnswer(command, command.getVolumeTOs()); + } catch (final Exception e) { + s_logger.warn("Catch Exception: " + e.getClass().toString() + " due to " + e.toString(), e); + return new DeleteVMSnapshotAnswer(command, false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDestroyCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDestroyCommandWrapper.java new file mode 100644 index 00000000000..0685a1b8eb9 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixDestroyCommandWrapper.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.util.Set; + +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.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; + +public final class CitrixDestroyCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixDestroyCommandWrapper.class); + + @Override + public Answer execute(final DestroyCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final VolumeTO vol = command.getVolume(); + // Look up the VDI + final String volumeUUID = vol.getPath(); + VDI vdi = null; + try { + vdi = citrixResourceBase.getVDIbyUuid(conn, volumeUUID); + } catch (final Exception e) { + return new Answer(command, true, "Success"); + } + Set vbds = null; + try { + vbds = vdi.getVBDs(conn); + } catch (final Exception e) { + final String msg = "VDI getVBDS for " + volumeUUID + " failed due to " + e.toString(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } + for (final VBD vbd : vbds) { + try { + vbd.unplug(conn); + vbd.destroy(conn); + } catch (final Exception e) { + final String msg = "VM destroy for " + volumeUUID + " failed due to " + e.toString(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } + } + try { + final Set snapshots = vdi.getSnapshots(conn); + for (final VDI snapshot : snapshots) { + snapshot.destroy(conn); + } + vdi.destroy(conn); + } catch (final Exception e) { + final String msg = "VDI destroy for " + volumeUUID + " failed due to " + e.toString(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } + + return new Answer(command, true, "Success"); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetHostStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetHostStatsCommandWrapper.java new file mode 100644 index 00000000000..21d9d3d9138 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetHostStatsCommandWrapper.java @@ -0,0 +1,48 @@ +// +// 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 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.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixGetHostStatsCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixGetHostStatsCommandWrapper.class); + + @Override + public Answer execute(final GetHostStatsCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final HostStatsEntry hostStats = citrixResourceBase.getHostStats(conn, command, command.getHostGuid(), command.getHostId()); + return new GetHostStatsAnswer(command, hostStats); + } catch (final Exception e) { + final String msg = "Unable to get Host stats" + e.toString(); + s_logger.warn(msg, e); + return new GetHostStatsAnswer(command, null); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetStorageStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetStorageStatsCommandWrapper.java new file mode 100644 index 00000000000..e0001ccd9fe --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetStorageStatsCommandWrapper.java @@ -0,0 +1,69 @@ +// +// 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.util.Set; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetStorageStatsAnswer; +import com.cloud.agent.api.GetStorageStatsCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixGetStorageStatsCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixGetStorageStatsCommandWrapper.class); + + @Override + public Answer execute(final GetStorageStatsCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final Set srs = SR.getByNameLabel(conn, command.getStorageId()); + if (srs.size() != 1) { + final String msg = "There are " + srs.size() + " storageid: " + command.getStorageId(); + s_logger.warn(msg); + return new GetStorageStatsAnswer(command, msg); + } + final SR sr = srs.iterator().next(); + sr.scan(conn); + final long capacity = sr.getPhysicalSize(conn); + final long used = sr.getPhysicalUtilisation(conn); + return new GetStorageStatsAnswer(command, capacity, used); + } catch (final XenAPIException e) { + final String msg = "GetStorageStats Exception:" + e.toString() + "host:" + citrixResourceBase.getHost().getUuid() + "storageid: " + command.getStorageId(); + s_logger.warn(msg); + return new GetStorageStatsAnswer(command, msg); + } catch (final XmlRpcException e) { + final String msg = "GetStorageStats Exception:" + e.getMessage() + "host:" + citrixResourceBase.getHost().getUuid() + "storageid: " + command.getStorageId(); + s_logger.warn(msg); + return new GetStorageStatsAnswer(command, msg); + } catch (final Exception e) { + final String msg = "GetStorageStats Exception:" + e.getMessage() + "host:" + citrixResourceBase.getHost().getUuid() + "storageid: " + command.getStorageId(); + s_logger.warn(msg); + return new GetStorageStatsAnswer(command, msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVmDiskStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVmDiskStatsCommandWrapper.java new file mode 100644 index 00000000000..682d2025056 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVmDiskStatsCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVmDiskStatsAnswer; +import com.cloud.agent.api.GetVmDiskStatsCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; + +public final class CitrixGetVmDiskStatsCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final GetVmDiskStatsCommand command, final CitrixResourceBase citrixResourceBase) { + return new GetVmDiskStatsAnswer(command, null, null, null); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVmStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVmStatsCommandWrapper.java new file mode 100644 index 00000000000..2b535ea1c41 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVmStatsCommandWrapper.java @@ -0,0 +1,82 @@ +// +// 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.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +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.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VM; + +public final class CitrixGetVmStatsCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixGetVmStatsCommandWrapper.class); + + @Override + public Answer execute(final GetVmStatsCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final List vmNames = command.getVmNames(); + final HashMap vmStatsNameMap = new HashMap(); + if (vmNames.size() == 0) { + return new GetVmStatsAnswer(command, vmStatsNameMap); + } + try { + + // Determine the UUIDs of the requested VMs + final List vmUUIDs = new ArrayList(); + + for (final String vmName : vmNames) { + final VM vm = citrixResourceBase.getVM(conn, vmName); + vmUUIDs.add(vm.getUuid(conn)); + } + + final HashMap vmStatsUUIDMap = citrixResourceBase.getVmStats(conn, command, vmUUIDs, command.getHostGuid()); + if (vmStatsUUIDMap == null) { + return new GetVmStatsAnswer(command, vmStatsNameMap); + } + + for (final Map.Entryentry : vmStatsUUIDMap.entrySet()) { + vmStatsNameMap.put(vmNames.get(vmUUIDs.indexOf(entry.getKey())), entry.getValue()); + } + + return new GetVmStatsAnswer(command, vmStatsNameMap); + } catch (final XenAPIException e) { + final String msg = "Unable to get VM stats" + e.toString(); + s_logger.warn(msg, e); + return new GetVmStatsAnswer(command, vmStatsNameMap); + } catch (final XmlRpcException e) { + final String msg = "Unable to get VM stats" + e.getMessage(); + s_logger.warn(msg, e); + return new GetVmStatsAnswer(command, vmStatsNameMap); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVncPortCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVncPortCommandWrapper.java new file mode 100644 index 00000000000..d69ce27d606 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixGetVncPortCommandWrapper.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.xenserver.resource.wrapper; + +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVncPortAnswer; +import com.cloud.agent.api.GetVncPortCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VM; + +public final class CitrixGetVncPortCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixGetVncPortCommandWrapper.class); + + @Override + public Answer execute(final GetVncPortCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final Set vms = VM.getByNameLabel(conn, command.getName()); + if (vms.size() == 1) { + String consoleurl; + consoleurl = "consoleurl=" + citrixResourceBase.getVncUrl(conn, vms.iterator().next()) + "&" + "sessionref=" + conn.getSessionReference(); + return new GetVncPortAnswer(command, consoleurl, -1); + } else { + return new GetVncPortAnswer(command, "There are " + vms.size() + " VMs named " + command.getName()); + } + } catch (final Exception e) { + final String msg = "Unable to get vnc port due to " + e.toString(); + s_logger.warn(msg, e); + return new GetVncPortAnswer(command, msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMaintainCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMaintainCommandWrapper.java new file mode 100644 index 00000000000..d1c5b70f1ff --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMaintainCommandWrapper.java @@ -0,0 +1,75 @@ +// +// 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.util.Iterator; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.MaintainAnswer; +import com.cloud.agent.api.MaintainCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.hypervisor.xenserver.resource.XsHost; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixMaintainCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixMaintainCommandWrapper.class); + + @Override + public Answer execute(final MaintainCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + + final XsHost xsHost = citrixResourceBase.getHost(); + final String uuid = xsHost.getUuid(); + final Host host = Host.getByUuid(conn, uuid); + // remove all tags cloud stack + final Host.Record hr = host.getRecord(conn); + + // Adding this check because could not get the mock to work. Will push the code and fix it afterwards. + if (hr == null) { + s_logger.warn("Host.Record is null."); + return new MaintainAnswer(command, false, "Host.Record is null"); + } + + final Iterator it = hr.tags.iterator(); + while (it.hasNext()) { + final String tag = it.next(); + if (tag.contains("cloud")) { + it.remove(); + } + } + host.setTags(conn, hr.tags); + return new MaintainAnswer(command); + } catch (final XenAPIException e) { + s_logger.warn("Unable to put server in maintainence mode", e); + return new MaintainAnswer(command, false, e.getMessage()); + } catch (final XmlRpcException e) { + s_logger.warn("Unable to put server in maintainence mode", e); + return new MaintainAnswer(command, false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMigrateCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMigrateCommandWrapper.java new file mode 100644 index 00000000000..6c5e55c071a --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixMigrateCommandWrapper.java @@ -0,0 +1,84 @@ +// +// 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.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.MigrateAnswer; +import com.cloud.agent.api.MigrateCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VM; + +public final class CitrixMigrateCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixMigrateCommandWrapper.class); + + @Override + public Answer execute(final MigrateCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final String vmName = command.getVmName(); + + try { + final Set vms = VM.getByNameLabel(conn, vmName); + + final String ipaddr = command.getDestinationIp(); + + final Set hosts = Host.getAll(conn); + Host dsthost = null; + if(hosts != null) { + for (final Host host : hosts) { + if (host.getAddress(conn).equals(ipaddr)) { + dsthost = host; + break; + } + } + } + if (dsthost == null) { + final String msg = "Migration failed due to unable to find host " + ipaddr + " in XenServer pool " + citrixResourceBase.getHost().getPool(); + s_logger.warn(msg); + return new MigrateAnswer(command, false, msg, null); + } + for (final VM vm : vms) { + final Set vbds = vm.getVBDs(conn); + for (final VBD vbd : vbds) { + final VBD.Record vbdRec = vbd.getRecord(conn); + if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) { + vbd.eject(conn); + break; + } + } + citrixResourceBase.migrateVM(conn, dsthost, vm, vmName); + vm.setAffinity(conn, dsthost); + } + return new MigrateAnswer(command, true, "migration succeeded", null); + } catch (final Exception e) { + s_logger.warn(e.getMessage(), e); + return new MigrateAnswer(command, false, e.getMessage(), null); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixModifySshKeysCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixModifySshKeysCommandWrapper.java new file mode 100644 index 00000000000..8ea852d9127 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixModifySshKeysCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ModifySshKeysCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; + +public final class CitrixModifySshKeysCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final ModifySshKeysCommand command, final CitrixResourceBase citrixResourceBase) { + return new Answer(command); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixModifyStoragePoolCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixModifyStoragePoolCommandWrapper.java new file mode 100644 index 00000000000..1a6fb2756aa --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixModifyStoragePoolCommandWrapper.java @@ -0,0 +1,96 @@ +// +// 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.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ModifyStoragePoolAnswer; +import com.cloud.agent.api.ModifyStoragePoolCommand; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.storage.template.TemplateProp; +import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixModifyStoragePoolCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixModifyStoragePoolCommandWrapper.class); + + @Override + public Answer execute(final ModifyStoragePoolCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final StorageFilerTO pool = command.getPool(); + final boolean add = command.getAdd(); + if (add) { + try { + final SR sr = citrixResourceBase.getStorageRepository(conn, pool.getUuid()); + citrixResourceBase.setupHeartbeatSr(conn, sr, false); + final long capacity = sr.getPhysicalSize(conn); + final long available = capacity - sr.getPhysicalUtilisation(conn); + if (capacity == -1) { + final String msg = "Pool capacity is -1! pool: " + pool.getHost() + pool.getPath(); + s_logger.warn(msg); + return new Answer(command, false, msg); + } + final Map tInfo = new HashMap(); + final ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(command, capacity, available, tInfo); + return answer; + } catch (final XenAPIException e) { + final String msg = "ModifyStoragePoolCommand add XenAPIException:" + e.toString() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: " + pool.getHost() + + pool.getPath(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } catch (final Exception e) { + final String msg = "ModifyStoragePoolCommand add XenAPIException:" + e.getMessage() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: " + + pool.getHost() + pool.getPath(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } + } else { + try { + final SR sr = citrixResourceBase.getStorageRepository(conn, pool.getUuid()); + final String srUuid = sr.getUuid(conn); + final String result = citrixResourceBase.callHostPluginPremium(conn, "setup_heartbeat_file", "host", citrixResourceBase.getHost().getUuid(), "sr", srUuid, "add", + "false"); + if (result == null || !result.split("#")[1].equals("0")) { + throw new CloudRuntimeException("Unable to remove heartbeat file entry for SR " + srUuid + " due to " + result); + } + return new Answer(command, true, "seccuss"); + } catch (final XenAPIException e) { + final String msg = "ModifyStoragePoolCommand remove XenAPIException:" + e.toString() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: " + + pool.getHost() + pool.getPath(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } catch (final Exception e) { + final String msg = "ModifyStoragePoolCommand remove XenAPIException:" + e.getMessage() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: " + + pool.getHost() + pool.getPath(); + s_logger.warn(msg, e); + return new Answer(command, false, msg); + } + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkElementCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkElementCommandWrapper.java new file mode 100644 index 00000000000..801a43b29b6 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkElementCommandWrapper.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.xenserver.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.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; + +public final class CitrixNetworkElementCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final NetworkElementCommand command, final CitrixResourceBase citrixResourceBase) { + final VirtualRoutingResource routingResource = citrixResourceBase.getVirtualRoutingResource(); + return routingResource.executeRequest(command); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkRulesSystemVmCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkRulesSystemVmCommandWrapper.java new file mode 100644 index 00000000000..cdd93ae665b --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkRulesSystemVmCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.NetworkRulesSystemVmCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.vm.VirtualMachine; +import com.xensource.xenapi.Connection; + +public final class CitrixNetworkRulesSystemVmCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final NetworkRulesSystemVmCommand command, final CitrixResourceBase citrixResourceBase) { + boolean success = true; + final Connection conn = citrixResourceBase.getConnection(); + if (command.getType() != VirtualMachine.Type.User) { + + final String result = citrixResourceBase.callHostPlugin(conn, "vmops", "default_network_rules_systemvm", "vmName", command.getVmName()); + if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { + success = false; + } + } + + return new Answer(command, success, ""); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkRulesVmSecondaryIpCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkRulesVmSecondaryIpCommandWrapper.java new file mode 100644 index 00000000000..48e57d8444a --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixNetworkRulesVmSecondaryIpCommandWrapper.java @@ -0,0 +1,44 @@ +// +// 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 com.cloud.agent.api.Answer; +import com.cloud.agent.api.NetworkRulesVmSecondaryIpCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixNetworkRulesVmSecondaryIpCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final NetworkRulesVmSecondaryIpCommand command, final CitrixResourceBase citrixResourceBase) { + boolean success = true; + final Connection conn = citrixResourceBase.getConnection(); + + final String result = citrixResourceBase.callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", command.getVmName(), "vmMac", command.getVmMac(), + "vmSecIp", command.getVmSecIp(), "action", command.getAction()); + + if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { + success = false; + } + + return new Answer(command, success, ""); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsCreateGreTunnelCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsCreateGreTunnelCommandWrapper.java new file mode 100644 index 00000000000..c944e9a16df --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsCreateGreTunnelCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsCreateGreTunnelAnswer; +import com.cloud.agent.api.OvsCreateGreTunnelCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.Types.BadServerResponse; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixOvsCreateGreTunnelCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsCreateGreTunnelCommandWrapper.class); + + @Override + public Answer execute(final OvsCreateGreTunnelCommand command, final CitrixResourceBase citrixResourceBase) { + citrixResourceBase.setIsOvs(true); + + final Connection conn = citrixResourceBase.getConnection(); + String bridge = "unkonwn"; + try { + final Network nw = citrixResourceBase.setupvSwitchNetwork(conn); + bridge = nw.getBridge(conn); + + final String result = citrixResourceBase.callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", command.getRemoteIp(), "greKey", + command.getKey(), "from", Long.toString(command.getFrom()), "to", Long.toString(command.getTo())); + final String[] res = result.split(":"); + if (res.length != 2 || res.length == 2 && res[1].equalsIgnoreCase("[]")) { + return new OvsCreateGreTunnelAnswer(command, false, result, citrixResourceBase.getHost().getIp(), bridge); + } else { + return new OvsCreateGreTunnelAnswer(command, true, result, citrixResourceBase.getHost().getIp(), bridge, Integer.parseInt(res[1])); + } + } catch (final BadServerResponse e) { + s_logger.error("An error occurred while creating a GRE tunnel to " + command.getRemoteIp() + " on host " + citrixResourceBase.getHost().getIp(), e); + } catch (final XenAPIException e) { + s_logger.error("An error occurred while creating a GRE tunnel to " + command.getRemoteIp() + " on host " + citrixResourceBase.getHost().getIp(), e); + } catch (final XmlRpcException e) { + s_logger.error("An error occurred while creating a GRE tunnel to " + command.getRemoteIp() + " on host " + citrixResourceBase.getHost().getIp(), e); + } + + return new OvsCreateGreTunnelAnswer(command, false, "EXCEPTION", citrixResourceBase.getHost().getIp(), bridge); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsCreateTunnelCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsCreateTunnelCommandWrapper.java new file mode 100644 index 00000000000..3e25a743822 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsCreateTunnelCommandWrapper.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.xenserver.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.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; + +public final class CitrixOvsCreateTunnelCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsCreateTunnelCommandWrapper.class); + + @Override + public Answer execute(final OvsCreateTunnelCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + String bridge = "unknown"; + try { + final Network nw = citrixResourceBase.findOrCreateTunnelNetwork(conn, command.getNetworkName()); + if (nw == null) { + s_logger.debug("Error during bridge setup"); + return new OvsCreateTunnelAnswer(command, false, "Cannot create network", bridge); + } + + citrixResourceBase.configureTunnelNetwork(conn, command.getNetworkId(), command.getFrom(), command.getNetworkName()); + bridge = nw.getBridge(conn); + final String result = + citrixResourceBase.callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", command.getRemoteIp(), + "key", command.getKey().toString(), "from", + command.getFrom().toString(), "to", command.getTo().toString(), "cloudstack-network-id", + command.getNetworkUuid()); + final String[] res = result.split(":"); + + if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) { + return new OvsCreateTunnelAnswer(command, true, result, res[1], bridge); + } else { + return new OvsCreateTunnelAnswer(command, 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(command, false, e.getMessage(), bridge); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDeleteFlowCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDeleteFlowCommandWrapper.java new file mode 100644 index 00000000000..e96f1364b37 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDeleteFlowCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsDeleteFlowCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.Types.BadServerResponse; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixOvsDeleteFlowCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsDeleteFlowCommandWrapper.class); + + @Override + public Answer execute(final OvsDeleteFlowCommand command, final CitrixResourceBase citrixResourceBase) { + citrixResourceBase.setIsOvs(true); + + final Connection conn = citrixResourceBase.getConnection(); + try { + final Network nw = citrixResourceBase.setupvSwitchNetwork(conn); + final String bridge = nw.getBridge(conn); + final String result = citrixResourceBase.callHostPlugin(conn, "ovsgre", "ovs_delete_flow", "bridge", bridge, "vmName", command.getVmName()); + + if (result.equalsIgnoreCase("SUCCESS")) { + return new Answer(command, true, "success to delete flows for " + command.getVmName()); + } else { + return new Answer(command, false, result); + } + } catch (final BadServerResponse e) { + s_logger.error("Failed to delete flow", e); + } catch (final XenAPIException e) { + s_logger.error("Failed to delete flow", e); + } catch (final XmlRpcException e) { + s_logger.error("Failed to delete flow", e); + } + return new Answer(command, false, "failed to delete flow for " + command.getVmName()); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDestroyBridgeCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDestroyBridgeCommandWrapper.java new file mode 100644 index 00000000000..ee6e4dd9c0e --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDestroyBridgeCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsDestroyBridgeCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; + +public final class CitrixOvsDestroyBridgeCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsDestroyBridgeCommandWrapper.class); + + @Override + public Answer execute(final OvsDestroyBridgeCommand command, final CitrixResourceBase citrixResourceBase) { + try { + final Connection conn = citrixResourceBase.getConnection(); + + final Network nw = citrixResourceBase.findOrCreateTunnelNetwork(conn, command.getBridgeName()); + citrixResourceBase.cleanUpTmpDomVif(conn, nw); + + citrixResourceBase.destroyTunnelNetwork(conn, nw, command.getHostId()); + + s_logger.debug("OVS Bridge destroyed"); + + return new Answer(command, true, null); + } catch (final Exception e) { + s_logger.warn("caught execption when destroying ovs bridge", e); + return new Answer(command, false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDestroyTunnelCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDestroyTunnelCommandWrapper.java new file mode 100644 index 00000000000..da0fd1f2f91 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsDestroyTunnelCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsDestroyTunnelCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; + +public final class CitrixOvsDestroyTunnelCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsDestroyTunnelCommandWrapper.class); + + @Override + public Answer execute(final OvsDestroyTunnelCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final Network nw = citrixResourceBase.findOrCreateTunnelNetwork(conn, command.getBridgeName()); + if (nw == null) { + s_logger.warn("Unable to find tunnel network for GRE key:" + command.getBridgeName()); + return new Answer(command, false, "No network found"); + } + + final String bridge = nw.getBridge(conn); + final String result = citrixResourceBase.callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", command.getInPortName()); + + 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 execption when destroy ovs tunnel", e); + return new Answer(command, false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsFetchInterfaceCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsFetchInterfaceCommandWrapper.java new file mode 100644 index 00000000000..1f211a48494 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsFetchInterfaceCommandWrapper.java @@ -0,0 +1,71 @@ +// +// 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 org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsFetchInterfaceAnswer; +import com.cloud.agent.api.OvsFetchInterfaceCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.hypervisor.xenserver.resource.XsLocalNetwork; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Types.BadServerResponse; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixOvsFetchInterfaceCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsFetchInterfaceCommandWrapper.class); + + @Override + public Answer execute(final OvsFetchInterfaceCommand command, final CitrixResourceBase citrixResourceBase) { + String label = command.getLabel(); + //FIXME: this is a tricky to pass the network checking in XCP. I temporary get default label from Host. + if (citrixResourceBase.isXcp()) { + label = citrixResourceBase.getLabel(); + } + s_logger.debug("Will look for network with name-label:" + label + " on host " + citrixResourceBase.getHost().getIp()); + final Connection conn = citrixResourceBase.getConnection(); + try { + final XsLocalNetwork nw = citrixResourceBase.getNetworkByName(conn, label); + if(nw == null) { + throw new CloudRuntimeException("Unable to locate the network with name-label: " + label + " on host: " + citrixResourceBase.getHost().getIp()); + } + s_logger.debug("Network object:" + nw.getNetwork().getUuid(conn)); + final PIF pif = nw.getPif(conn); + final PIF.Record pifRec = pif.getRecord(conn); + s_logger.debug("PIF object:" + pifRec.uuid + "(" + pifRec.device + ")"); + return new OvsFetchInterfaceAnswer(command, true, "Interface " + pifRec.device + " retrieved successfully", pifRec.IP, pifRec.netmask, pifRec.MAC); + } catch (final BadServerResponse e) { + s_logger.error("An error occurred while fetching the interface for " + label + " on host " + citrixResourceBase.getHost().getIp(), e); + return new OvsFetchInterfaceAnswer(command, false, "EXCEPTION:" + e.getMessage()); + } catch (final XenAPIException e) { + s_logger.error("An error occurred while fetching the interface for " + label + " on host " + citrixResourceBase.getHost().getIp(), e); + return new OvsFetchInterfaceAnswer(command, false, "EXCEPTION:" + e.getMessage()); + } catch (final XmlRpcException e) { + s_logger.error("An error occurred while fetching the interface for " + label + " on host " + citrixResourceBase.getHost().getIp(), e); + return new OvsFetchInterfaceAnswer(command, false, "EXCEPTION:" + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsSetTagAndFlowCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsSetTagAndFlowCommandWrapper.java new file mode 100644 index 00000000000..2048f4d16d2 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsSetTagAndFlowCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsSetTagAndFlowAnswer; +import com.cloud.agent.api.OvsSetTagAndFlowCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.Types.BadServerResponse; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixOvsSetTagAndFlowCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsSetTagAndFlowCommandWrapper.class); + + @Override + public Answer execute(final OvsSetTagAndFlowCommand command, final CitrixResourceBase citrixResourceBase) { + citrixResourceBase.setIsOvs(true); + + final Connection conn = citrixResourceBase.getConnection(); + try { + final Network nw = citrixResourceBase.setupvSwitchNetwork(conn); + final String bridge = nw.getBridge(conn); + + /* + * If VM is domainRouter, this will try to set flow and tag on its + * none guest network nic. don't worry, it will fail silently at + * host plugin side + */ + final String result = citrixResourceBase.callHostPlugin(conn, "ovsgre", "ovs_set_tag_and_flow", "bridge", bridge, "vmName", command.getVmName(), "tag", + command.getTag(), "vlans", command.getVlans(), "seqno", command.getSeqNo()); + s_logger.debug("set flow for " + command.getVmName() + " " + result); + + if (result != null && result.equalsIgnoreCase("SUCCESS")) { + return new OvsSetTagAndFlowAnswer(command, true, result); + } else { + return new OvsSetTagAndFlowAnswer(command, false, result); + } + } catch (final BadServerResponse e) { + s_logger.error("Failed to set tag and flow", e); + } catch (final XenAPIException e) { + s_logger.error("Failed to set tag and flow", e); + } catch (final XmlRpcException e) { + s_logger.error("Failed to set tag and flow", e); + } + + return new OvsSetTagAndFlowAnswer(command, false, "EXCEPTION"); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsSetupBridgeCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsSetupBridgeCommandWrapper.java new file mode 100644 index 00000000000..0c553b4981a --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsSetupBridgeCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsSetupBridgeCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixOvsSetupBridgeCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsSetupBridgeCommandWrapper.class); + + @Override + public Answer execute(final OvsSetupBridgeCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + + citrixResourceBase.findOrCreateTunnelNetwork(conn, command.getBridgeName()); + citrixResourceBase.configureTunnelNetwork(conn, command.getNetworkId(), command.getHostId(), command.getBridgeName()); + + s_logger.debug("OVS Bridge configured"); + + return new Answer(command, true, null); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsVpcPhysicalTopologyConfigCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsVpcPhysicalTopologyConfigCommandWrapper.java new file mode 100644 index 00000000000..0dc4fb6df74 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsVpcPhysicalTopologyConfigCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; + +public final class CitrixOvsVpcPhysicalTopologyConfigCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsVpcPhysicalTopologyConfigCommandWrapper.class); + + @Override + public Answer execute(final OvsVpcPhysicalTopologyConfigCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final Network nw = citrixResourceBase.findOrCreateTunnelNetwork(conn, command.getBridgeName()); + final String bridgeName = nw.getBridge(conn); + final long sequenceNo = command.getSequenceNumber(); + + final String result = citrixResourceBase.callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", + bridgeName, "config", command.getVpcConfigInJson(), "host-id", ((Long)command.getHostId()).toString(), + "seq-no", Long.toString(sequenceNo)); + + if (result.startsWith("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/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsVpcRoutingPolicyConfigCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsVpcRoutingPolicyConfigCommandWrapper.java new file mode 100644 index 00000000000..4b1e56d7598 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixOvsVpcRoutingPolicyConfigCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; + +public final class CitrixOvsVpcRoutingPolicyConfigCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixOvsVpcRoutingPolicyConfigCommandWrapper.class); + + @Override + public Answer execute(final OvsVpcRoutingPolicyConfigCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final Network nw = citrixResourceBase.findOrCreateTunnelNetwork(conn, command.getBridgeName()); + final String bridgeName = nw.getBridge(conn); + final long sequenceNo = command.getSequenceNumber(); + + final String result = citrixResourceBase.callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_routing_policies", "bridge", + bridgeName, "host-id", ((Long)command.getHostId()).toString(), "config", + command.getVpcConfigInJson(), "seq-no", Long.toString(sequenceNo)); + + if (result.startsWith("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 policies", e); + return new Answer(command, false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPerformanceMonitorCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPerformanceMonitorCommandWrapper.java new file mode 100644 index 00000000000..ad670c1fa3b --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPerformanceMonitorCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.PerformanceMonitorAnswer; +import com.cloud.agent.api.PerformanceMonitorCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixPerformanceMonitorCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final PerformanceMonitorCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final String perfMon = citrixResourceBase.getPerfMon(conn, command.getParams(), command.getWait()); + if (perfMon == null) { + return new PerformanceMonitorAnswer(command, false, perfMon); + } else { + return new PerformanceMonitorAnswer(command, true, perfMon); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPingTestCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPingTestCommandWrapper.java new file mode 100644 index 00000000000..8a7a01cf7b0 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPingTestCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.PingTestCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixPingTestCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final PingTestCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + boolean result = false; + final String computingHostIp = command.getComputingHostIp(); + + if (computingHostIp != null) { + result = citrixResourceBase.doPingTest(conn, computingHostIp); + } else { + result = citrixResourceBase.doPingTest(conn, command.getRouterIp(), command.getPrivateIp()); + } + + if (!result) { + return new Answer(command, false, "PingTestCommand failed"); + } + return new Answer(command); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPlugNicCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPlugNicCommandWrapper.java new file mode 100644 index 00000000000..a3edfbe13f1 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPlugNicCommandWrapper.java @@ -0,0 +1,92 @@ +// +// 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.util.Set; + +import org.apache.log4j.Logger; + +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.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VM; + +public final class CitrixPlugNicCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixPlugNicCommandWrapper.class); + + @Override + public Answer execute(final PlugNicCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final String vmName = command.getVmName(); + try { + final Set vms = VM.getByNameLabel(conn, vmName); + if (vms == null || vms.isEmpty()) { + return new PlugNicAnswer(command, false, "Can not find VM " + vmName); + } + final VM vm = vms.iterator().next(); + final NicTO nic = command.getNic(); + + String mac = nic.getMac(); + final Set routerVIFs = vm.getVIFs(conn); + mac = mac.trim(); + + int counter = 0; + for (final VIF vif : routerVIFs) { + final String lmac = vif.getMAC(conn); + if (lmac.trim().equals(mac)) { + counter++; + } + } + // We allow 2 routers with the same mac. It's needed for the redundant vpc routers. + // [FIXME] Find a way to identify the type of the router or if it's + // redundant. + if (counter > 2) { + final String msg = " Plug Nic failed due to a VIF with the same mac " + nic.getMac() + " exists in more than 2 routers."; + s_logger.error(msg); + return new PlugNicAnswer(command, false, msg); + } + + // Wilder Rodrigues - replaced this code with the code above. + // VIF vif = getVifByMac(conn, vm, nic.getMac()); + // if (vif != null) { + // final String msg = " Plug Nic failed due to a VIF with the same mac " + nic.getMac() + " exists"; + // s_logger.warn(msg); + // return new PlugNicAnswer(cmd, false, msg); + // } + + final String deviceId = citrixResourceBase.getLowestAvailableVIFDeviceNum(conn, vm); + nic.setDeviceId(Integer.parseInt(deviceId)); + final VIF vif = citrixResourceBase.createVif(conn, vmName, vm, null, nic); + // vif = createVif(conn, vmName, vm, null, nic); + vif.plug(conn); + return new PlugNicAnswer(command, true, "success"); + } catch (final Exception e) { + final String msg = " Plug Nic failed due to " + e.toString(); + s_logger.error(msg, e); + return new PlugNicAnswer(command, false, msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPrepareForMigrationCommandWrapper.java new file mode 100644 index 00000000000..a8bc18248be --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPrepareForMigrationCommandWrapper.java @@ -0,0 +1,61 @@ +// +// 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 org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.PrepareForMigrationAnswer; +import com.cloud.agent.api.PrepareForMigrationCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixPrepareForMigrationCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixPrepareForMigrationCommandWrapper.class); + + @Override + public Answer execute(final PrepareForMigrationCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + + final VirtualMachineTO vm = command.getVirtualMachine(); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Preparing host for migrating " + vm); + } + + final NicTO[] nics = vm.getNics(); + try { + citrixResourceBase.prepareISO(conn, vm.getName()); + + for (final NicTO nic : nics) { + citrixResourceBase.getNetwork(conn, nic); + } + s_logger.debug("4. The VM " + vm.getName() + " is in Migrating state"); + + return new PrepareForMigrationAnswer(command); + } catch (final Exception e) { + s_logger.warn("Catch Exception " + e.getClass().getName() + " prepare for migration failed due to " + e.toString(), e); + return new PrepareForMigrationAnswer(command, e); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPrimaryStorageDownloadCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPrimaryStorageDownloadCommandWrapper.java new file mode 100644 index 00000000000..270520777d4 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPrimaryStorageDownloadCommandWrapper.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.net.URI; +import java.util.HashMap; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.VDI; + +public final class CitrixPrimaryStorageDownloadCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixPrimaryStorageDownloadCommandWrapper.class); + + @Override + public Answer execute(final PrimaryStorageDownloadCommand command, final CitrixResourceBase citrixResourceBase) { + final String tmplturl = command.getUrl(); + final String poolName = command.getPoolUuid(); + final int wait = command.getWait(); + try { + final URI uri = new URI(tmplturl); + final String tmplpath = uri.getHost() + ":" + uri.getPath(); + final Connection conn = citrixResourceBase.getConnection(); + SR poolsr = null; + final Set srs = SR.getByNameLabel(conn, poolName); + if (srs.size() != 1) { + final String msg = "There are " + srs.size() + " SRs with same name: " + poolName; + s_logger.warn(msg); + return new PrimaryStorageDownloadAnswer(msg); + } else { + poolsr = srs.iterator().next(); + } + final String pUuid = poolsr.getUuid(conn); + final boolean isISCSI = citrixResourceBase.IsISCSI(poolsr.getType(conn)); + final String uuid = citrixResourceBase.copyVhdFromSecondaryStorage(conn, tmplpath, pUuid, wait); + final VDI tmpl = citrixResourceBase.getVDIbyUuid(conn, uuid); + final VDI snapshotvdi = tmpl.snapshot(conn, new HashMap()); + final String snapshotUuid = snapshotvdi.getUuid(conn); + snapshotvdi.setNameLabel(conn, "Template " + command.getName()); + final String parentuuid = citrixResourceBase.getVhdParent(conn, pUuid, snapshotUuid, isISCSI); + final VDI parent = citrixResourceBase.getVDIbyUuid(conn, parentuuid); + final Long phySize = parent.getPhysicalUtilisation(conn); + tmpl.destroy(conn); + poolsr.scan(conn); + try { + Thread.sleep(5000); + } catch (final Exception e) { + } + return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize); + } catch (final Exception e) { + final String msg = "Catch Exception " + e.getClass().getName() + " on host:" + citrixResourceBase.getHost().getUuid() + " for template: " + tmplturl + " due to " + + e.toString(); + s_logger.warn(msg, e); + return new PrimaryStorageDownloadAnswer(msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPvlanSetupCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPvlanSetupCommandWrapper.java new file mode 100644 index 00000000000..6db9383a79a --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixPvlanSetupCommandWrapper.java @@ -0,0 +1,92 @@ +// +// 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 org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.PvlanSetupCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.hypervisor.xenserver.resource.XsLocalNetwork; +import com.cloud.network.Networks.TrafficType; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixPvlanSetupCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixPvlanSetupCommandWrapper.class); + + @Override + public Answer execute(final PvlanSetupCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + + 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(); + final String networkTag = command.getNetworkTag(); + + String nwNameLabel = null; + try { + final XsLocalNetwork nw = citrixResourceBase.getNativeNetworkForTraffic(conn, TrafficType.Guest, networkTag); + if (nw == null) { + s_logger.error("Network is not configured on the backend for pvlan " + primaryPvlan); + throw new CloudRuntimeException("Network for the backend is not configured correctly for pvlan primary: " + primaryPvlan); + } + nwNameLabel = nw.getNetwork().getNameLabel(conn); + } catch (final XenAPIException e) { + s_logger.warn("Fail to get network", e); + return new Answer(command, false, e.toString()); + } catch (final XmlRpcException e) { + s_logger.warn("Fail to get network", e); + return new Answer(command, false, e.toString()); + } + + String result = null; + if (command.getType() == PvlanSetupCommand.Type.DHCP) { + result = citrixResourceBase.callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", + isolatedPvlan, "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac); + + if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { + 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) { + result = citrixResourceBase.callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", + isolatedPvlan, "vm-mac", vmMac); + + if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { + 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); + } + } + return new Answer(command, true, result); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixReadyCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixReadyCommandWrapper.java new file mode 100644 index 00000000000..d4c73ebb272 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixReadyCommandWrapper.java @@ -0,0 +1,75 @@ +// +// 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.util.Set; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ReadyAnswer; +import com.cloud.agent.api.ReadyCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VM; + +public final class CitrixReadyCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixReadyCommandWrapper.class); + + @Override + public Answer execute(final ReadyCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final Long dcId = command.getDataCenterId(); + // Ignore the result of the callHostPlugin. Even if unmounting the + // snapshots dir fails, let Ready command + // succeed. + citrixResourceBase.umountSnapshotDir(conn, dcId); + + citrixResourceBase.setupLinkLocalNetwork(conn); + // try to destroy CD-ROM device for all system VMs on this host + try { + final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid()); + final Set vms = host.getResidentVMs(conn); + for (final VM vm : vms) { + citrixResourceBase.destroyPatchVbd(conn, vm.getNameLabel(conn)); + } + } catch (final Exception e) { + } + try { + final boolean result = citrixResourceBase.cleanupHaltedVms(conn); + if (!result) { + return new ReadyAnswer(command, "Unable to cleanup halted vms"); + } + } catch (final XenAPIException e) { + s_logger.warn("Unable to cleanup halted vms", e); + return new ReadyAnswer(command, "Unable to cleanup halted vms"); + } catch (final XmlRpcException e) { + s_logger.warn("Unable to cleanup halted vms", e); + return new ReadyAnswer(command, "Unable to cleanup halted vms"); + } + + return new ReadyAnswer(command); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootCommandWrapper.java new file mode 100644 index 00000000000..f2cb54c3cc1 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootCommandWrapper.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.xenserver.resource.wrapper; + +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.RebootAnswer; +import com.cloud.agent.api.RebootCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VM; + +public final class CitrixRebootCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixRebootCommandWrapper.class); + + @Override + public Answer execute(final RebootCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + s_logger.debug("7. The VM " + command.getVmName() + " is in Starting state"); + try { + Set vms = null; + try { + vms = VM.getByNameLabel(conn, command.getVmName()); + } catch (final XenAPIException e0) { + s_logger.debug("getByNameLabel failed " + e0.toString()); + return new RebootAnswer(command, "getByNameLabel failed " + e0.toString(), false); + } catch (final Exception e0) { + s_logger.debug("getByNameLabel failed " + e0.getMessage()); + return new RebootAnswer(command, "getByNameLabel failed", false); + } + for (final VM vm : vms) { + try { + citrixResourceBase.rebootVM(conn, vm, vm.getNameLabel(conn)); + } catch (final Exception e) { + final String msg = e.toString(); + s_logger.warn(msg, e); + return new RebootAnswer(command, msg, false); + } + } + return new RebootAnswer(command, "reboot succeeded", true); + } finally { + s_logger.debug("8. The VM " + command.getVmName() + " is in Running state"); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootRouterCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootRouterCommandWrapper.java new file mode 100644 index 00000000000..5d860b9e633 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRebootRouterCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixRebootRouterCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final RebootRouterCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + + final RebootCommand rebootCommand = new RebootCommand(command.getVmName()); + final Answer answer = wrapper.execute(rebootCommand, citrixResourceBase); + + if (answer.getResult()) { + final String cnct = citrixResourceBase.connect(conn, command.getVmName(), command.getPrivateIpAddress()); + citrixResourceBase.networkUsage(conn, command.getPrivateIpAddress(), "create", null); + + if (cnct == null) { + return answer; + } else { + return new Answer(command, false, cnct); + } + } + return answer; + } +} \ 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 new file mode 100644 index 00000000000..b68ef38ddc4 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java @@ -0,0 +1,280 @@ +// +// 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.util.Hashtable; + +import org.apache.log4j.Logger; + +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.CheckOnHostCommand; +import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.CleanupNetworkRulesCmd; +import com.cloud.agent.api.ClusterVMMetaDataSyncCommand; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.CreateVMSnapshotCommand; +import com.cloud.agent.api.DeleteStoragePoolCommand; +import com.cloud.agent.api.DeleteVMSnapshotCommand; +import com.cloud.agent.api.FenceCommand; +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; +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.NetworkUsageCommand; +import com.cloud.agent.api.OvsCreateGreTunnelCommand; +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.OvsFetchInterfaceCommand; +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.PerformanceMonitorCommand; +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; +import com.cloud.agent.api.RevertToVMSnapshotCommand; +import com.cloud.agent.api.ScaleVmCommand; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SetupCommand; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.UnPlugNicCommand; +import com.cloud.agent.api.UpdateHostPasswordCommand; +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.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.xenserver.resource.CitrixResourceBase; +import com.cloud.hypervisor.xenserver.resource.XenServer56FP1Resource; +import com.cloud.hypervisor.xenserver.resource.XenServer56Resource; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.RequestWrapper; +import com.cloud.resource.ServerResource; + +public class CitrixRequestWrapper extends RequestWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixRequestWrapper.class); + + private static CitrixRequestWrapper instance; + + static { + instance = new CitrixRequestWrapper(); + } + + @SuppressWarnings("rawtypes") + private final Hashtable, Hashtable, CommandWrapper>> resources; + + @SuppressWarnings("rawtypes") + private CitrixRequestWrapper() { + resources = new Hashtable, Hashtable, CommandWrapper>>(); + init(); + } + + @SuppressWarnings("rawtypes") + private void init() { + // CitrixResourceBase commands + final Hashtable, CommandWrapper> citrixCommands = new Hashtable, CommandWrapper>(); + citrixCommands.put(RebootRouterCommand.class, new CitrixRebootRouterCommandWrapper()); + citrixCommands.put(CreateCommand.class, new CitrixCreateCommandWrapper()); + citrixCommands.put(CheckConsoleProxyLoadCommand.class, new CitrixCheckConsoleProxyLoadCommandWrapper()); + citrixCommands.put(WatchConsoleProxyLoadCommand.class, new CitrixWatchConsoleProxyLoadCommandWrapper()); + citrixCommands.put(ReadyCommand.class, new CitrixReadyCommandWrapper()); + citrixCommands.put(GetHostStatsCommand.class, new CitrixGetHostStatsCommandWrapper()); + citrixCommands.put(GetVmStatsCommand.class, new CitrixGetVmStatsCommandWrapper()); + citrixCommands.put(GetVmDiskStatsCommand.class, new CitrixGetVmDiskStatsCommandWrapper()); + citrixCommands.put(CheckHealthCommand.class, new CitrixCheckHealthCommandWrapper()); + citrixCommands.put(StopCommand.class, new CitrixStopCommandWrapper()); + citrixCommands.put(RebootCommand.class, new CitrixRebootCommandWrapper()); + citrixCommands.put(CheckVirtualMachineCommand.class, new CitrixCheckVirtualMachineCommandWrapper()); + citrixCommands.put(PrepareForMigrationCommand.class, new CitrixPrepareForMigrationCommandWrapper()); + citrixCommands.put(MigrateCommand.class, new CitrixMigrateCommandWrapper()); + citrixCommands.put(DestroyCommand.class, new CitrixDestroyCommandWrapper()); + citrixCommands.put(CreateStoragePoolCommand.class, new CitrixCreateStoragePoolCommandWrapper()); + citrixCommands.put(ModifyStoragePoolCommand.class, new CitrixModifyStoragePoolCommandWrapper()); + citrixCommands.put(DeleteStoragePoolCommand.class, new CitrixDeleteStoragePoolCommandWrapper()); + citrixCommands.put(ResizeVolumeCommand.class, new CitrixResizeVolumeCommandWrapper()); + citrixCommands.put(AttachVolumeCommand.class, new CitrixAttachVolumeCommandWrapper()); + citrixCommands.put(AttachIsoCommand.class, new CitrixAttachIsoCommandWrapper()); + citrixCommands.put(UpgradeSnapshotCommand.class, new CitrixUpgradeSnapshotCommandWrapper()); + citrixCommands.put(GetStorageStatsCommand.class, new CitrixGetStorageStatsCommandWrapper()); + citrixCommands.put(PrimaryStorageDownloadCommand.class, new CitrixPrimaryStorageDownloadCommandWrapper()); + citrixCommands.put(GetVncPortCommand.class, new CitrixGetVncPortCommandWrapper()); + citrixCommands.put(SetupCommand.class, new CitrixSetupCommandWrapper()); + citrixCommands.put(MaintainCommand.class, new CitrixMaintainCommandWrapper()); + citrixCommands.put(PingTestCommand.class, new CitrixPingTestCommandWrapper()); + citrixCommands.put(CheckOnHostCommand.class, new CitrixCheckOnHostCommandWrapper()); + citrixCommands.put(ModifySshKeysCommand.class, new CitrixModifySshKeysCommandWrapper()); + citrixCommands.put(StartCommand.class, new CitrixStartCommandWrapper()); + citrixCommands.put(OvsSetTagAndFlowCommand.class, new CitrixOvsSetTagAndFlowCommandWrapper()); + citrixCommands.put(CheckSshCommand.class, new CitrixCheckSshCommandWrapper()); + citrixCommands.put(SecurityGroupRulesCmd.class, new CitrixSecurityGroupRulesCommandWrapper()); + citrixCommands.put(OvsFetchInterfaceCommand.class, new CitrixOvsFetchInterfaceCommandWrapper()); + citrixCommands.put(OvsCreateGreTunnelCommand.class, new CitrixOvsCreateGreTunnelCommandWrapper()); + citrixCommands.put(OvsDeleteFlowCommand.class, new CitrixOvsDeleteFlowCommandWrapper()); + citrixCommands.put(OvsVpcPhysicalTopologyConfigCommand.class, new CitrixOvsVpcPhysicalTopologyConfigCommandWrapper()); + citrixCommands.put(OvsVpcRoutingPolicyConfigCommand.class, new CitrixOvsVpcRoutingPolicyConfigCommandWrapper()); + citrixCommands.put(CleanupNetworkRulesCmd.class, new CitrixCleanupNetworkRulesCmdWrapper()); + citrixCommands.put(NetworkRulesSystemVmCommand.class, new CitrixNetworkRulesSystemVmCommandWrapper()); + citrixCommands.put(OvsCreateTunnelCommand.class, new CitrixOvsCreateTunnelCommandWrapper()); + citrixCommands.put(OvsSetupBridgeCommand.class, new CitrixOvsSetupBridgeCommandWrapper()); + citrixCommands.put(OvsDestroyBridgeCommand.class, new CitrixOvsDestroyBridgeCommandWrapper()); + citrixCommands.put(OvsDestroyTunnelCommand.class, new CitrixOvsDestroyTunnelCommandWrapper()); + citrixCommands.put(UpdateHostPasswordCommand.class, new CitrixUpdateHostPasswordCommandWrapper()); + citrixCommands.put(ClusterVMMetaDataSyncCommand.class, new CitrixClusterVMMetaDataSyncCommandWrapper()); + citrixCommands.put(CheckNetworkCommand.class, new CitrixCheckNetworkCommandWrapper()); + citrixCommands.put(PlugNicCommand.class, new CitrixPlugNicCommandWrapper()); + citrixCommands.put(UnPlugNicCommand.class, new CitrixUnPlugNicCommandWrapper()); + citrixCommands.put(CreateVMSnapshotCommand.class, new CitrixCreateVMSnapshotCommandWrapper()); + citrixCommands.put(DeleteVMSnapshotCommand.class, new CitrixDeleteVMSnapshotCommandWrapper()); + citrixCommands.put(RevertToVMSnapshotCommand.class, new CitrixRevertToVMSnapshotCommandWrapper()); + citrixCommands.put(NetworkRulesVmSecondaryIpCommand.class, new CitrixNetworkRulesVmSecondaryIpCommandWrapper()); + citrixCommands.put(ScaleVmCommand.class, new CitrixScaleVmCommandWrapper()); + citrixCommands.put(PvlanSetupCommand.class, new CitrixPvlanSetupCommandWrapper()); + citrixCommands.put(PerformanceMonitorCommand.class, new CitrixPerformanceMonitorCommandWrapper()); + citrixCommands.put(NetworkElementCommand.class, new CitrixNetworkElementCommandWrapper()); + resources.put(CitrixResourceBase.class, citrixCommands); + + // XenServer56Resource commands + final Hashtable, CommandWrapper> xenServer56Commands = new Hashtable, CommandWrapper>(); + xenServer56Commands.put(CheckOnHostCommand.class, new XenServer56CheckOnHostCommandWrapper()); + xenServer56Commands.put(FenceCommand.class, new XenServer56FenceCommandWrapper()); + xenServer56Commands.put(NetworkUsageCommand.class, new XenServer56NetworkUsageCommandWrapper()); + resources.put(XenServer56Resource.class, xenServer56Commands); + + // XenServer56FP1Resource commands + final Hashtable, CommandWrapper> xenServer56P1Commands = new Hashtable, CommandWrapper>(); + xenServer56P1Commands.put(FenceCommand.class, new XenServer56FP1FenceCommandWrapper()); + resources.put(XenServer56FP1Resource.class, xenServer56P1Commands); + } + + public static CitrixRequestWrapper 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); + } + + @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/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixResizeVolumeCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixResizeVolumeCommandWrapper.java new file mode 100644 index 00000000000..62f90933bd2 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixResizeVolumeCommandWrapper.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.xenserver.resource.wrapper; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.ResizeVolumeAnswer; +import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VDI; + +public final class CitrixResizeVolumeCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixResizeVolumeCommandWrapper.class); + + @Override + public Answer execute(final ResizeVolumeCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final String volid = command.getPath(); + final long newSize = command.getNewSize(); + + try { + final VDI vdi = citrixResourceBase.getVDIbyUuid(conn, volid); + vdi.resize(conn, newSize); + return new ResizeVolumeAnswer(command, true, "success", newSize); + } catch (final Exception e) { + s_logger.warn("Unable to resize volume", e); + final String error = "failed to resize volume:" + e; + return new ResizeVolumeAnswer(command, false, error); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRevertToVMSnapshotCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRevertToVMSnapshotCommandWrapper.java new file mode 100644 index 00000000000..a9291322ad8 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRevertToVMSnapshotCommandWrapper.java @@ -0,0 +1,110 @@ +// +// 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.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.RevertToVMSnapshotAnswer; +import com.cloud.agent.api.RevertToVMSnapshotCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.vm.VirtualMachine.PowerState; +import com.cloud.vm.snapshot.VMSnapshot; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; + +public final class CitrixRevertToVMSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixRevertToVMSnapshotCommandWrapper.class); + + @Override + public Answer execute(final RevertToVMSnapshotCommand command, final CitrixResourceBase citrixResourceBase) { + final String vmName = command.getVmName(); + final List listVolumeTo = command.getVolumeTOs(); + final VMSnapshot.Type vmSnapshotType = command.getTarget().getType(); + final Boolean snapshotMemory = vmSnapshotType == VMSnapshot.Type.DiskAndMemory; + final Connection conn = citrixResourceBase.getConnection(); + PowerState vmState = null; + VM vm = null; + try { + + final Set vmSnapshots = VM.getByNameLabel(conn, command.getTarget().getSnapshotName()); + if (vmSnapshots == null || vmSnapshots.size() == 0) { + return new RevertToVMSnapshotAnswer(command, false, "Cannot find vmSnapshot with name: " + command.getTarget().getSnapshotName()); + } + + final VM vmSnapshot = vmSnapshots.iterator().next(); + + // find target VM or creating a work VM + try { + vm = citrixResourceBase.getVM(conn, vmName); + } catch (final Exception e) { + vm = citrixResourceBase.createWorkingVM(conn, vmName, command.getGuestOSType(), command.getPlatformEmulator(), listVolumeTo); + } + + if (vm == null) { + return new RevertToVMSnapshotAnswer(command, false, "Revert to VM Snapshot Failed due to can not find vm: " + vmName); + } + + // call plugin to execute revert + citrixResourceBase.revertToSnapshot(conn, vmSnapshot, vmName, vm.getUuid(conn), snapshotMemory, citrixResourceBase.getHost().getUuid()); + vm = citrixResourceBase.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); + } + } + + if (!snapshotMemory) { + vm.destroy(conn); + vmState = PowerState.PowerOff; + } else { + vmState = PowerState.PowerOn; + } + + // 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)); + } + + return new RevertToVMSnapshotAnswer(command, listVolumeTo, vmState); + } catch (final Exception e) { + s_logger.error("revert vm " + vmName + " to snapshot " + command.getTarget().getSnapshotName() + " failed due to " + e.getMessage()); + return new RevertToVMSnapshotAnswer(command, false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixScaleVmCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixScaleVmCommandWrapper.java new file mode 100644 index 00000000000..47a30f59fa7 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixScaleVmCommandWrapper.java @@ -0,0 +1,106 @@ +// +// 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.util.Iterator; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ScaleVmAnswer; +import com.cloud.agent.api.ScaleVmCommand; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types.VmPowerState; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VM; + +public final class CitrixScaleVmCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixScaleVmCommandWrapper.class); + + @Override + public Answer execute(final ScaleVmCommand command, final CitrixResourceBase citrixResourceBase) { + final VirtualMachineTO vmSpec = command.getVirtualMachine(); + final String vmName = vmSpec.getName(); + try { + final Connection conn = citrixResourceBase.getConnection(); + final Set vms = VM.getByNameLabel(conn, vmName); + final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid()); + + // If DMC is not enable then don't execute this command. + if (!citrixResourceBase.isDmcEnabled(conn, host)) { + throw new CloudRuntimeException("Unable to scale the vm: " + vmName + " as DMC - Dynamic memory control is not enabled for the XenServer:" + + citrixResourceBase.getHost().getUuid() + " ,check your license and hypervisor version."); + } + + if (vms == null || vms.size() == 0) { + s_logger.info("No running VM " + vmName + " exists on XenServer" + citrixResourceBase.getHost().getUuid()); + return new ScaleVmAnswer(command, false, "VM does not exist"); + } + + // 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 && !citrixResourceBase.isRefNull(vmr.residentOn) + && !vmr.residentOn.getUuid(conn).equals(citrixResourceBase.getHost().getUuid())) { + iter.remove(); + } + } + + for (final VM vm : vms) { + vm.getRecord(conn); + try { + citrixResourceBase.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(command, false, msg); + } + + } + final String msg = "scaling VM " + vmName + " is successful on host " + host; + s_logger.debug(msg); + return new ScaleVmAnswer(command, 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(command, 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(command, 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(command, false, msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSecurityGroupRulesCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSecurityGroupRulesCommandWrapper.java new file mode 100644 index 00000000000..0cf4a8ab29b --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSecurityGroupRulesCommandWrapper.java @@ -0,0 +1,61 @@ +// +// 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 org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixSecurityGroupRulesCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixSecurityGroupRulesCommandWrapper.class); + + @Override + public Answer execute(final SecurityGroupRulesCmd command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + if (s_logger.isTraceEnabled()) { + s_logger.trace("Sending network rules command to " + citrixResourceBase.getHost().getIp()); + } + + if (!citrixResourceBase.canBridgeFirewall()) { + s_logger.warn("Host " + citrixResourceBase.getHost().getIp() + " cannot do bridge firewalling"); + return new SecurityGroupRuleAnswer(command, false, "Host " + citrixResourceBase.getHost().getIp() + " cannot do bridge firewalling", + SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); + } + + final String result = citrixResourceBase.callHostPlugin(conn, "vmops", "network_rules", "vmName", command.getVmName(), "vmIP", command.getGuestIp(), "vmMAC", + command.getGuestMac(), "vmID", Long.toString(command.getVmId()), "signature", command.getSignature(), "seqno", Long.toString(command.getSeqNum()), "deflated", + "true", "rules", command.compressStringifiedRules(), "secIps", command.getSecIpsString()); + + if (result == null || result.isEmpty() || !Boolean.parseBoolean(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.info("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/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSetupCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSetupCommandWrapper.java new file mode 100644 index 00000000000..3b24aa38876 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixSetupCommandWrapper.java @@ -0,0 +1,200 @@ +// +// 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.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.SetupAnswer; +import com.cloud.agent.api.SetupCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; +import com.xensource.xenapi.Bond; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Pool; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.XenAPIException; + +public final class CitrixSetupCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixSetupCommandWrapper.class); + + @Override + public Answer execute(final SetupCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + try { + final Map poolRecs = Pool.getAllRecords(conn); + if (poolRecs.size() != 1) { + throw new CloudRuntimeException("There are " + poolRecs.size() + " pool for host :" + citrixResourceBase.getHost().getUuid()); + } + final Host master = poolRecs.values().iterator().next().master; + citrixResourceBase.setupServer(conn, master); + final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid()); + citrixResourceBase.setupServer(conn, host); + + if (!citrixResourceBase.setIptables(conn)) { + s_logger.warn("set xenserver Iptable failed"); + return null; + } + + if (citrixResourceBase.isSecurityGroupEnabled()) { + final boolean canBridgeFirewall = citrixResourceBase.canBridgeFirewall(conn); + citrixResourceBase.setCanBridgeFirewall(canBridgeFirewall); + if (!canBridgeFirewall) { + final String msg = "Failed to configure brige firewall"; + s_logger.warn(msg); + s_logger.warn("Check host " + citrixResourceBase.getHost().getIp() +" for CSP is installed or not and check network mode for bridge"); + return new SetupAnswer(command, msg); + } + + } + + + final boolean r = citrixResourceBase.launchHeartBeat(conn); + if (!r) { + return null; + } + citrixResourceBase.cleanupTemplateSR(conn); + try { + if (command.useMultipath()) { + // the config value is set to true + host.addToOtherConfig(conn, "multipathing", "true"); + host.addToOtherConfig(conn, "multipathhandle", "dmp"); + } + + } catch (final Types.MapDuplicateKey e) { + s_logger.debug("multipath is already set"); + } + + if (command.needSetup() ) { + final String result = citrixResourceBase.callHostPlugin(conn, "vmops", "setup_iscsi", "uuid", citrixResourceBase.getHost().getUuid()); + + if (!result.contains("> DONE <")) { + s_logger.warn("Unable to setup iscsi: " + result); + return new SetupAnswer(command, result); + } + + Pair mgmtPif = null; + final Set hostPifs = host.getPIFs(conn); + for (final PIF pif : hostPifs) { + final PIF.Record rec = pif.getRecord(conn); + if (rec.management) { + if (rec.VLAN != null && rec.VLAN != -1) { + final String msg = + new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(citrixResourceBase.getHost().getUuid()) + .append("; pif=") + .append(rec.uuid) + .append("; vlan=") + .append(rec.VLAN) + .toString(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Management network is on pif=" + rec.uuid); + } + mgmtPif = new Pair(pif, rec); + break; + } + } + + if (mgmtPif == null) { + final String msg = "Unable to find management network for " + citrixResourceBase.getHost().getUuid(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + + final Map networks = Network.getAllRecords(conn); + if(networks == null) { + final String msg = "Unable to setup as there are no networks in the host: " + citrixResourceBase.getHost().getUuid(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + for (final Network.Record network : networks.values()) { + if (network.nameLabel.equals("cloud-private")) { + for (final PIF pif : network.PIFs) { + final PIF.Record pr = pif.getRecord(conn); + if (citrixResourceBase.getHost().getUuid().equals(pr.host.getUuid(conn))) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found a network called cloud-private. host=" + citrixResourceBase.getHost().getUuid() + "; Network=" + network.uuid + "; pif=" + pr.uuid); + } + if (pr.VLAN != null && pr.VLAN != -1) { + final String msg = + new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) + .append(" ; pif=") + .append(pr.uuid) + .toString(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + if (!pr.management && pr.bondMasterOf != null && pr.bondMasterOf.size() > 0) { + if (pr.bondMasterOf.size() > 1) { + final String msg = + new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) + .append("; pif=") + .append(pr.uuid) + .toString(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + final Bond bond = pr.bondMasterOf.iterator().next(); + final Set slaves = bond.getSlaves(conn); + for (final PIF slave : slaves) { + final PIF.Record spr = slave.getRecord(conn); + if (spr.management) { + if (!citrixResourceBase.transferManagementNetwork(conn, host, slave, spr, pif)) { + final String msg = + new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + + citrixResourceBase.getHost().getUuid()).toString(); + s_logger.warn(msg); + return new SetupAnswer(command, msg); + } + break; + } + } + } + } + } + } + } + } + return new SetupAnswer(command, false); + + } catch (final XmlRpcException e) { + s_logger.warn("Unable to setup", e); + return new SetupAnswer(command, e.getMessage()); + } catch (final XenAPIException e) { + s_logger.warn("Unable to setup", e); + return new SetupAnswer(command, e.getMessage()); + } catch (final Exception e) { + s_logger.warn("Unable to setup", e); + return new SetupAnswer(command, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixStartCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixStartCommandWrapper.java new file mode 100644 index 00000000000..ceaaf3498d6 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixStartCommandWrapper.java @@ -0,0 +1,210 @@ +// +// 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.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.OvsSetTagAndFlowAnswer; +import com.cloud.agent.api.OvsSetTagAndFlowCommand; +import com.cloud.agent.api.StartAnswer; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.GPUDeviceTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.network.Networks; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.IsolationType; +import com.cloud.resource.CommandWrapper; +import com.cloud.vm.VirtualMachine; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Types.VmPowerState; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; + +public final class CitrixStartCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixStartCommandWrapper.class); + + @Override + public Answer execute(final StartCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final VirtualMachineTO vmSpec = command.getVirtualMachine(); + final String vmName = vmSpec.getName(); + VmPowerState state = VmPowerState.HALTED; + VM vm = null; + // if a VDI is created, record its UUID to send back to the CS MS + final Map iqnToPath = new HashMap(); + try { + final Set vms = VM.getByNameLabel(conn, vmName); + if (vms != null) { + for (final VM v : vms) { + final VM.Record vRec = v.getRecord(conn); + if (vRec.powerState == VmPowerState.HALTED) { + v.destroy(conn); + } else if (vRec.powerState == VmPowerState.RUNNING) { + final String host = vRec.residentOn.getUuid(conn); + final String msg = "VM " + vmName + " is runing on host " + host; + s_logger.debug(msg); + return new StartAnswer(command, msg, host); + } else { + final String msg = "There is already a VM having the same name " + vmName + " vm record " + vRec.toString(); + s_logger.warn(msg); + return new StartAnswer(command, msg); + } + } + } + s_logger.debug("1. The VM " + vmName + " is in Starting state."); + + final Host host = Host.getByUuid(conn, citrixResourceBase.getHost().getUuid()); + vm = citrixResourceBase.createVmFromTemplate(conn, vmSpec, host); + + final GPUDeviceTO gpuDevice = vmSpec.getGpuDevice(); + if (gpuDevice != null) { + s_logger.debug("Creating VGPU for of VGPU type: " + gpuDevice.getVgpuType() + " in GPU group " + gpuDevice.getGpuGroup() + " for VM " + vmName); + citrixResourceBase.createVGPU(conn, command, vm, gpuDevice); + } + + for (final DiskTO disk : vmSpec.getDisks()) { + final VDI newVdi = citrixResourceBase.prepareManagedDisk(conn, disk, vmName); + + if (newVdi != null) { + final String path = newVdi.getUuid(conn); + + iqnToPath.put(disk.getDetails().get(DiskTO.IQN), path); + } + + citrixResourceBase.createVbd(conn, disk, vmName, vm, vmSpec.getBootloader(), newVdi); + } + + if (vmSpec.getType() != VirtualMachine.Type.User) { + citrixResourceBase.createPatchVbd(conn, vmName, vm); + } + + for (final NicTO nic : vmSpec.getNics()) { + citrixResourceBase.createVif(conn, vmName, vm, vmSpec, nic); + } + + citrixResourceBase.startVM(conn, host, vm, vmName); + + if (citrixResourceBase.isOvs()) { + // TODO(Salvatore-orlando): This code should go + for (final NicTO nic : vmSpec.getNics()) { + if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) { + final HashMap args = citrixResourceBase.parseDefaultOvsRuleComamnd(BroadcastDomainType.getValue(nic.getBroadcastUri())); + final OvsSetTagAndFlowCommand flowCmd = new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), + Long.parseLong(args.get("vmId"))); + + final CitrixRequestWrapper citrixRequestWrapper = CitrixRequestWrapper.getInstance(); + + final OvsSetTagAndFlowAnswer r = (OvsSetTagAndFlowAnswer) citrixRequestWrapper.execute(flowCmd, citrixResourceBase); + + if (!r.getResult()) { + s_logger.warn("Failed to set flow for VM " + r.getVmId()); + } else { + s_logger.info("Success to set flow for VM " + r.getVmId()); + } + } + } + } + + if (citrixResourceBase.canBridgeFirewall()) { + String result = null; + if (vmSpec.getType() != VirtualMachine.Type.User) { + final NicTO[] nics = vmSpec.getNics(); + boolean secGrpEnabled = false; + for (final NicTO nic : nics) { + if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { + secGrpEnabled = true; + break; + } + } + if (secGrpEnabled) { + result = citrixResourceBase.callHostPlugin(conn, "vmops", "default_network_rules_systemvm", "vmName", vmName); + if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { + s_logger.warn("Failed to program default network rules for " + vmName); + } else { + s_logger.info("Programmed default network rules for " + vmName); + } + } + + } else { + // For user vm, program the rules for each nic if the + // isolation uri scheme is ec2 + final NicTO[] nics = vmSpec.getNics(); + for (final NicTO nic : nics) { + if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { + 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:"; + } + result = citrixResourceBase.callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), + "vmID", Long.toString(vmSpec.getId()), "secIps", secIpsStr); + + if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { + s_logger.warn("Failed to program default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac()); + } else { + s_logger.info("Programmed default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac()); + } + } + } + } + } + + state = VmPowerState.RUNNING; + + final StartAnswer startAnswer = new StartAnswer(command); + + startAnswer.setIqnToPath(iqnToPath); + + return startAnswer; + } catch (final Exception e) { + s_logger.warn("Catch Exception: " + e.getClass().toString() + " due to " + e.toString(), e); + final String msg = citrixResourceBase.handleVmStartFailure(conn, vmName, vm, "", e); + + final StartAnswer startAnswer = new StartAnswer(command, msg); + + startAnswer.setIqnToPath(iqnToPath); + + return startAnswer; + } finally { + if (state != VmPowerState.HALTED) { + s_logger.debug("2. The VM " + vmName + " is in " + state + " state."); + } else { + s_logger.debug("The VM is in stopped state, detected problem during startup : " + vmName); + } + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixStopCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixStopCommandWrapper.java new file mode 100644 index 00000000000..ce8517f85c8 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixStopCommandWrapper.java @@ -0,0 +1,173 @@ +// +// 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.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.VgpuTypesInfo; +import com.cloud.agent.api.to.GPUDeviceTO; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.StringUtils; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Types.VmPowerState; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VGPU; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VM; + +public final class CitrixStopCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixStopCommandWrapper.class); + + @Override + public Answer execute(final StopCommand command, final CitrixResourceBase citrixResourceBase) { + final String vmName = command.getVmName(); + String platformstring = null; + try { + final Connection conn = citrixResourceBase.getConnection(); + final Set vms = VM.getByNameLabel(conn, vmName); + // 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.RUNNING) { + continue; + } + if (citrixResourceBase.isRefNull(vmr.residentOn)) { + continue; + } + if (vmr.residentOn.getUuid(conn).equals(citrixResourceBase.getHost().getUuid())) { + continue; + } + iter.remove(); + } + + if (vms.size() == 0) { + return new StopAnswer(command, "VM does not exist", true); + } + for (final VM vm : vms) { + final VM.Record vmr = vm.getRecord(conn); + platformstring = StringUtils.mapToString(vmr.platform); + if (vmr.isControlDomain) { + final String msg = "Tring to Shutdown control domain"; + s_logger.warn(msg); + return new StopAnswer(command, msg, false); + } + + if (vmr.powerState == VmPowerState.RUNNING && !citrixResourceBase.isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(citrixResourceBase.getHost().getUuid())) { + final String msg = "Stop Vm " + vmName + " failed due to this vm is not running on this host: " + citrixResourceBase.getHost().getUuid() + " but host:" + vmr.residentOn.getUuid(conn); + s_logger.warn(msg); + return new StopAnswer(command, msg, platformstring, false); + } + + if (command.checkBeforeCleanup() && vmr.powerState == VmPowerState.RUNNING) { + final String msg = "Vm " + vmName + " is running on host and checkBeforeCleanup flag is set, so bailing out"; + s_logger.debug(msg); + return new StopAnswer(command, msg, false); + } + + s_logger.debug("9. The VM " + vmName + " is in Stopping state"); + + try { + if (vmr.powerState == VmPowerState.RUNNING) { + /* when stop a vm, set affinity to current xenserver */ + vm.setAffinity(conn, vm.getResidentOn(conn)); + + if (citrixResourceBase.canBridgeFirewall()) { + final String result = citrixResourceBase.callHostPlugin(conn, "vmops", "destroy_network_rules_for_vm", "vmName", command.getVmName()); + if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { + s_logger.warn("Failed to remove network rules for vm " + command.getVmName()); + } else { + s_logger.info("Removed network rules for vm " + command.getVmName()); + } + } + citrixResourceBase.shutdownVM(conn, vm, vmName); + } + } catch (final Exception e) { + final String msg = "Catch exception " + e.getClass().getName() + " when stop VM:" + command.getVmName() + " due to " + e.toString(); + s_logger.debug(msg); + return new StopAnswer(command, msg, platformstring, false); + } finally { + + try { + if (vm.getPowerState(conn) == VmPowerState.HALTED) { + Set vGPUs = null; + // Get updated GPU details + try { + vGPUs = vm.getVGPUs(conn); + } catch (final XenAPIException e2) { + s_logger.debug("VM " + vmName + " does not have GPU support."); + } + if (vGPUs != null && !vGPUs.isEmpty()) { + final HashMap> groupDetails = citrixResourceBase.getGPUGroupDetails(conn); + command.setGpuDevice(new GPUDeviceTO(null, null, groupDetails)); + } + + final Set vifs = vm.getVIFs(conn); + final List networks = new ArrayList(); + for (final VIF vif : vifs) { + networks.add(vif.getNetwork(conn)); + } + vm.destroy(conn); + final SR sr = citrixResourceBase.getISOSRbyVmName(conn, command.getVmName()); + citrixResourceBase.removeSR(conn, sr); + // Disable any VLAN networks that aren't used + // anymore + for (final Network network : networks) { + try { + if (network.getNameLabel(conn).startsWith("VLAN")) { + citrixResourceBase.disableVlanNetwork(conn, network); + } + } catch (final Exception e) { + // network might be destroyed by other host + } + } + return new StopAnswer(command, "Stop VM " + vmName + " Succeed", platformstring, true); + } + } catch (final Exception e) { + final String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.getMessage(); + s_logger.warn(msg, e); + } finally { + s_logger.debug("10. The VM " + vmName + " is in Stopped state"); + } + } + } + + } catch (final Exception e) { + final String msg = "Stop Vm " + vmName + " fail due to " + e.toString(); + s_logger.warn(msg, e); + return new StopAnswer(command, msg, platformstring, false); + } + return new StopAnswer(command, "Stop VM failed", platformstring, false); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUnPlugNicCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUnPlugNicCommandWrapper.java new file mode 100644 index 00000000000..625083504de --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUnPlugNicCommandWrapper.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.xenserver.resource.wrapper; + +import java.util.Set; + +import org.apache.log4j.Logger; + +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.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VM; + +public final class CitrixUnPlugNicCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixUnPlugNicCommandWrapper.class); + + @Override + public Answer execute(final UnPlugNicCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + final String vmName = command.getVmName(); + try { + final Set vms = VM.getByNameLabel(conn, vmName); + if (vms == null || vms.isEmpty()) { + return new UnPlugNicAnswer(command, false, "Can not find VM " + vmName); + } + final VM vm = vms.iterator().next(); + final NicTO nic = command.getNic(); + final String mac = nic.getMac(); + final VIF vif = citrixResourceBase.getVifByMac(conn, vm, mac); + if (vif != null) { + vif.unplug(conn); + final Network network = vif.getNetwork(conn); + vif.destroy(conn); + try { + if (network.getNameLabel(conn).startsWith("VLAN")) { + citrixResourceBase.disableVlanNetwork(conn, network); + } + } catch (final Exception e) { + } + } + return new UnPlugNicAnswer(command, true, "success"); + } catch (final Exception e) { + final String msg = " UnPlug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new UnPlugNicAnswer(command, false, msg); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpdateHostPasswordCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpdateHostPasswordCommandWrapper.java new file mode 100644 index 00000000000..f2f1fb5fce9 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpdateHostPasswordCommandWrapper.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.xenserver.resource.wrapper; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.UpdateHostPasswordCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; + +public final class CitrixUpdateHostPasswordCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final UpdateHostPasswordCommand command, final CitrixResourceBase citrixResourceBase) { + citrixResourceBase.addToPwdQueue(command.getNewPassword()); + return new Answer(command, true, null); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpgradeSnapshotCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpgradeSnapshotCommandWrapper.java new file mode 100644 index 00000000000..a7f3a5008bc --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpgradeSnapshotCommandWrapper.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.xenserver.resource.wrapper; + +import java.net.URI; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.UpgradeSnapshotCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; + +public final class CitrixUpgradeSnapshotCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixUpgradeSnapshotCommandWrapper.class); + + @Override + public Answer execute(final UpgradeSnapshotCommand command, final CitrixResourceBase citrixResourceBase) { + final String secondaryStorageUrl = command.getSecondaryStorageUrl(); + final String backedUpSnapshotUuid = command.getSnapshotUuid(); + final Long volumeId = command.getVolumeId(); + final Long accountId = command.getAccountId(); + final Long templateId = command.getTemplateId(); + final Long tmpltAcountId = command.getTmpltAccountId(); + final String version = command.getVersion(); + + if (!version.equals("2.1")) { + return new Answer(command, true, "success"); + } + try { + final Connection conn = citrixResourceBase.getConnection(); + final URI uri = new URI(secondaryStorageUrl); + final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); + final String snapshotPath = secondaryStorageMountPath + "/snapshots/" + accountId + "/" + volumeId + "/" + backedUpSnapshotUuid + ".vhd"; + final String templatePath = secondaryStorageMountPath + "/template/tmpl/" + tmpltAcountId + "/" + templateId; + citrixResourceBase.upgradeSnapshot(conn, templatePath, snapshotPath); + return new Answer(command, true, "success"); + } catch (final Exception e) { + final String details = "upgrading snapshot " + backedUpSnapshotUuid + " failed due to " + e.toString(); + s_logger.error(details, e); + + } + return new Answer(command, false, "failure"); + } +} \ 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 new file mode 100644 index 00000000000..4ee961402f9 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixWatchConsoleProxyLoadCommandWrapper.java @@ -0,0 +1,38 @@ +// +// 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 com.cloud.agent.api.Answer; +import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; + +public final class CitrixWatchConsoleProxyLoadCommandWrapper extends CommandWrapper { + + @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(); + + return executeProxyLoadScan(command, proxyVmId, proxyVmName, proxyManagementIp, cmdPort); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56CheckOnHostCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56CheckOnHostCommandWrapper.java new file mode 100644 index 00000000000..972936ec8d3 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56CheckOnHostCommandWrapper.java @@ -0,0 +1,48 @@ +// +// 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 org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckOnHostAnswer; +import com.cloud.agent.api.CheckOnHostCommand; +import com.cloud.hypervisor.xenserver.resource.XenServer56Resource; +import com.cloud.resource.CommandWrapper; + +public final class XenServer56CheckOnHostCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(XenServer56CheckOnHostCommandWrapper.class); + + @Override + public Answer execute(final CheckOnHostCommand command, final XenServer56Resource xenServer56) { + final Boolean alive = xenServer56.checkHeartbeat(command.getHost().getGuid()); + String msg = ""; + if (alive == null) { + msg = " cannot determine "; + } else if ( alive == true) { + msg = "Heart beat is still going"; + } else { + msg = "Heart beat is gone so dead."; + } + s_logger.debug(msg); + return new CheckOnHostAnswer(command, alive, msg); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FP1FenceCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FP1FenceCommandWrapper.java new file mode 100644 index 00000000000..b169636cb4a --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FP1FenceCommandWrapper.java @@ -0,0 +1,92 @@ +// +// 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.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.FenceAnswer; +import com.cloud.agent.api.FenceCommand; +import com.cloud.hypervisor.xenserver.resource.XenServer56Resource; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; + +public final class XenServer56FP1FenceCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(XenServer56FP1FenceCommandWrapper.class); + + @Override + public Answer execute(final FenceCommand command, final XenServer56Resource xenServer56) { + final Connection conn = xenServer56.getConnection(); + try { + final Boolean alive = xenServer56.checkHeartbeat(command.getHostGuid()); + if ( alive == null ) { + s_logger.debug("Failed to check heartbeat, so unable to fence"); + return new FenceAnswer(command, false, "Failed to check heartbeat, so unable to fence"); + } + if ( alive ) { + s_logger.debug("Heart beat is still going so unable to fence"); + return new FenceAnswer(command, false, "Heartbeat is still going on unable to fence"); + } + final Set vms = VM.getByNameLabel(conn, command.getVmName()); + for (final VM vm : vms) { + final Set vdis = new HashSet(); + final Set vbds = vm.getVBDs(conn); + for (final VBD vbd : vbds) { + final VDI vdi = vbd.getVDI(conn); + if (!xenServer56.isRefNull(vdi)) { + vdis.add(vdi); + } + } + s_logger.info("Fence command for VM " + command.getVmName()); + vm.powerStateReset(conn); + vm.destroy(conn); + for (final VDI vdi : vdis) { + final Map smConfig = vdi.getSmConfig(conn); + for (final String key : smConfig.keySet()) { + if (key.startsWith("host_")) { + vdi.removeFromSmConfig(conn, key); + break; + } + } + } + } + return new FenceAnswer(command); + } catch (final XmlRpcException e) { + s_logger.warn("Unable to fence", e); + return new FenceAnswer(command, false, e.getMessage()); + } catch (final XenAPIException e) { + s_logger.warn("Unable to fence", e); + return new FenceAnswer(command, false, e.getMessage()); + } catch (final Exception 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/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FenceCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FenceCommandWrapper.java new file mode 100644 index 00000000000..ece3329594d --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FenceCommandWrapper.java @@ -0,0 +1,71 @@ +// +// 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.util.Set; + +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.FenceAnswer; +import com.cloud.agent.api.FenceCommand; +import com.cloud.hypervisor.xenserver.resource.XenServer56Resource; +import com.cloud.resource.CommandWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VM; + +public final class XenServer56FenceCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(XenServer56FenceCommandWrapper.class); + + @Override + public Answer execute(final FenceCommand command, final XenServer56Resource xenServer56) { + final Connection conn = xenServer56.getConnection(); + try { + final Boolean alive = xenServer56.checkHeartbeat(command.getHostGuid()); + if (alive == null) { + s_logger.debug("Failed to check heartbeat, so unable to fence"); + return new FenceAnswer(command, false, "Failed to check heartbeat, so unable to fence"); + } + if (alive) { + s_logger.debug("Heart beat is still going so unable to fence"); + return new FenceAnswer(command, false, "Heartbeat is still going on unable to fence"); + } + final Set vms = VM.getByNameLabel(conn, command.getVmName()); + for (final VM vm : vms) { + s_logger.info("Fence command for VM " + command.getVmName()); + vm.powerStateReset(conn); + vm.destroy(conn); + } + return new FenceAnswer(command); + } catch (final XmlRpcException e) { + s_logger.warn("Unable to fence", e); + return new FenceAnswer(command, false, e.getMessage()); + } catch (final XenAPIException e) { + s_logger.warn("Unable to fence", e); + return new FenceAnswer(command, false, e.getMessage()); + } catch (final Exception 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/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56NetworkUsageCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56NetworkUsageCommandWrapper.java new file mode 100644 index 00000000000..0e3f922f630 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56NetworkUsageCommandWrapper.java @@ -0,0 +1,102 @@ +// +// 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 org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.NetworkUsageAnswer; +import com.cloud.agent.api.NetworkUsageCommand; +import com.cloud.hypervisor.xenserver.resource.XenServer56Resource; +import com.cloud.resource.CommandWrapper; +import com.cloud.utils.ExecutionResult; +import com.xensource.xenapi.Connection; + +public final class XenServer56NetworkUsageCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(XenServer56NetworkUsageCommandWrapper.class); + + @Override + public Answer execute(final NetworkUsageCommand command, final XenServer56Resource xenServer56) { + if (command.isForVpc()) { + return executeNetworkUsage(command, xenServer56); + } + try { + final Connection conn = xenServer56.getConnection(); + if (command.getOption() != null && command.getOption().equals("create")) { + final String result = xenServer56.networkUsage(conn, command.getPrivateIP(), "create", null); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, result, 0L, 0L); + return answer; + } + final long[] stats = xenServer56.getNetworkStats(conn, command.getPrivateIP()); + final NetworkUsageAnswer answer = new NetworkUsageAnswer(command, "", stats[0], stats[1]); + return answer; + } catch (final Exception ex) { + s_logger.warn("Failed to get network usage stats due to ", ex); + return new NetworkUsageAnswer(command, ex); + } + } + + protected NetworkUsageAnswer executeNetworkUsage(final NetworkUsageCommand command, final XenServer56Resource xenServer56) { + try { + final String option = command.getOption(); + final String publicIp = command.getGatewayIP(); + + String args = " -l " + publicIp + " "; + if (option.equals("get")) { + args += "-g"; + } else if (option.equals("create")) { + args += "-c"; + final String vpcCIDR = command.getVpcCIDR(); + args += " -v " + vpcCIDR; + } else if (option.equals("reset")) { + args += "-r"; + } else if (option.equals("vpn")) { + args += "-n"; + } else if (option.equals("remove")) { + args += "-d"; + } else { + return new NetworkUsageAnswer(command, "success", 0L, 0L); + } + + final ExecutionResult result = xenServer56.executeInVR(command.getPrivateIP(), "vpc_netusage.sh", args); + final String detail = result.getDetails(); + if (!result.isSuccess()) { + throw new Exception(" vpc network usage plugin call failed "); + } + if (option.equals("get") || option.equals("vpn")) { + final long[] stats = new long[2]; + if (detail != null) { + final String[] splitResult = detail.split(":"); + int i = 0; + while (i < splitResult.length - 1) { + stats[0] += new Long(splitResult[i++]).longValue(); + stats[1] += new Long(splitResult[i++]).longValue(); + } + return new NetworkUsageAnswer(command, "success", stats[0], stats[1]); + } + } + return new NetworkUsageAnswer(command, "success", 0L, 0L); + } catch (final Exception ex) { + s_logger.warn("Failed to get network usage stats due to ", ex); + return new NetworkUsageAnswer(command, ex); + } + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java b/plugins/hypervisors/xenserver/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java index 161a7b22abf..4971eb38593 100644 --- a/plugins/hypervisors/xenserver/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java +++ b/plugins/hypervisors/xenserver/src/org/apache/cloudstack/hypervisor/xenserver/XenServerResourceNewBase.java @@ -25,6 +25,11 @@ import java.util.concurrent.TimeoutException; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; +import com.cloud.agent.api.StartupCommand; +import com.cloud.hypervisor.xenserver.resource.XenServer620SP1Resource; +import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.VirtualMachine; import com.xensource.xenapi.Connection; import com.xensource.xenapi.Event; import com.xensource.xenapi.EventBatch; @@ -35,12 +40,6 @@ import com.xensource.xenapi.Types; import com.xensource.xenapi.Types.XenAPIException; import com.xensource.xenapi.VM; -import com.cloud.agent.api.StartupCommand; -import com.cloud.hypervisor.xenserver.resource.XenServer620SP1Resource; -import com.cloud.utils.Pair; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.VirtualMachine; - /** * * XenServerResourceNewBase is an abstract base class that encapsulates how @@ -67,16 +66,16 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { @Override public StartupCommand[] initialize() throws IllegalArgumentException { - StartupCommand[] cmds = super.initialize(); + final StartupCommand[] cmds = super.initialize(); - Connection conn = getConnection(); + final Connection conn = getConnection(); Pool pool; try { - pool = Pool.getByUuid(conn, _host.pool); - Pool.Record poolr = pool.getRecord(conn); + pool = Pool.getByUuid(conn, _host.getPool()); + final Pool.Record poolr = pool.getRecord(conn); - Host.Record masterRecord = poolr.master.getRecord(conn); - if (_host.uuid.equals(masterRecord.uuid)) { + final Host.Record masterRecord = poolr.master.getRecord(conn); + if (_host.getUuid().equals(masterRecord.uuid)) { _listener = new VmEventListener(true); // @@ -87,36 +86,37 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { } else { _listener = new VmEventListener(false); } - } catch (XenAPIException e) { + } catch (final XenAPIException e) { throw new CloudRuntimeException("Unable to determine who is the master", e); - } catch (XmlRpcException e) { + } catch (final XmlRpcException e) { throw new CloudRuntimeException("Unable to determine who is the master", e); } return cmds; } - protected void waitForTask2(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException, TimeoutException { - long beginTime = System.currentTimeMillis(); + protected void waitForTask2(final Connection c, final Task task, final long pollInterval, final long timeout) throws XenAPIException, XmlRpcException, TimeoutException { + final long beginTime = System.currentTimeMillis(); if (s_logger.isTraceEnabled()) { s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getType(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout + - "ms timeout"); + "ms timeout"); } - Set classes = new HashSet(); + final Set classes = new HashSet(); classes.add("Task/" + task.toWireString()); String token = ""; - Double t = new Double(timeout / 1000); + final Double t = new Double(timeout / 1000); while (true) { - EventBatch map = Event.from(c, classes, token, t); + final EventBatch map = Event.from(c, classes, token, t); token = map.token; @SuppressWarnings("unchecked") + final Set events = map.events; if (events.size() == 0) { - String msg = "No event for task " + task.toWireString(); + final String msg = "No event for task " + task.toWireString(); s_logger.warn(msg); task.cancel(c); throw new TimeoutException(msg); } - for (Event.Record rec : events) { + for (final Event.Record rec : events) { if (!(rec.snapshot instanceof Task.Record)) { if (s_logger.isDebugEnabled()) { s_logger.debug("Skipping over " + rec); @@ -124,7 +124,7 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { continue; } - Task.Record taskRecord = (Task.Record)rec.snapshot; + final Task.Record taskRecord = (Task.Record)rec.snapshot; if (taskRecord.status != Types.TaskStatusType.PENDING) { if (s_logger.isDebugEnabled()) { @@ -139,7 +139,7 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { } } if (System.currentTimeMillis() - beginTime > timeout) { - String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString(); + final String msg = "Async " + timeout / 1000 + " seconds timeout for task " + task.toString(); s_logger.warn(msg); task.cancel(c); throw new TimeoutException(msg); @@ -155,7 +155,7 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { Set _classes; String _token = ""; - public VmEventListener(boolean isMaster) { + public VmEventListener(final boolean isMaster) { _isMaster = isMaster; _classes = new HashSet(); _classes.add("VM"); @@ -163,22 +163,23 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { @Override public void run() { - setName("XS-Listener-" + _host.ip); + setName("XS-Listener-" + _host.getIp()); while (!_stop) { try { - Connection conn = getConnection(); + final Connection conn = getConnection(); EventBatch results; try { results = Event.from(conn, _classes, _token, new Double(30)); - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("Retrying the waiting on VM events due to: ", e); continue; } _token = results.token; @SuppressWarnings("unchecked") + final Set events = results.events; - for (Event.Record event : events) { + for (final Event.Record event : events) { try { if (!(event.snapshot instanceof VM.Record)) { if (s_logger.isDebugEnabled()) { @@ -186,24 +187,24 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { } continue; } - VM.Record vm = (VM.Record)event.snapshot; + final VM.Record vm = (VM.Record)event.snapshot; String hostUuid = null; if (vm.residentOn != null && !vm.residentOn.toWireString().contains("OpaqueRef:NULL")) { hostUuid = vm.residentOn.getUuid(conn); } recordChanges(conn, vm, hostUuid); - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("Skipping over " + event, e); } } - } catch (Throwable th) { + } catch (final Throwable th) { s_logger.error("Exception caught in eventlistener thread: ", th); } } } - protected void recordChanges(Connection conn, VM.Record rec, String hostUuid) { + protected void recordChanges(final Connection conn, final VM.Record rec, final String hostUuid) { } @@ -211,16 +212,16 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { public void start() { if (_isMaster) { // Throw away the initial set of events because they're history - Connection conn = getConnection(); + final Connection conn = getConnection(); EventBatch results; try { results = Event.from(conn, _classes, _token, new Double(30)); - } catch (Exception e) { + } catch (final Exception e) { s_logger.error("Retrying the waiting on VM events due to: ", e); throw new CloudRuntimeException("Unable to start a listener thread to listen to VM events", e); } _token = results.token; - s_logger.debug("Starting the event listener thread for " + _host.uuid); + s_logger.debug("Starting the event listener thread for " + _host.getUuid()); super.start(); } } @@ -234,7 +235,7 @@ public class XenServerResourceNewBase extends XenServer620SP1Resource { if (_changes.size() == 0) { return null; } - HashMap> diff = _changes; + final HashMap> diff = _changes; _changes = new HashMap>(); return diff; } diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java deleted file mode 100644 index 0c2944c8d8f..00000000000 --- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixResourceBaseTest.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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; - -import static org.junit.Assert.fail; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.apache.xmlrpc.XmlRpcException; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.Spy; - -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Types; -import com.xensource.xenapi.VIF; -import com.xensource.xenapi.VM; -import com.xensource.xenapi.XenAPIObject; - -import com.cloud.agent.api.ScaleVmAnswer; -import com.cloud.agent.api.ScaleVmCommand; -import com.cloud.agent.api.to.IpAddressTO; -import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.XsHost; - -public class CitrixResourceBaseTest { - - @Spy - CitrixResourceBase _resource = new CitrixResourceBase() { - - @Override - public ScaleVmAnswer execute(ScaleVmCommand cmd) { - return super.execute(cmd); - } - - @Override - public String callHostPlugin(Connection conn, String plugin, String cmd, String... params) { - return "Success"; - } - - @Override - protected void scaleVM(Connection conn, VM vm, VirtualMachineTO vmSpec, Host host) throws Types.XenAPIException, XmlRpcException { - _host.speed = 500; - super.scaleVM(conn, vm, vmSpec, host); - } - - @Override - protected boolean isDmcEnabled(Connection conn, Host host) throws Types.XenAPIException, XmlRpcException { - return true; - } - }; - @Mock - XsHost _host; - @Mock - Host host; - @Mock - ScaleVmCommand cmd; - @Mock - VirtualMachineTO vmSpec; - @Mock - Connection conn; - @Mock - VM vm; - - @Before - public void setup() { - - MockitoAnnotations.initMocks(this); - - doReturn(vmSpec).when(cmd).getVirtualMachine(); - doReturn("i-2-3-VM").when(vmSpec).getName(); - - } - - // Expecting XmlRpcException while trying to get the record of vm using connection - @Test(expected = XmlRpcException.class) - public void testScaleVMF1() throws Types.BadServerResponse, Types.XenAPIException, XmlRpcException { - doReturn(conn).when(_resource).getConnection(); - Set vms = mock(Set.class); - - Iterator iter = mock(Iterator.class); - doReturn(iter).when(vms).iterator(); - when(iter.hasNext()).thenReturn(true).thenReturn(false); - doReturn(vm).when(iter).next(); - VM.Record vmr = mock(VM.Record.class); - when(vm.getRecord(conn)).thenThrow(new XmlRpcException("XmlRpcException")); - when(vm.getRecord(conn)).thenReturn(vmr); - vmr.powerState = Types.VmPowerState.RUNNING; - vmr.residentOn = mock(Host.class); - XenAPIObject object = mock(XenAPIObject.class); - doReturn(new String("OpaqueRef:NULL")).when(object).toWireString(); - doNothing().when(_resource).scaleVM(conn, vm, vmSpec, host); - - _resource.execute(cmd); - verify(iter, times(2)).hasNext(); - verify(iter, times(2)).next(); - - } - - // Test to scale vm "i-2-3-VM" cpu-cap disabled - @Test - public void testScaleVMF2() throws Types.XenAPIException, XmlRpcException { - - when(vm.getMemoryStaticMax(conn)).thenReturn(1073741824L); - when(vm.getMemoryStaticMin(conn)).thenReturn(268435456L); - doReturn(536870912L).when(vmSpec).getMinRam(); - doReturn(536870912L).when(vmSpec).getMaxRam(); - doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L); - doReturn(1).when(vmSpec).getCpus(); - doNothing().when(vm).setVCPUsNumberLive(conn, 1L); - doReturn(500).when(vmSpec).getMinSpeed(); - doReturn(false).when(vmSpec).getLimitCpuUse(); - Map args = mock(HashMap.class); - when(host.callPlugin(conn, "vmops", "add_to_VCPUs_params_live", args)).thenReturn("Success"); - doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM"); - - _resource.scaleVM(conn, vm, vmSpec, host); - - verify(vmSpec, times(1)).getLimitCpuUse(); - verify(_resource, times(1)).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM"); - } - - // Test to scale vm "i-2-3-VM" cpu-cap enabled - @Test - public void testScaleVMF3() throws Types.XenAPIException, XmlRpcException { - - when(vm.getMemoryStaticMax(conn)).thenReturn(1073741824L); - when(vm.getMemoryStaticMin(conn)).thenReturn(268435456L); - doReturn(536870912L).when(vmSpec).getMinRam(); - doReturn(536870912L).when(vmSpec).getMaxRam(); - doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L); - doReturn(1).when(vmSpec).getCpus(); - doNothing().when(vm).setVCPUsNumberLive(conn, 1L); - doReturn(500).when(vmSpec).getMinSpeed(); - doReturn(500).when(vmSpec).getMaxSpeed(); - doReturn(true).when(vmSpec).getLimitCpuUse(); - doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", "99", "vmname", "i-2-3-VM"); - Map args = mock(HashMap.class); - when(host.callPlugin(conn, "vmops", "add_to_VCPUs_params_live", args)).thenReturn("Success"); - doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM"); - - _resource.scaleVM(conn, vm, vmSpec, host); - - verify(vmSpec, times(1)).getLimitCpuUse(); - verify(_resource, times(1)).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM"); - verify(_resource, times(1)).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", "99", "vmname", "i-2-3-VM"); - } - - - @Test - public void testSetNicDevIdIfCorrectVifIsNotNull() throws Exception { - IpAddressTO ip = mock(IpAddressTO.class); - when(ip.isAdd()).thenReturn(false); - VIF correctVif = null; - try { - _resource.setNicDevIdIfCorrectVifIsNotNull(conn, ip, correctVif); - } catch (NullPointerException e) { - fail("this test is meant to show that null pointer is not thrown"); - } - } -} 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 new file mode 100644 index 00000000000..1a02af4b57c --- /dev/null +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java @@ -0,0 +1,1804 @@ +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.xmlrpc.XmlRpcException; +import org.apache.xmlrpc.client.XmlRpcClient; +import org.junit.Test; +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; +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.ClusterVMMetaDataSyncCommand; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.CreateVMSnapshotCommand; +import com.cloud.agent.api.DeleteStoragePoolCommand; +import com.cloud.agent.api.DeleteVMSnapshotCommand; +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; +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.OvsCreateGreTunnelCommand; +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.OvsFetchInterfaceCommand; +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.PerformanceMonitorCommand; +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.RebootAnswer; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.api.RevertToVMSnapshotCommand; +import com.cloud.agent.api.ScaleVmCommand; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SetupCommand; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.UnPlugNicCommand; +import com.cloud.agent.api.UpdateHostPasswordCommand; +import com.cloud.agent.api.UpgradeSnapshotCommand; +import com.cloud.agent.api.VMSnapshotTO; +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.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; +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.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.IpAddressTO; +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.host.HostEnvironment; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.hypervisor.xenserver.resource.XsHost; +import com.cloud.hypervisor.xenserver.resource.XsLocalNetwork; +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.VMTemplateStorageResourceAssoc; +import com.cloud.vm.DiskProfile; +import com.cloud.vm.VirtualMachine; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Marshalling; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Pool; +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 + private CitrixResourceBase citrixResourceBase; + @Mock + private RebootAnswer rebootAnswer; + @Mock + private CreateAnswer createAnswer; + + @Test + public void testWrapperInstance() { + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + } + + @Test + public void testUnknownCommand() { + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + try { + wrapper.execute(new NotAValidCommand(), citrixResourceBase); + } catch (final Exception e) { + assertTrue(e instanceof NullPointerException); + } + } + + @Test + public void testExecuteRebootRouterCommand() { + final RebootRouterCommand rebootRouterCommand = new RebootRouterCommand("Test", "127.0.0.1"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(rebootRouterCommand, citrixResourceBase); + + verify(citrixResourceBase, times(2)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testExecuteCreateCommand() { + final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class); + final DiskProfile diskProfile = Mockito.mock(DiskProfile.class); + final CreateCommand createCommand = new CreateCommand(diskProfile, "", poolVO, false); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(createCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testCheckConsoleProxyLoadCommand() { + final CheckConsoleProxyLoadCommand consoleProxyCommand = new CheckConsoleProxyLoadCommand(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(consoleProxyCommand, citrixResourceBase); + + assertFalse(answer.getResult()); + } + + @Test + public void testWatchConsoleProxyLoadCommand() { + final WatchConsoleProxyLoadCommand watchConsoleProxyCommand = new WatchConsoleProxyLoadCommand(0, 0, "", "", 0); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(watchConsoleProxyCommand, citrixResourceBase); + + assertFalse(answer.getResult()); + } + + @Test + public void testReadyCommand() { + final ReadyCommand readyCommand = new ReadyCommand(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(readyCommand, citrixResourceBase); + + assertFalse(answer.getResult()); + } + + @Test + public void testGetHostStatsCommand() { + final GetHostStatsCommand statsCommand = new GetHostStatsCommand(null, null, 0); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(statsCommand, citrixResourceBase); + + assertTrue(answer.getResult()); + } + + @Test + public void testGetVmStatsCommand() { + final GetVmStatsCommand statsCommand = new GetVmStatsCommand(new ArrayList(), null, null); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(statsCommand, citrixResourceBase); + + assertTrue(answer.getResult()); + } + + @Test + public void testGetVmDiskStatsCommand() { + final GetVmDiskStatsCommand diskStatsCommand = new GetVmDiskStatsCommand(new ArrayList(), null, null); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(diskStatsCommand, citrixResourceBase); + + assertTrue(answer.getResult()); + } + + @Test + public void testCheckHealthCommand() { + final CheckHealthCommand checkHealthCommand = new CheckHealthCommand(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(checkHealthCommand, citrixResourceBase); + + assertFalse(answer.getResult()); + } + + @Test + public void testStopCommandCommand() { + final StopCommand stopCommand = new StopCommand("Test", false, false); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(stopCommand, citrixResourceBase); + + assertFalse(answer.getResult()); + } + + @Test + public void testRebootCommand() { + final RebootCommand rebootCommand = new RebootCommand("Test"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(rebootCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testCheckVirtualMachineCommand() { + final CheckVirtualMachineCommand virtualMachineCommand = new CheckVirtualMachineCommand("Test"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(virtualMachineCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testPrepareForMigrationCommand() { + final VirtualMachineTO machineTO = Mockito.mock(VirtualMachineTO.class); + final PrepareForMigrationCommand prepareCommand = new PrepareForMigrationCommand(machineTO); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(prepareCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testMigrateCommand() { + final VirtualMachineTO machineTO = Mockito.mock(VirtualMachineTO.class); + final MigrateCommand migrateCommand = new MigrateCommand("Test", "127.0.0.1", false, machineTO, false); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(migrateCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testDestroyCommand() { + + final VMTemplateStorageResourceAssoc templateStorage = Mockito.mock(VMTemplateStorageResourceAssoc.class); + final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class); + + final DestroyCommand destroyCommand = new DestroyCommand(poolVO, templateStorage); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testCreateStoragePoolCommand() { + final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + + final CreateStoragePoolCommand createStorageCommand = new CreateStoragePoolCommand(false, poolVO); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(createStorageCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testModifyStoragePoolCommand() { + final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + + final ModifyStoragePoolCommand modifyStorageCommand = new ModifyStoragePoolCommand(false, poolVO); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(modifyStorageCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testDeleteStoragePoolCommand() { + final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + + final DeleteStoragePoolCommand deleteStorageCommand = new DeleteStoragePoolCommand(poolVO); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(deleteStorageCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testResizeVolumeCommand() { + final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class); + + final ResizeVolumeCommand resizeCommand = new ResizeVolumeCommand("Test", pool, 1l, 3l, false, "Tests-1"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(resizeCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testAttachVolumeCommand() { + final AttachVolumeCommand attachCommand = new AttachVolumeCommand(false, true, "Test", StoragePoolType.LVM, "/", "DATA", 100l, 1l, "123"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(attachCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testAttachIsoCommand() { + final AttachIsoCommand attachCommand = new AttachIsoCommand("Test", "/", true); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(attachCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testUpgradeSnapshotCommand() { + final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class); + + final UpgradeSnapshotCommand upgradeSnapshotCommand = new UpgradeSnapshotCommand(poolVO, "http", 1l, 1l, 1l, 1l, 1l, "/", "58c5778b-7dd1-47cc-a7b5-f768541bf278", "Test", + "2.1"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(upgradeSnapshotCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testUpgradeSnapshotCommandNo21() { + final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class); + + final UpgradeSnapshotCommand upgradeSnapshotCommand = new UpgradeSnapshotCommand(poolVO, "http", 1l, 1l, 1l, 1l, 1l, "/", "58c5778b-7dd1-47cc-a7b5-f768541bf278", "Test", + "3.1"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(upgradeSnapshotCommand, citrixResourceBase); + verify(citrixResourceBase, times(0)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testGetStorageStatsCommand() { + final XsHost xsHost = Mockito.mock(XsHost.class); + final DataStoreTO store = Mockito.mock(DataStoreTO.class); + + final GetStorageStatsCommand storageStatsCommand = new GetStorageStatsCommand(store); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(storageStatsCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testPrimaryStorageDownloadCommand() { + final XsHost xsHost = Mockito.mock(XsHost.class); + final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class); + + final PrimaryStorageDownloadCommand storageDownloadCommand = new PrimaryStorageDownloadCommand("Test", "http://127.0.0.1", ImageFormat.VHD, 1l, poolVO, 200); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(storageDownloadCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testGetVncPortCommand() { + final GetVncPortCommand vncPortCommand = new GetVncPortCommand(1l, "Test"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(vncPortCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testSetupCommand() { + final XsHost xsHost = Mockito.mock(XsHost.class); + final HostEnvironment env = Mockito.mock(HostEnvironment.class); + + final SetupCommand setupCommand = new SetupCommand(env); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(setupCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testMaintainCommand() { + // This test needs further work. + + final String uuid = "befc4dcd-f5c6-4015-8791-3c18622b7c7f"; + + final Connection conn = Mockito.mock(Connection.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + final XmlRpcClient client = Mockito.mock(XmlRpcClient.class); + + // final Host.Record hr = PowerMockito.mock(Host.Record.class); + // final Host host = PowerMockito.mock(Host.class); + + final MaintainCommand maintainCommand = new MaintainCommand(); + + final Map map = new Hashtable(); + map.put("Value", "Xen"); + + final Map spiedMap = spy(map); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getHost()).thenReturn(xsHost); + when(xsHost.getUuid()).thenReturn(uuid); + when(conn.getSessionReference()).thenReturn("befc4dcd"); + + try { + final Object[] params = { Marshalling.toXMLRPC("befc4dcd"), Marshalling.toXMLRPC(uuid) }; + when(client.execute("host.get_by_uuid", new Object[] { "befc4dcd", uuid })).thenReturn(spiedMap); + PowerMockito.when(conn, "dispatch", "host.get_by_uuid", params).thenReturn(spiedMap); + } catch (final Exception e) { + } + + // try { + // PowerMockito.mockStatic(Host.class); + // //BDDMockito.given(Host.getByUuid(conn, + // xsHost.getUuid())).willReturn(host); + // PowerMockito.when(Host.getByUuid(conn, + // xsHost.getUuid())).thenReturn(host); + // PowerMockito.verifyStatic(times(1)); + // } catch (final BadServerResponse e) { + // fail(e.getMessage()); + // } catch (final XenAPIException e) { + // fail(e.getMessage()); + // } catch (final XmlRpcException e) { + // fail(e.getMessage()); + // } + // + // PowerMockito.mockStatic(Types.class); + // PowerMockito.when(Types.toHostRecord(spiedMap)).thenReturn(hr); + // PowerMockito.verifyStatic(times(1)); + // + // try { + // PowerMockito.mockStatic(Host.Record.class); + // when(host.getRecord(conn)).thenReturn(hr); + // verify(host, times(1)).getRecord(conn); + // } catch (final BadServerResponse e) { + // fail(e.getMessage()); + // } catch (final XenAPIException e) { + // fail(e.getMessage()); + // } catch (final XmlRpcException e) { + // fail(e.getMessage()); + // } + + final Answer answer = wrapper.execute(maintainCommand, citrixResourceBase); + + assertFalse(answer.getResult()); + } + + @Test + public void testPingTestCommandHostIp() { + final PingTestCommand pingTestCommand = new PingTestCommand("127.0.0.1"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(pingTestCommand, citrixResourceBase); + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testPingTestCommandRouterPvtIps() { + final PingTestCommand pingTestCommand = new PingTestCommand("127.0.0.1", "192.168.0.1"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(pingTestCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testCheckOnHostCommand() { + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + final CheckOnHostCommand onHostCommand = new CheckOnHostCommand(host); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(onHostCommand, citrixResourceBase); + + assertFalse(answer.getResult()); + } + + @Test + public void testModifySshKeysCommand() { + final ModifySshKeysCommand sshKeysCommand = new ModifySshKeysCommand("", ""); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(sshKeysCommand, citrixResourceBase); + + assertTrue(answer.getResult()); + } + + @Test + public void testStartCommand() { + final VirtualMachineTO vm = Mockito.mock(VirtualMachineTO.class); + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + + final StartCommand startCommand = new StartCommand(vm, host, false); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(startCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testOvsSetTagAndFlowCommand() { + final Network network = Mockito.mock(Network.class); + final Connection conn = Mockito.mock(Connection.class); + + final OvsSetTagAndFlowCommand tagAndFlowCommand = new OvsSetTagAndFlowCommand("Test", "tag", "vlan://1", "123", 1l); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.setupvSwitchNetwork(conn)).thenReturn(network); + try { + when(network.getBridge(conn)).thenReturn("br0"); + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(tagAndFlowCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + verify(citrixResourceBase, times(1)).setupvSwitchNetwork(conn); + verify(citrixResourceBase, times(1)).setIsOvs(true); + + assertFalse(answer.getResult()); + } + + @Test + public void testCheckSshCommand() { + final CheckSshCommand sshCommand = new CheckSshCommand("Test", "127.0.0.1", 22); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(sshCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testSecurityGroupRulesCommand() { + final Connection conn = Mockito.mock(Connection.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + + final SecurityGroupRulesCmd sshCommand = new SecurityGroupRulesCmd(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(sshCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testOvsFetchInterfaceCommand() { + final String label = "[abc]"; + final String uuid = "befc4dcd-f5c6-4015-8791-3c18622b7c7f"; + + final Connection conn = Mockito.mock(Connection.class); + final XsLocalNetwork network = Mockito.mock(XsLocalNetwork.class); + final Network network2 = Mockito.mock(Network.class); + final PIF pif = Mockito.mock(PIF.class); + final PIF.Record pifRec = Mockito.mock(PIF.Record.class); + + final XsHost xsHost = Mockito.mock(XsHost.class); + + final OvsFetchInterfaceCommand fetchInterCommand = new OvsFetchInterfaceCommand(label); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.isXcp()).thenReturn(true); + when(citrixResourceBase.getLabel()).thenReturn("[abc]"); + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getHost()).thenReturn(xsHost); + + try { + when(network.getNetwork()).thenReturn(network2); + when(network.getPif(conn)).thenReturn(pif); + when(network.getPif(conn)).thenReturn(pif); + when(pif.getRecord(conn)).thenReturn(pifRec); + when(network.getNetwork().getUuid(conn)).thenReturn(uuid); + when(citrixResourceBase.getNetworkByName(conn, label)).thenReturn(network); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(fetchInterCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testOvsCreateGreTunnelCommand() { + final String bridge = "gre"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + + final OvsCreateGreTunnelCommand createGreCommand = new OvsCreateGreTunnelCommand("172.0.0.1", "KEY", 1l, 2l); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getHost()).thenReturn(xsHost); + when(citrixResourceBase.setupvSwitchNetwork(conn)).thenReturn(network); + try { + when(network.getBridge(conn)).thenReturn(bridge); + when( + citrixResourceBase.callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", createGreCommand.getRemoteIp(), "greKey", + createGreCommand.getKey(), "from", Long.toString(createGreCommand.getFrom()), "to", Long.toString(createGreCommand.getTo()))).thenReturn("1:2"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(createGreCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + verify(citrixResourceBase, times(1)).setIsOvs(true); + + assertTrue(answer.getResult()); + } + + @Test + public void testOvsDeleteFlowCommandSuccess() { + final String bridge = "gre"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsDeleteFlowCommand deleteFlowCommand = new OvsDeleteFlowCommand("Test"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.setupvSwitchNetwork(conn)).thenReturn(network); + try { + when(network.getBridge(conn)).thenReturn(bridge); + when(citrixResourceBase.callHostPlugin(conn, "ovsgre", "ovs_delete_flow", "bridge", bridge, "vmName", deleteFlowCommand.getVmName())).thenReturn("SUCCESS"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(deleteFlowCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + verify(citrixResourceBase, times(1)).setIsOvs(true); + + assertTrue(answer.getResult()); + } + + @Test + public void testOvsDeleteFlowCommandFailure() { + final String bridge = "gre"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsDeleteFlowCommand deleteFlowCommand = new OvsDeleteFlowCommand("Test"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.setupvSwitchNetwork(conn)).thenReturn(network); + try { + when(network.getBridge(conn)).thenReturn(bridge); + when(citrixResourceBase.callHostPlugin(conn, "ovsgre", "ovs_delete_flow", "bridge", bridge, "vmName", deleteFlowCommand.getVmName())).thenReturn("FAILED"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(deleteFlowCommand, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + verify(citrixResourceBase, times(1)).setIsOvs(true); + + assertFalse(answer.getResult()); + } + + @Test + public void testOvsVpcPhysicalTopologyConfigCommand() { + final String bridge = "gre"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsVpcPhysicalTopologyConfigCommand.Host[] hosts = new OvsVpcPhysicalTopologyConfigCommand.Host[0]; + final OvsVpcPhysicalTopologyConfigCommand.Tier[] tiers = new OvsVpcPhysicalTopologyConfigCommand.Tier[0]; + final OvsVpcPhysicalTopologyConfigCommand.Vm[] vms = new OvsVpcPhysicalTopologyConfigCommand.Vm[0]; + + final OvsVpcPhysicalTopologyConfigCommand physicalTopology = new OvsVpcPhysicalTopologyConfigCommand(hosts, tiers, vms, "10.0.0.1/24"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.findOrCreateTunnelNetwork(conn, physicalTopology.getBridgeName())).thenReturn(network); + when(network.getBridge(conn)).thenReturn(bridge); + + when( + citrixResourceBase.callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", bridge, "config", + physicalTopology.getVpcConfigInJson(), "host-id", ((Long) physicalTopology.getHostId()).toString(), "seq-no", Long.toString(1))).thenReturn("SUCCESS"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(physicalTopology, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testOvsVpcRoutingPolicyConfigCommand() { + final String bridge = "gre"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsVpcRoutingPolicyConfigCommand.Acl[] acls = new OvsVpcRoutingPolicyConfigCommand.Acl[0]; + final OvsVpcRoutingPolicyConfigCommand.Tier[] tiers = new OvsVpcRoutingPolicyConfigCommand.Tier[0]; + + final OvsVpcRoutingPolicyConfigCommand routingPolicy = new OvsVpcRoutingPolicyConfigCommand("v1", "10.0.0.1/24", acls, tiers); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.findOrCreateTunnelNetwork(conn, routingPolicy.getBridgeName())).thenReturn(network); + when(network.getBridge(conn)).thenReturn(bridge); + + when( + citrixResourceBase.callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_routing_policies", "bridge", bridge, "host-id", + ((Long) routingPolicy.getHostId()).toString(), "config", routingPolicy.getVpcConfigInJson(), "seq-no", Long.toString(1))).thenReturn("SUCCESS"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(routingPolicy, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testCleanupNetworkRulesCmd() { + final Connection conn = Mockito.mock(Connection.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + + final CleanupNetworkRulesCmd cleanupNets = new CleanupNetworkRulesCmd(20); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.canBridgeFirewall()).thenReturn(true); + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getHost()).thenReturn(xsHost); + when(citrixResourceBase.getVMInstanceName()).thenReturn("VM"); + when(citrixResourceBase.callHostPlugin(conn, "vmops", "cleanup_rules", "instance", citrixResourceBase.getVMInstanceName())).thenReturn("1"); + + final Answer answer = wrapper.execute(cleanupNets, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testCleanupNetworkRulesCmdLTZ() { + final Connection conn = Mockito.mock(Connection.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + + final CleanupNetworkRulesCmd cleanupNets = new CleanupNetworkRulesCmd(20); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.canBridgeFirewall()).thenReturn(true); + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getHost()).thenReturn(xsHost); + when(citrixResourceBase.getVMInstanceName()).thenReturn("VM"); + when(citrixResourceBase.callHostPlugin(conn, "vmops", "cleanup_rules", "instance", citrixResourceBase.getVMInstanceName())).thenReturn("-1"); + + final Answer answer = wrapper.execute(cleanupNets, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + verify(xsHost, times(1)).getIp(); + + assertFalse(answer.getResult()); + assertEquals(answer.getDetails(), "-1"); + } + + @Test + public void testCleanupNetworkRulesCmdNullDetails() { + final CleanupNetworkRulesCmd cleanupNets = new CleanupNetworkRulesCmd(20); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.canBridgeFirewall()).thenReturn(false); + final Answer answer = wrapper.execute(cleanupNets, citrixResourceBase); + + assertTrue(answer.getResult()); + assertNull(answer.getDetails()); + } + + @Test + public void testNetworkRulesSystemVmCommand() { + final Connection conn = Mockito.mock(Connection.class); + + final NetworkRulesSystemVmCommand netRules = new NetworkRulesSystemVmCommand("Test", VirtualMachine.Type.User); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + + final Answer answer = wrapper.execute(netRules, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testNetworkRulesSystemVmCommandNonUser() { + final Connection conn = Mockito.mock(Connection.class); + + final NetworkRulesSystemVmCommand netRules = new NetworkRulesSystemVmCommand("Test", VirtualMachine.Type.DomainRouter); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.callHostPlugin(conn, "vmops", "default_network_rules_systemvm", "vmName", netRules.getVmName())).thenReturn("true"); + + final Answer answer = wrapper.execute(netRules, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testNetworkRulesSystemVmCommandNonUserFalse() { + final Connection conn = Mockito.mock(Connection.class); + + final NetworkRulesSystemVmCommand netRules = new NetworkRulesSystemVmCommand("Test", VirtualMachine.Type.DomainRouter); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.callHostPlugin(conn, "vmops", "default_network_rules_systemvm", "vmName", netRules.getVmName())).thenReturn("false"); + + final Answer answer = wrapper.execute(netRules, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testOvsCreateTunnelCommandSuccess() { + final String bridge = "tunnel"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsCreateTunnelCommand createTunnel = new OvsCreateTunnelCommand("127.0.0.1", 1, 1l, 2l, 1l, "127.0.1.1", "net01", "cd84c713-f448-48c9-ba25-e6740d4a9003"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.findOrCreateTunnelNetwork(conn, createTunnel.getNetworkName())).thenReturn(network); + when(network.getBridge(conn)).thenReturn(bridge); + + when(citrixResourceBase.callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", createTunnel.getRemoteIp(), + "key", createTunnel.getKey().toString(), "from", + createTunnel.getFrom().toString(), "to", createTunnel.getTo().toString(), "cloudstack-network-id", + createTunnel.getNetworkUuid())).thenReturn("SUCCESS:0"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(createTunnel, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + verify(citrixResourceBase, times(1)).configureTunnelNetwork(conn, createTunnel.getNetworkId(), createTunnel.getFrom(), createTunnel.getNetworkName()); + + assertTrue(answer.getResult()); + } + + @Test + public void testOvsCreateTunnelCommandFail() { + final String bridge = "tunnel"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsCreateTunnelCommand createTunnel = new OvsCreateTunnelCommand("127.0.0.1", 1, 1l, 2l, 1l, "127.0.1.1", "net01", "cd84c713-f448-48c9-ba25-e6740d4a9003"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.findOrCreateTunnelNetwork(conn, createTunnel.getNetworkName())).thenReturn(network); + when(network.getBridge(conn)).thenReturn(bridge); + + when(citrixResourceBase.callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", createTunnel.getRemoteIp(), + "key", createTunnel.getKey().toString(), "from", + createTunnel.getFrom().toString(), "to", createTunnel.getTo().toString(), "cloudstack-network-id", + createTunnel.getNetworkUuid())).thenReturn("FAIL:1"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(createTunnel, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + verify(citrixResourceBase, times(1)).configureTunnelNetwork(conn, createTunnel.getNetworkId(), createTunnel.getFrom(), createTunnel.getNetworkName()); + + assertFalse(answer.getResult()); + } + + @Test + public void testOvsCreateTunnelCommandNoNet() { + final Connection conn = Mockito.mock(Connection.class); + + final OvsCreateTunnelCommand createTunnel = new OvsCreateTunnelCommand("127.0.0.1", 1, 1l, 2l, 1l, "127.0.1.1", "net01", "cd84c713-f448-48c9-ba25-e6740d4a9003"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.findOrCreateTunnelNetwork(conn, createTunnel.getNetworkName())).thenReturn(null); + + final Answer answer = wrapper.execute(createTunnel, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testOvsSetupBridgeCommand() { + final Connection conn = Mockito.mock(Connection.class); + + final OvsSetupBridgeCommand setupBridge = new OvsSetupBridgeCommand("Test", 1l, 1l); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + + + final Answer answer = wrapper.execute(setupBridge, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + verify(citrixResourceBase, times(1)).findOrCreateTunnelNetwork(conn, setupBridge.getBridgeName()); + verify(citrixResourceBase, times(1)).configureTunnelNetwork(conn, setupBridge.getNetworkId(), setupBridge.getHostId(), setupBridge.getBridgeName()); + + assertTrue(answer.getResult()); + } + + @Test + public void testOvsDestroyBridgeCommand() { + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsDestroyBridgeCommand destroyBridge = new OvsDestroyBridgeCommand(1l, "bridge", 1l); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.findOrCreateTunnelNetwork(conn, destroyBridge.getBridgeName())).thenReturn(network); + + final Answer answer = wrapper.execute(destroyBridge, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + try { + verify(citrixResourceBase, times(1)).cleanUpTmpDomVif(conn, network); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + verify(citrixResourceBase, times(1)).destroyTunnelNetwork(conn, network, destroyBridge.getHostId()); + + assertTrue(answer.getResult()); + } + + @Test + public void testOvsDestroyTunnelCommandSuccess() { + final String bridge = "tunnel"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsDestroyTunnelCommand destroyTunnel = new OvsDestroyTunnelCommand(1l, "net01", "port11"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.findOrCreateTunnelNetwork(conn, destroyTunnel.getBridgeName())).thenReturn(network); + when(network.getBridge(conn)).thenReturn(bridge); + + when(citrixResourceBase.callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", destroyTunnel.getInPortName())).thenReturn("SUCCESS"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(destroyTunnel, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testOvsDestroyTunnelCommandFailed() { + final String bridge = "tunnel"; + final Connection conn = Mockito.mock(Connection.class); + final Network network = Mockito.mock(Network.class); + + final OvsDestroyTunnelCommand destroyTunnel = new OvsDestroyTunnelCommand(1l, "net01", "port11"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.findOrCreateTunnelNetwork(conn, destroyTunnel.getBridgeName())).thenReturn(network); + when(network.getBridge(conn)).thenReturn(bridge); + + when(citrixResourceBase.callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", destroyTunnel.getInPortName())).thenReturn("FAILED"); + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(destroyTunnel, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testUpdateHostPasswordCommand() { + final UpdateHostPasswordCommand updatePwd = new UpdateHostPasswordCommand("test", "123"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(updatePwd, citrixResourceBase); + + assertTrue(answer.getResult()); + } + + @Test + public void testClusterVMMetaDataSyncCommand() { + final String uuid = "6172d8b7-ba10-4a70-93f9-ecaf41f51d53"; + + final Connection conn = Mockito.mock(Connection.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + + final Pool pool = PowerMockito.mock(Pool.class); + final Pool.Record poolr = Mockito.mock(Pool.Record.class); + final Host.Record hostr = Mockito.mock(Host.Record.class); + final Host master = Mockito.mock(Host.class); + + final ClusterVMMetaDataSyncCommand vmDataSync = new ClusterVMMetaDataSyncCommand(10, 1l); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.getHost()).thenReturn(xsHost); + when(citrixResourceBase.getHost().getUuid()).thenReturn(uuid); + + PowerMockito.mockStatic(Pool.Record.class); + + when(pool.getRecord(conn)).thenReturn(poolr); + poolr.master = master; + when(poolr.master.getRecord(conn)).thenReturn(hostr); + hostr.uuid = uuid; + + } catch (final BadServerResponse e) { + fail(e.getMessage()); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(vmDataSync, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testCheckNetworkCommandSuccess() { + final List setupInfos = new ArrayList(); + + final CheckNetworkCommand checkNet = new CheckNetworkCommand(setupInfos); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(checkNet, citrixResourceBase); + + assertTrue(answer.getResult()); + } + + @Test + public void testCheckNetworkCommandFailure() { + final PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo(); + + final List setupInfos = new ArrayList(); + setupInfos.add(info); + + final CheckNetworkCommand checkNet = new CheckNetworkCommand(setupInfos); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(checkNet, citrixResourceBase); + + assertFalse(answer.getResult()); + } + + @Test + public void testPlugNicCommand() { + final NicTO nicTO = Mockito.mock(NicTO.class); + final Connection conn = Mockito.mock(Connection.class); + + final PlugNicCommand plugNic = new PlugNicCommand(nicTO, "Test", VirtualMachine.Type.User); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + + final Answer answer = wrapper.execute(plugNic, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testUnPlugNicCommand() { + final NicTO nicTO = Mockito.mock(NicTO.class); + final Connection conn = Mockito.mock(Connection.class); + + final UnPlugNicCommand unplugNic = new UnPlugNicCommand(nicTO, "Test"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + + final Answer answer = wrapper.execute(unplugNic, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testCreateVMSnapshotCommand() { + final Connection conn = Mockito.mock(Connection.class); + + final VMSnapshotTO snapshotTO = Mockito.mock(VMSnapshotTO.class); + final List volumeTOs = new ArrayList(); + + final CreateVMSnapshotCommand vmSnapshot = new CreateVMSnapshotCommand("Test", snapshotTO, volumeTOs, "Debian"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + + final Answer answer = wrapper.execute(vmSnapshot, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testDeleteVMSnapshotCommand() { + final Connection conn = Mockito.mock(Connection.class); + + final VMSnapshotTO snapshotTO = Mockito.mock(VMSnapshotTO.class); + final List volumeTOs = new ArrayList(); + + final DeleteVMSnapshotCommand vmSnapshot = new DeleteVMSnapshotCommand("Test", snapshotTO, volumeTOs, "Debian"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + + final Answer answer = wrapper.execute(vmSnapshot, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testRevertToVMSnapshotCommand() { + final Connection conn = Mockito.mock(Connection.class); + + final VMSnapshotTO snapshotTO = Mockito.mock(VMSnapshotTO.class); + final List volumeTOs = new ArrayList(); + + final RevertToVMSnapshotCommand vmSnapshot = new RevertToVMSnapshotCommand("Test", snapshotTO, volumeTOs, "Debian"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + + final Answer answer = wrapper.execute(vmSnapshot, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testNetworkRulesVmSecondaryIpCommandSuccess() { + final Connection conn = Mockito.mock(Connection.class); + + final NetworkRulesVmSecondaryIpCommand rulesVm = new NetworkRulesVmSecondaryIpCommand("Test", VirtualMachine.Type.User); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", rulesVm.getVmName(), "vmMac", rulesVm.getVmMac(), + "vmSecIp", rulesVm.getVmSecIp(), "action", rulesVm.getAction())).thenReturn("true"); + + final Answer answer = wrapper.execute(rulesVm, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testNetworkRulesVmSecondaryIpCommandFailure() { + final Connection conn = Mockito.mock(Connection.class); + + final NetworkRulesVmSecondaryIpCommand rulesVm = new NetworkRulesVmSecondaryIpCommand("Test", VirtualMachine.Type.User); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", rulesVm.getVmName(), "vmMac", rulesVm.getVmMac(), + "vmSecIp", rulesVm.getVmSecIp(), "action", rulesVm.getAction())).thenReturn("false"); + + final Answer answer = wrapper.execute(rulesVm, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testScaleVmCommand() { + final String uuid = "6172d8b7-ba10-4a70-93f9-ecaf41f51d53"; + + final VirtualMachineTO machineTO = Mockito.mock(VirtualMachineTO.class); + final Connection conn = Mockito.mock(Connection.class); + final XsHost xsHost = Mockito.mock(XsHost.class); + final Host host = Mockito.mock(Host.class); + + final ScaleVmCommand scaleVm = new ScaleVmCommand(machineTO); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getHost()).thenReturn(xsHost); + when(citrixResourceBase.getHost().getUuid()).thenReturn(uuid); + + try { + when(citrixResourceBase.isDmcEnabled(conn, host)).thenReturn(true); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + final Answer answer = wrapper.execute(scaleVm, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testPvlanSetupCommandDhcpSuccess() { + final String label = "net"; + + final Connection conn = Mockito.mock(Connection.class); + final XsLocalNetwork network = Mockito.mock(XsLocalNetwork.class); + final Network network2 = Mockito.mock(Network.class); + + final PvlanSetupCommand lanSetup = PvlanSetupCommand.createDhcpSetup("add", URI.create("http://127.0.0.1"), "tag", "dhcp", "0:0:0:0:0:0", "127.0.0.1"); + + final String primaryPvlan = lanSetup.getPrimary(); + final String isolatedPvlan = lanSetup.getIsolated(); + final String op = lanSetup.getOp(); + final String dhcpName = lanSetup.getDhcpName(); + final String dhcpMac = lanSetup.getDhcpMac(); + final String dhcpIp = lanSetup.getDhcpIp(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.getNativeNetworkForTraffic(conn, TrafficType.Guest, "tag")).thenReturn(network); + when(network.getNetwork()).thenReturn(network2); + when(network2.getNameLabel(conn)).thenReturn(label); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + when(citrixResourceBase.callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", label, "primary-pvlan", primaryPvlan, "isolated-pvlan", + isolatedPvlan, "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac)).thenReturn("true"); + + final Answer answer = wrapper.execute(lanSetup, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testPvlanSetupCommandDhcpFailure() { + final String label = "net"; + + final Connection conn = Mockito.mock(Connection.class); + final XsLocalNetwork network = Mockito.mock(XsLocalNetwork.class); + final Network network2 = Mockito.mock(Network.class); + + final PvlanSetupCommand lanSetup = PvlanSetupCommand.createDhcpSetup("add", URI.create("http://127.0.0.1"), "tag", "dhcp", "0:0:0:0:0:0", "127.0.0.1"); + + final String primaryPvlan = lanSetup.getPrimary(); + final String isolatedPvlan = lanSetup.getIsolated(); + final String op = lanSetup.getOp(); + final String dhcpName = lanSetup.getDhcpName(); + final String dhcpMac = lanSetup.getDhcpMac(); + final String dhcpIp = lanSetup.getDhcpIp(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.getNativeNetworkForTraffic(conn, TrafficType.Guest, "tag")).thenReturn(network); + when(network.getNetwork()).thenReturn(network2); + when(network2.getNameLabel(conn)).thenReturn(label); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + when(citrixResourceBase.callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", label, "primary-pvlan", primaryPvlan, "isolated-pvlan", + isolatedPvlan, "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac)).thenReturn("false"); + + final Answer answer = wrapper.execute(lanSetup, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testPvlanSetupCommandVmSuccess() { + final String label = "net"; + + final Connection conn = Mockito.mock(Connection.class); + final XsLocalNetwork network = Mockito.mock(XsLocalNetwork.class); + final Network network2 = Mockito.mock(Network.class); + + final PvlanSetupCommand lanSetup = PvlanSetupCommand.createVmSetup("add", URI.create("http://127.0.0.1"), "tag", "0:0:0:0:0:0"); + + final String primaryPvlan = lanSetup.getPrimary(); + final String isolatedPvlan = lanSetup.getIsolated(); + final String op = lanSetup.getOp(); + final String vmMac = lanSetup.getVmMac(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.getNativeNetworkForTraffic(conn, TrafficType.Guest, "tag")).thenReturn(network); + when(network.getNetwork()).thenReturn(network2); + when(network2.getNameLabel(conn)).thenReturn(label); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + when(citrixResourceBase.callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", label, "primary-pvlan", primaryPvlan, "isolated-pvlan", + isolatedPvlan, "vm-mac", vmMac)).thenReturn("true"); + + final Answer answer = wrapper.execute(lanSetup, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testPvlanSetupCommandVmFailure() { + final String label = "net"; + + final Connection conn = Mockito.mock(Connection.class); + final XsLocalNetwork network = Mockito.mock(XsLocalNetwork.class); + final Network network2 = Mockito.mock(Network.class); + + final PvlanSetupCommand lanSetup = PvlanSetupCommand.createVmSetup("add", URI.create("http://127.0.0.1"), "tag", "0:0:0:0:0:0"); + + final String primaryPvlan = lanSetup.getPrimary(); + final String isolatedPvlan = lanSetup.getIsolated(); + final String op = lanSetup.getOp(); + final String vmMac = lanSetup.getVmMac(); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + try { + when(citrixResourceBase.getNativeNetworkForTraffic(conn, TrafficType.Guest, "tag")).thenReturn(network); + when(network.getNetwork()).thenReturn(network2); + when(network2.getNameLabel(conn)).thenReturn(label); + } catch (final XenAPIException e) { + fail(e.getMessage()); + } catch (final XmlRpcException e) { + fail(e.getMessage()); + } + + when(citrixResourceBase.callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", label, "primary-pvlan", primaryPvlan, "isolated-pvlan", + isolatedPvlan, "vm-mac", vmMac)).thenReturn("false"); + + final Answer answer = wrapper.execute(lanSetup, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testPerformanceMonitorCommandSuccess() { + final Connection conn = Mockito.mock(Connection.class); + + final PerformanceMonitorCommand performanceMonitor = new PerformanceMonitorCommand(new Hashtable(), 200); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getPerfMon(conn, performanceMonitor.getParams(), performanceMonitor.getWait())).thenReturn("performance"); + + final Answer answer = wrapper.execute(performanceMonitor, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testPerformanceMonitorCommandFailure() { + final Connection conn = Mockito.mock(Connection.class); + + final PerformanceMonitorCommand performanceMonitor = new PerformanceMonitorCommand(new Hashtable(), 200); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getConnection()).thenReturn(conn); + when(citrixResourceBase.getPerfMon(conn, performanceMonitor.getParams(), performanceMonitor.getWait())).thenReturn(null); + + final Answer answer = wrapper.execute(performanceMonitor, citrixResourceBase); + + verify(citrixResourceBase, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testIpAssocVpcCommand() { + final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class); + final IpAddressTO [] ips = new IpAddressTO[0]; + + final IpAssocVpcCommand ipAssociation = new IpAssocVpcCommand(ips); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getVirtualRoutingResource()).thenReturn(routingResource); + + final Answer answer = wrapper.execute(ipAssociation, citrixResourceBase); + + verify(routingResource, times(1)).executeRequest(ipAssociation); + + // Requires more testing, but the VirtualResourceRouting is quite big. + assertNull(answer); + } + + @Test + public void testIpAssocCommand() { + final VirtualRoutingResource routingResource = Mockito.mock(VirtualRoutingResource.class); + final IpAddressTO [] ips = new IpAddressTO[0]; + + final IpAssocCommand ipAssociation = new IpAssocCommand(ips); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(citrixResourceBase.getVirtualRoutingResource()).thenReturn(routingResource); + + final Answer answer = wrapper.execute(ipAssociation, citrixResourceBase); + + verify(routingResource, times(1)).executeRequest(ipAssociation); + + // Requires more testing, but the VirtualResourceRouting is quite big. + assertNull(answer); + } +} + +class NotAValidCommand extends Command { + + @Override + public boolean executeInSequence() { + return false; + } + +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FP1WrapperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FP1WrapperTest.java new file mode 100644 index 00000000000..578302ecb4d --- /dev/null +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56FP1WrapperTest.java @@ -0,0 +1,49 @@ +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.FenceCommand; +import com.cloud.host.Host; +import com.cloud.hypervisor.xenserver.resource.XenServer56FP1Resource; +import com.cloud.vm.VMInstanceVO; +import com.xensource.xenapi.Connection; + +@RunWith(PowerMockRunner.class) +public class XenServer56FP1WrapperTest { + + @Mock + private XenServer56FP1Resource xenServer56Resource; + + @Test + public void testFenceCommand() { + final VMInstanceVO vm = Mockito.mock(VMInstanceVO.class); + final Host host = Mockito.mock(Host.class); + + final Connection conn = Mockito.mock(Connection.class); + + final FenceCommand fenceCommand = new FenceCommand(vm, host); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(xenServer56Resource.getConnection()).thenReturn(conn); + + final Answer answer = wrapper.execute(fenceCommand, xenServer56Resource); + + verify(xenServer56Resource, times(1)).getConnection(); + verify(xenServer56Resource, times(1)).checkHeartbeat(fenceCommand.getHostGuid()); + + assertFalse(answer.getResult()); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56WrapperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56WrapperTest.java new file mode 100644 index 00000000000..a004344cfa8 --- /dev/null +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer56WrapperTest.java @@ -0,0 +1,161 @@ +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckOnHostCommand; +import com.cloud.agent.api.FenceCommand; +import com.cloud.agent.api.NetworkUsageCommand; +import com.cloud.agent.api.SetupCommand; +import com.cloud.host.Host; +import com.cloud.host.HostEnvironment; +import com.cloud.hypervisor.xenserver.resource.XenServer56Resource; +import com.cloud.hypervisor.xenserver.resource.XsHost; +import com.cloud.utils.ExecutionResult; +import com.cloud.vm.VMInstanceVO; +import com.xensource.xenapi.Connection; + +@RunWith(PowerMockRunner.class) +public class XenServer56WrapperTest { + + @Mock + private XenServer56Resource xenServer56Resource; + + @Test + public void testCheckOnHostCommand() { + final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class); + final CheckOnHostCommand onHostCommand = new CheckOnHostCommand(host); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final Answer answer = wrapper.execute(onHostCommand, xenServer56Resource); + + assertTrue(answer.getResult()); + } + + @Test + public void testFenceCommand() { + final VMInstanceVO vm = Mockito.mock(VMInstanceVO.class); + final Host host = Mockito.mock(Host.class); + + final Connection conn = Mockito.mock(Connection.class); + + final FenceCommand fenceCommand = new FenceCommand(vm, host); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(xenServer56Resource.getConnection()).thenReturn(conn); + + final Answer answer = wrapper.execute(fenceCommand, xenServer56Resource); + + verify(xenServer56Resource, times(1)).getConnection(); + verify(xenServer56Resource, times(1)).checkHeartbeat(fenceCommand.getHostGuid()); + + assertFalse(answer.getResult()); + } + + @Test + public void testNetworkUsageCommandSuccess() { + final Connection conn = Mockito.mock(Connection.class); + + final NetworkUsageCommand networkCommand = new NetworkUsageCommand("192.168.10.10", "domRName", false, "192.168.10.1"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(xenServer56Resource.getConnection()).thenReturn(conn); + when(xenServer56Resource.getNetworkStats(conn, networkCommand.getPrivateIP())).thenReturn(new long[]{1, 1}); + + final Answer answer = wrapper.execute(networkCommand, xenServer56Resource); + + verify(xenServer56Resource, times(1)).getConnection(); + + assertTrue(answer.getResult()); + } + + @Test + public void testNetworkUsageCommandFailure() { + final Connection conn = Mockito.mock(Connection.class); + + final NetworkUsageCommand networkCommand = new NetworkUsageCommand("192.168.10.10", "domRName", false, "192.168.10.1"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(xenServer56Resource.getConnection()).thenReturn(conn); + when(xenServer56Resource.getNetworkStats(conn, networkCommand.getPrivateIP())).thenReturn(new long[0]); + + final Answer answer = wrapper.execute(networkCommand, xenServer56Resource); + + verify(xenServer56Resource, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } + + @Test + public void testNetworkUsageCommandCreateVpc() { + final ExecutionResult executionResult = Mockito.mock(ExecutionResult.class); + + final NetworkUsageCommand networkCommand = new NetworkUsageCommand("192.168.10.10", "domRName", true, "192.168.10.1", "10.1.1.1/24"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final String args = " -l 192.168.10.1 -c -v 10.1.1.1/24"; + when(xenServer56Resource.executeInVR(networkCommand.getPrivateIP(), "vpc_netusage.sh", args)).thenReturn(executionResult); + when(executionResult.isSuccess()).thenReturn(true); + + final Answer answer = wrapper.execute(networkCommand, xenServer56Resource); + + assertTrue(answer.getResult()); + } + + @Test + public void testNetworkUsageCommandCreateVpcFailure() { + final ExecutionResult executionResult = Mockito.mock(ExecutionResult.class); + + final NetworkUsageCommand networkCommand = new NetworkUsageCommand("192.168.10.10", "domRName", true, "192.168.10.1", "10.1.1.1/24"); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + final String args = " -l 192.168.10.1 -c -v 10.1.1.1/24"; + when(xenServer56Resource.executeInVR(networkCommand.getPrivateIP(), "vpc_netusage.sh", args)).thenReturn(executionResult); + when(executionResult.isSuccess()).thenReturn(false); + + final Answer answer = wrapper.execute(networkCommand, xenServer56Resource); + + assertFalse(answer.getResult()); + } + + @Test + public void testSetupCommand() { + final XsHost xsHost = Mockito.mock(XsHost.class); + final HostEnvironment env = Mockito.mock(HostEnvironment.class); + + final SetupCommand setupCommand = new SetupCommand(env); + + final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance(); + assertNotNull(wrapper); + + when(xenServer56Resource.getHost()).thenReturn(xsHost); + + final Answer answer = wrapper.execute(setupCommand, xenServer56Resource); + verify(xenServer56Resource, times(1)).getConnection(); + + assertFalse(answer.getResult()); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer610WrapperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer610WrapperTest.java new file mode 100644 index 00000000000..edc4b6d93d0 --- /dev/null +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer610WrapperTest.java @@ -0,0 +1,56 @@ +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckNetworkCommand; +import com.cloud.agent.api.SetupCommand; +import com.cloud.host.HostEnvironment; +import com.cloud.hypervisor.xenserver.resource.XenServer610Resource; +import com.cloud.network.PhysicalNetworkSetupInfo; + +@RunWith(PowerMockRunner.class) +public class XenServer610WrapperTest { + + @Mock + protected XenServer610Resource xenServer610Resource; + + @Test + public void testCheckNetworkCommandFailure() { + final XenServer610Resource xenServer610Resource = new XenServer610Resource(); + + final PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo(); + + final List setupInfos = new ArrayList(); + setupInfos.add(info); + + final CheckNetworkCommand checkNet = new CheckNetworkCommand(setupInfos); + + final Answer answer = xenServer610Resource.executeRequest(checkNet); + + assertTrue(answer.getResult()); + } + + @Test + public void testSetupCommand() { + final XenServer610Resource xenServer610Resource = new XenServer610Resource(); + + final HostEnvironment env = Mockito.mock(HostEnvironment.class); + + final SetupCommand setupCommand = new SetupCommand(env); + + final Answer answer = xenServer610Resource.executeRequest(setupCommand); + + assertFalse(answer.getResult()); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer620WrapperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer620WrapperTest.java new file mode 100644 index 00000000000..74fc9cd04c7 --- /dev/null +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/XenServer620WrapperTest.java @@ -0,0 +1,35 @@ +package com.cloud.hypervisor.xenserver.resource.wrapper; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.CheckNetworkCommand; +import com.cloud.hypervisor.xenserver.resource.XenServer620Resource; +import com.cloud.network.PhysicalNetworkSetupInfo; + +@RunWith(PowerMockRunner.class) +public class XenServer620WrapperTest { + + @Test + public void testCheckNetworkCommandFailure() { + final XenServer620Resource xenServer620Resource = new XenServer620Resource(); + + final PhysicalNetworkSetupInfo info = new PhysicalNetworkSetupInfo(); + + final List setupInfos = new ArrayList(); + setupInfos.add(info); + + final CheckNetworkCommand checkNet = new CheckNetworkCommand(setupInfos); + + final Answer answer = xenServer620Resource.executeRequest(checkNet); + + assertTrue(answer.getResult()); + } +} \ No newline at end of file