// 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(); } }