VMware Cloud Community
prashanthbk
Contributor
Contributor

Not able to do VM Relocation...getting 'fault_string' => 'The object has already been deleted or has not been completely created' - Need help

use VMware::VIRuntime;
use Data::Dumper;

my $service_url_01 = "https://10.xxx.yyy.zzz/sdk/vimService";

my $vim_obj = Vim->new(service_url => $service_url_01 );
my $vim_obj_session = $vim_obj->login(
            user_name => "abcd",
            password  => "xyz"
        );
       
my $source_host_view = $vim_obj_session->find_entity_view(view_type => 'HostSystem');     

my $service_url_02 = "https://10.xxx.yyy.zza/sdk/vimService";

my $vim_obj_02 = Vim->new(service_url => $service_url_02 );
my $vim_obj_session_02 = $vim_obj_02->login(
            user_name => "abcd",
            password  => "xyz"
        );

my $target_host_view = $vim_obj_session_02->find_entity_view(view_type => 'HostSystem');


my $source_vm;


my $target_datastore_mor;
if(defined $target_host_view->datastore) {
      $target_datastore_mor = $target_host_view->datastore;
      my $target_datastores = $vim_obj_session_02->get_views(mo_ref_array => $target_datastore_mor);


      foreach (@$target_datastores) {
         my $name = $_->summary->name;
         if($name eq 'VOL_f2240-132-112') {
            $target_datastore_mor = $_->{mo_ref};
         }
      }
   }


#Following is Virtual Center related  
my $service_url_03 = "https://10.xxx.yyy.bb/sdk/vimService";

my $vim_obj_03 = Vim->new(service_url => $service_url_03 );
my $vim_obj_session_03 = $vim_obj_03->login(
            user_name => "abcd",
            password  => "xyz"
        );

  
  
my $begin = $vim_obj_session_03->get_service_content()->rootFolder;

my $vmviews = $vim_obj_session_03->find_entity_views (view_type => 'VirtualMachine',
                                            begin_entity => $begin);
                                           
foreach my $vm (@{$vmviews}) {
    if ($vm->name eq 'RHEL6U2_ESXA_64') {
        ($source_vm) = $vm;
        last;
    }
}

my $target_pool = $vim_obj_session_03->find_entity_views(view_type => 'ResourcePool',
                                            begin_entity => $begin,
                                            filter => {name => 'Pool-101'});


my $resource_pool_mor_temp = @$target_pool[0];
my $resource_pool_mor = $resource_pool_mor_temp->{mo_ref};


my $relocate_spec = VirtualMachineRelocateSpec->new (
                                    datastore => $target_datastore_mor,
                                    host => $target_host_view,
                                    pool => $resource_pool_mor
                                );

eval {
$result = $source_vm->RelocateVM_Task(spec => $relocate_spec);
};
if($@){
    print "Fault Dump\n";
    print Dumper $@;
    print "\n";
}

Not able to do RelocateVM with the above code, I keep getting the following (it is dump of $@)

Fault Dump
$VAR1 = bless( {
                 'detail' => bless( {
                                      'obj' => bless( {
                                                        'value' => '10.xxx.yyy.ccc:/VOL112_ESXQUAL',
                                                        'type' => 'ManagedEntity'
                                                      }, 'ManagedObjectReference' )
                                    }, 'ManagedObjectNotFound' ),
                 'fault_string' => 'The object has already been deleted or has not been completely created',
                 'name' => 'ManagedObjectNotFoundFault'
               }, 'SoapFault' );

What is it that I am missing?  Need help

Reply
0 Kudos
10 Replies
lamw
Community Manager
Community Manager

Are you trying to do a Storage vMotion or vMotion?

The RelocateVM_Task() is for Storage vMotion and MigrateVM_Task() is for vMotion, in any case, I'll assume you're looking to use RelocateVM_Task.

Below is working script for a very basic Storage vMotion (e.g. moving all disks from the current datastore to the destination datatstore). I see that your code below is getting quite a bit of information and not all of that is necessary, as defined by the vSphere API reference guide.

#!/usr/bin/perl -w
# William Lam

use strict;
use warnings;
use VMware::VIRuntime;
use VMware::VILib;

my %opts = (
   vmname => {
      type => "=s",
      help => "Name of VM to relocate",
      required => 1,
   },
   datastore => {
      type => "=s",
      help => "Name of Datastore to relocate to",
      required => 1,
   },
);

Opts::add_options(%opts);
Opts::parse();
Opts::validate();
Util::connect();

my $vmname = Opts::get_option('vmname');
my $datastore = Opts::get_option('datastore');

my $vm_view = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'name' => $vmname});
my $ds_view = Vim::find_entity_view(view_type => 'Datastore', filter => {'name' => $datastore});

my $spec = VirtualMachineRelocateSpec->new(datastore => $ds_view);
eval {
        print "Relocating VM to " . $datastore . "\n";
        my $task = $vm_view->RelocateVM_Task(spec => $spec);
        &getStatus($task,"Successfully relocated VM!\n");
};
if($@) {
        print "Error: "  . $@ . "\n";
}

Util::disconnect();

sub getStatus {
        my ($taskRef,$message) = @_;

        my $task_view = Vim::get_view(mo_ref => $taskRef);
        my $taskinfo = $task_view->info->state->val;
        my $continue = 1;
        while ($continue) {
                my $info = $task_view->info;
                if ($info->state->val eq 'success') {
                        print $message;
                        $continue = 0;
                } elsif ($info->state->val eq 'error') {
                        my $soap_fault = SoapFault->new;
                        $soap_fault->name($info->error->fault);
                        $soap_fault->detail($info->error->fault);
                        $soap_fault->fault_string($info->error->localizedMessage);
                        die "$soap_fault\n";
                }
                sleep 5;
                $task_view->ViewBase::update_view_data();
        }
}

To run the script, you just need to point it to your vCenter Server and specify the --vmname and --datastore:

./relocate.pl --server reflex --username administrator --vmname DUMMY --datastore himalaya-local-SATA-intel.510:1
Relocating VM to himalaya-local-SATA-intel.510:1
Successfully relocated VM!
prashanthbk
Contributor
Contributor

Yes, you are assuming right, I am doing a storage vMotion.

I tried your sugesstion, but no luck yet Smiley Sad, still get the same error.

Does it make any difference if the datastore is nfs (nas).  My datastore summary is as below:

'summary' => bless( {
                                                             'datastore' => bless( {
                                                                                     'value' => '10.xxx.yyy.zzz:/VOL112_ESXQUAL',
                                                                                     'type' => 'Datastore'
                                                                                   }, 'ManagedObjectReference' ),
                                                             'url' => '/vmfs/volumes/b4c785f1-2c426a8e',
                                                             'name' => 'VOL_f2240-132-112',
                                                             'type' => 'NFS',
                                                             'accessible' => '1',
                                                             'capacity' => '1099511627776',
                                                             'uncommitted' => '76252086272',
                                                             'freeSpace' => '963681652736'
                                                           }, 'DatastoreSummary' ),

Or is there anything that needs to be set on the datastore before doing a relocate.

Also I is there any problem in 'value' => '10.xxx.yyy.zzz:/VOL112_ESXQUAL', should there be any port number kind of thing after 10.xxx.yyy.zzz:  ?

Reply
0 Kudos
prashanthbk
Contributor
Contributor

Adding a little more info to the previous reply

The follwing is the NasDatastoreInfo:

'info' => bless( {
                                                          'nas' => bless( {
                                                                            'remoteHost' => '10.xxx.yyy.zzz',
                                                                            'remotePath' => '/VOL112_ESXQUAL',
                                                                            'name' => 'VOL_f2240-132-112',
                                                                            'type' => 'NFS',
                                                                            'capacity' => '1099511627776'
                                                                          }, 'HostNasVolume' ),
                                                          'timestamp' => '2012-05-09T08:53:06.778674Z',
                                                          'maxFileSize' => '9223372036854775807',
                                                          'url' => '/vmfs/volumes/b4c785f1-2c426a8e',
                                                          'name' => 'VOL_f2240-132-112',
                                                          'freeSpace' => '963681652736'
                                                        }, 'NasDatastoreInfo' ),

Reply
0 Kudos
lamw
Community Manager
Community Manager

It does not matter if the datastore is iSCSI/FC, NFS or even local storage, as long as the host can see the storage.

Can you create a dummy VM to test to ensure that your configuration is okay? Also can you perform the Storage vMotion to the destination datastore using the vSphere Client?

Reply
0 Kudos
prashanthbk
Contributor
Contributor

I think I found what the problem was, the cue was in your code itself, I was using different vim sessions, one (target host vim session) for getting target datastore view and the other (vcenter vim session) for getting the vm view and invoking RelocateVM_Task.  This was causing the problem. I changed the code to use only one vim session (vcenter vim session) to get the target datastore view and and the vm view, then everything started working.

Thanks for your suggestions and interest in resolving this problem.

Reply
0 Kudos
prashanthbk
Contributor
Contributor

Posting this for others to use.

Following is the changed code that started working

use VMware::VIRuntime;
use VMware::VILib;
use Data::Dumper;


my $service_url_03 = "https://10.xxx.yyy.zz/sdk/vimService";
my $vim_obj_03 = Vim->new(service_url => $service_url_03 );
            user_name => "pqrst",
            password  => "abcd"
   
     $vim_obj_session_03 = $vim_obj_03->login(
);

my $vm_view = $vim_obj_session_03->find_entity_view (view_type => 'VirtualMachine', filter => {'name' => 'RHEL6U2_ESXA_64'});   
my $ds_view = $vim_obj_session_03->find_entity_view(view_type => 'Datastore', filter => {'name' => 'VOL_f2240-132-110'});

my $spec = VirtualMachineRelocateSpec->new(datastore => $ds_view);

Reply
0 Kudos
prashanthbk
Contributor
Contributor

sorry for the incomplete code find the complete on below

use VMware::VIRuntime;
use VMware::VILib;
use Data::Dumper;


my $service_url_03 = "https://10.xxx.yyy.zz/sdk/vimService";
my $vim_obj_03 = Vim->new(service_url => $service_url_03 );
my $vim_obj_session_03 = $vim_obj_03->login(
            user_name => "administrator",
            password  => "abcd"
   
    );

my  $vm_view = $vim_obj_session_03->find_entity_view (view_type =>  'VirtualMachine', filter => {'name' => 'RHEL6U2_ESXA_64'});   
my  $ds_view = $vim_obj_session_03->find_entity_view(view_type =>  'Datastore', filter => {'name' => 'VOL_f2240-132-110'});

my $spec = VirtualMachineRelocateSpec->new(datastore => $ds_view);

eval {
        print "Relocating VM to " . $datastore . "\n";
        my $task = $vm_view->RelocateVM_Task(spec => $spec);
        &getStatus($task,"Successfully relocated VM!\n",$vim_obj_session_03);
};
if($@) {
        print "Error: "  . $@ . "\n";
}


    sub getStatus {
            my ($taskRef,$message,$vim_obj_session_03) = @_;

            my $task_view = $vim_obj_session_03->get_view(mo_ref => $taskRef);
            my $taskinfo = $task_view->info->state->val;
            my $continue = 1;
            while ($continue) {
                    my $info = $task_view->info;
                    if ($info->state->val eq 'success') {
                            print $message;
                            $continue = 0;
                    } elsif ($info->state->val eq 'error') {
                            my $soap_fault = SoapFault->new;
                            $soap_fault->name($info->error->fault);
                            $soap_fault->detail($info->error->fault);
                            $soap_fault->fault_string($info->error->localizedMessage);
                            die "$soap_fault\n";
                    }
                    sleep 5;
                    $task_view->ViewBase::update_view_data();
            }
    }

PS: the get_status code is a direct copy from lamw's code

Reply
0 Kudos
lamw
Community Manager
Community Manager

Hi,

I'm not sure what you mean by issue with my code, it does exactly the same thing you're doing except you're specifying the vimService URL which is by done for you by default. It only connects to a single VIM session which you should be pointing to vCenter Server. Anyway glad you got it working but you should be able to use the snippet I provided and if the input params are correct, it should work as well

Reply
0 Kudos
prashanthbk
Contributor
Contributor

Oh!!!

I did not mean that there was an issue with your code, I meant that for my code.  Two differences that I observed betweem my code and your's (which I learnt from) was that 1) in your code, as you said you were using a single and global vim session, but I was opening different vim sessions (1 for vcenter, 1 for target and 1 for source hosts), 2) the way that I was getting the DataStore view was very much round about and not straight forward in my code, though I was using the vcenter vim session for getting the VM and using to invoke RelocateVM_Task, the wrong way of getting the DataStore might have been causing trouble.  Thanks for the snippet you provided, it worked perfectly and helped me correct my code.

Reply
0 Kudos
lamw
Community Manager
Community Manager

np. Yea for all opeations, you only need a single connection to your vCenter Server, you can reach all your inventory as long as it's being managed by the vCenter Server.

Reply
0 Kudos