Author: arkurth
Date: Fri Jan 21 15:32:29 2011
New Revision: 1061849

URL: http://svn.apache.org/viewvc?rev=1061849&view=rev
Log:
VCL-394
Updated subroutines which copy and rename vmdk files to detect if the operation 
failed because the destination is out of space.  If this occurs a critical 
notification is sent.  This makes the cause of the problem more obvious.

Updated VMware.pm::capture() to revert the changes it made to the vmdk file 
name/path if the image fails to be copied to the image repository.  Also added 
calls to power the VM back on if a capture fails.  This is done to return the 
state of the VM being captured back to the original before the capture was 
attempted, making it easier to attempt the capture again.

Added check when vmkfstools is called to detect if the utility prompted for the 
username.

Modified:
    
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
    
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm

Modified: 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm?rev=1061849&r1=1061848&r2=1061849&view=diff
==============================================================================
--- 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm 
(original)
+++ 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm 
Fri Jan 21 15:32:29 2011
@@ -573,8 +573,7 @@ sub capture {
        # Rename the vmdk to the new image directory and file name
        # First check if vmdk file path already matches the destination file 
path
        if ($vmdk_file_path_original eq $vmdk_file_path_renamed) {
-               notify($ERRORS{'OK'}, 0, "vmdk files will not be renamed, vmdk 
file path being captured is already named as the image being captured: 
'$vmdk_file_path_original'");
-               
+               notify($ERRORS{'DEBUG'}, 0, "vmdk files will not be renamed, 
vmdk file path being captured is already named as the image being captured: 
'$vmdk_file_path_original'");
        }
        else {
                if (!$self->rename_vmdk($vmdk_file_path_original, 
$vmdk_file_path_renamed)) {
@@ -586,6 +585,8 @@ sub capture {
        # Copy the vmdk to the image repository if the repository path is 
defined in the VM profile
        my $repository_directory_path = 
$self->get_repository_vmdk_directory_path();
        if ($repository_directory_path) {
+               my $repository_copy_successful = 0;
+               
                # Check if the image repository path configured in the VM 
profile is mounted on the host or on the management node
                my $repository_mounted_on_vmhost = 
$self->is_repository_mounted_on_vmhost();
                if ($repository_mounted_on_vmhost) {
@@ -593,9 +594,11 @@ sub capture {
                        
                        # Files can be copied directly to the image repository 
and converted while they are copied
                        my $repository_vmdk_file_path = 
$self->get_repository_vmdk_file_path();
-                       if (!$self->copy_vmdk($vmdk_file_path_renamed, 
$repository_vmdk_file_path, '2gbsparse')) {
+                       if ($self->copy_vmdk($vmdk_file_path_renamed, 
$repository_vmdk_file_path, '2gbsparse')) {
+                               $repository_copy_successful = 1;
+                       }
+                       else {
                                notify($ERRORS{'WARNING'}, 0, "failed to copy 
the vmdk files after the VM was powered off: '$vmdk_file_path_renamed' --> 
'$repository_vmdk_file_path'");
-                               return;
                        }
                }
                else {
@@ -609,12 +612,11 @@ sub capture {
                        my $virtual_disk_type = 
$self->api->get_virtual_disk_type($vmdk_file_path_renamed);
                        if (!$virtual_disk_type) {
                                notify($ERRORS{'WARNING'}, 0, "failed to 
determine the virtual disk type of the vmdk being captured: 
$vmdk_file_path_renamed");
-                               return;
                        }
                        elsif ($virtual_disk_type =~ /sparse/) {
                                # Virtual disk is sparse, get a list of the 
vmdk file paths
                                notify($ERRORS{'DEBUG'}, 0, "vmdk can be copied 
directly from VM host $vmhost_hostname to the image repository because the 
virtual disk type is sparse: $virtual_disk_type");
-                               @vmdk_copy_paths = 
$self->vmhost_os->find_files($vmdk_file_path_renamed, '*.vmdk');
+                               @vmdk_copy_paths = 
$self->vmhost_os->find_files($vmdk_directory_path_original, '*.vmdk');
                        }
                        else {
                                # Virtual disk is NOT sparse - a sparse copy 
must first be created before being copied to the repository
@@ -623,34 +625,39 @@ sub capture {
                                # Construct the vmdk file path where the 
2gbsparse copy will be created
                                # The vmdk files are copied to a directory with 
the same name but with '_2gbsparse' appended to the directory name
                                # The vmdk files in the '_2gbsparse' are named 
the same as the original non-sparse directory
-                               $vmdk_directory_path_sparse = 
"$vmdk_base_directory_path/$image_name\_2gbsparse";
+                               $vmdk_directory_path_sparse = 
"$vmdk_directory_path_original\_2gbsparse";
                                $vmdk_file_path_sparse = 
"$vmdk_directory_path_sparse/$image_name.vmdk";
                                
                                # Create a sparse copy of the virtual disk
-                               if (!$self->copy_vmdk($vmdk_file_path_renamed, 
$vmdk_file_path_sparse, '2gbsparse')) {
+                               if ($self->copy_vmdk($vmdk_file_path_renamed, 
$vmdk_file_path_sparse, '2gbsparse')) {
+                                       # Get a list of the 2gbsparse vmdk file 
paths
+                                       @vmdk_copy_paths = 
$self->vmhost_os->find_files($vmdk_directory_path_sparse, '*.vmdk');
+                               }
+                               else {
                                        notify($ERRORS{'WARNING'}, 0, "failed 
to create a temporary 2gbsparse copy of the vmdk file: 
'$vmdk_file_path_renamed' --> '$vmdk_file_path_sparse'");
-                                       return;
                                }
-                               
-                               # Get a list of the 2gbsparse vmdk file paths
-                               @vmdk_copy_paths = 
$self->vmhost_os->find_files($vmdk_directory_path_sparse, '*.vmdk');
                        }
                        
                        # Copy the vmdk directory from the VM host to the image 
repository
-                       if (!@vmdk_copy_paths) {
-                               notify($ERRORS{'WARNING'}, 0, "failed to find 
the vmdk files on VM host $vmhost_hostname to copy back to the managment node's 
image repository");
-                               return;
-                       }
-                       
-                       # Loop through the files, copy each to the management 
node's repository directory
-                       notify($ERRORS{'DEBUG'}, 0, "vmdk files will be copied 
from VM host $vmhost_hostname to the image repository on the management 
node:\n" . join("\n", sort @vmdk_copy_paths));
-                       for my $vmdk_copy_path (@vmdk_copy_paths) {
-                               my ($vmdk_copy_name) = $vmdk_copy_path =~ 
/([^\/]+)$/;
-                               if 
(!$self->vmhost_os->copy_file_from($vmdk_copy_path, 
"$repository_directory_path/$vmdk_copy_name")) {
-                                       notify($ERRORS{'WARNING'}, 0, "failed 
to copy vmdk file from VM host $vmhost_hostname to the management node:\n 
'$vmdk_copy_path' --> '$repository_directory_path/$vmdk_copy_name'");
-                                       return;
+                       if (@vmdk_copy_paths) {
+                               # Loop through the files, copy each to the 
management node's repository directory
+                               notify($ERRORS{'DEBUG'}, 0, "vmdk files will be 
copied from VM host $vmhost_hostname to the image repository on the management 
node:\n" . join("\n", sort @vmdk_copy_paths));
+                               VMDK_COPY_PATH: for my $vmdk_copy_path 
(@vmdk_copy_paths) {
+                                       my ($vmdk_copy_name) = $vmdk_copy_path 
=~ /([^\/]+)$/;
+                                       
+                                       # Set the flag to 1 before copying, set 
it back to 0 if any files fail to be copied
+                                       $repository_copy_successful = 1;
+                                       
+                                       if 
(!$self->vmhost_os->copy_file_from($vmdk_copy_path, 
"$repository_directory_path/$vmdk_copy_name")) {
+                                               notify($ERRORS{'WARNING'}, 0, 
"failed to copy vmdk file from VM host $vmhost_hostname to the management 
node:\n '$vmdk_copy_path' --> '$repository_directory_path/$vmdk_copy_name'");
+                                               $repository_copy_successful = 0;
+                                               last VMDK_COPY_PATH;
+                                       }
                                }
                        }
+                       else {
+                               notify($ERRORS{'WARNING'}, 0, "failed to find 
the vmdk files on VM host $vmhost_hostname to copy back to the managment node's 
image repository");
+                       }
                        
                        # Check if the $vmdk_directory_path_sparse variable has 
been set
                        # If set, a sparse copy of the vmdk files had to be 
created
@@ -660,11 +667,42 @@ sub capture {
                                
                                if 
(!$self->vmhost_os->delete_file($vmdk_directory_path_sparse)) {
                                        notify($ERRORS{'WARNING'}, 0, "failed 
to delete the directory containing the 2gbsparse copy of the vmdk files: 
$vmdk_directory_path_sparse");
-                                       return;
                                }
                        }
                }
                
+               # The $repository_copy_successful flag should be set to 1 by 
this point if the copy was successful
+               if (!$repository_copy_successful) {
+                       # Rename the vmdk back to the original file name
+                       # This is necessary to power the VM back on in order to 
fix the problem because the VM's vmx file still contains the path to the 
original vmdk
+                       # First check if vmdk file path already matches the 
destination file path
+                       if ($vmdk_file_path_original eq 
$vmdk_file_path_renamed) {
+                               notify($ERRORS{'DEBUG'}, 0, "vmdk file does not 
need to be renamed back to the original name, vmdk file path being captured is 
already named as the image being captured: '$vmdk_file_path_original'");
+                               
+                               # Attempt to power the VM back on
+                               # This saves a step when troubleshooting the 
problem
+                               notify($ERRORS{'DEBUG'}, 0, "attempting to 
power the VM back on so that it can be captured again");
+                               
$self->api->vm_power_on($vmx_file_path_original);
+                       }
+                       else {
+                               if ($self->rename_vmdk($vmdk_file_path_renamed, 
$vmdk_file_path_original)) {
+                                       if ($vmdk_directory_path_original ne 
$vmdk_directory_path_renamed) {
+                                               notify($ERRORS{'DEBUG'}, 0, 
"attempting to delete directory where renamed vmdk resided before reverting the 
name back to the original: $vmdk_directory_path_renamed");
+                                               
$self->vmhost_os->delete_file($vmdk_directory_path_renamed);
+                                       }
+                                       
+                                       # Attempt to power the VM back on
+                                       # This saves a step when 
troubleshooting the problem
+                                       notify($ERRORS{'DEBUG'}, 0, "attempting 
to power the VM back on so that it can be captured again");
+                                       
$self->api->vm_power_on($vmx_file_path_original);
+                               }
+                               else {
+                                       notify($ERRORS{'WARNING'}, 0, "failed 
to rename the vmdk files back to the original name after copying to the 
repository failed: '$vmdk_file_path_renamed' --> '$vmdk_file_path_original'");
+                               }
+                       }
+                       return;
+               }
+               
                # Attempt to set permissions on the image repository directory
                # Don't fail the capture if this fails, it only affects image 
retrieval from another managment node
                $self->set_image_repository_permissions();
@@ -1259,7 +1297,10 @@ sub get_vmhost_api_object {
        
        # Create an API object to control the VM host and VMs
        my $api;
-       eval { $api = ($api_perl_package)->new({data_structure => 
$vmhost_datastructure, vmhost_os => $self->{vmhost_os}}) };
+       eval { $api = ($api_perl_package)->new({data_structure => $self->data,
+                                                                               
                                 vmhost_data => $vmhost_datastructure,
+                                                                               
                                 vmhost_os => $self->{vmhost_os}
+                                                                               
                                 })};
        if (!$api) {
                if ($EVAL_ERROR) {
                        notify($ERRORS{'WARNING'}, 0, "API object could not be 
created: $api_perl_package, error:\n$EVAL_ERROR");
@@ -2944,13 +2985,13 @@ sub get_vmdk_file_path_persistent {
                return;
        }
        
-       my $image_name = $self->data->get_image_name();
-       if (!$image_name) {
-               notify($ERRORS{'WARNING'}, 0, "unable to construct vmdk file 
path, image name could not be determined");
+       my $vmdk_directory_name_persistent = 
$self->get_vmdk_directory_name_persistent();
+       if (!$vmdk_directory_name_persistent) {
+               notify($ERRORS{'WARNING'}, 0, "unable to determine the 
persistent vmdk file path");
                return;
        }
        
-       return "$vmdk_directory_path_persistent/$image_name.vmdk";
+       return 
"$vmdk_directory_path_persistent/$vmdk_directory_name_persistent.vmdk";
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -3215,15 +3256,21 @@ sub get_vmdk_directory_path_persistent {
                return;
        }
        
-       # Use the same path that's used for the persistent vmx directory path
-       my $vmdk_directory_path_persistent = $self->get_vmx_directory_path();
-       if ($vmdk_directory_path_persistent) {
-               return $vmdk_directory_path_persistent;
+       # Get the vmdk base directory path
+       # Pass '1' to the subroutine to specify that the path should be 
retrieved directly from the vmprofile table
+       my $vmdk_base_directory_path = $self->get_vmdk_base_directory_path(1);
+       if (!$vmdk_base_directory_path) {
+               notify($ERRORS{'WARNING'}, 0, "unable to determine the 
nonpersistent vmdk base directory path, failed to retrieve datastore path for 
the VM profile");
+               return;
        }
-       else {
-               notify($ERRORS{'WARNING'}, 0, "unable to determine persistent 
vmdk directory path because vmx directory path could not be retrieved");
+       
+       my $vmdk_directory_name_persistent = 
$self->get_vmdk_directory_name_persistent();
+       if (!$vmdk_directory_name_persistent) {
+               notify($ERRORS{'WARNING'}, 0, "unable to determine persistent 
vmdk directory path because persistent vmdk directory name could not be 
determined");
                return;
        }
+       
+       return "$vmdk_base_directory_path/$vmdk_directory_name_persistent";
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -4673,6 +4720,9 @@ sub copy_vmdk {
                return;
        }
        
+       $source_vmdk_file_path = 
$self->_get_normal_path($source_vmdk_file_path) || return;
+       $destination_vmdk_file_path = 
$self->_get_normal_path($destination_vmdk_file_path) || return;
+       
        # Set the default virtual disk type if the argument was not specified
        if (!$virtual_disk_type) {
                if ($vmhost_product_name =~ /esx/i) {
@@ -4691,20 +4741,20 @@ sub copy_vmdk {
        
        # Make sure the source vmdk file exists
        if (!$self->vmhost_os->file_exists($source_vmdk_file_path)) {
-               notify($ERRORS{'WARNING'}, 0, "source vmdk file path does not 
exist: $source_vmdk_file_path");
+               notify($ERRORS{'WARNING'}, 0, "source vmdk file path does not 
exist on VM host $vmhost_name: $source_vmdk_file_path");
                return;
        }
        
        # Make sure the destination vmdk file doesn't already exist
        if ($self->vmhost_os->file_exists($destination_vmdk_file_path)) {
-               notify($ERRORS{'WARNING'}, 0, "destination vmdk file path 
already exists: $destination_vmdk_file_path");
+               notify($ERRORS{'WARNING'}, 0, "destination vmdk file path 
already exists on VM host $vmhost_name: $destination_vmdk_file_path");
                return;
        }
        
        # Get the destination parent directory path and create the directory
        my ($destination_directory_path) = $destination_vmdk_file_path =~ 
/(.+)\/[^\/]+/;
        if (!$self->vmhost_os->create_directory($destination_directory_path)) {
-               notify($ERRORS{'WARNING'}, 0, "unable to copy vmdk, destination 
directory could not be created on the VM host: $destination_directory_path");
+               notify($ERRORS{'WARNING'}, 0, "unable to copy vmdk, destination 
directory could not be created on VM host $vmhost_name: 
$destination_directory_path");
                return;
        }
        
@@ -4712,8 +4762,21 @@ sub copy_vmdk {
        my $copy_result = 0;
        
        # Attempt to use the API's copy_virtual_disk subroutine
-       if ($self->api->can('copy_virtual_disk') && ($copy_result = 
$self->api->copy_virtual_disk($source_vmdk_file_path, 
$destination_vmdk_file_path, $virtual_disk_type))) {
-               notify($ERRORS{'OK'}, 0, "copied vmdk using API's 
copy_virtual_disk subroutine");
+       if ($self->api->can('copy_virtual_disk')) {
+               if ($self->api->copy_virtual_disk($source_vmdk_file_path, 
$destination_vmdk_file_path, $virtual_disk_type)) {
+                       notify($ERRORS{'OK'}, 0, "copied vmdk using API's 
copy_virtual_disk subroutine");
+                       $copy_result = 1;
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "failed to copy vmdk 
using API's copy_virtual_disk subroutine");
+                       return;
+               }
+       }
+       
+       # Make sure VM host OS object implements 'execute' before attempting to 
call utilities
+       if (!$copy_result && !$self->vmhost_os->can('execute')) {
+               notify($ERRORS{'WARNING'}, 0, "failed to copy vmdk on VM host 
$vmhost_name, unable to copy using API's copy_virtual_disk subroutine and an 
'execute' subroutine is not implemented by the VM host OS object");
+               return;
        }
        
        if (!$copy_result) {
@@ -4729,8 +4792,18 @@ sub copy_vmdk {
                elsif (grep(/command not found/i, @$output)) {
                        notify($ERRORS{'DEBUG'}, 0, "unable to copy virtual 
disk using vmkfstools because the command is not available on VM host 
$vmhost_name");
                }
-               elsif (!grep(/(100\% done|success)/, @$output)) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to copy virtual 
disk, output does not contain '100% done' or 'success', command: '$command', 
output:\n" . join("\n", @$output));
+               elsif (grep(/Enter username/i, @$output)) {
+                       notify($ERRORS{'DEBUG'}, 0, "unable to copy virtual 
disk using vmkfstools, the command is not compatible on VM host $vmhost_name");
+               }
+               elsif (grep(/No space left/, @$output)) {
+                       # Check if the output indicates there is not enough 
space to copy the vmdk
+                       # Output will contain:
+                       #    Failed to clone disk : No space left on device 
(1835017).
+                       notify($ERRORS{'CRITICAL'}, 0, "failed to copy virtual 
disk, no space is left on the destination device on VM host $vmhost_name: 
'$destination_directory_path'\ncommand: '$command'\noutput:\n" . join("\n", 
@$output));
+                       return;
+               }
+               elsif (grep(/Failed to clone disk/, @$output) || !grep(/(100\% 
done|success)/, @$output)) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to copy virtual 
disk\ncommand: '$command'\noutput:\n" . join("\n", @$output));
                }
                else {
                        notify($ERRORS{'OK'}, 0, "copied virtual disk on VM 
host using vmkfstools, destination disk type: 
$virtual_disk_type:\n'$source_vmdk_file_path' --> 
'$destination_vmdk_file_path'");
@@ -4775,18 +4848,24 @@ sub copy_vmdk {
                                        ($exit_status, $output) = 
$self->vmhost_os->execute($vdisk_command);
                                }
                                else {
-                                       notify($ERRORS{'WARNING'}, 0, "failed 
to repair the virtual disk on VM host, output:\n" . join("\n", 
@$vdisk_repair_output));
+                                       notify($ERRORS{'WARNING'}, 0, "failed 
to repair the virtual disk on VM host $vmhost_name, output:\n" . join("\n", 
@$vdisk_repair_output));
                                }
                        }
                        
                        if (!defined($output)) {
-                               notify($ERRORS{'WARNING'}, 0, "failed to run 
command on VM host: $vdisk_command");
+                               notify($ERRORS{'WARNING'}, 0, "failed to run 
command on VM host $vmhost_name: $vdisk_command");
+                       }
+                       elsif (grep(/disk is full/i, @$output)) {
+                               # vmware-vdiskmgr output if not enough space is 
available:
+                               #    Failed to convert disk: An error occurred 
while writing a file; the disk is full. Data has not been saved. Free some 
space and try again (0xa00800000008).
+                               notify($ERRORS{'CRITICAL'}, 0, "failed to copy 
virtual disk on VM host $vmhost_name, no space is left on the destination 
device: '$destination_directory_path'\ncommand: '$vdisk_command'\noutput:\n" . 
join("\n", @$output));
+                               return;
                        }
                        elsif (!grep(/(100\% done|success)/, @$output)) {
-                               notify($ERRORS{'WARNING'}, 0, "failed to copy 
virtual disk, output does not contain '100% done' or 'success', command: 
'$vdisk_command', output:\n" . join("\n", @$output));
+                               notify($ERRORS{'WARNING'}, 0, "failed to copy 
virtual disk on VM host $vmhost_name, output does not contain '100% done' or 
'success', command: '$vdisk_command', output:\n" . join("\n", @$output));
                        }
                        else {
-                               notify($ERRORS{'OK'}, 0, "copied virtual disk 
on VM host using vmware-vdiskmanager:\n'$source_vmdk_file_path' --> 
'$destination_vmdk_file_path'");
+                               notify($ERRORS{'OK'}, 0, "copied virtual disk 
on VM host $vmhost_name using vmware-vdiskmanager:\n'$source_vmdk_file_path' 
--> '$destination_vmdk_file_path'");
                                $copy_result = 1;
                        }
                }
@@ -4794,7 +4873,7 @@ sub copy_vmdk {
        
        # Check if any of the methods was successful
        if (!$copy_result) {
-               notify($ERRORS{'WARNING'}, 0, "failed to copy virtual disk 
using any available methods:\n'$source_vmdk_file_path' --> 
'$destination_vmdk_file_path'");
+               notify($ERRORS{'WARNING'}, 0, "failed to copy virtual disk on 
VM host $vmhost_name using any available methods:\n'$source_vmdk_file_path' --> 
'$destination_vmdk_file_path'");
                return;
        }
        
@@ -4817,7 +4896,7 @@ sub copy_vmdk {
        
        my $image_size_bytes = $self->vmhost_os->get_file_size($search_path);
        if (!defined($image_size_bytes) || $image_size_bytes !~ /^\d+$/) {
-               notify($ERRORS{'WARNING'}, 0, "copied vmdk but failed to 
retrieve destination file size:\n'$source_vmdk_file_path' --> 
'$destination_vmdk_file_path'");
+               notify($ERRORS{'WARNING'}, 0, "copied vmdk on VM host 
$vmhost_name but failed to retrieve destination file 
size:\n'$source_vmdk_file_path' --> '$destination_vmdk_file_path'");
                return 1;
        }
        
@@ -4847,7 +4926,7 @@ sub copy_vmdk {
        my $gb_per_minute = ($image_size_gb / $duration_seconds * 60);
        
        
-       notify($ERRORS{'OK'}, 0, "copied vmdk: '$source_vmdk_file_path' --> 
'$destination_vmdk_file_path'\n" .
+       notify($ERRORS{'OK'}, 0, "copied vmdk on VM host $vmhost_name: 
'$source_vmdk_file_path' --> '$destination_vmdk_file_path'\n" .
                "time to copy: $minutes:$seconds (" . 
format_number($duration_seconds) . " seconds)\n" .
                "---\n" .
                "bits copied:  " . format_number($image_size_bits) . " 
($image_size_bits)\n" .
@@ -6042,10 +6121,10 @@ sub _check_datastore_paths {
                        'get_vmx_directory_path',
                        'get_vmx_file_path',
                        
+                       'get_vmdk_base_directory_path',
                        'get_vmdk_directory_path',
                        'get_vmdk_file_path',
                        
-                       'get_vmdk_base_directory_path',
                        'get_vmdk_directory_path_nonpersistent',
                        'get_vmdk_file_path_nonpersistent',
                        

Modified: 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm?rev=1061849&r1=1061848&r2=1061849&view=diff
==============================================================================
--- 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
 (original)
+++ 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
 Fri Jan 21 15:32:29 2011
@@ -474,10 +474,12 @@ sub copy_virtual_disk {
                return;
        }
        
+       my $vmhost_name = $self->data->get_vmhost_hostname();
+       
        # Get a virtual disk manager object
        my $service_content = Vim::get_service_content() || return;
        if (!$service_content->{virtualDiskManager}) {
-               notify($ERRORS{'WARNING'}, 0, "unable to copy virtual disk, 
virtual disk manager is not available through the vSphere SDK");
+               notify($ERRORS{'WARNING'}, 0, "unable to copy virtual disk on 
VM host $vmhost_name, virtual disk manager is not available through the vSphere 
SDK");
                return;
        }
        my $virtual_disk_manager = Vim::get_view(mo_ref => 
$service_content->{virtualDiskManager}) || return;
@@ -501,7 +503,7 @@ sub copy_virtual_disk {
        my $source_disk_type = $source_info->{$info_file_name}{diskType};
        my $source_file_size_bytes = $source_info->{$info_file_name}{fileSize};
        if ($source_adapter_type !~ /\w/ || $source_disk_type !~ /\w/ || 
$source_file_size_bytes !~ /\d/) {
-               notify($ERRORS{'WARNING'}, 0, "unable to retrieve adapter type, 
disk type, and file size of source file: '$source_path', file info:\n" . 
format_data($source_info));
+               notify($ERRORS{'WARNING'}, 0, "unable to retrieve adapter type, 
disk type, and file size of source file on VM host $vmhost_name: 
'$source_path', file info:\n" . format_data($source_info));
                return;
        }
        
@@ -509,7 +511,7 @@ sub copy_virtual_disk {
        local $SIG{__DIE__} = sub{};
        
        # Attempt to copy the file
-       notify($ERRORS{'DEBUG'}, 0, "attempting to copy file: '$source_path' 
--> '$destination_path'
+       notify($ERRORS{'DEBUG'}, 0, "attempting to copy file on VM host 
$vmhost_name: '$source_path' --> '$destination_path'
                         adapter type: $source_adapter_type --> 
$destination_adapter_type
                         disk type: $source_disk_type --> $destination_disk_type
                         source file size: " . 
format_number($source_file_size_bytes));
@@ -523,11 +525,21 @@ sub copy_virtual_disk {
        
        # Check if an error occurred
        if (my $fault = $@) {
-               notify($ERRORS{'WARNING'}, 0, "failed to copy vmdk: 
'$source_path' --> '$destination_path'\nerror:\n$fault");
+               if ($fault =~ /No space left/i) {
+                       # Check if the output indicates there is not enough 
space to copy the vmdk
+                       # Output will contain:
+                       #    Fault string: A general system error occurred: No 
space left on device
+                       #    Fault detail: SystemError
+                       notify($ERRORS{'CRITICAL'}, 0, "failed to copy vmdk on 
VM host $vmhost_name, no space is left on the destination device: 
'$destination_path'\nerror:\n$fault");
+                       return;
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "failed to copy vmdk on 
VM host $vmhost_name: '$source_path' --> '$destination_path'\nerror:\n$fault");
+               }
                return;
        }
        
-       notify($ERRORS{'OK'}, 0, "copied vmdk: '$source_path' --> 
'$destination_path'");
+       notify($ERRORS{'OK'}, 0, "copied vmdk on VM host $vmhost_name: 
'$source_path' --> '$destination_path'");
        return 1;
 }
 
@@ -552,6 +564,8 @@ sub move_virtual_disk {
        my $source_path = $self->_get_datastore_path(shift) || return;
        my $destination_path = $self->_get_datastore_path(shift) || return;
        
+       my $vmhost_name = $self->data->get_vmhost_hostname();
+       
        # Make sure the source path ends with .vmdk
        if ($source_path !~ /\.vmdk$/i || $destination_path !~ /\.vmdk$/i) {
                notify($ERRORS{'WARNING'}, 0, "source and destination path 
arguments must end with .vmdk:\nsource path argument: $source_path\ndestination 
path argument: $destination_path");
@@ -560,13 +574,13 @@ sub move_virtual_disk {
        
        # Make sure the source file exists
        if (!$self->file_exists($source_path)) {
-               notify($ERRORS{'WARNING'}, 0, "source file does not exist: 
'$source_path'");
+               notify($ERRORS{'WARNING'}, 0, "source file does not exist on VM 
host $vmhost_name: '$source_path'");
                return;
        }
        
        # Make sure the destination file does not exist
        if ($self->file_exists($destination_path)) {
-               notify($ERRORS{'WARNING'}, 0, "destination file already exists: 
'$destination_path'");
+               notify($ERRORS{'WARNING'}, 0, "destination file already exists 
on VM host $vmhost_name: '$destination_path'");
                return;
        }
        
@@ -579,21 +593,21 @@ sub move_virtual_disk {
        
        # Check if the virtual disk manager is available
        if (!$service_content->{virtualDiskManager}) {
-               notify($ERRORS{'OK'}, 0, "unable to move virtual disk using 
vSphere SDK because virtual disk manager object is not available on the VM 
host");
+               notify($ERRORS{'OK'}, 0, "unable to move virtual disk using 
vSphere SDK because virtual disk manager object is not available on VM host 
$vmhost_name");
                return 0;
        }
        
        # Create a virtual disk manager object
        my $virtual_disk_manager = Vim::get_view(mo_ref => 
$service_content->{virtualDiskManager});
        if (!$virtual_disk_manager) {
-               notify($ERRORS{'WARNING'}, 0, "failed to create vSphere SDK 
virtual disk manager object");
+               notify($ERRORS{'WARNING'}, 0, "failed to create vSphere SDK 
virtual disk manager object on VM host $vmhost_name");
                return;
        }
        
        # Create a datacenter object
        my $datacenter = Vim::find_entity_view(view_type => 'Datacenter');
        if (!$datacenter) {
-               notify($ERRORS{'WARNING'}, 0, "failed to create vSphere SDK 
datacenter object");
+               notify($ERRORS{'WARNING'}, 0, "failed to create vSphere SDK 
datacenter object on VM host $vmhost_name");
                return;
        }
        
@@ -601,7 +615,7 @@ sub move_virtual_disk {
        local $SIG{__DIE__} = sub{};
        
        # Attempt to move the virtual disk using MoveVirtualDisk
-       notify($ERRORS{'DEBUG'}, 0, "attempting to move virtual disk: 
'$source_path' --> '$destination_path'");
+       notify($ERRORS{'DEBUG'}, 0, "attempting to move virtual disk on VM host 
$vmhost_name: '$source_path' --> '$destination_path'");
        eval { $virtual_disk_manager->MoveVirtualDisk(sourceName => 
$source_path,
                                                                                
                                                 sourceDatacenter => 
$datacenter,
                                                                                
                                                 destName => $destination_path,
@@ -616,19 +630,22 @@ sub move_virtual_disk {
                
                # A FileNotFound fault will be generated if the source vmdk 
file exists but there is a problem with it
                if ($fault->isa('SoapFault') && ref($fault->detail) eq 
'FileNotFound' && defined($source_file_info->{type}) && 
$source_file_info->{type} !~ /vmdisk/i) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to move virtual 
disk, source file is either not a virtual disk file or there is a problem with 
its configuration, check the 'Extent description' section of the vmdk file: 
'$source_path'\nsource file info:\n" . format_data($source_file_info));
+                       notify($ERRORS{'WARNING'}, 0, "failed to move virtual 
disk on VM host $vmhost_name, source file is either not a virtual disk file or 
there is a problem with its configuration, check the 'Extent description' 
section of the vmdk file: '$source_path'\nsource file info:\n" . 
format_data($source_file_info));
+               }
+               elsif ($fault =~ /No space left/i) {
+                       notify($ERRORS{'CRITICAL'}, 0, "failed to move virtual 
disk on VM host $vmhost_name, no space is left on the destination device: 
'$destination_path'\nerror:\n$fault");
                }
                elsif ($source_file_info) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to move virtual 
disk:\n'$source_path' --> '$destination_path'\nsource file info:\n" . 
format_data($source_file_info) . "\n$fault");
+                       notify($ERRORS{'WARNING'}, 0, "failed to move virtual 
disk on VM host $vmhost_name:\n'$source_path' --> '$destination_path'\nsource 
file info:\n" . format_data($source_file_info) . "\n$fault");
                }
                else {
-                       notify($ERRORS{'WARNING'}, 0, "failed to move virtual 
disk:\n'$source_path' --> '$destination_path'\nsource file info: 
unavailable\n$fault");
+                       notify($ERRORS{'WARNING'}, 0, "failed to move virtual 
disk on VM host $vmhost_name:\n'$source_path' --> '$destination_path'\nsource 
file info: unavailable\n$fault");
                }
                
                return;
        }
        
-       notify($ERRORS{'OK'}, 0, "moved virtual disk:\n'$source_path' --> 
'$destination_path'");
+       notify($ERRORS{'OK'}, 0, "moved virtual disk on VM host 
$vmhost_name:\n'$source_path' --> '$destination_path'");
        return 1;
 }
 


Reply via email to