tvrlk
Contributor
Contributor

RecommendDatastores with C# throws an error - The object has already been deleted or has not been completely created

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

0 Kudos
0 Replies