1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-03 13:47:01 +03:00

Initial commit of VMM driver for VMWare.

git-svn-id: http://svn.opennebula.org/one/trunk@482 3034c82b-c49b-4eb3-8279-a7acafdc01c0
This commit is contained in:
Constantino Vázquez Blanco 2009-04-22 14:44:34 +00:00
parent 1deda2d723
commit 2d60ce3229
4 changed files with 778 additions and 0 deletions

View File

@ -0,0 +1,401 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
import com.vmware.vim.*;
import com.vmware.apputils.*;
import com.vmware.apputils.vim.*;
import java.util.*;
import java.io.*;
import java.lang.*;
import java.rmi.RemoteException;
/*
* Used to register a VM preloaded
*/
public class DeployVM
{
// Helpers from VI samples
private static ServiceContent content;
private static AppUtil cb = null;
private static VimPortType service;
private String datacenterName ="";
private String datastoreName ="";
private String vmName ="";
ParseXML pXML;
// VM configuration objects
VirtualMachineConfigSpec vmConfigSpec;
VirtualMachineConfigInfo vmConfigInfo;
ManagedObjectReference virtualMachine;
com.vmware.vim.ManagedObjectReference hostMor;
public boolean registerVirtualMachine() throws Exception
{
boolean registered = false;
ManagedObjectReference host = null;
ManagedObjectReference dcmor
= cb.getServiceUtil().getDecendentMoRef(null, "Datacenter", getDataCenterName());
com.vmware.vim.ManagedObjectReference vmFolderMor
= (com.vmware.vim.ManagedObjectReference)
cb.getServiceUtil().getDynamicProperty(dcmor,"vmFolder");
// Default Host
com.vmware.vim.ManagedObjectReference hostFolderMor
= (com.vmware.vim.ManagedObjectReference)
cb.getServiceUtil().getDynamicProperty(dcmor,"hostFolder");
ArrayList hostList = (ArrayList)cb.getServiceUtil().getDecendentMoRefs(
hostFolderMor,"HostSystem");
if(hostList.size() < 1)
{
System.out.println("No host found in datacenter to"
+" register the Virtual Machine");
return registered;
}
else
{
boolean hostFound = false;
for(int i=0; i<hostList.size(); i++)
{
com.vmware.vim.ManagedObjectReference [] datastores
= (com.vmware.vim.ManagedObjectReference [])
cb.getServiceUtil().getDynamicProperty(hostMor,"datastore");
for(int j=0; j<datastores.length; j++)
{
com.vmware.vim.DatastoreSummary datastoreSummary
= (com.vmware.vim.DatastoreSummary)
cb.getServiceUtil().getDynamicProperty(datastores[j],"summary");
if(datastoreSummary.getName().equalsIgnoreCase(getDataStoreName()))
{
com.vmware.vim.DatastoreInfo datastoreInfo
= (com.vmware.vim.DatastoreInfo)
cb.getServiceUtil().getDynamicProperty(datastores[j],"info");
host = hostMor;
hostFound = true;
i = hostList.size()+1;
j = datastores.length+1;
}
}
}
if(hostFound)
{
String vmxPath = "[" + getDataStoreName() + "]"+getVmName()+"/"+getVmName()+".vmx";
// Resource Pool
ManagedObjectReference resourcePool
= cb.getServiceUtil().getFirstDecendentMoRef(null, "ResourcePool");
// Registering The Virtual machine
ManagedObjectReference taskmor
= cb.getConnection().getService().registerVM_Task(
vmFolderMor,vmxPath,getVmName(),false,resourcePool,host);
String result = cb.getServiceUtil().waitForTask(taskmor);
if (result.equalsIgnoreCase("Sucess"))
{
registered = true;
}
else
{
System.out.println("Some Exception While Registering The VM");
registered = false;
}
return registered;
}
else
{
System.out.println("No host in datacenter got the"
+" specified datastore and free space");
return registered;
}
}
}
/**
* Gets the name of the VM
* @returns name of the VM
*/
private String getVmName()
{
return vmName;
}
/**
* Gets the name of the datacenter
* @returns name of the datacenter
*/
private String getDataCenterName()
{
return datacenterName;
}
/**
* Gets the name of the datastore
* @returns name of the datastore
*/
private String getDataStoreName()
{
return datastoreName;
}
private boolean shapeVM() throws Exception
{
virtualMachine
= cb.getServiceUtil().getDecendentMoRef(null, "VirtualMachine", vmName);
vmConfigInfo
= (VirtualMachineConfigInfo)cb.getServiceUtil().getDynamicProperty(
virtualMachine,"config");
vmConfigSpec = new VirtualMachineConfigSpec();
ResourceAllocationInfo raInfo = new ResourceAllocationInfo();
SharesInfo sharesInfo = new SharesInfo();
// Memory
sharesInfo.setLevel(SharesLevel.custom);
sharesInfo.setShares(Integer.parseInt(pXML.getMemory()));
raInfo.setShares(sharesInfo);
vmConfigSpec.setMemoryAllocation(raInfo);
// CPU
sharesInfo = new SharesInfo();
raInfo = new ResourceAllocationInfo();
sharesInfo.setLevel(SharesLevel.custom);
sharesInfo.setShares(Integer.parseInt(pXML.getCPU()));
raInfo.setShares(sharesInfo);
vmConfigSpec.setCpuAllocation(raInfo);
// DISKs
addDisks();
// Network
configureNetwork();
// TODO CD for contextualization
/* if(deviceType.equalsIgnoreCase("cd")) {
System.out.println("Reconfiguring The Virtual Machine For CD Update "
+ cb.get_option("vmname"));
VirtualDeviceConfigSpec cdSpec = getCDDeviceConfigSpec();
if(cdSpec != null) {
VirtualDeviceConfigSpec [] cdSpecArray = {cdSpec};
vmConfigSpec.setDeviceChange(cdSpecArray);
}*/
ManagedObjectReference tmor
= cb.getConnection().getService().reconfigVM_Task(
virtualMachine, vmConfigSpec);
String result = cb.getServiceUtil().waitForTask(tmor);
if(!result.equalsIgnoreCase("sucess"))
{
return false;
}
return true;
}
void addDisks()
{
String[] disks = pXML.getDisk();
VirtualDeviceConfigSpec [] vdiskSpecArray = new VirtualDeviceConfigSpec[disks.length];
for(int i=0;i<disks.length;i++)
{
VirtualDeviceConfigSpec diskSpec = new VirtualDeviceConfigSpec();
VirtualDisk disk = new VirtualDisk();
VirtualDiskFlatVer2BackingInfo diskfileBacking
= new VirtualDiskFlatVer2BackingInfo();
int ckey = 0;
int unitNumber = 0;
VirtualDevice [] test = vmConfigInfo.getHardware().getDevice();
for(int k=0;k<test.length;k++)
{
if(test[k].getDeviceInfo().getLabel().equalsIgnoreCase(
"SCSI Controller 0"))
{
ckey = test[k].getKey();
}
}
unitNumber = test.length + 1;
String fileName = "["+datastoreName+"] "+ getVmName()
+ "/"+ disks[i];
diskfileBacking.setFileName(fileName);
// TODO make this configurable
diskfileBacking.setDiskMode("persistent");
disk.setControllerKey(ckey);
disk.setUnitNumber(unitNumber);
// TODO does this work
disk.setBacking(diskfileBacking);
//int size = 1024 * (Integer.parseInt(cb.get_option("disksize")));
disk.setCapacityInKB(8388608);
disk.setKey(-1);
diskSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
diskSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.create);
diskSpec.setDevice(disk);
vdiskSpecArray[i]=diskSpec;
}
vmConfigSpec.setDeviceChange(vdiskSpecArray);
}
void configureNetwork()
{
// Firt, let's find out the number of NICs to be removed
VirtualDevice [] test = vmConfigInfo.getHardware().getDevice();
String[] nics = pXML.getNet();
// Lenth of array is #nicsToBeRemoved-#nicsToBeAdded
VirtualDeviceConfigSpec [] nicSpecArray = new VirtualDeviceConfigSpec[test.length+
nics.length];
// Let's remove existing NICs
for(int i=0;i<test.length;i++)
{
VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
VirtualEthernetCard nic;
nicSpec.setOperation(VirtualDeviceConfigSpecOperation.remove);
nic = (VirtualEthernetCard)test[i];
nicSpec.setDevice(nic);
nicSpecArray[i] = nicSpec;
}
// Let's add specified NICs
for(int i=0;i<nics.length;i++)
{
VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
// TODO make this dynamic?
String networkName = "one-net";
nicSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
VirtualEthernetCard nic = new VirtualPCNet32();
VirtualEthernetCardNetworkBackingInfo nicBacking
= new VirtualEthernetCardNetworkBackingInfo();
nicBacking.setDeviceName(networkName);
nic.setAddressType(nics[i]);
nic.setBacking(nicBacking);
nic.setKey(4);
nicSpec.setDevice(nic);
nicSpecArray[i+test.length] = nicSpec;
}
}
/*
private String getDataStoreName(int size) throws Exception{
String dsName = null;
ManagedObjectReference [] datastores
= (ManagedObjectReference [])cb.getServiceUtil().getDynamicProperty(
_virtualMachine,"datastore");
for(int i=0; i<datastores.length; i++) {
DatastoreSummary ds
= (DatastoreSummary)cb.getServiceUtil().getDynamicProperty(datastores[i],
"summary");
if(ds.getFreeSpace() > size) {
dsName = ds.getName();
i = datastores.length + 1;
}
}
return dsName;
}
*/
DeployVM(String[] args, String hostName, String _vmName, ParseXML _pXML) throws Exception
{
cb = AppUtil.initialize("RegisterVM", null, args);
cb.connect();
// TODO get this dynamically
datastoreName = "datastore1";
datacenterName = "ha-datacenter";
vmName = _vmName;
pXML = _pXML;
// Get reference to host
hostMor = cb.getServiceUtil().getDecendentMoRef(null,"HostSystem",
hostName);
com.vmware.apputils.vim.ServiceConnection sc = cb.getConnection();
content = sc.getServiceContent();
service = sc.getService();
}
protected void finalize() throws Throwable
{
cb.disConnect();
}
}

View File

@ -0,0 +1,181 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad */
/* Complutense de Madrid (dsa-research.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
import java.io.*;
import com.vmware.vim.*;
import com.vmware.apputils.*;
import com.vmware.apputils.vim.*;
class OneVmmVmware extends Thread
{
private String[] arguments;
// Entry point - main procedure
public static void main(String[] args)
{
// first, make redirection
PrintStream stdout = System.out;
PrintStream stderr = System.err;
System.setOut(stderr);
System.setErr(stdout);
OneVmmVmware omv = new OneVmmVmware(args);
omv.loop();
}
// Constructor
OneVmmVmware(String[] args)
{
arguments = args;
}
// Main loop, threaded
void loop()
{
String str = null;
String action = null;
String vid_str = null;
String hostName;
String fileName;
boolean fin = false;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (!fin)
{
// Read a line a parse it
try
{
str = in.readLine();
}
catch (IOException e)
{
String message = e.getMessage().replace('\n', ' ');
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " " + message);
}
}
String str_split[] = str.split(" ", 4);
action = str_split[0].toUpperCase();
// Perform the action
if (action.equals("INIT"))
{
init();
}
else if (action.equals("FINALIZE"))
{
finalize_mad();
fin = true;
}
else
{
if (action.equals("DEPLOY"))
{
if (str_split.length != 4)
{
synchronized (System.err)
{
System.err.println("FAILURE Unknown command");
}
}
else
{
vid_str = str_split[1];
hostName = str_split[2];
fileName = str_split[3];
try
{
// First, register the VM
String[] argsWithHost = new String[arguments.length+2];
for(int i=0;i<arguments.length;i++)
{
argsWithHost[i] = arguments[i];
}
argsWithHost[arguments.length] = "--url";
// TODO this is just for testing
// argsWithHost[arguments.length + 1 ] = "https://" + hostName + ":443/sdk";
argsWithHost[arguments.length + 1 ] = "https://localhost:8008/sdk";
RegisterVM rVM = new RegisterVM(argsWithHost, hostName, "one-" + vid_str);
if(!rVM.registerVirtualMachine())
{
throw new Exception("Error registering VM.")
}
// Now, let's read the XML file and extract needed info
ParseXML pXML = new ParseXML(fileName);
// Now, proceed with the reconfiguration
if(!rVM.shapeVM())
{
throw new Exception("Error reconfiguring VM.")
}
}
catch(Exception e)
{
System.out.println("Failed deploying VM " + vid_str + " into " + hostName +
".Reason:" + e.getMessage());
e.printStackTrace();
System.err.println("DEPLOY FAILURE " + vid_str + " Failed deploying VM in host " +
hostName + ". Please check the VM log.");
} // catch
} // else if (str_split.length != 4)
} // if (action.equals("DEPLOY"))
} // else if (action.equals("FINALIZE"))
} // while(!fin)
} // loop
void init()
{
// Nothing to do here
synchronized(System.err)
{
System.err.println("INIT SUCCESS");
}
}
void finalize_mad()
{
// Nothing to do here
synchronized(System.err)
{
System.err.println("FINALIZE SUCCESS");
}
}
}

View File

@ -0,0 +1,140 @@
import java.io.File;
import org.w3c.dom.Document;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* Parses an XML file containing a VM description created by OpenNebula Core
**/
public class ParseXML
{
private String cpu;
private String[] disk;
private String memory;
private String[] macs;
/**
* Parses the XML file and fills the values
* @param fileName full path of the file to be parsed
**/
ParseXML(String fileName) throws Exception
{
try
{
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File(fileName));
doc.getDocumentElement().normalize();
NodeList vm = doc.getElementsByTagName("VM");
if(vm.getLength()!=1)
{
throw new Exception("Number of VM tags different of 1: [" + vm.getLength() + "]");
}
// CPU
NodeList cpuNL = doc.getElementsByTagName("CPU");
if(cpuNL.getLength()!=1)
{
throw new Exception("Number of CPU tags different of 1: [" + cpuNL.getLength() + "]");
}
cpu = ((Node)cpuNL.item(0)).getNodeValue().trim();
// Memory
NodeList memoryNL = doc.getElementsByTagName("MEMORY");
if(memoryNL.getLength()!=1)
{
throw new Exception("Number of MEMORY tags different of 1: [" + memoryNL.getLength() + "]");
}
memory = ((Node)memoryNL.item(0)).getNodeValue().trim();
// DISK
NodeList diskNL = doc.getElementsByTagName("DISK");
if(diskNL.getLength()!=0)
{
disk = new String[diskNL.getLength()];
for(int i=0; i<diskNL.getLength(); i++)
{
NodeList sourceNode = ((Element)diskNL).getElementsByTagName("SOURCE");
disk[i] = ((Node)sourceNode.item(0)).getNodeValue().trim();
}
}
// Network
NodeList nwNL = doc.getElementsByTagName("NIC");
if(nwNL.getLength()!=0)
{
macs = new String[nwNL.getLength()];
for(int i=0; i<nwNL.getLength(); i++)
{
NodeList mac = ((Element)nwNL).getElementsByTagName("MAC");
macs[i] = ((Node)mac.item(0)).getNodeValue().trim();
}
}
}
catch (SAXParseException err)
{
throw new Exception("** Parsing error" + ", line "
+ err.getLineNumber () + ", uri " + err.getSystemId ());
}
}// end ParseXML
/**
* Returns cpu value
* @return cpu number of cpus to be used by the VM
**/
String getCPU()
{
return cpu;
}
/**
* Returns disk value
* @return cpu array with the full local path of disks
**/
String[] getDisk()
{
return disk;
}
/**
* Returns memory value
* @return memory amount of memory in Kb to be used by this VM
**/
String getMemory()
{
return memory;
}
/**
* Returns networks MACs
* @return macs array with the macs of the NICs to be added to this VM
**/
String[] getNet()
{
return macs;
}
}

View File

@ -0,0 +1,56 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2009, Distributed Systems Architecture Group, Universidad #
# Complutense de Madrid (dsa-research.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
#Setup driver variables
DRIVER_NAME=`basename $0`
if [ -z "${ONE_LOCATION}" ]; then
DRIVERRC=/etc/one/${DRIVER_NAME}/${DRIVER_NAME}rc
MADCOMMON=/usr/lib/one/mads/madcommon.sh
else
DRIVERRC=$ONE_LOCATION/etc/${DRIVER_NAME}/${DRIVER_NAME}rc
MADCOMMON=$ONE_LOCATION/lib/mads/madcommon.sh
fi
. $MADCOMMON
# Export the im_mad specific rc
export_rc_vars $DRIVERRC
LOG_FILE=$DRIVER_NAME
MAD_FILE="OneVmmVmware"
if [ -z "${ONE_LOCATION}" ]; then
MAD_LOG_PATH=/var/log/one/$LOG_FILE.log
else
MAD_LOG_PATH=$ONE_LOCATION/var/$LOG_FILE.log
fi
# Execute the actual MAD
if [ -n "${ONE_MAD_DEBUG}" ]; then
exec nice -n $PRIORITY java -cp .:$CLASSPATH -Djavax.net.ssl.trustStore=$VMWARE_TRUSTORE -Xmx1024M $MAD_FILE $* 2>> $MAD_LOG_PATH
else
exec nice -n $PRIORITY java -cp .:$CLASSPATH -Djavax.net.ssl.trustStore=$VMWARE_TRUSTORE -Xmx1024M $MAD_FILE $* 2> /dev/null
fi