/* * Claudia Project * http://claudia.morfeo-project.org * * (C) Copyright 2010 Telefonica Investigacion y Desarrollo * S.A.Unipersonal (Telefonica I+D) * * See CREDITS file for info about members and contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Affero GNU General Public License (AGPL) as * published by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the Affero GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * If you want to use this software an plan to distribute a * proprietary application in any way, and you are not licensing and * distributing your source code under AGPL, you probably need to * purchase a commercial license of the product. Please contact * claudia-support@lists.morfeo-project.org for more information. */ package com.telefonica.claudia.smi.provisioning; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; import org.dmtf.schemas.ovf.envelope._1.ContentType; import org.dmtf.schemas.ovf.envelope._1.DiskSectionType; import org.dmtf.schemas.ovf.envelope._1.EnvelopeType; import org.dmtf.schemas.ovf.envelope._1.FileType; import org.dmtf.schemas.ovf.envelope._1.ProductSectionType; import org.dmtf.schemas.ovf.envelope._1.RASDType; import org.dmtf.schemas.ovf.envelope._1.ReferencesType; import org.dmtf.schemas.ovf.envelope._1.VirtualDiskDescType; import org.dmtf.schemas.ovf.envelope._1.VirtualHardwareSectionType; import org.dmtf.schemas.ovf.envelope._1.VirtualSystemCollectionType; import org.dmtf.schemas.ovf.envelope._1.VirtualSystemType; import org.dmtf.schemas.ovf.envelope._1.ProductSectionType.Property; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.abiquo.ovf.OVFEnvelopeUtils; import com.abiquo.ovf.exceptions.EmptyEnvelopeException; import com.abiquo.ovf.section.OVFProductUtils; import com.abiquo.ovf.xml.OVFSerializer; import com.telefonica.claudia.smi.DataTypesUtils; import com.telefonica.claudia.smi.Main; import com.telefonica.claudia.smi.TCloudConstants; import com.telefonica.claudia.smi.URICreation; import com.telefonica.claudia.smi.task.Task; import com.telefonica.claudia.smi.task.TaskManager; public class ONEProvisioningDriver implements ProvisioningDriver { public static enum ControlActionType {shutdown, hold, release, stop, suspend, resume, finalize}; //public static enum VmStateType {INIT, PENDING, HOLD, ACTIVE, STOPPED, SUSPENDED, DONE, FAILED}; private final static int INIT_STATE = 0; private final static int PENDING_STATE = 1; private final static int HOLD_STATE = 2; private final static int ACTIVE_STATE = 3; private final static int STOPPED_STATE = 4; private final static int SUSPENDED_STATE = 5; private final static int DONE_STATE = 6; private final static int FAILED_STATE = 7; // LCM_INIT, PROLOG, BOOT, RUNNING, MIGRATE, SAVE_STOP, SAVE_SUSPEND, SAVE_MIGRATE, PROLOG_MIGRATE, EPILOG_STOP, EPILOG, SHUTDOWN, CANCEL private final static int INIT_SUBSTATE = 0; private final static int PROLOG_SUBSTATE = 1; private final static int BOOT_SUBSTATE = 2; private final static int RUNNING_SUBSTATE = 3; private final static int MIGRATE_SUBSTATE = 4; private final static int SAVE_STOP_SUBSTATE = 5; private final static int SAVE_SUSPEND_SUBSTATE = 6; private final static int SAVE_MIGRATE_SUBSTATE = 7; private final static int PROLOG_MIGRATE_SUBSTATE = 8; private final static int PROLOG_RESUME_SUBSTATE = 9; private final static int EPILOG_STOP_SUBSTATE = 10; private final static int EPILOG_SUBSTATE = 11; private final static int SHUDTOWN_SUBSTATE = 12; private final static int CANCEL_SUBSTATE = 13; private HashMap<String, String> text_migrability = new HashMap(); private static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger("com.telefonica.claudia.smi.provisioning.ONEProvisioningDriver"); // Tag names of the returning info doc for Virtual machines public static final String VM_STATE = "STATE"; public static final String VM_SUBSTATE = "LCM_STATE"; // XMLRPC commands to access OpenNebula features private final static String VM_ALLOCATION_COMMAND = "one.vm.allocate"; private final static String VM_UPDATE_COMMAND = "one.vm.action"; private final static String VM_GETINFO_COMMAND = "one.vm.info"; private final static String VM_GETALL_COMMAND = "one.vmpool.info"; private final static String VM_DELETE_COMMAND = "one.vm.delete"; private final static String NET_ALLOCATION_COMMAND = "one.vn.allocate"; private final static String NET_GETINFO_COMMAND = "one.vn.info"; private final static String NET_GETALL_COMMAND = "one.vnpool.info"; private final static String NET_DELETE_COMMAND = "one.vn.delete"; //private final static String DEBUGGING_CONSOLE = "RAW = [ type =\"kvm\", data =\"<devices><serial type='pty'><source path='/dev/pts/5'/><target port='0'/></serial><console type='pty' tty='/dev/pts/5'><source path='/dev/pts/5'/><target port='0'/></console></devices>\" ]"; /** * Connection URL for OpenNebula. It defaults to localhost, but can be * overriden with the property oneURL of the server configuration file. */ private String oneURL = "http://localhost:2633/RPC2"; /** * Server configuration file URL property identifier. */ private final static String URL_PROPERTY = "oneUrl"; private final static String USER_PROPERTY = "oneUser"; private final static String PASSWORD_PROPERTY = "onePassword"; private static final String KERNEL_PROPERTY = "oneKernel"; private static final String INITRD_PROPERTY = "oneInitrd"; private static final String ARCH_PROPERTY = "arch"; private static final String ENVIRONMENT_PROPERTY = "oneEnvironmentPath"; private final static String SSHKEY_PROPERTY = "oneSshKey"; private final static String SCRIPTPATH_PROPERTY = "oneScriptPath"; private final static String ETH0_GATEWAY_PROPERTY = "eth0Gateway"; private final static String ETH0_DNS_PROPERTY = "eth0Dns"; private final static String ETH1_GATEWAY_PROPERTY = "eth1Gateway"; private final static String ETH1_DNS_PROPERTY = "eth1Dns"; private final static String NET_INIT_SCRIPT0 = "netInitScript0"; private final static String NET_INIT_SCRIPT1 = "netInitScript1"; private String oneSession = "oneadmin:5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8"; private XmlRpcClient xmlRpcClient = null; private static final String NETWORK_BRIDGE = "oneNetworkBridge"; private static final String XEN_DISK = "xendisk"; OneOperations operations = null; OneNetUtilities netUtils = null; /** * Collection containing the mapping from fqns to ids. This mapped is used as a cache * of the getVmId method (vm ids never change once assigned). */ private Map<String, Integer> idVmMap = new HashMap<String, Integer>(); /** * Collection containing the mapping from fqns to ids. This mapped is used as a cache * of the getVmId method (vm ids never change once assigned). */ private Map<String, Integer> idNetMap = new HashMap<String, Integer>(); private String hypervisorInitrd=""; private String arch=""; private String hypervisorKernel=""; private String customizationPort; private String environmentRepositoryPath; private static String networkBridge=""; private static String xendisk=""; private static String oneSshKey=""; private static String oneScriptPath=""; private static String eth0Gateway=""; private static String eth1Gateway=""; private static String eth0Dns=""; private static String eth1Dns=""; private static String netInitScript0=""; private static String netInitScript1=""; public static final String ASSIGNATION_SYMBOL = "="; public static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static final String ONE_VM_ID = "NAME"; public static final String ONE_VM_TYPE = "TYPE"; public static final String ONE_VM_STATE = "STATE"; public static final String ONE_VM_MEMORY = "MEMORY"; public static final String ONE_VM_NAME = "NAME"; public static final String ONE_VM_UUID = "UUID"; public static final String ONE_VM_CPU = "CPU"; public static final String ONE_VM_VCPU = "VCPU"; public static final String ONE_VM_RAW_VMI = "RAW_VMI"; public static final String ONE_VM_OS = "OS"; public static final String ONE_VM_OS_PARAM_KERNEL = "kernel"; public static final String ONE_VM_OS_PARAM_INITRD = "initrd"; public static final String ONE_VM_OS_PARAM_ROOT = "root"; public static final String ONE_VM_OS_PARAM_BOOT = "boot"; public static final String ONE_VM_GRAPHICS = "GRAPHICS"; public static final String ONE_VM_GRAPHICS_TYPE = "type"; public static final String ONE_VM_GRAPHICS_LISTEN = "listen"; public static final String ONE_VM_GRAPHICS_PORT = "port"; public static final String ONE_VM_DISK_COLLECTION = "DISKS"; public static final String ONE_VM_DISK = "DISK"; public static final String ONE_VM_DISK_PARAM_IMAGE = "source"; public static final String ONE_VM_DISK_PARAM_FORMAT = "format"; public static final String ONE_VM_DISK_PARAM_SIZE = "size"; public static final String ONE_VM_DISK_PARAM_TARGET = "target"; public static final String ONE_VM_DISK_PARAM_DIGEST = "digest"; public static final String ONE_VM_DISK_PARAM_TYPE = "type"; public static final String ONE_VM_DISK_PARAM_DRIVER = "driver"; public static final String ONE_VM_NIC_COLLECTION = "NICS"; public static final String ONE_VM_NIC = "NIC"; public static final String ONE_VM_NIC_PARAM_IP = "ip"; public static final String ONE_VM_NIC_PARAM_NETWORK = "NETWORK"; public static final String ONE_NET_ID = "ID"; public static final String ONE_NET_NAME = "NAME"; public static final String ONE_NET_BRIDGE = "BRIDGE"; public static final String ONE_NET_TYPE = "TYPE"; public static final String ONE_NET_ADDRESS = "NETWORK_ADDRESS"; public static final String ONE_NET_SIZE = "NETWORK_SIZE"; public static final String ONE_NET_LEASES = "LEASES"; public static final String ONE_NET_IP = "IP"; public static final String ONE_NET_MAC = "MAC"; public static final String ONE_DISK_ID = "ID"; public static final String ONE_DISK_NAME = "NAME"; public static final String ONE_DISK_URL = "URL"; public static final String ONE_DISK_SIZE = "SIZE"; public static final String ONE_OVF_URL = "OVF"; public static final String ONE_CONTEXT = "CONTEXT"; public static final String ONE_VERSION = "ONEVERSION"; public static final String RESULT_NET_ID = "ID"; public static final String RESULT_NET_NAME = "NAME"; public static final String RESULT_NET_ADDRESS = "NETWORK_ADDRESS"; public static final String RESULT_NET_BRIDGE = "BRIDGE"; public static final String RESULT_NET_TYPE = "TYPE"; public static final String MULT_CONF_LEFT_DELIMITER = "["; public static final String MULT_CONF_RIGHT_DELIMITER = "]"; public static final String MULT_CONF_SEPARATOR = ","; public static final String QUOTE = "\""; private static final int ResourceTypeCPU = 3; private static final int ResourceTypeMEMORY = 4; private static final int ResourceTypeNIC = 10; private static final int ResourceTypeDISK = 17; private String oneversion = "2.2"; public class DeployVMTask extends Task { public static final long POLLING_INTERVAL= 10000; private static final int MAX_CONNECTION_ATEMPTS = 5; String fqnVm; String ovf; public DeployVMTask(String fqn, String ovf) { super(); this.fqnVm = fqn; this.ovf = ovf; } @Override public void execute() { this.status = TaskStatus.RUNNING; this.startTime = System.currentTimeMillis(); try { // Create the Virtual Machine String result = createVirtualMachine(); if (result==null) { this.status= TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); return; } // Wait until the state is RUNNING this.status = TaskStatus.WAITING; int connectionAttempts=0; while (true) { try { Document vmInfo = getVirtualMachineState(result); Integer state = Integer.parseInt(vmInfo.getElementsByTagName(VM_STATE).item(0).getTextContent()); Integer subState = Integer.parseInt(vmInfo.getElementsByTagName(VM_SUBSTATE).item(0).getTextContent()); if (state == ACTIVE_STATE && subState == RUNNING_SUBSTATE ) { this.status= TaskStatus.SUCCESS; this.endTime = System.currentTimeMillis(); break; } else if (state ==FAILED_STATE) { this.status= TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); break; } connectionAttempts=0; } catch (IOException ioe) { if (connectionAttempts> MAX_CONNECTION_ATEMPTS) { this.status= TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); break; } else connectionAttempts++; log.warn("Connection exception accessing ONE. Trying again. Error: " + ioe.getMessage()); } Thread.sleep(POLLING_INTERVAL); } } catch (IOException e) { log.error("Error connecting to ONE: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); this.status = TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); return; } catch (Exception e) { log.error("Unexpected error creating VM: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); this.status = TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); e.printStackTrace(); return; } } public String createVirtualMachine() throws Exception { String idvm = null; try { idvm = operations.deployVirtualMachine (ovf, fqnVm ); this.returnMsg = "Virtual machine internal id: " + idvm; } catch (Exception e) { this.error = new TaskError(); this.error.message = e.getMessage(); } return idvm; } } public class DeployNetworkTask extends Task { String fqnNet; String ovf; public DeployNetworkTask(String netFqn, String ovf) { this.fqnNet = netFqn; this.ovf = ovf; } @Override public void execute() { this.status = TaskStatus.RUNNING; this.startTime = System.currentTimeMillis(); try { if (!createNetwork()) { this.status= TaskStatus.ERROR; return; } this.status= TaskStatus.SUCCESS; } catch (IOException e) { log.error("Error connecting to ONE: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); this.endTime = System.currentTimeMillis(); this.status = TaskStatus.ERROR; return; } catch (Exception e) { log.error("Unknown error creating network: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); this.endTime = System.currentTimeMillis(); this.status = TaskStatus.ERROR; } } public boolean createNetwork() throws Exception { String idvm = null; String xml = netUtils.TCloud2ONENet(ovf); try { idvm = operations.deployNetwork(xml); this.returnMsg = "Virtual network machine internal id: " + idvm; } catch (Exception e) { this.error = new TaskError(); this.error.message = e.getMessage(); return false; } return true; /* List<String> rpcParams = new ArrayList<String>(); rpcParams.add(oneSession); rpcParams.add(TCloud2ONENet(ovf)); Object[] result = null; try { result = (Object[])xmlRpcClient.execute(NET_ALLOCATION_COMMAND, rpcParams); } catch (XmlRpcException ex) { log.error("Connection error. Could not reach ONE host: " + ex.getMessage()); throw new IOException ("Error on allocation of the new network , XMLRPC call failed", ex); } boolean success = (Boolean)result[0]; if(success) { log.debug("Network creation request succeded: " + result[1]); this.returnMsg = ((Integer)result[1]).toString(); return true; } else { log.error("Error recieved from ONE: " + (String)result[1]); this.error = new TaskError(); this.error.message = (String)result[1]; return false; }*/ } } public class UndeployVMTask extends Task { String fqnVm; public UndeployVMTask(String vmFqn) { this.fqnVm = vmFqn; } @Override public void execute() { this.status= TaskStatus.RUNNING; this.startTime = System.currentTimeMillis(); // Undeploy the VM try { String id = getVmId(fqnVm).toString(); // deleteVirtualMachine(id); operations.deleteVirtualMachine(id); this.status= TaskStatus.SUCCESS; this.endTime = System.currentTimeMillis(); } catch (IOException e) { System.out.println ( e.getMessage()); log.error("Error connecting to ONE: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); this.status = TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); return; } catch (Exception e) { System.out.println ( e.getMessage()); log.error("Unknown error undeploying VM: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); this.status = TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); return; } } /* @SuppressWarnings("unchecked") public boolean deleteVirtualMachine(String id) throws IOException { List rpcParams = new ArrayList (); ControlActionType controlAction = ControlActionType.finalize; log.info("PONG deleteVirtualMachine id: "+ id); rpcParams.add(oneSession); rpcParams.add(controlAction.toString()); rpcParams.add(Integer.parseInt(id)); Object[] result = null; try { result = (Object[])xmlRpcClient.execute(VM_UPDATE_COMMAND, rpcParams); } catch (XmlRpcException ex) { log.error("Connection error trying to update VM: " + ex.getMessage()); throw new IOException ("Error updating VEE replica , XMLRPC call failed", ex); } if (result==null) { throw new IOException("No result returned from XMLRPC call"); } else { return (Boolean)result[0]; } }*/ } public class UndeployNetworkTask extends Task { String fqnNet; public UndeployNetworkTask(String netFqn) { this.fqnNet = netFqn; log.info("Network fqn " + fqnNet); } @Override public void execute() { this.status= TaskStatus.RUNNING; this.startTime = System.currentTimeMillis(); // Undeploy the VM try { //deleteNetwork(getNetId(fqnNet).toString()); operations.deleteNetwork(getNetId(fqnNet).toString()); this.status= TaskStatus.SUCCESS; this.endTime = System.currentTimeMillis(); } catch (IOException e) { log.error("Error connecting to ONE: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); System.out.println ( e.getMessage()); this.status = TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); System.out.println ( e.getMessage()); return; } catch (Exception e) { log.error("Unknown error undeploying Network: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); System.out.println ( e.getMessage()); this.status = TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); return; } } /* @SuppressWarnings("unchecked") public void deleteNetwork(String id) throws IOException { List rpcParams = new ArrayList<String>(); rpcParams.add(oneSession); rpcParams.add(new Integer(id) ); Object[] result = null; try { result = (Object[])xmlRpcClient.execute(NET_DELETE_COMMAND, rpcParams); } catch (XmlRpcException ex) { throw new IOException ("Error deleting the network , XMLRPC call failed", ex); } boolean success = (Boolean)result[0]; if(success) { } else { throw new IOException("Unknown error trying to delete network: " + (String)result[1]); } }*/ } public class ActionVMTask extends Task { String fqnVM; String action; String errorMessage=""; public ActionVMTask(String fqnVM, String action) { this.fqnVM = fqnVM; this.action = action; } @Override public void execute() { this.status= TaskStatus.RUNNING; this.startTime = System.currentTimeMillis(); // Undeploy the VM try { boolean result = operations.doAction(getVmId(fqnVM).toString(), action); if (result) this.status= TaskStatus.SUCCESS; else { this.status = TaskStatus.ERROR; this.error = new TaskError(); this.error.message = errorMessage; } this.endTime = System.currentTimeMillis(); } catch (IOException e) { log.error("Error connecting to VMWare: " + e.getMessage()); this.error = new TaskError(); this.error.message = e.getMessage(); this.status = TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); return; } catch (Exception e) { log.error("Unknown error executing action" + action + ": " + e.getMessage() + " -> " + e.getClass().getCanonicalName()); e.printStackTrace(); this.error = new TaskError(); this.error.message = e.getMessage(); this.status = TaskStatus.ERROR; this.endTime = System.currentTimeMillis(); return; } } } protected static String ONEVM2TCloud(String ONETemplate) { // TODO: ONE Template to TCloud translation return ""; } /* protected static String getNetContext(VirtualHardwareSectionType vh, String veeFqn,String xml, String scriptListProp) throws Exception { // log.debug("PONG2 xml" +xml+ "\n"); StringBuffer allParametersString = new StringBuffer(); List<RASDType> items = vh.getItem(); int i=0; for (Iterator<RASDType> iteratorRASD = items.iterator(); iteratorRASD.hasNext();) { RASDType item = (RASDType) iteratorRASD.next(); // Get the resource type and process it accordingly int rsType = new Integer(item.getResourceType().getValue()); int quantity = 1; if (item.getVirtualQuantity() != null) { quantity = item.getVirtualQuantity().getValue().intValue(); } switch (rsType) { case ResourceTypeNIC: try { // log.debug("PONG eth0Dns" + eth0Dns + "\n"); // log.debug("PONG eth0Gateway" + eth0Gateway + "\n"); // log.debug("PONG eth1Dns" + eth1Dns + "\n"); // log.debug("PONG eth1Gateway" + eth1Gateway + "\n"); String fqnNet = URICreation.getService(veeFqn) + ".networks." + item.getConnection().get(0).getValue(); allParametersString.append("ip_eth"+i).append(ASSIGNATION_SYMBOL).append("\"$NIC[IP, NETWORK=\\\""+fqnNet+"\\\"]\"").append(MULT_CONF_SEPARATOR).append(LINE_SEPARATOR); String dns=""; String gateway=""; if(i==0){ dns=eth0Dns; gateway=eth0Gateway; } if(i==1){ dns=eth1Dns; gateway=eth1Gateway; } if(dns.length()>0) { allParametersString.append("dns_eth"+i).append(ASSIGNATION_SYMBOL).append(dns).append(MULT_CONF_SEPARATOR).append(LINE_SEPARATOR); } if(gateway.length()>0) { allParametersString.append("gateway_eth"+i).append(ASSIGNATION_SYMBOL).append(gateway).append(MULT_CONF_SEPARATOR).append(LINE_SEPARATOR); } i++; } catch (FactoryConfigurationError e) { log.error("Error retrieving parser: " + e.getMessage()); throw new Exception("Error retrieving parser: " + e.getMessage()); } catch (Exception e) { log.error("Error configuring a XML Builder."); throw new Exception("Error configuring a XML Builder: " + e.getMessage()); } break; default: //throw new IllegalArgumentException("unknown hw type: " + rsType); } } StringBuffer scriptexec=new StringBuffer();; if (i==1){ if(netInitScript0.length()>0) { scriptexec.append("SCRIPT_EXEC=\""+netInitScript0); } } if (i==2){ if(netInitScript1.length()>0) { scriptexec.append("SCRIPT_EXEC=\""+netInitScript1); } } if (scriptListProp != null & scriptListProp.length()!=0) { String[] scriptList = scriptListProp.split("/"); String scriptListTemplate = ""; for (String scrt: scriptList){ if (scrt.indexOf(".py")!=-1) { if (scrt.equals("OVFParser.py")) { System.out.println ("python /mnt/stratuslab/"+scrt); scriptexec.append("; python /mnt/stratuslab/"+scrt+""); } if (scrt.equals("restful-server.py")) { System.out.println ("/etc/init.d/lb_server start"); scriptexec.append("; /etc/init.d/lb_server start"); } if (scrt.equals("torqueProbe.py")) { System.out.println ("/etc/init.d/probe start"); scriptexec.append("; /etc/init.d/probe start"); } } } } if (scriptexec.length()>0){ scriptexec.append("\"").append(MULT_CONF_SEPARATOR).append(LINE_SEPARATOR); } else { scriptexec.append(""); } allParametersString.append(scriptexec); return allParametersString.toString(); } */ /*protected String TCloud2ONENet(String xml) throws Exception { try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes())); Element root = (Element) doc.getFirstChild(); String fqn = root.getAttribute(TCloudConstants.ATTR_NETWORK_NAME); StringBuffer allParametersString = new StringBuffer(); NodeList macEnabled = doc.getElementsByTagName(TCloudConstants.TAG_NETWORK_MAC_ENABLED); Element firstmacenElement = (Element)macEnabled.item(0); String macenabled = null; if (firstmacenElement!=null) { NodeList textMacenList = firstmacenElement.getChildNodes(); if (((Node)textMacenList.item(0))!=null) macenabled= ((Node)textMacenList.item(0)).getNodeValue().trim(); } NodeList netmaskList = doc.getElementsByTagName(TCloudConstants.TAG_NETWORK_NETMASK); NodeList baseAddressList = doc.getElementsByTagName(TCloudConstants.TAG_NETWORK_BASE_ADDRESS); NodeList ipLeaseList = doc.getElementsByTagName(TCloudConstants.TAG_NETWORK_IPLEASES); if (baseAddressList.getLength()==0) { allParametersString.append(getTCloud2FixedONENet (fqn)); } else if (ipLeaseList.getLength()==0) { int size = 0; if (netmaskList.getLength() >0) { size = getSizeNetwork ((Element) netmaskList.item(0)); } allParametersString.append(getTCloud2RangedONENet (fqn, size, baseAddressList.item(0).getTextContent())); } else if (ipLeaseList.getLength()>0) { int size = 0; if (netmaskList.getLength() >0) { size = getSizeNetwork ((Element) netmaskList.item(0)); } allParametersString.append(getTCloud2IPElasedONENet (fqn, size, baseAddressList.item(0).getTextContent(), ipLeaseList)); } System.out.println("Network data sent:\n\n" + allParametersString.toString() + "\n\n"); return allParametersString.toString(); } catch (IOException e1) { System.out.println("OVF of the virtual machine was not well formed or it contained some errors."); throw new Exception("OVF of the virtual machine was not well formed or it contained some errors: " + e1.getMessage()); } catch (ParserConfigurationException e) { System.out.println("Error configuring parser: " + e.getMessage()); throw new Exception("Error configuring parser: " + e.getMessage()); } catch (FactoryConfigurationError e) { System.out.println("Error retrieving parser: " + e.getMessage()); throw new Exception("Error retrieving parser: " + e.getMessage()); } catch (Exception e) { e.printStackTrace(); System.out.println("Error configuring a XML Builder."); throw new Exception("Error configuring a XML Builder: " + e.getMessage()); } } */ /*public String getTCloud2FixedONENet (String fqn) { StringBuffer allParametersString = new StringBuffer(); // Translate the simple data to RPC format allParametersString.append(ONE_NET_NAME).append(ASSIGNATION_SYMBOL).append(fqn).append(LINE_SEPARATOR); allParametersString.append(ONE_NET_TYPE).append(ASSIGNATION_SYMBOL).append("FIXED").append(LINE_SEPARATOR); allParametersString.append(ONE_NET_BRIDGE).append(ASSIGNATION_SYMBOL).append(networkBridge).append(LINE_SEPARATOR); return allParametersString.toString(); } public String getTCloud2RangedONENet (String fqn, int size, String network) { StringBuffer allParametersString = new StringBuffer(); // Translate the simple data to RPC format allParametersString.append(ONE_NET_NAME).append(ASSIGNATION_SYMBOL).append(fqn).append(LINE_SEPARATOR); allParametersString.append(ONE_NET_TYPE).append(ASSIGNATION_SYMBOL).append("RANGED").append(LINE_SEPARATOR); allParametersString.append(ONE_NET_BRIDGE).append(ASSIGNATION_SYMBOL).append(networkBridge).append(LINE_SEPARATOR); if (size != 0) allParametersString.append(ONE_NET_SIZE).append(ASSIGNATION_SYMBOL).append(size).append(LINE_SEPARATOR); allParametersString.append(ONE_NET_ADDRESS).append(ASSIGNATION_SYMBOL).append(network).append(LINE_SEPARATOR); return allParametersString.toString(); } public String getTCloud2IPElasedONENet (String fqn, int size, String network, NodeList ipLeaseList) { StringBuffer allParametersString = new StringBuffer(); // Translate the simple data to RPC format allParametersString.append(ONE_NET_NAME).append(ASSIGNATION_SYMBOL).append(fqn).append(LINE_SEPARATOR); allParametersString.append(ONE_NET_TYPE).append(ASSIGNATION_SYMBOL).append("FIXED").append(LINE_SEPARATOR); allParametersString.append(ONE_NET_BRIDGE).append(ASSIGNATION_SYMBOL).append(networkBridge).append(LINE_SEPARATOR); if (size != 0) allParametersString.append(ONE_NET_SIZE).append(ASSIGNATION_SYMBOL).append(size).append(LINE_SEPARATOR); // allParametersString.append(ONE_NET_ADDRESS).append(ASSIGNATION_SYMBOL).append(network).append(LINE_SEPARATOR); for (int i=0; i<ipLeaseList .getLength(); i++){ Node firstIpLeaseNode = ipLeaseList.item(i); if (firstIpLeaseNode.getNodeType() == Node.ELEMENT_NODE){ Element firstIpLeaseElement = (Element)firstIpLeaseNode; NodeList ipList =firstIpLeaseElement.getElementsByTagName(TCloudConstants.TAG_NETWORK_IP); Element firstIpElement = (Element)ipList.item(0); NodeList textIpList = firstIpElement.getChildNodes(); String ipString = ("IP="+((Node)textIpList.item(0)).getNodeValue().trim()); NodeList macList =firstIpLeaseElement.getElementsByTagName(TCloudConstants.TAG_NETWORK_MAC); Element firstMacElement = (Element)macList.item(0); NodeList textMacList = firstMacElement.getChildNodes(); String macString = ("MAC="+((Node)textMacList.item(0)).getNodeValue().trim()); allParametersString.append(ONE_NET_LEASES).append(ASSIGNATION_SYMBOL).append(MULT_CONF_LEFT_DELIMITER); allParametersString.append(ipString).append(MULT_CONF_SEPARATOR).append(macString).append(MULT_CONF_RIGHT_DELIMITER).append(LINE_SEPARATOR); } } return allParametersString.toString(); }*/ /* public static int getSizeNetwork (Element netmask) { if (!netmask.getTextContent().matches("\\d+\\.\\d+\\.\\d+\\.\\d+")) throw new IllegalArgumentException("Wrong IPv4 format. Expected example: 192.168.0.0 Got: " + netmask.getTextContent()); String[] ipBytes = netmask.getTextContent().split("\\."); short[] result = new short[4]; for (int i=0; i < 4; i++) { try { result[i] = Short.parseShort(ipBytes[i]); if (result[i]>255) throw new NumberFormatException("Should be in the range [0-255]."); } catch (NumberFormatException nfe) { throw new IllegalArgumentException("Number out of bounds. Bytes should be on the range 0-255."); } } // The network can host 2^n where n is the number of bits in the network address, // substracting the broadcast and the network value (all 1s and all 0s). int size = (int) Math.pow(2, 32.0-getBitNumber(result)); if (size < 8) size = 8; else size -= 2; return size ; }*/ protected static String ONENet2TCloud(String ONETemplate) { return ""; } /** * Get the number of bits with value 1 in the given IP. * * @return */ /* public static int getBitNumber (short[] ip) { if (ip == null || ip.length != 4) return 0; int bits=0; for (int i=0; i < 4; i++) for (int j=0; j< 15; j++) bits += ( ((short)Math.pow(2, j))& ip[i]) / Math.pow(2, j); return bits; }*/ /** * Retrieve the virtual network id given its fqn. * * @param fqn * FQN of the Virtual Network (mapped to its name property in ONE). * * @return * The internal id of the Virtual Network if it exists or -1 otherwise. * * @throws Exception * */ protected Integer getNetId(String fqn) throws Exception { if (!idNetMap.containsKey(fqn)) idNetMap = getNetworkIds(); if (idNetMap.containsKey(fqn)) return idNetMap.get(fqn); else return -1; } /** * Retrieve the vm's id given its fqn. * * @param fqn * FQN of the Virtual Machine (mapped to its name property in ONE). * * @return * The internal id of the Virtual Machine if it exists or -1 otherwise. * * @throws Exception * */ protected Integer getVmId(String fqn) throws Exception { if (!idVmMap.containsKey(fqn)) idVmMap = getVmIds(); if (idVmMap.containsKey(fqn)) return idVmMap.get(fqn); else return -1; } /** * Retrieve a map of the currently deployed VMs, and its ids. * * @return * A map where the key is the VM's FQN and the value the VM's id. * @throws Exception */ @SuppressWarnings("unchecked") protected Map<String, Integer> getVmIds() throws Exception { List rpcParams = new ArrayList<String>(); rpcParams.add(oneSession); rpcParams.add(-2); if (this.oneversion.equals("3.0")) { rpcParams.add(-1); rpcParams.add(-1); rpcParams.add(-2); } HashMap<String, Integer> mapResult = new HashMap<String, Integer>(); Object[] result = null; try { result = (Object[])xmlRpcClient.execute(VM_GETALL_COMMAND, rpcParams); } catch (XmlRpcException ex) { System.out.println (" getVmIds" + ex.getMessage()); throw new IOException ("Error obtaining the VM list: " + ex.getMessage(), ex); } boolean success = (Boolean)result[0]; if(success) { String resultList = (String) result[1]; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ByteArrayInputStream(resultList.getBytes())); NodeList vmList = doc.getElementsByTagName("VM"); for (int i=0; i < vmList.getLength(); i++) { Element vm = (Element) vmList.item(i); String fqn = ((Element)vm.getElementsByTagName("NAME").item(0)).getTextContent(); try { Integer value = Integer.parseInt(((Element)vm.getElementsByTagName("ID").item(0)).getTextContent()); mapResult.put(fqn, value); } catch(NumberFormatException nfe) { log.warn("Numerical id expected, got [" + ((Element)vm.getElementsByTagName("ID").item(0)).getTextContent() + "]"); continue; } } return mapResult; } catch (ParserConfigurationException e) { log.error("Parser Configuration Error: " + e.getMessage()); throw new IOException ("Parser Configuration Error", e); } catch (SAXException e) { log.error("Parse error reading the answer: " + e.getMessage()); throw new IOException ("XML Parse error", e); } } else { log.error("Error recieved from ONE: " + result[1]); throw new Exception("Error recieved from ONE: " + result[1]); } } @SuppressWarnings("unchecked") protected HashMap<String, Integer> getNetworkIds() throws IOException { List rpcParams = new ArrayList(); rpcParams.add(oneSession); rpcParams.add(-2); if (this.oneversion.equals("3.0")) { rpcParams.add(-1); rpcParams.add(-1); } Object[] result = null; try { result = (Object[])xmlRpcClient.execute(NET_GETALL_COMMAND, rpcParams); } catch (XmlRpcException ex) { throw new IOException ("Error obtaining the network list", ex); } boolean success = (Boolean)result[0]; if(success) { HashMap<String, Integer> mapResult = new HashMap<String, Integer>(); String resultList = (String) result[1]; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); try { DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ByteArrayInputStream(resultList.getBytes())); NodeList vmList = doc.getElementsByTagName("VNET"); for (int i=0; i < vmList.getLength(); i++) { Element vm = (Element) vmList.item(i); String fqn = ((Element)vm.getElementsByTagName("NAME").item(0)).getTextContent(); try { Integer value = Integer.parseInt(((Element)vm.getElementsByTagName("ID").item(0)).getTextContent()); mapResult.put(fqn, value); } catch(NumberFormatException nfe) { log.warn("Numerical id expected, got [" + ((Element)vm.getElementsByTagName("ID").item(0)).getTextContent() + "]"); continue; } } return mapResult; } catch (ParserConfigurationException e) { throw new IOException ("Parser Configuration Error", e); } catch (SAXException e) { throw new IOException ("XML Parse error", e); } } else { throw new IOException("Error recieved from ONE: " +(String)result[1]); } } public ONEProvisioningDriver(Properties prop) { XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); log.info("Creating OpenNebula conector"); if (prop.containsKey(URL_PROPERTY)) { oneURL = (String) prop.get(URL_PROPERTY); log.info("URL created: " + oneURL); } if (prop.containsKey(USER_PROPERTY)&&prop.containsKey(PASSWORD_PROPERTY)) { oneSession = ((String) prop.get(USER_PROPERTY)) + ":" + ((String) prop.get(PASSWORD_PROPERTY)); log.info("Session created: " + oneSession); } if (prop.containsKey(KERNEL_PROPERTY)) { hypervisorKernel = ((String) prop.get(KERNEL_PROPERTY)); } if (prop.containsKey(INITRD_PROPERTY)) { hypervisorInitrd = ((String) prop.get(INITRD_PROPERTY)); } if (prop.containsKey(ARCH_PROPERTY)) { arch = ((String) prop.get(ARCH_PROPERTY)); } if (prop.containsKey("com.telefonica.claudia.customization.port")) { customizationPort = ((String) prop.get(Main.CUSTOMIZATION_PORT_PROPERTY)); } if (prop.containsKey(ENVIRONMENT_PROPERTY)) { environmentRepositoryPath = (String) prop.get(ENVIRONMENT_PROPERTY); } if (prop.containsKey(NETWORK_BRIDGE)) { networkBridge = ((String) prop.get(NETWORK_BRIDGE)); } if (prop.containsKey(this.ONE_VERSION)) { oneversion = ((String) prop.get(ONE_VERSION)); } if (prop.containsKey(XEN_DISK)) { xendisk = ((String) prop.get(XEN_DISK)); } if (prop.containsKey(SSHKEY_PROPERTY)) { oneSshKey = ((String) prop.get(SSHKEY_PROPERTY)); } if (prop.containsKey(SCRIPTPATH_PROPERTY)) { oneScriptPath = ((String) prop.get(SCRIPTPATH_PROPERTY)); log.info("oneScriptPath " + oneScriptPath); } if (prop.containsKey(ETH0_GATEWAY_PROPERTY)) { eth0Gateway= ((String) prop.get(ETH0_GATEWAY_PROPERTY)); } if (prop.containsKey(ETH0_DNS_PROPERTY)) { eth0Dns = ((String) prop.get(ETH0_DNS_PROPERTY)); } if (prop.containsKey(ETH1_GATEWAY_PROPERTY)) { eth1Gateway = ((String) prop.get(ETH1_GATEWAY_PROPERTY)); } if (prop.containsKey(ETH1_DNS_PROPERTY)) { eth1Dns = ((String) prop.get(ETH1_DNS_PROPERTY)); } if (prop.containsKey(NET_INIT_SCRIPT0)) { netInitScript0 = ((String) prop.get(NET_INIT_SCRIPT0)); } if (prop.containsKey(NET_INIT_SCRIPT1)) { netInitScript1 = ((String) prop.get(NET_INIT_SCRIPT1)); } try { config.setServerURL(new URL(oneURL)); } catch (MalformedURLException e) { log.error("Malformed URL: " + oneURL); throw new RuntimeException(e); } String server = null; if (prop.containsKey("com.telefonica.claudia.server.host")) { server = ((String) prop.get("com.telefonica.claudia.server.host")); } xmlRpcClient = new XmlRpcClient(); log.info("XMLRPC client created"); xmlRpcClient.setConfig(config); log.info("XMLRPC client configured"); /* MIGRABILITY TAG */ text_migrability.put("cross-host", "HOST"); text_migrability.put("cross-sitehost", "SITE"); text_migrability.put("none", "NONE"); operations = new OneOperations(oneSession, xmlRpcClient); operations.configOperations(oneversion, networkBridge, environmentRepositoryPath, oneScriptPath,oneSshKey, customizationPort, hypervisorInitrd, hypervisorKernel, xendisk, arch, server,netInitScript0,netInitScript1); netUtils = new OneNetUtilities(networkBridge); // FULL?? } @SuppressWarnings("unchecked") public Document getVirtualMachineState(String id) throws IOException { List rpcParams = new ArrayList (); rpcParams.add(oneSession); rpcParams.add(new Integer(id)); log.debug("Virtual machine info requested for id: " + id); Object[] result = null; try { result = (Object[])xmlRpcClient.execute(VM_GETINFO_COMMAND, rpcParams); } catch (XmlRpcException ex) { log.error("Connection error trying to get VM information: " + ex.getMessage()); throw new IOException ("Error on reading VM state , XMLRPC call failed", ex); } boolean completed = (Boolean) result[0]; if (completed) { String resultList = (String) result[1]; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // RESERVOIR ONLY: the info cames with a XML inside the element RAW_VMI, WITH HEADERS if (resultList.contains("<RAW_VMI>")) { resultList = resultList.replace(resultList.substring(resultList.indexOf("<RAW_VMI>"), resultList.indexOf("</RAW_VMI>") + 10), ""); } try { DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ByteArrayInputStream(resultList.getBytes())); log.debug("VM Info request succeded"); return doc; } catch (ParserConfigurationException e) { log.error("Error configuring parser: " + e.getMessage()); throw new IOException ("Parser Configuration Error", e); } catch (SAXException e) { log.error("Parse error obtaining info: " + e.getMessage()); throw new IOException ("XML Parse error", e); } } else { log.error("VM Info request failed: " + result[1]); return null; } } public String getAtributeVirtualSystem(VirtualSystemType vs, String attribute) throws NumberFormatException { Iterator itr = vs.getOtherAttributes().entrySet().iterator(); while (itr.hasNext()) { Map.Entry e = (Map.Entry)itr.next(); if ((e.getKey()).equals(new QName ("http://schemas.telefonica.com/claudia/ovf", attribute))) return (String)e.getValue(); } return ""; } public ArrayList<VirtualSystemType> getVirtualSystem (EnvelopeType envelope) throws Exception { ContentType entityInstance = null; ArrayList<VirtualSystemType> virtualSystems = new ArrayList (); try { entityInstance = OVFEnvelopeUtils.getTopLevelVirtualSystemContent(envelope); } catch (EmptyEnvelopeException e) { log.error(e); } HashMap<String,VirtualSystemType> virtualsystems = new HashMap(); if (entityInstance instanceof VirtualSystemType) { virtualSystems.add((VirtualSystemType)entityInstance); } else if (entityInstance instanceof VirtualSystemCollectionType) { VirtualSystemCollectionType virtualSystemCollectionType = (VirtualSystemCollectionType) entityInstance; for (VirtualSystemType vs : OVFEnvelopeUtils.getVirtualSystems(virtualSystemCollectionType)) { virtualSystems.add(vs); } }//End for return virtualSystems; } @Override public long deleteNetwork(String netFqn) throws IOException { return TaskManager.getInstance().addTask(new UndeployNetworkTask(netFqn), URICreation.getVDC(netFqn)).getTaskId(); } @Override public long deleteVirtualMachine(String vmFqn) throws IOException { return TaskManager.getInstance().addTask(new UndeployVMTask(vmFqn), URICreation.getVDC(vmFqn)).getTaskId(); } @Override public long deployNetwork(String org, String vdc, String network, String ovf) throws IOException { String netFqn = URICreation.getNetworkFQN(org, vdc, network); return TaskManager.getInstance().addTask(new DeployNetworkTask(netFqn, ovf), URICreation.getVDC(netFqn)).getTaskId(); } @Override public long deployVirtualMachine(String fqn, String ovf) throws IOException { return TaskManager.getInstance().addTask(new DeployVMTask(fqn, ovf), URICreation.getVDC(fqn)).getTaskId(); } public long powerActionVirtualMachine(String fqn, String action) throws IOException { return TaskManager.getInstance().addTask(new ActionVMTask(fqn, action), URICreation.getVDC(fqn)).getTaskId(); } public String getNetwork(String fqn) throws IOException { // TODO Auto-generated method stub return null; } @Override public String getNetworkList() throws IOException { // TODO Auto-generated method stub return null; } @Override public String getVirtualMachine(String fqn) throws IOException { String id = null; try { id = getVmId(fqn).toString(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // deleteVirtualMachine(id); String xml = null; try { String result = operations.getVirtualMachine(id); System.out.println ("RESULT " + result); ONEUtilities utils = new ONEUtilities (); HashMap data = utils.getCpuRamDisk (result); HashMap ips = utils.getNetworksIp(result); xml = utils.generateXMLVEE (fqn, ips, (String)data.get("CPU"), (String)data.get("MEMORY"), (String)data.get("DISK")); } catch (Exception e) { return null; } return xml; } }