vcl-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arku...@apache.org
Subject svn commit: r1061849 - in /incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware: VMware.pm vSphere_SDK.pm
Date Fri, 21 Jan 2011 15:32:29 GMT
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;
 }
 



Mime
View raw message