1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-16 22:50:10 +03:00

Adding migrate capabilities to VMWare VMM

git-svn-id: http://svn.opennebula.org/one/trunk@497 3034c82b-c49b-4eb3-8279-a7acafdc01c0
This commit is contained in:
Constantino Vázquez Blanco 2009-04-30 18:02:08 +00:00
parent 7f2a1129b9
commit 5e106d57d7
4 changed files with 571 additions and 95 deletions

View File

@ -39,9 +39,10 @@ public class DeployVM
static AppUtil cb = null;
private static VimPortType service;
private String datacenterName ="";
private String datastoreName ="";
private String vmName ="";
private String datacenterName = "";
private String datastoreName = "";
private String vmName = "";
private String vmDiskName = "";
ParseXML pXML;
@ -111,7 +112,7 @@ public class DeployVM
if(hostFound)
{
String vmxPath = "[" + getDataStoreName() + "]"+getVmName()+"/"+getVmName()+".vmx";
String vmxPath = "[" + getDataStoreName() + "]"+getDiskName()+"/"+getDiskName()+".vmx";
// Resource Pool
ManagedObjectReference resourcePool
= cb.getServiceUtil().getFirstDecendentMoRef(null, "ResourcePool");
@ -149,6 +150,15 @@ public class DeployVM
{
return vmName;
}
/**
* Gets the name of the VMX file and folder
* @returns name of the VMX file and folder
*/
private String getDiskName()
{
return vmDiskName;
}
/**
@ -382,22 +392,71 @@ public class DeployVM
}
*/
DeployVM(AppUtil _cb, String hostName, ParseXML _pXML) throws Exception
DeployVM(String[] args, String hostName, ParseXML _pXML) throws Exception
{
cb = _cb;
String[] argsWithHost = new String[args.length+2];
for(int i=0;i<args.length;i++)
{
argsWithHost[i] = args[i];
}
argsWithHost[args.length] = "--url";
// TODO this is just for testing
// argsWithHost[arguments.length + 1 ] = "https://" + hostName + ":443/sdk";
argsWithHost[args.length + 1 ] = "https://localhost:8008/sdk";
cb = AppUtil.initialize("DeployVM", null, argsWithHost);
cb.connect();
// TODO get this dynamically
datastoreName = "datastore1";
datacenterName = "ha-datacenter";
vmName = _pXML.getName();
pXML = _pXML;
vmName = _pXML.getName();
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();
}
DeployVM(String[] args, String hostName, String _vmName) throws Exception
{
String[] argsWithHost = new String[args.length+2];
for(int i=0;i<args.length;i++)
{
argsWithHost[i] = args[i];
}
argsWithHost[args.length] = "--url";
// TODO this is just for testing
// argsWithHost[arguments.length + 1 ] = "https://" + hostName + ":443/sdk";
argsWithHost[args.length + 1 ] = "https://localhost:8008/sdk";
cb = AppUtil.initialize("DeployVM", null, argsWithHost);
cb.connect();
// TODO get this dynamically
datastoreName = "datastore1";
datacenterName = "ha-datacenter";
vmName = _vmName;
vmDiskName = _vmName.substring(0,_vmName.lastIndexOf("-"));
// 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();

View File

@ -25,7 +25,7 @@ import com.vmware.apputils.vim.*;
class OneVmmVmware extends Thread
{
private String[] argsWithHost;
private String[] arguments;
OperationsOverVM oVM;
// Helpers from VI samples
@ -47,31 +47,7 @@ class OneVmmVmware extends Thread
// Constructor
OneVmmVmware(String[] args)
{
argsWithHost = new String[args.length+2];
for(int i=0;i<args.length;i++)
{
argsWithHost[i] = args[i];
}
argsWithHost[args.length] = "--url";
// TODO this is just for testing
// argsWithHost[arguments.length + 1 ] = "https://" + hostName + ":443/sdk";
argsWithHost[args.length + 1 ] = "https://localhost:8008/sdk";
try
{
cb = AppUtil.initialize("OneVmmVmware", null, argsWithHost);
cb.connect();
oVM = new OperationsOverVM(cb);
}
catch(Exception e)
{
System.out.println("Error stablishing connection to ESX host. Reason: " +
e.getMessage());
System.exit(-1);
}
arguments = args;
}
protected void finalize() throws Throwable
@ -109,7 +85,7 @@ class OneVmmVmware extends Thread
}
}
String str_split[] = str.split(" ", 4);
String str_split[] = str.split(" ", 5);
action = str_split[0].toUpperCase();
@ -128,12 +104,14 @@ class OneVmmVmware extends Thread
if (action.equals("DEPLOY"))
{
if (str_split.length != 4)
{
{
System.out.println("FAILURE Wrong number of arguments for DEPLOY action. Number args = [" +
str_split.length + "].");
synchronized (System.err)
{
System.out.println("FAILURE Wrong number of arguments for DEPLOY action. Number args = [" +
str_split.length + "].");
}
System.err.println(action + " FAILURE " + vid_str);
continue;
}
}
else
{
@ -147,11 +125,11 @@ class OneVmmVmware extends Thread
ParseXML pXML = new ParseXML(fileName);
// First, register the VM
DeployVM dVM = new DeployVM(cb, hostName, pXML);
DeployVM dVM = new DeployVM(arguments, hostName, pXML);
if(!dVM.registerVirtualMachine())
{
throw new Exception("Error registering VM(" + pXML.getName() + ").");
// We will skip this error, it may be pre-registered
}
// Now, proceed with the reconfiguration
@ -161,13 +139,29 @@ class OneVmmVmware extends Thread
throw new Exception("Error reconfiguring VM (" + pXML.getName() + ").");
}
try
{
oVM = new OperationsOverVM(arguments,hostName);
}
catch(Exception e)
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed connection to host " +
hostName +". Reason: " + e.getMessage());
}
continue;
}
if(!oVM.powerOn(pXML.getName()))
{
throw new Exception("Error powering on VM(" + pXML.getName() + ").");
}
System.err.println("DEPLOY SUCCESS " + vid_str + " " + pXML.getName());
synchronized (System.err)
{
System.err.println("DEPLOY SUCCESS " + vid_str + " " + pXML.getName() + "-" + vid_str);
}
continue;
@ -176,10 +170,14 @@ class OneVmmVmware extends Thread
{
System.out.println("Failed deploying VM " + vid_str + " into " + hostName +
".Reason:" + e.getMessage());
e.printStackTrace();
// TODO make DEBUG option
// e.printStackTrace();
System.err.println("DEPLOY FAILURE " + vid_str + " Failed deploying VM in host " +
hostName + ". Please check the VM log.");
synchronized (System.err)
{
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"))
@ -187,11 +185,14 @@ class OneVmmVmware extends Thread
if (action.equals("SHUTDOWN"))
{
if (str_split.length < 3 )
{
{
System.out.println("FAILURE Wrong number of arguments for SHUTDOWN action. Number args = [" +
str_split.length + "].");
synchronized (System.err)
{
System.out.println("FAILURE Wrong number of arguments for SHUTDOWN action. Number args = [" +
str_split.length + "].");
System.err.println(action + " FAILURE " + vid_str);
continue;
}
}
else
@ -201,14 +202,34 @@ class OneVmmVmware extends Thread
hostName = str_split[2];
String vmName = str_split[3];
try
{
oVM = new OperationsOverVM(arguments,hostName);
}
catch(Exception e)
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed connection to host " +
hostName +". Reason: " + e.getMessage());
}
continue;
}
if(!oVM.powerOff(vmName))
{
System.err.println("SHUTDOWN FAILURE " + vid_str + " Failed shutdown VM in host " +
hostName);
synchronized (System.err)
{
System.err.println("SHUTDOWN FAILURE " + vid_str + " Failed shutdown VM in host " +
hostName);
}
}
else
{
System.err.println("SHUTDOWN SUCCESS " + vid_str);
synchronized (System.err)
{
System.err.println("SHUTDOWN SUCCESS " + vid_str);
}
}
}
@ -218,12 +239,15 @@ class OneVmmVmware extends Thread
if (action.equals("SHUTDOWN") || action.equals("CANCEL"))
{
if (str_split.length < 3 )
{
{
System.out.println("FAILURE Wrong number of arguments for " + action +
" action. Number args = [" +
str_split.length + "].");
synchronized (System.err)
{
System.out.println("FAILURE Wrong number of arguments for " + action +
" action. Number args = [" +
str_split.length + "].");
System.err.println(action + " FAILURE " + vid_str);
continue;
}
}
else
@ -233,77 +257,313 @@ class OneVmmVmware extends Thread
hostName = str_split[2];
String vmName = str_split[3];
try
{
oVM = new OperationsOverVM(arguments,hostName);
}
catch(Exception e)
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed connection to host " +
hostName +". Reason: " + e.getMessage());
}
continue;
}
if(!oVM.powerOff(vmName))
{
System.err.println(action + " FAILURE " + vid_str + " Failed shutdown VM in host " +
hostName);
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed shutdown VM in host " +
hostName);
}
}
else
{
System.err.println(action + " SUCCESS " + vid_str);
synchronized (System.err)
{
System.err.println(action + " SUCCESS " + vid_str);
}
}
}
continue;
} // if (action.equals("SHUTDOWN or CANCEL"))
if (action.equals("SUSPEND"))
if (action.equals("SAVE"))
{
if (str_split.length < 4)
{
{
System.out.println("FAILURE Wrong number of arguments for SAVE action. Number args = [" +
str_split.length + "].");
synchronized (System.err)
{
System.out.println("FAILURE Wrong number of arguments for SUSPEND action. Number args = [" +
str_split.length + "].");
System.err.println(action + " FAILURE " + vid_str);
continue;
}
}
else
{
vid_str = str_split[1];
hostName = str_split[2];
String vmName = str_split[3];
vid_str = str_split[1];
hostName = str_split[2];
String vmName = str_split[3];
String checkpointName = str_split[4];
if(!oVM.suspend(vmName))
try
{
System.err.println(action + " FAILURE " + vid_str + " Failed suspending VM in host " +
hostName);
oVM = new OperationsOverVM(arguments,hostName);
}
catch(Exception e)
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed connection to host " +
hostName +". Reason: " + e.getMessage());
}
continue;
}
if(!oVM.save(vmName,checkpointName))
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed suspending VM in host " +
hostName);
}
}
else
{
System.err.println(action + " SUCCESS " + vid_str);
synchronized (System.err)
{
System.err.println(action + " SUCCESS " + vid_str);
}
}
continue;
}
} // if (action.equals("SUSPEND"))
} // if (action.equals("SAVE"))
if (action.equals("CHECKPOINT"))
{
vid_str = str_split[1];
System.err.println(action + " FAILURE " + vid_str + " Action not supported");
continue;
if (str_split.length < 4)
{
System.out.println("FAILURE Wrong number of arguments for CHECKPOINT action. Number args = [" +
str_split.length + "].");
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str);
continue;
}
}
else
{
vid_str = str_split[1];
hostName = str_split[2];
String vmName = str_split[3];
String checkpointName = str_split[4];
try
{
oVM = new OperationsOverVM(arguments,hostName);
}
catch(Exception e)
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed connection to host " +
hostName +". Reason: " + e.getMessage());
}
continue;
}
if(!oVM.createCheckpoint(vmName,checkpointName))
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed suspending VM in host " +
hostName);
}
}
else
{
synchronized (System.err)
{
System.err.println(action + " SUCCESS " + vid_str);
}
}
continue;
}
} // if (action.equals("CHECKPOINT"))
if (action.equals("RESTORE"))
{
vid_str = str_split[1];
System.err.println(action + " FAILURE " + vid_str + " Action not supported");
continue;
if (str_split.length < 4)
{
System.out.println("FAILURE Wrong number of arguments for RESTORE " +
"action. Number args = [" + str_split.length + "].");
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str);
continue;
}
}
else
{
vid_str = str_split[1];
hostName = str_split[2];
String checkpointName = str_split[3];
boolean result;
try
{
oVM = new OperationsOverVM(arguments,hostName);
}
catch(Exception e)
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed connection to host " +
hostName +". Reason: " + e.getMessage());
continue;
}
}
if(!oVM.restoreCheckpoint("one-"+vid_str,checkpointName))
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed restoring VM in host " +
hostName);
}
}
else
{
synchronized (System.err)
{
System.err.println(action + " SUCCESS " + vid_str);
}
}
continue;
}
} // if (action.equals("RESTORE"))
if (action.equals("MIGRATE"))
{
vid_str = str_split[1];
System.err.println(action + " FAILURE " + vid_str + " Action not supported");
continue;
} // if (action.equals("MIGRATE"))
{
if (str_split.length < 4)
{
System.out.println("FAILURE Wrong number of arguments for MIGTRATE " +
"action. Number args = [" + str_split.length + "].");
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str);
continue;
}
}
else
{
vid_str = str_split[1];
String sourceHostName = str_split[2];
String vmName = str_split[3];
String destHostName = str_split[4];
// First, create the checkpoint
try
{
oVM = new OperationsOverVM(arguments,sourceHostName);
}
catch(Exception e)
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed connection to host " +
sourceHostName +". Reason: " + e.getMessage());
}
continue;
}
// First, checkpoint the running virtual machine
String checkpointName = "one-migrate-" + vid_str;
if(!oVM.save(vmName,checkpointName))
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed saving VM in host " +
sourceHostName);
continue;
}
}
// Now, we stop it
if(!oVM.powerOff(vmName))
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed shutdown VM in host " +
sourceHostName);
}
}
// Now, register machine in new host
DeployVM dVM;
try
{
oVM = new OperationsOverVM(arguments,destHostName);
dVM = new DeployVM(arguments, destHostName, vmName);
if(!dVM.registerVirtualMachine())
{
// We will skip this error, it may be pre-registered
}
// Power it On
if(!oVM.powerOn(vmName))
{
throw new Exception();
}
}
catch(Exception e)
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed registering VM ["
+ vmName + "] in host " + destHostName);
}
continue;
}
// Restore the virtual machine checkpoint
if(!oVM.restoreCheckpoint(vmName,checkpointName))
{
synchronized (System.err)
{
System.err.println(action + " FAILURE " + vid_str + " Failed restoring VM [" +
vmName + "] in host " + destHostName);
}
}
else
{
synchronized (System.err)
{
System.err.println(action + " SUCCESS " + vid_str);
}
}
continue;
}
} // if (action.equals("MIGRATE"))
} // else if (action.equals("FINALIZE"))
} // while(!fin)
} // loop

View File

@ -106,8 +106,15 @@ public class OperationsOverVM
}
}
public boolean suspend(String vmName)
public boolean save(String vmName, String checkpointName)
{
// first, create the checkpoint
if(!createCheckpoint(vmName,checkpointName))
{
return false;
}
try
{
ManagedObjectReference taskmor = null;
@ -127,11 +134,143 @@ public class OperationsOverVM
return false;
}
}
OperationsOverVM(AppUtil _cb) throws Exception
public boolean createCheckpoint(String vmName, String checkpointName)
{
cb = _cb;
try
{
ManagedObjectReference virtualMachine
= cb.getServiceUtil().getDecendentMoRef(null, "VirtualMachine", vmName);
ManagedObjectReference taskMor
= cb.getConnection().getService().createSnapshot_Task(
virtualMachine, checkpointName,
"This checkpoint corresponds to filename = " +
checkpointName, false, false);
String res = cb.getServiceUtil().waitForTask(taskMor);
if(res.equalsIgnoreCase("sucess")) // sic
{
return true;
}
else
{
return false;
}
}
catch(Exception e)
{
System.out.println("Error checkpointing VirtualMachine [" + vmName + "]. Reason:" + e.getMessage());
return false;
}
}
public boolean restoreCheckpoint(String vmName, String checkpointName)
{
try
{
ManagedObjectReference snapmor = null;
ManagedObjectReference virtualMachine
= cb.getServiceUtil().getDecendentMoRef(null, "VirtualMachine", vmName);
ObjectContent[] snaps = cb.getServiceUtil().getObjectProperties(
null, virtualMachine, new String[] { "snapshot" } );
VirtualMachineSnapshotInfo snapInfo = null;
if (snaps != null && snaps.length > 0)
{
ObjectContent snapobj = snaps[0];
DynamicProperty[] snapary = snapobj.getPropSet();
if (snapary != null && snapary.length > 0)
{
snapInfo = ((VirtualMachineSnapshotInfo)(snapary[0]).getVal());
}
}
else
{
throw new Exception("No Snapshots found for VirtualMachine : " + vmName);
}
VirtualMachineSnapshotTree[] snapTree = snapInfo.getRootSnapshotList();
if (snapTree == null)
{
throw new Exception("No Snapshots Tree found for VirtualMachine : " + vmName);
}
snapmor = traverseSnapshotInTree(snapTree, checkpointName);
if (snapmor == null)
{
throw new Exception("No Snapshot named " + checkpointName +
" found for VirtualMachine : " + vmName);
}
ManagedObjectReference taskMor
= cb.getConnection().getService().revertToSnapshot_Task(snapmor,null);
String res = cb.getServiceUtil().waitForTask(taskMor);
if(!res.equalsIgnoreCase("sucess")) // sic
{
throw new Exception("Unknown problem while creating the snapshot.");
}
return true;
}
catch(Exception e)
{
System.out.println("Error checkpointing VirtualMachine [" + vmName + "]. Reason:" + e.getMessage());
return false;
}
}
private ManagedObjectReference traverseSnapshotInTree(
VirtualMachineSnapshotTree[] snapTree,
String checkpointName)
{
ManagedObjectReference snapmor = null;
if (snapTree == null)
{
return snapmor;
}
for (int i = 0; i < snapTree.length && snapmor == null; i++)
{
VirtualMachineSnapshotTree node = snapTree[i];
if ( checkpointName != null && node.getName().equals(checkpointName) )
{
snapmor = node.getSnapshot();
}
else
{
VirtualMachineSnapshotTree[] childTree = node.getChildSnapshotList();
snapmor = traverseSnapshotInTree(childTree, checkpointName);
}
}
return snapmor;
}
OperationsOverVM(String[] args, String hostName) throws Exception
{
String[] argsWithHost = new String[args.length+2];
for(int i=0;i<args.length;i++)
{
argsWithHost[i] = args[i];
}
argsWithHost[args.length] = "--url";
// TODO this is just for testing
// argsWithHost[arguments.length + 1 ] = "https://" + hostName + ":443/sdk";
argsWithHost[args.length + 1 ] = "https://localhost:8008/sdk";
cb = AppUtil.initialize("DeployVM", null, argsWithHost);
cb.connect();
// TODO get this dynamically
datastoreName = "datastore1";

View File

@ -18,6 +18,7 @@ public class ParseXML
private String[] disk = {""};
private String memory = "";
private String[] macs = {""};
private String vmID = "";
/**
* Parses the XML file and fills the values
@ -50,6 +51,14 @@ public class ParseXML
}
name = ((Node)nameNL.item(0)).getFirstChild().getNodeValue().trim();
// VM_ID
NodeList vmIDNL = vm.getElementsByTagName("VM_ID");
if(vmIDNL.getLength()!=1)
{
throw new Exception("Number of VM_ID tags different of 1: [" + vmIDNL.getLength() + "]");
}
vmID = ((Node)vmIDNL.item(0)).getFirstChild().getNodeValue().trim();
// CPU
NodeList cpuNL = vm.getElementsByTagName("CPU");
@ -143,10 +152,19 @@ public class ParseXML
/**
* Returns VM name
* @return anme of the VM
* @return name of the VM
**/
String getName()
{
return name;
}
/**
* Returns VM id
* @return ID of the VM
**/
String getVMID()
{
return vmID;
}
}