Hi All,
I'm new to VSphere. I have written a C# program to clone VM. Earlier we have used CloneVM_Task and it worked fine but now we are changing our environment to Datastore-clusters
so I have modified my code to use "ApplyStorageDrsRecommendation_Task".
Every time I'm running the code, the error "The object has already been deleted or has not been completely created" is thrown from "_service.RecommendDatastores.." Method.
I have been working with this more than a week now and still couldn't figure out the issue. Search in the internet didn't return me a any single example of C# Dot net.
Can you help me to figure this out ?
Herewith I have attached the code that I have written ( CreateVMTask and SetUpVMClone ) and I'm using SDK Version 5.5.
public string CreateVMTask(string url, string userId, string pwd, string dcName, string vmTemplate, string vCenterCluster, string newVMName, long vmRequiredMinSize, string vmSandboxPath, string vmTemplatePath, string vmNote)
{
log("Enter CreateVM:CreateVMTask()",true);
this.CreateServiceRef();
try
{
this.Connect(url, userId, pwd);
// Check whether the connection is made to a vCenter
if (!"VirtualCenter".Equals(_sic.about.apiType))
{
//_service.Logout(searchIndex);
return "Failed to Create VM. The connection to the vCenter has been failed.";
}
// MOR for searching
searchIndex = new ManagedObjectReference();
searchIndex = _sic.searchIndex;
// 1. Check whether the Datacenter is exist
ManagedObjectReference datacenterRef = _service.FindByInventoryPath(searchIndex, dcName);
if (datacenterRef == null)
{
// _service.Logout(searchIndex);
return "Failed to Create VM. No Datacenter found with name, " + dcName;
}
// 2. Finding the VM folder that used to save the newly created VM
ManagedObjectReference vmCreateLocation = _service.FindByInventoryPath(searchIndex, vmSandboxPath);
if (vmCreateLocation == null)
{
// _service.Logout(searchIndex);
return "Failed to Create VM. Invalid path to craete Sandbox, " + vmSandboxPath;
}
// 3. Finding the template Virtual Machine
ManagedObjectReference vmRef = _service.FindByInventoryPath(searchIndex, vmTemplatePath + "/" + vmTemplate);
if (vmRef == null)
{
// _service.Logout(searchIndex);
return "Failed to Create VM. No VM Template found in path " + vmTemplatePath + " named - " + vmTemplate;
}
// 4. Finding the hosts for the given Datacenter
ManagedObjectReference hostFolderRef = (ManagedObjectReference)getObjectProperty(datacenterRef, "hostFolder");
ManagedObjectReference[] hostRef = (ManagedObjectReference[])getObjectProperty(hostFolderRef, "childEntity");
if (hostRef == null)
{
//_service.Logout(searchIndex); ;
return "Failed to Create VM. No Hosts are found in the Datacenter " + dcName;
}
// 5. Finding the vCenter cluster location
int vCenterClusterIndex = 0;
for (int i = 0; i < hostRef.Length; i++)
{
if (vCenterCluster.Equals((string)getObjectProperty(hostRef[i], "name")))
{
vCenterClusterIndex = i;
break;
}
}
//////ManagedObjectReference vCenterClusterRefTest = _service.FindByInventoryPath(searchIndex, "StoragePod");
// 7. Find Resource Pool for the Host
ManagedObjectReference resourcePoolRootRef = (ManagedObjectReference)getObjectProperty(hostRef[vCenterClusterIndex], "resourcePool");
if (resourcePoolRootRef == null)
return "Failed to Create VM. Unable to Find the Resource Pool for the Host";
// 8. Find the Customization Spec
string specName = dcName + "_" + vmTemplate; // Example : PDE-StdEnv-v3
ManagedObjectReference specManager = _sic.customizationSpecManager;
CustomizationSpecItem customizationSpecItem = _service.GetCustomizationSpec(specManager, specName);
if( customizationSpecItem == null )
return "Failed to Create VM. Unable to Find the Customization Spec : " + specName;
this.SetUpVMClone(datacenterRef, resourcePoolRootRef, customizationSpecItem, vmRef, vmCreateLocation, newVMName, vmNote);
log("Exist CreateVM:CreateVMTask()");
}
catch (Exception e)
{
//_service.Logout(searchIndex);
sReturnMsg = "Failed to create VM " + newVMName + " Exception : " + e.Message;
}
finally {
this.Disconnect();
}
return sReturnMsg;
}
private void SetUpVMClone(ManagedObjectReference datastoreRef, ManagedObjectReference resourcePoolRootRef, CustomizationSpecItem customizationSpecItem, ManagedObjectReference vmRef, ManagedObjectReference vmCreateLocation, string newVMName, string sVMNote)
{
// 9. Set up Virtual Machine Clone Spec
VirtualMachineRelocateSpec relocSpec = new VirtualMachineRelocateSpec();
relocSpec.pool = resourcePoolRootRef;
VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
configSpec.annotation = sVMNote;
VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
cloneSpec.location = relocSpec;
cloneSpec.powerOn = true;
cloneSpec.template = false;
cloneSpec.customization = customizationSpecItem.spec;
cloneSpec.config = configSpec;
ManagedObjectReference storagePod = new ManagedObjectReference();
storagePod.Value = "DONOTUSE-01"; //Name of the DataStore Cluster
storagePod.type = "StoragePod";
StorageDrsPodSelectionSpec stDrsPodSpec = new StorageDrsPodSelectionSpec();
stDrsPodSpec.storagePod = storagePod;
StoragePlacementSpec stPlcMntSpec = new StoragePlacementSpec();
stPlcMntSpec.cloneName = newVMName;
stPlcMntSpec.cloneSpec = cloneSpec;
stPlcMntSpec.podSelectionSpec = stDrsPodSpec;
stPlcMntSpec.folder = vmCreateLocation;
stPlcMntSpec.type = "clone";
stPlcMntSpec.vm = vmRef;
ManagedObjectReference stRecManager = _sic.storageResourceManager;
StoragePlacementResult stPlacMntResult = _service.RecommendDatastores(stRecManager, stPlcMntSpec); // Error Throws at this line
string []keys = new string[ stPlacMntResult.recommendations.Length ];
for (int i = 0; i < stPlacMntResult.recommendations.Length; i++ )
{
keys[i] = stPlacMntResult.recommendations[i].key;
}
log("Start creating the VM clonning task - ApplyStorageDrsRecommendation_Task ");
ManagedObjectReference cloneTask = _service.ApplyStorageDrsRecommendation_Task(stRecManager, keys );
if (cloneTask != null)
{
object[] result =
WaitForValues(cloneTask, new string[] { "info.state", "info.error" },
new string[] { "state" }, // info has a property - state for state of the task
new object[][] { new object[] { TaskInfoState.success, TaskInfoState.error } });
// Wait till the task completes.
if (result[0].Equals(TaskInfoState.success))
{
//_service.Logout(searchIndex);
sReturnMsg = SSUtil.SUCCESS;
}
else
{
//_service.Logout(searchIndex);
sReturnMsg = "Failed to create VM (" + result[0] + ") -" + newVMName;
}
}
else
{
sReturnMsg = "Failed to create VM " + newVMName + "VM clonning task failed.";
}
log("CreateVM:SetUpVMClone() - Return Message : " + sReturnMsg);
}