You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by al...@apache.org on 2012/06/29 02:45:07 UTC
[47/50] [abbrv] Moving out XenServer support code into
plugins/hypervisors/xen
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpServerResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpServerResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpServerResource.java
new file mode 100644
index 0000000..8325b06
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpServerResource.java
@@ -0,0 +1,103 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+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.NetworkUsageAnswer;
+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.VM;
+import com.xensource.xenapi.Types.XenAPIException;
+
+@Local(value=ServerResource.class)
+public class XcpServerResource extends CitrixResourceBase {
+ private final static Logger s_logger = Logger.getLogger(XcpServerResource.class);
+
+ public XcpServerResource() {
+ super();
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof NetworkUsageCommand) {
+ return execute((NetworkUsageCommand) cmd);
+ } else {
+ return super.executeRequest(cmd);
+ }
+ }
+
+ @Override
+ protected String getGuestOsType(String stdType, boolean bootFromCD) {
+ return CitrixHelper.getXcpGuestOsType(stdType);
+ }
+
+ @Override
+ protected List<File> getPatchFiles() {
+ List<File> files = new ArrayList<File>();
+ String patch = "scripts/vm/hypervisor/xenserver/xcpserver/patch";
+ String patchfilePath = Script.findScript("", patch);
+ if (patchfilePath == null) {
+ throw new CloudRuntimeException("Unable to find patch file " + patch);
+ }
+ File file = new File(patchfilePath);
+ files.add(file);
+ return files;
+ }
+
+ @Override
+ protected void setMemory(Connection conn, VM vm, long memsize) throws XmlRpcException, XenAPIException {
+
+ vm.setMemoryStaticMin(conn, 33554432L);
+ vm.setMemoryDynamicMin(conn, 33554432L);
+ vm.setMemoryDynamicMax(conn, 33554432L);
+ vm.setMemoryStaticMax(conn, 33554432L);
+
+ vm.setMemoryStaticMax(conn, memsize);
+ vm.setMemoryDynamicMax(conn, memsize);
+ vm.setMemoryDynamicMin(conn, memsize);
+ vm.setMemoryStaticMin(conn, memsize);
+ }
+
+
+ protected NetworkUsageAnswer execute(NetworkUsageCommand 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);
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java
new file mode 100644
index 0000000..d689393
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java
@@ -0,0 +1,213 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+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.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.resource.ServerResource;
+import com.cloud.storage.Volume;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Console;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VM;
+import com.xensource.xenapi.Types.XenAPIException;
+
+@Local(value=ServerResource.class)
+public class XenServer56FP1Resource extends XenServer56Resource {
+ private static final Logger s_logger = Logger.getLogger(XenServer56FP1Resource.class);
+
+ public XenServer56FP1Resource() {
+ super();
+ }
+
+ @Override
+ protected String getGuestOsType(String stdType, boolean bootFromCD) {
+ return CitrixHelper.getXenServer56FP1GuestOsType(stdType, bootFromCD);
+ }
+
+ @Override
+ protected List<File> getPatchFiles() {
+ List<File> files = new ArrayList<File>();
+ String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch";
+ String patchfilePath = Script.findScript("" , patch);
+ if ( patchfilePath == null ) {
+ throw new CloudRuntimeException("Unable to find patch file " + patch);
+ }
+ File file = new File(patchfilePath);
+ files.add(file);
+ return files;
+ }
+
+
+ @Override
+ protected FenceAnswer execute(FenceCommand cmd) {
+ Connection conn = getConnection();
+ try {
+ String result = callHostPluginPremium(conn, "check_heartbeat", "host", cmd.getHostGuid(), "interval",
+ Integer.toString(_heartbeatInterval * 2));
+ if (!result.contains("> DEAD <")) {
+ 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<VM> vms = VM.getByNameLabel(conn, cmd.getVmName());
+ for (VM vm : vms) {
+ Set<VDI> vdis = new HashSet<VDI>();
+ Set<VBD> vbds = vm.getVBDs(conn);
+ for( VBD vbd : vbds ) {
+ VDI vdi = vbd.getVDI(conn);
+ if( !isRefNull(vdi) ) {
+ vdis.add(vdi);
+ }
+ }
+ synchronized (_cluster.intern()) {
+ s_vms.remove(_cluster, _name, vm.getNameLabel(conn));
+ }
+ s_logger.info("Fence command for VM " + cmd.getVmName());
+ vm.powerStateReset(conn);
+ vm.destroy(conn);
+ for (VDI vdi : vdis) {
+ Map<String, String> 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());
+ }
+ }
+
+ @Override
+ protected VM createVmFromTemplate(Connection conn, VirtualMachineTO vmSpec, Host host) throws XenAPIException, XmlRpcException {
+ String guestOsTypeName = getGuestOsType(vmSpec.getOs(), vmSpec.getBootloader() == BootloaderType.CD);
+ Set<VM> templates = VM.getByNameLabel(conn, guestOsTypeName);
+ assert templates.size() == 1 : "Should only have 1 template but found " + templates.size();
+ VM template = templates.iterator().next();
+
+ VM.Record record = template.getRecord(conn);
+ record.affinity = host;
+ record.otherConfig.remove("disks");
+ record.otherConfig.remove("default_template");
+ record.isATemplate = false;
+ record.nameLabel = vmSpec.getName();
+ record.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY;
+ record.actionsAfterShutdown = Types.OnNormalExit.DESTROY;
+ record.memoryDynamicMax = vmSpec.getMinRam();
+ record.memoryDynamicMin = vmSpec.getMinRam();
+ record.memoryStaticMax = vmSpec.getMinRam();
+ record.memoryStaticMin = vmSpec.getMinRam();
+ record.VCPUsMax = (long) vmSpec.getCpus();
+ record.VCPUsAtStartup = (long) vmSpec.getCpus();
+ record.consoles.clear();
+
+ VM vm = VM.create(conn, record);
+ VM.Record vmr = vm.getRecord(conn);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Created VM " + vmr.uuid + " for " + vmSpec.getName());
+ }
+
+ Map<String, String> vcpuParams = new HashMap<String, String>();
+
+ Integer speed = vmSpec.getSpeed();
+ if (speed != null) {
+
+ int cpuWeight = _maxWeight; // cpu_weight
+ int utilization = 0; // max CPU cap, default is unlimited
+
+ // weight based allocation
+ cpuWeight = (int) ((speed * 0.99) / _host.speed * _maxWeight);
+ if (cpuWeight > _maxWeight) {
+ cpuWeight = _maxWeight;
+ }
+
+ if (vmSpec.getLimitCpuUse()) {
+ utilization = (int) ((speed * 0.99) / _host.speed * 100);
+ }
+
+ vcpuParams.put("weight", Integer.toString(cpuWeight));
+ vcpuParams.put("cap", Integer.toString(utilization));
+
+ }
+
+ if (vcpuParams.size() > 0) {
+ vm.setVCPUsParams(conn, vcpuParams);
+ }
+
+ String bootArgs = vmSpec.getBootArgs();
+ if (bootArgs != null && bootArgs.length() > 0) {
+ String pvargs = vm.getPVArgs(conn);
+ pvargs = pvargs + vmSpec.getBootArgs().replaceAll(" ", "%");
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("PV args are " + pvargs);
+ }
+ vm.setPVArgs(conn, pvargs);
+ }
+
+ if (!(guestOsTypeName.startsWith("Windows") || guestOsTypeName.startsWith("Citrix") || guestOsTypeName.startsWith("Other"))) {
+ if (vmSpec.getBootloader() == BootloaderType.CD) {
+ VolumeTO[] disks = vmSpec.getDisks();
+ for (VolumeTO disk : disks) {
+ if (disk.getType() == Volume.Type.ISO && disk.getOsType() != null) {
+ String isoGuestOsName = getGuestOsType(disk.getOsType(), vmSpec.getBootloader() == BootloaderType.CD);
+ if (!isoGuestOsName.equals(guestOsTypeName)) {
+ vmSpec.setBootloader(BootloaderType.PyGrub);
+ }
+ }
+ }
+ }
+ if (vmSpec.getBootloader() == BootloaderType.CD) {
+ vm.setPVBootloader(conn, "eliloader");
+ if (!vm.getOtherConfig(conn).containsKey("install-repository")) {
+ vm.addToOtherConfig(conn, "install-repository", "cdrom");
+ }
+ } else if (vmSpec.getBootloader() == BootloaderType.PyGrub) {
+ vm.setPVBootloader(conn, "pygrub");
+ } else {
+ vm.destroy(conn);
+ throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader());
+ }
+ }
+ return vm;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java
new file mode 100644
index 0000000..ff0c5d7
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java
@@ -0,0 +1,307 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+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.PoolEjectCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+import com.xensource.xenapi.Bond;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Network;
+import com.xensource.xenapi.PBD;
+import com.xensource.xenapi.PIF;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.IpConfigurationMode;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VLAN;
+import com.xensource.xenapi.VM;
+
+@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 PoolEjectCommand) {
+ return execute((PoolEjectCommand) cmd);
+ } else if (cmd instanceof NetworkUsageCommand) {
+ return execute((NetworkUsageCommand) cmd);
+ } else {
+ return super.executeRequest(cmd);
+ }
+ }
+
+ @Override
+ protected void setMemory(Connection conn, VM vm, long memsize) throws XmlRpcException, XenAPIException {
+ vm.setMemoryLimits(conn, memsize, memsize, memsize, memsize);
+ }
+
+
+ @Override
+ protected String getGuestOsType(String stdType, boolean bootFromCD) {
+ return CitrixHelper.getXenServerGuestOsType(stdType, bootFromCD);
+ }
+
+
+ @Override
+ protected List<File> getPatchFiles() {
+ List<File> files = new ArrayList<File>();
+ String patch = "scripts/vm/hypervisor/xenserver/xenserver56/patch";
+ String patchfilePath = Script.findScript("", patch);
+ if (patchfilePath == null) {
+ throw new CloudRuntimeException("Unable to find patch file " + patch);
+ }
+ File file = new File(patchfilePath);
+ files.add(file);
+
+ return files;
+ }
+
+ @Override
+ protected void disableVlanNetwork(Connection conn, Network network) {
+ try {
+ 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)) {
+ continue;
+ }
+
+ VLAN vlan = pifr.VLANMasterOf;
+ if (vlan != null) {
+ String vlannum = pifr.VLAN.toString();
+ String device = pifr.device.trim();
+ if (vlannum.equals("-1")) {
+ return;
+ }
+ try {
+ vlan.destroy(conn);
+ Host host = Host.getByUuid(conn, _host.uuid);
+ 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.info("Catch " + e.getClass().getName() + ": failed to destory VLAN " + device + " on host " + _host.uuid
+ + " due to " + e.toString());
+ }
+ }
+ return;
+ }
+ } catch (XenAPIException e) {
+ 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();
+ s_logger.warn(msg, e);
+ }
+ }
+
+ @Override
+ protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) {
+ String args = null;
+ if (option.equals("get")) {
+ args = "-g";
+ } else if (option.equals("create")) {
+ args = "-c";
+ } else if (option.equals("reset")) {
+ args = "-r";
+ } else if (option.equals("addVif")) {
+ args = "-a";
+ args += vif;
+ } else if (option.equals("deleteVif")) {
+ args = "-d";
+ args += vif;
+ }
+
+ args += " -i ";
+ args += privateIpAddress;
+ return callHostPlugin(conn, "vmops", "networkUsage", "args", args);
+ }
+
+ protected NetworkUsageAnswer execute(NetworkUsageCommand 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);
+ }
+ }
+
+ @Override
+ protected Answer execute(PoolEjectCommand cmd) {
+ Connection conn = getConnection();
+ String hostuuid = cmd.getHostuuid();
+ try {
+ Host host = Host.getByUuid(conn, hostuuid);
+ // remove all tags cloud stack add before eject
+ Host.Record hr = host.getRecord(conn);
+ Iterator<String> it = hr.tags.iterator();
+ while (it.hasNext()) {
+ String tag = it.next();
+ if (tag.contains("cloud-heartbeat-")) {
+ it.remove();
+ }
+ }
+ return super.execute(cmd);
+
+ } catch (XenAPIException e) {
+ String msg = "Unable to eject host " + _host.uuid + " due to " + e.toString();
+ s_logger.warn(msg, e);
+ return new Answer(cmd, false, msg);
+ } catch (Exception e) {
+ s_logger.warn("Unable to eject host " + _host.uuid, e);
+ String msg = "Unable to eject host " + _host.uuid + " due to " + e.getMessage();
+ s_logger.warn(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+
+ }
+
+ protected FenceAnswer execute(FenceCommand cmd) {
+ Connection conn = getConnection();
+ try {
+ String result = callHostPluginPremium(conn, "check_heartbeat", "host", cmd.getHostGuid(), "interval",
+ Integer.toString(_heartbeatInterval * 2));
+ if (!result.contains("> DEAD <")) {
+ 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<VM> vms = VM.getByNameLabel(conn, cmd.getVmName());
+ for (VM vm : vms) {
+ synchronized (_cluster.intern()) {
+ s_vms.remove(_cluster, _name, vm.getNameLabel(conn));
+ }
+ 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 {
+ dest.reconfigureIp(conn, spr.ipConfigurationMode, spr.IP, spr.netmask, spr.gateway, spr.DNS);
+ Host.managementReconfigure(conn, dest);
+ String hostUuid = null;
+ int count = 0;
+ while (count < 10) {
+ try {
+ Thread.sleep(10000);
+ hostUuid = host.getUuid(conn);
+ if (hostUuid != null) {
+ break;
+ }
+ } catch (XmlRpcException e) {
+ s_logger.debug("Waiting for host to come back: " + e.getMessage());
+ } catch (XenAPIException e) {
+ s_logger.debug("Waiting for host to come back: " + e.getMessage());
+ } catch (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, IpConfigurationMode.NONE, null, null, null, null);
+ return true;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+ pingXenServer();
+ StartupCommand[] cmds = super.initialize();
+ return cmds;
+ }
+
+ @Override
+ protected CheckOnHostAnswer execute(CheckOnHostCommand cmd) {
+ try {
+ Connection conn = getConnection();
+ String result = callHostPluginPremium(conn, "check_heartbeat", "host", cmd.getHost().getGuid(), "interval",
+ Integer.toString(_heartbeatInterval * 2));
+ if (result == null) {
+ return new CheckOnHostAnswer(cmd, "Unable to call plugin");
+ }
+ if (result.contains("> DEAD <")) {
+ s_logger.debug("Heart beat is gone so dead.");
+ return new CheckOnHostAnswer(cmd, false, "Heart Beat is done");
+ } else if (result.contains("> ALIVE <")) {
+ s_logger.debug("Heart beat is still going");
+ return new CheckOnHostAnswer(cmd, true, "Heartbeat is still going");
+ }
+ return new CheckOnHostAnswer(cmd, null, "Unable to determine");
+ } catch (Exception e) {
+ s_logger.warn("Unable to fence", e);
+ return new CheckOnHostAnswer(cmd, e.getMessage());
+ }
+ }
+
+ public XenServer56Resource() {
+ super();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56SP2Resource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56SP2Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56SP2Resource.java
new file mode 100644
index 0000000..420d4df
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56SP2Resource.java
@@ -0,0 +1,56 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+
+import java.io.File;
+import java.util.ArrayList;
+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();
+ _xs_memory_used = 128 * 1024 * 1024L;
+ _xs_virtualization_factor = 62.0/64.0;
+ }
+
+ @Override
+ protected String getGuestOsType(String stdType, boolean bootFromCD) {
+ return CitrixHelper.getXenServer56SP2GuestOsType(stdType, bootFromCD);
+ }
+
+ @Override
+ protected List<File> getPatchFiles() {
+ List<File> files = new ArrayList<File>();
+ String patch = "scripts/vm/hypervisor/xenserver/xenserver56fp1/patch";
+ String patchfilePath = Script.findScript("" , patch);
+ if ( patchfilePath == null ) {
+ throw new CloudRuntimeException("Unable to find patch file " + patch);
+ }
+ File file = new File(patchfilePath);
+ files.add(file);
+ return files;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer600Resource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer600Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer600Resource.java
new file mode 100644
index 0000000..03aa9b4
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer600Resource.java
@@ -0,0 +1,55 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+
+import java.io.File;
+import java.util.ArrayList;
+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 XenServer56FP1Resource {
+ private static final Logger s_logger = Logger.getLogger(XenServer600Resource.class);
+
+ public XenServer600Resource() {
+ super();
+ }
+
+ @Override
+ protected String getGuestOsType(String stdType, boolean bootFromCD) {
+ return CitrixHelper.getXenServer600GuestOsType(stdType, bootFromCD);
+ }
+
+ @Override
+ protected List<File> getPatchFiles() {
+ List<File> files = new ArrayList<File>();
+ String patch = "scripts/vm/hypervisor/xenserver/xenserver60/patch";
+ String patchfilePath = Script.findScript("" , patch);
+ if ( patchfilePath == null ) {
+ throw new CloudRuntimeException("Unable to find patch file " + patch);
+ }
+ File file = new File(patchfilePath);
+ files.add(file);
+ return files;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer602Resource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer602Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer602Resource.java
new file mode 100644
index 0000000..9c2e914
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer602Resource.java
@@ -0,0 +1,55 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+
+import java.io.File;
+import java.util.ArrayList;
+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 XenServer602Resource extends XenServer56FP1Resource {
+ private static final Logger s_logger = Logger.getLogger(XenServer602Resource.class);
+
+ public XenServer602Resource() {
+ super();
+ }
+
+ @Override
+ protected String getGuestOsType(String stdType, boolean bootFromCD) {
+ return CitrixHelper.getXenServer602GuestOsType(stdType, bootFromCD);
+ }
+
+ @Override
+ protected List<File> getPatchFiles() {
+ List<File> files = new ArrayList<File>();
+ String patch = "scripts/vm/hypervisor/xenserver/xenserver60/patch";
+ String patchfilePath = Script.findScript("" , patch);
+ if ( patchfilePath == null ) {
+ throw new CloudRuntimeException("Unable to find patch file " + patch);
+ }
+ File file = new File(patchfilePath);
+ files.add(file);
+ return files;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java
new file mode 100644
index 0000000..11fbd49
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java
@@ -0,0 +1,979 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.SocketException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.Set;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.client.XmlRpcClientException;
+
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.APIVersion;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.Host;
+import com.xensource.xenapi.Pool;
+import com.xensource.xenapi.Session;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadServerResponse;
+import com.xensource.xenapi.Types.UuidInvalid;
+import com.xensource.xenapi.Types.XenAPIException;
+
+public class XenServerConnectionPool {
+ private static final Logger s_logger = Logger.getLogger(XenServerConnectionPool.class);
+ protected HashMap<String /* poolUuid */, XenServerConnection> _conns = new HashMap<String, XenServerConnection>();
+ protected int _retries;
+ protected int _interval;
+ protected static boolean s_managePool = true;
+ protected static long s_sleepOnError = 10 * 1000; // in ms
+ static {
+ File file = PropertiesUtil.findConfigFile("environment.properties");
+ if (file == null) {
+ s_logger.debug("Unable to find environment.properties");
+ } else {
+ FileInputStream finputstream;
+ try {
+ finputstream = new FileInputStream(file);
+ final Properties props = new Properties();
+ props.load(finputstream);
+ finputstream.close();
+ String search = props.getProperty("manage.xenserver.pool.master");
+ if (search != null) {
+ s_managePool = Boolean.parseBoolean(search);
+ }
+ search = props.getProperty("sleep.interval.on.error");
+ if (search != null) {
+ s_sleepOnError = NumbersUtil.parseInterval(search, 10) * 1000;
+ }
+ s_logger.info("XenServer Connection Pool Configs: manage.xenserver.pool.master=" + s_managePool + "; sleep.interval.on.error=" + s_sleepOnError);
+ } catch (FileNotFoundException e) {
+ s_logger.debug("File is not found", e);
+ } catch (IOException e) {
+ s_logger.debug("IO Exception while reading file", e);
+ }
+ }
+ try {
+ javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
+ javax.net.ssl.TrustManager tm = new TrustAllManager();
+ trustAllCerts[0] = tm;
+ javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("TLS");
+ sc.init(null, trustAllCerts, null);
+ javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+ HostnameVerifier hv = new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostName, SSLSession session) {
+ return true;
+ }
+ };
+ HttpsURLConnection.setDefaultHostnameVerifier(hv);
+ } catch (Exception e) {
+ }
+ }
+
+
+ protected XenServerConnectionPool() {
+ _retries = 3;
+ _interval = 3;
+ }
+
+ private void addConnect(String poolUuid, XenServerConnection conn){
+ if( poolUuid == null ) return;
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Add master connection through " + conn.getIp() + " for pool(" + conn.getPoolUuid() + ")");
+ }
+ synchronized (_conns) {
+ _conns.put(poolUuid, conn);
+ }
+ }
+
+ private XenServerConnection getConnect(String poolUuid) {
+ if( poolUuid == null ) return null;
+ synchronized (_conns) {
+ return _conns.get(poolUuid);
+ }
+ }
+
+ private void removeConnect(String poolUuid) {
+ if( poolUuid == null ) {
+ return;
+ }
+ XenServerConnection conn = null;
+ synchronized (_conns) {
+ conn = _conns.remove(poolUuid);
+ }
+ if ( conn != null ) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Remove master connection through " + conn.getIp() + " for pool(" + conn.getPoolUuid() + ")");
+ }
+
+ }
+ }
+
+ static void forceSleep(long sec) {
+ long firetime = System.currentTimeMillis() + (sec * 1000);
+ long msec = sec * 1000;
+ while (true) {
+ if (msec < 100)
+ break;
+ try {
+ Thread.sleep(msec);
+ return;
+ } catch (InterruptedException e) {
+ msec = firetime - System.currentTimeMillis();
+ }
+ }
+ }
+
+ public boolean joinPool(Connection conn, String hostIp, String masterIp, String username, Queue<String> password) {
+ try {
+ join(conn, masterIp, username, password);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Host(" + hostIp + ") Join the pool at " + masterIp);
+ }
+ try {
+ // slave will restart xapi in 10 sec
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ }
+ for (int i = 0 ; i < 15; i++) {
+ Connection slaveConn = null;
+ Session slaveSession = null;
+ try {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Logging on as the slave to " + hostIp);
+ }
+ slaveConn = new Connection(getURL(hostIp), 10);
+ slaveSession = slaveLocalLoginWithPassword(slaveConn, username, password);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Slave logon successful. session= " + slaveSession);
+ }
+ Pool.Record pr = getPoolRecord(slaveConn);
+ Host master = pr.master;
+ String ma = master.getAddress(slaveConn);
+ if (ma.trim().equals(masterIp.trim())) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Host(" + hostIp + ") Joined the pool at " + masterIp);
+ }
+ return true;
+ }
+ } catch (Exception e) {
+ } finally {
+ if (slaveSession != null) {
+ try {
+ Session.logout(slaveConn);
+ } catch (Exception e) {
+ }
+ slaveConn.dispose();
+ }
+ }
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ } catch (Exception e) {
+ String msg = "Catch " + e.getClass().getName() + " Unable to allow host " + hostIp + " to join pool " + masterIp + " due to " + e.toString();
+ s_logger.warn(msg, e);
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Host(" + hostIp + ") unable to Join the pool at " + masterIp);
+ }
+ return false;
+ }
+
+ public void switchMaster(String slaveIp, String poolUuid,
+ Connection conn, Host host, String username, Queue<String> password,
+ int wait) throws XmlRpcException, XenAPIException {
+ synchronized (poolUuid.intern()) {
+ String masterIp = host.getAddress(conn);
+ s_logger.debug("Designating the new master to " + masterIp);
+ Pool.designateNewMaster(conn, host);
+ Connection slaveConn = null;
+ Connection masterConn = null;
+ int retry = 30;
+ for (int i = 0; i < retry; i++) {
+ forceSleep(5);
+ try {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Logging on as the slave to " + slaveIp);
+ }
+ slaveConn = null;
+ masterConn = null;
+ Session slaveSession = null;
+
+ slaveConn = new Connection(getURL(slaveIp), 10);
+ slaveSession = slaveLocalLoginWithPassword(slaveConn, username, password);
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Slave logon successful. session= "
+ + slaveSession);
+ }
+
+ Pool.Record pr = getPoolRecord(slaveConn);
+ Host master = pr.master;
+ String ma = master.getAddress(slaveConn);
+ if (!ma.trim().equals(masterIp.trim())) {
+ continue;
+ }
+ s_logger.debug("Logging on as the master to " + masterIp);
+ masterConn = new Connection(getURL(masterIp), 10);
+ loginWithPassword(masterConn, username, password, APIVersion.latest().toString());
+ removeConnect(poolUuid);
+ ensurePoolIntegrity(masterConn, masterIp, username, password, wait);
+ return;
+ } catch (Types.HostIsSlave e) {
+ s_logger.debug("HostIsSlaveException: Still waiting for the conversion to the master");
+ } catch (XmlRpcException e) {
+ s_logger.debug("XmlRpcException: Still waiting for the conversion to the master " + e.getMessage());
+ } catch (Exception e) {
+ s_logger.debug("Exception: Still waiting for the conversion to the master" + e.getMessage());
+ } finally {
+ if (masterConn != null) {
+ try {
+ Session.logout(masterConn);
+ } catch (Exception e) {
+ s_logger.debug("Unable to log out of session: "
+ + e.getMessage());
+ }
+ masterConn.dispose();
+ masterConn = null;
+ }
+ localLogout(slaveConn);
+ slaveConn = null;
+ }
+ }
+ throw new CloudRuntimeException(
+ "Unable to logon to the new master after " + retry + " retries");
+ }
+ }
+
+ private void localLogout(Connection conn) {
+ if ( conn == null )
+ return;
+ try {
+ if( s_logger.isTraceEnabled()) {
+ s_logger.trace("Logging out of the session "
+ + conn.getSessionReference());
+ }
+ Session.localLogout(conn);
+ } catch (Exception e) {
+ s_logger.debug("localLogout has problem " + e.getMessage());
+ } finally {
+ conn.dispose();
+ conn = null;
+ }
+ }
+
+ public Connection slaveConnect(String ip, String username, Queue<String> password) {
+ Connection conn = null;
+ try{
+ conn = new Connection(getURL(ip), 10);
+ slaveLocalLoginWithPassword(conn, username, password);
+ return conn;
+ }catch ( Exception e){
+ s_logger.debug("Failed to slave local login to " + ip);
+ }
+ return null;
+ }
+
+ public Connection masterConnect(String ip, String username, Queue<String> password) {
+ Connection conn = null;
+ try{
+ conn = new Connection(getURL(ip), 10);
+ s_logger.debug("Logging on as the master to " + ip);
+ loginWithPassword(conn, username, password, APIVersion.latest().toString());
+ return conn;
+ }catch ( Exception e){
+ s_logger.debug("Failed to slave local login to " + ip);
+ }
+ throw new RuntimeException("can not log in to master " + ip);
+ }
+
+
+ public String getMasterIp(String ip, String username, Queue<String> password) throws XenAPIException {
+ Connection slaveConn = null;
+ try{
+ slaveConn = new Connection(getURL(ip), 10);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Slave logon to " + ip);
+ }
+ String masterIp = null;
+ Pool.Record pr = getPoolRecord(slaveConn);
+ Host master = pr.master;
+ masterIp = master.getAddress(slaveConn);
+ return masterIp;
+ }catch(Types.SessionAuthenticationFailed e){
+ s_logger.debug("Failed to slave local login to " + ip + " due to " + e.toString());
+ throw e;
+ }catch ( Exception e){
+ s_logger.debug("Failed to slave local login to " + ip + " due to " + e.toString());
+ } finally {
+ localLogout(slaveConn);
+ slaveConn = null;
+ }
+ throw new RuntimeException("can not get master ip");
+ }
+
+
+ void PoolEmergencyTransitionToMaster(String slaveIp, String username, Queue<String> password) {
+ if (!s_managePool) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Don't manage pool on error so sleeping for " + s_sleepOnError);
+ try {
+ Thread.sleep(s_sleepOnError);
+ } catch (InterruptedException ie) {
+ }
+ }
+ return;
+ }
+
+ Connection slaveConn = null;
+ Connection c = null;
+ try{
+ s_logger.debug("Trying to transition master to " + slaveIp);
+ slaveConn = new Connection(getURL(slaveIp), 10);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
+ Pool.emergencyTransitionToMaster(slaveConn);
+ // restart xapi in 10 sec
+ forceSleep(10);
+ // check if the master of this host is set correctly.
+ c = new Connection(getURL(slaveIp), 10);
+ for (int i = 0; i < 30; i++) {
+ try {
+ loginWithPassword(c, username, password, APIVersion.latest().toString());
+ s_logger.debug("Succeeded to transition master to " + slaveIp);
+ return;
+ } catch (Types.HostIsSlave e) {
+ s_logger.debug("HostIsSlave: Still waiting for the conversion to the master " + slaveIp);
+ } catch (Exception e) {
+ s_logger.debug("Exception: Still waiting for the conversion to the master");
+ }
+ forceSleep(2);
+ }
+ throw new RuntimeException("EmergencyTransitionToMaster failed after retry 30 times");
+ } catch (Exception e) {
+ throw new RuntimeException("EmergencyTransitionToMaster failed due to " + e.getMessage());
+ } finally {
+ localLogout(slaveConn);
+ slaveConn = null;
+ if(c != null) {
+ try {
+ Session.logout(c);
+ c.dispose();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ }
+
+ private void PoolEmergencyResetMaster(String slaveIp, String masterIp, String username, Queue<String> password) {
+ if (!s_managePool) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Don't manage pool on error so sleeping for " + s_sleepOnError);
+ try {
+ Thread.sleep(s_sleepOnError);
+ } catch (InterruptedException ie) {
+ }
+ }
+ return;
+ }
+
+ Connection slaveConn = null;
+ try {
+ s_logger.debug("Trying to reset master of slave " + slaveIp
+ + " to " + masterIp);
+ slaveConn = new Connection(getURL(slaveIp), 10);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
+ Pool.emergencyResetMaster(slaveConn, masterIp);
+ forceSleep(10);
+ for (int i = 0; i < 30; i++) {
+ try {
+ slaveLocalLoginWithPassword(slaveConn, username, password);
+ Pool.Record pr = getPoolRecord(slaveConn);
+ String mIp = pr.master.getAddress(slaveConn);
+ if (mIp.trim().equals(masterIp.trim())) {
+ s_logger.debug("Succeeded to reset master of slave " + slaveIp + " to " + masterIp);
+ return;
+ }
+ } catch (Exception e) {
+ } finally {
+ localLogout(slaveConn);
+ slaveConn = null;
+ }
+ // wait 2 second
+ forceSleep(2);
+ }
+ throw new CloudRuntimeException("Unable to reset master of slave " + slaveIp
+ + " to " + masterIp + "after 30 retry");
+ } catch (Exception e) {
+ throw new CloudRuntimeException("Unable to reset master of slave " + slaveIp
+ + " to " + masterIp + " due to " + e.toString());
+ } finally {
+ localLogout(slaveConn);
+ slaveConn = null;
+ }
+ }
+
+ protected void ensurePoolIntegrity(Connection conn,
+ String masterIp, String username, Queue<String> password, int wait) {
+ try {
+ // try recoverSlave first
+ Set<Host> rcSlaves = Pool.recoverSlaves(conn);
+ // wait 10 second
+ forceSleep(10);
+ for(Host slave : rcSlaves ) {
+ for (int i = 0; i < 30; i++) {
+ Connection slaveConn = null;
+ try {
+
+ String slaveIp = slave.getAddress(conn);
+ s_logger.debug("Logging on as the slave to " + slaveIp);
+ slaveConn = new Connection(getURL(slaveIp), 10);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
+ Pool.Record pr = getPoolRecord(slaveConn);
+ String mIp = pr.master.getAddress(slaveConn);
+ if (mIp.trim().equals(masterIp.trim())) {
+ break;
+ }
+ } catch (Exception e) {
+ } finally {
+ localLogout(slaveConn);
+ slaveConn = null;
+ }
+ // wait 2 second
+ forceSleep(2);
+ }
+ }
+ // then try emergency reset master
+ Set<Host> slaves = Host.getAll(conn);
+ for (Host slave : slaves) {
+ String slaveIp = slave.getAddress(conn);
+ Connection slaveConn = null;
+ try {
+ s_logger.debug("Logging on as the slave to " + slaveIp);
+
+ slaveConn = new Connection(getURL(slaveIp), 10);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
+ Pool.Record slavePoolr = getPoolRecord(slaveConn);
+ String ip = slavePoolr.master.getAddress(slaveConn);
+ if (!masterIp.trim().equals(ip.trim())) {
+ PoolEmergencyResetMaster(slaveIp, masterIp, username, password);
+ }
+ } catch (Exception e) {
+ s_logger.debug("Unable to login to slave " + slaveIp + " error " + e.getMessage());
+ } finally {
+ localLogout(slaveConn);
+ slaveConn = null;
+ }
+ }
+ } catch (Exception e) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Catch " + e.getClass().getName() + " due to " + e.toString());
+ }
+ }
+ }
+
+ public URL getURL(String ip){
+ try {
+ return new URL("https://" + ip);
+ } catch (Exception e) {
+ String msg = "Unable to convert IP " + ip + " to URL due to " + e.toString();
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ throw new CloudRuntimeException(msg, e);
+ }
+ }
+
+ public Connection connect(String hostUuid, String poolUuid, String ipAddress,
+ String username, Queue<String> password, int wait) {
+ XenServerConnection mConn = null;
+ Connection sConn = null;
+ String masterIp = null;
+ if (hostUuid == null || poolUuid == null || ipAddress == null || username == null || password == null) {
+ String msg = "Connect some parameter are null hostUuid:" + hostUuid + " ,poolUuid:" + poolUuid
+ + " ,ipAddress:" + ipAddress;
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+ }
+ Host host = null;
+ synchronized (poolUuid.intern()) {
+ // Let's see if it is an existing connection.
+ mConn = getConnect(poolUuid);
+ if (mConn != null){
+ try{
+ host = Host.getByUuid(mConn, hostUuid);
+ } catch (Types.SessionInvalid e) {
+ s_logger.debug("Session thgrough ip " + mConn.getIp() + " is invalid for pool(" + poolUuid + ") due to " + e.toString());
+ try {
+ loginWithPassword(mConn, mConn.getUsername(), mConn.getPassword(), APIVersion.latest().toString());
+ } catch (Exception e1) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("connect through IP(" + mConn.getIp() + " for pool(" + poolUuid + ") is broken due to " + e.toString());
+ }
+ removeConnect(poolUuid);
+ mConn = null;
+ }
+ } catch (UuidInvalid e) {
+ String msg = "Host(" + hostUuid + ") doesn't belong to pool(" + poolUuid + "), please execute 'xe pool-join master-address=" + mConn.getIp()
+ + " master-username=" + mConn.getUsername() + " master-password=" + mConn.getPassword();
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ throw new CloudRuntimeException(msg, e);
+ } catch (Exception e) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("connect through IP(" + mConn.getIp() + " for pool(" + poolUuid + ") is broken due to " + e.toString());
+ }
+ removeConnect(poolUuid);
+ mConn = null;
+ }
+ }
+
+ if ( mConn == null ) {
+ try {
+ try {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Logging on as the slave to " + ipAddress);
+ }
+ sConn = new Connection(getURL(ipAddress), 5);
+ slaveLocalLoginWithPassword(sConn, username, password);
+ } catch (Exception e){
+ String msg = "Unable to create slave connection to host(" + hostUuid +") due to " + e.toString();
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ throw new CloudRuntimeException(msg, e);
+ }
+ Pool.Record pr = null;
+ try {
+ pr = getPoolRecord(sConn);
+ } catch (Exception e) {
+ PoolEmergencyTransitionToMaster(ipAddress, username, password);
+ mConn = new XenServerConnection(getURL(ipAddress), ipAddress, username, password, _retries, _interval, wait);
+ try {
+ loginWithPassword(mConn, username, password, APIVersion.latest().toString());
+ pr = getPoolRecord(mConn);
+ } catch (Exception e1) {
+ String msg = "Unable to create master connection to host(" + hostUuid +") after transition it to master, due to " + e1.toString();
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ throw new CloudRuntimeException(msg, e1);
+ }
+ if ( !pr.uuid.equals(poolUuid) ) {
+ String msg = "host(" + hostUuid +") should be in pool(" + poolUuid + "), but it is actually in pool(" + pr.uuid + ")";
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ throw new CloudRuntimeException(msg);
+ } else {
+ if (s_managePool) {
+ ensurePoolIntegrity(mConn, ipAddress, username, password, wait);
+ }
+ addConnect(poolUuid, mConn);
+ return mConn;
+ }
+ }
+ if ( !pr.uuid.equals(poolUuid) ) {
+ String msg = "host(" + hostUuid +") should be in pool(" + poolUuid + "), but it is actually in pool(" + pr.uuid + ")";
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ throw new CloudRuntimeException(msg);
+ }
+ try {
+ masterIp = pr.master.getAddress(sConn);
+ mConn = new XenServerConnection(getURL(masterIp), masterIp, username, password, _retries, _interval, wait);
+ loginWithPassword(mConn, username, password, APIVersion.latest().toString());
+ addConnect(poolUuid, mConn);
+ return mConn;
+ } catch (Exception e) {
+ String msg = "Unable to logon in " + masterIp + " as master in pool(" + poolUuid + ")";
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ throw new CloudRuntimeException(msg);
+ }
+ } finally {
+ localLogout(sConn);
+ sConn = null;
+ }
+ }
+ }
+
+ if ( mConn != null ) {
+ if (s_managePool) {
+ try {
+ Map<String, String> args = new HashMap<String, String>();
+ host.callPlugin(mConn, "echo", "main", args);
+ } catch (Types.SessionInvalid e) {
+ if (s_logger.isDebugEnabled()) {
+ String msg = "Catch Exception: " + e.getClass().getName() + " Can't connect host " + ipAddress + " due to " + e.toString();
+ s_logger.debug(msg);
+ }
+ PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword());
+ } catch (Types.CannotContactHost e ) {
+ if (s_logger.isDebugEnabled()) {
+ String msg = "Catch Exception: " + e.getClass().getName() + " Can't connect host " + ipAddress + " due to " + e.toString();
+ s_logger.debug(msg);
+ }
+ PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword());
+ } catch (Types.HostOffline e ) {
+ if (s_logger.isDebugEnabled()) {
+ String msg = "Catch Exception: " + e.getClass().getName() + " Host is offline " + ipAddress + " due to " + e.toString();
+ s_logger.debug(msg);
+ }
+ PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword());
+ } catch (Types.HostNotLive e ) {
+ String msg = "Catch Exception: " + e.getClass().getName() + " Host Not Live " + ipAddress + " due to " + e.toString();
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug(msg);
+ }
+ PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword());
+ } catch (Exception e) {
+ String msg = "Echo test failed on host " + hostUuid + " IP " + ipAddress;
+ s_logger.warn(msg, e);
+ throw new CloudRuntimeException(msg, e);
+ }
+ }
+ }
+ return mConn;
+ }
+
+
+ protected Session slaveLocalLoginWithPassword(Connection conn, String username, Queue<String> password) throws
+ BadServerResponse,
+ XenAPIException,
+ XmlRpcException {
+ Session s = null;
+ boolean logged_in=false;
+ Exception ex = null;
+ while (!logged_in){
+ try {
+ s = Session.slaveLocalLoginWithPassword(conn, username, password.peek());
+ logged_in=true;
+ } catch (BadServerResponse e) {
+ logged_in=false; ex = e;
+ } catch (XenAPIException e) {
+ logged_in=false; ex = e;
+ } catch (XmlRpcException e) {
+ logged_in=false; ex = e;
+ }
+ if (logged_in && conn != null){
+ break;
+ }
+ else {
+ if (password.size() > 1){
+ password.remove();
+ continue;
+ }
+ else {
+ // the last password did not work leave it and flag error
+ if (ex instanceof BadServerResponse){
+ throw (BadServerResponse)ex;
+ }
+ else if (ex instanceof XmlRpcException){
+ throw (XmlRpcException)ex;
+ }
+ else if (ex instanceof Types.SessionAuthenticationFailed){
+ throw (Types.SessionAuthenticationFailed)ex;
+ }
+ else if (ex instanceof XenAPIException){
+ throw (XenAPIException)ex;
+ }
+ break;
+ }
+ }
+ }
+ return s;
+ }
+
+
+ protected Session loginWithPassword(Connection conn, String username, Queue<String> password, String version)throws
+ BadServerResponse,
+ XenAPIException,
+ XmlRpcException {
+ Session s = null;
+ boolean logged_in=false;
+ Exception ex = null;
+ while (!logged_in){
+ try {
+ s = Session.loginWithPassword(conn, username, password.peek(), APIVersion.latest().toString());
+ logged_in=true;
+ } catch (BadServerResponse e) {
+ logged_in=false; ex = e;
+ } catch (XenAPIException e) {
+ logged_in=false; ex = e;
+ } catch (XmlRpcException e) {
+ logged_in=false; ex = e;
+ }
+
+ if (logged_in && conn != null){
+ break;
+ }
+ else {
+ if (password.size() > 1){
+ password.remove();
+ continue;
+ }
+ else {
+ // the last password did not work leave it and flag error
+ if (ex instanceof BadServerResponse){
+ throw (BadServerResponse)ex;
+ }
+ else if (ex instanceof XmlRpcException){
+ throw (XmlRpcException)ex;
+ }
+ else if (ex instanceof Types.SessionAuthenticationFailed){
+ throw (Types.SessionAuthenticationFailed)ex;
+ }
+ else if (ex instanceof XenAPIException){
+ throw (XenAPIException)ex;
+ }
+ }
+ }
+ }
+ return s;
+ }
+
+
+ protected void join(Connection conn, String masterIp, String username, Queue<String> password) throws
+ BadServerResponse,
+ XenAPIException,
+ XmlRpcException,
+ Types.JoiningHostCannotContainSharedSrs {
+
+ boolean logged_in=false;
+ Exception ex = null;
+ while (!logged_in){
+ try {
+ Pool.join(conn, masterIp, username, password.peek());
+ logged_in=true;
+ } catch (BadServerResponse e) {
+ logged_in=false; ex = e;
+ } catch (XenAPIException e) {
+ logged_in=false; ex = e;
+ } catch (XmlRpcException e) {
+ logged_in=false; ex = e;
+ }
+ if (logged_in && conn != null){
+ break;
+ }
+ else {
+ if (password.size() > 1){
+ password.remove();
+ continue;
+ }
+ else {
+ // the last password did not work leave it and flag error
+ if (ex instanceof BadServerResponse){
+ throw (BadServerResponse)ex;
+ }
+ else if (ex instanceof XmlRpcException){
+ throw (XmlRpcException)ex;
+ }
+ else if (ex instanceof Types.SessionAuthenticationFailed){
+ throw (Types.SessionAuthenticationFailed)ex;
+ }
+ else if (ex instanceof XenAPIException){
+ throw (XenAPIException)ex;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ static public Pool.Record getPoolRecord(Connection conn)
+ throws XmlRpcException, XenAPIException {
+ Map<Pool, Pool.Record> pools = Pool.getAllRecords(conn);
+ assert pools.size() == 1 : "Pool size is not one....hmmm....wth? "
+ + pools.size();
+
+ return pools.values().iterator().next();
+ }
+
+ private static final XenServerConnectionPool s_instance = new XenServerConnectionPool();
+
+ public static XenServerConnectionPool getInstance() {
+ return s_instance;
+ }
+
+
+
+ public class XenServerConnection extends Connection {
+ long _interval;
+ int _retries;
+ String _ip;
+ String _username;
+ Queue<String> _password;
+ String _poolUuid;
+
+ public XenServerConnection(URL url, String ip, String username, Queue<String> password,
+ int retries, int interval, int wait) {
+ super(url, wait);
+ _ip = ip;
+ _retries = retries;
+ _username = username;
+ _password = password;
+ _interval = (long) interval * 1000;
+
+ }
+
+ public String getPoolUuid() {
+ return _poolUuid;
+ }
+
+ public String getUsername() {
+ return _username;
+ }
+
+ public Queue<String> getPassword() {
+ return _password;
+ }
+
+ public String getIp() {
+ return _ip;
+ }
+
+ @Override
+ protected Map dispatch(String method_call, Object[] method_params) throws XmlRpcException, XenAPIException {
+ if (method_call.equals("session.local_logout")
+ || method_call.equals("session.slave_local_login_with_password")
+ || method_call.equals("session.logout")) {
+ return super.dispatch(method_call, method_params);
+ }
+
+ if (method_call.equals("session.login_with_password")) {
+ int retries = 0;
+ while (retries++ < _retries) {
+ try {
+ return super.dispatch(method_call, method_params);
+ } catch (XmlRpcException e) {
+ Throwable cause = e.getCause();
+ if (cause == null
+ || !(cause instanceof SocketException)) {
+ throw e;
+ }
+ if (retries >= _retries) {
+ throw e;
+ }
+ s_logger.debug("Unable to login...retrying " + retries);
+ }
+ try {
+ Thread.sleep(_interval);
+ } catch (InterruptedException e) {
+ s_logger
+ .debug("Man....I was just getting comfortable there....who woke me up?");
+ }
+ }
+ } else {
+ int retries = 0;
+ while (retries++ < _retries) {
+ try {
+ return super.dispatch(method_call, method_params);
+ } catch (Types.SessionInvalid e) {
+ s_logger.debug("Session is invalid for method: " + method_call + " due to " + e.getMessage() + ". Reconnecting...retry="
+ + retries);
+ if (retries >= _retries) {
+ removeConnect(_poolUuid);
+ throw e;
+ }
+ loginWithPassword(this, _username, _password, APIVersion.latest().toString());
+ method_params[0] = getSessionReference();
+ } catch (XmlRpcClientException e) {
+ s_logger.debug("XmlRpcClientException for method: " + method_call + " due to " + e.getMessage());
+ removeConnect(_poolUuid);
+ throw e;
+ } catch (XmlRpcException e) {
+ s_logger.debug("XmlRpcException for method: " + method_call + " due to " + e.getMessage() + ". Reconnecting...retry="
+ + retries);
+ if (retries >= _retries) {
+ removeConnect(_poolUuid);
+ throw e;
+ }
+ Throwable cause = e.getCause();
+ if (cause == null || !(cause instanceof SocketException)) {
+ removeConnect(_poolUuid);
+ throw e;
+ }
+ } catch (Types.HostIsSlave e) {
+ s_logger.debug("HostIsSlave Exception for method: " + method_call + " due to " + e.getMessage() + ". Reconnecting...retry="
+ + retries);
+ removeConnect(_poolUuid);
+ throw e;
+ }
+ try {
+ Thread.sleep(_interval);
+ } catch (InterruptedException e) {
+ s_logger.info("Who woke me from my slumber?");
+ }
+ }
+ assert false : "We should never get here";
+ removeConnect(_poolUuid);
+ }
+ throw new CloudRuntimeException("After " + _retries
+ + " retries, we cannot contact the host ");
+ }
+
+ }
+
+ public static class TrustAllManager implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
+ return true;
+ }
+
+ public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
+ return true;
+ }
+
+ @Override
+ public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
+ throws java.security.cert.CertificateException {
+ return;
+ }
+
+ @Override
+ public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
+ throws java.security.cert.CertificateException {
+ return;
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java
new file mode 100644
index 0000000..7650d44
--- /dev/null
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerPoolVms.java
@@ -0,0 +1,82 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License. Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.hypervisor.xen.resource;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.log4j.Logger;
+import java.util.concurrent.ConcurrentHashMap;
+import com.cloud.utils.Pair;
+import com.cloud.vm.VirtualMachine.State;
+
+
+public class XenServerPoolVms {
+ private static final Logger s_logger = Logger.getLogger(XenServerPoolVms.class);
+ private final Map<String/* clusterId */, HashMap<String/* vm name */, Pair<String/* host uuid */, State/* vm state */>>> _cluster_vms =
+ new ConcurrentHashMap<String, HashMap<String, Pair<String, State>>>();
+
+
+ public HashMap<String, Pair<String, State>> getClusterVmState(String clusterId){
+ HashMap<String, Pair<String, State>> _vms= _cluster_vms.get(clusterId);
+ if (_vms==null) {
+ HashMap<String, Pair<String, State>> vmStates = new HashMap<String, Pair<String, State>>();
+ _cluster_vms.put(clusterId, vmStates);
+ return vmStates;
+ }
+ else return _vms;
+ }
+
+ public void clear(String clusterId){
+ HashMap<String, Pair<String, State>> _vms= getClusterVmState(clusterId);
+ _vms.clear();
+ }
+
+ public State getState(String clusterId, String name){
+ HashMap<String, Pair<String, State>> vms = getClusterVmState(clusterId);
+ Pair<String, State> pv = vms.get(name);
+ return pv == null ? State.Stopped : pv.second(); // if a VM is absent on the cluster, it is effectively in stopped state.
+ }
+
+ public void put(String clusterId, String hostUuid, String name, State state){
+ HashMap<String, Pair<String, State>> vms= getClusterVmState(clusterId);
+ vms.put(name, new Pair<String, State>(hostUuid, state));
+ }
+
+ public void remove(String clusterId, String hostUuid, String name){
+ HashMap<String, Pair<String, State>> vms= getClusterVmState(clusterId);
+ vms.remove(name);
+ }
+
+ public void putAll(String clusterId, HashMap<String, Pair<String, State>> new_vms){
+ HashMap<String, Pair<String, State>> vms= getClusterVmState(clusterId);
+ vms.putAll(new_vms);
+ }
+
+ public int size(String clusterId){
+ HashMap<String, Pair<String, State>> vms= getClusterVmState(clusterId);
+ return vms.size();
+ }
+
+ @Override
+ public String toString(){
+ StringBuilder sbuf = new StringBuilder("PoolVms=");
+ for (HashMap<String/* vm name */, Pair<String/* host uuid */, State/* vm state */>> clusterVM: _cluster_vms.values()){
+ for (String vmname: clusterVM.keySet()){
+ sbuf.append(vmname).append("-").append(clusterVM.get(vmname).second()).append(",");
+ }
+ }
+ return sbuf.toString();
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/server/src/com/cloud/baremetal/BareMetalResourceBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/baremetal/BareMetalResourceBase.java b/server/src/com/cloud/baremetal/BareMetalResourceBase.java
index 7b4556c..7aa8f37 100755
--- a/server/src/com/cloud/baremetal/BareMetalResourceBase.java
+++ b/server/src/com/cloud/baremetal/BareMetalResourceBase.java
@@ -53,7 +53,6 @@ import com.cloud.api.ApiConstants;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase;
-import com.cloud.hypervisor.xen.resource.CitrixResourceBase;
import com.cloud.resource.ServerResource;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.OutputInterpreter;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/550b2257/server/src/com/cloud/ha/XenServerFencer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/ha/XenServerFencer.java b/server/src/com/cloud/ha/XenServerFencer.java
deleted file mode 100755
index c9c701a..0000000
--- a/server/src/com/cloud/ha/XenServerFencer.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2012 Citrix Systems, Inc. Licensed under the
-// Apache License, Version 2.0 (the "License"); you may not use this
-// file except in compliance with the License. Citrix Systems, Inc.
-// reserves all rights not expressly granted by 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.
-//
-// Automatically generated by addcopyright.py at 04/03/2012
-package com.cloud.ha;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.FenceAnswer;
-import com.cloud.agent.api.FenceCommand;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.OperationTimedoutException;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ResourceManager;
-import com.cloud.utils.component.Inject;
-import com.cloud.vm.VMInstanceVO;
-
-@Local(value=FenceBuilder.class)
-public class XenServerFencer implements FenceBuilder {
- private static final Logger s_logger = Logger.getLogger(XenServerFencer.class);
- String _name;
-
- @Inject HostDao _hostDao;
- @Inject AgentManager _agentMgr;
- @Inject ResourceManager _resourceMgr;
-
- @Override
- public Boolean fenceOff(VMInstanceVO vm, HostVO host) {
- if (host.getHypervisorType() != HypervisorType.XenServer) {
- s_logger.debug("Don't know how to fence non XenServer hosts " + host.getHypervisorType());
- return null;
- }
-
- List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host.getClusterId());
- FenceCommand fence = new FenceCommand(vm, host);
-
- for (HostVO h : hosts) {
- if (h.getHypervisorType() == HypervisorType.XenServer) {
- if( h.getStatus() != Status.Up ) {
- continue;
- }
- if( h.getId() == host.getId() ) {
- continue;
- }
- FenceAnswer answer;
- try {
- Answer ans = _agentMgr.send(h.getId(), fence);
- if (!(ans instanceof FenceAnswer)) {
- s_logger.debug("Answer is not fenceanswer. Result = " + ans.getResult() + "; Details = " + ans.getDetails());
- continue;
- }
- answer = (FenceAnswer) ans;
- } catch (AgentUnavailableException e) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable");
- }
- continue;
- } catch (OperationTimedoutException e) {
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Moving on to the next host because " + h.toString() + " is unavailable");
- }
- continue;
- }
- if (answer != null && answer.getResult()) {
- return true;
- }
- }
- }
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Unable to fence off " + vm.toString() + " on " + host.toString());
- }
-
- return false;
- }
-
- public XenServerFencer() {
- super();
- }
-
- @Override
- public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
- _name = name;
- return true;
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- @Override
- public boolean start() {
- return true;
- }
-
- @Override
- public boolean stop() {
- return true;
- }
-
-}