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