You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2010/10/28 20:00:57 UTC

svn commit: r1028403 [2/2] - in /incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware: VIM_SSH.pm VMware.pm vSphere_SDK.pm

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=1028403&r1=1028402&r2=1028403&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 Thu Oct 28 18:00:57 2010
@@ -394,7 +394,7 @@ sub get_vm_power_state {
                   -physical compatibility mode (pass-through) raw disk mapping
                   -passes SCSI commands directly to the hardware
                   -cannot participate in snapshots
-               -sparse2Gb
+               -sparse2Gb, 2Gbsparse
                   -sparse disk with 2GB maximum extent size
                   -can be used with other VMware products
                   -2GB extent size makes these disks easier to burn to dvd or use on filesystems that don't support large files
@@ -447,6 +447,19 @@ sub copy_virtual_disk {
 	# Get the adapter type and disk type arguments if they were specified
 	# If not specified, set the default values
 	my $destination_disk_type = shift || 'thin';
+	
+	# Fix the disk type in case 2gbsparse was passed
+	if ($destination_disk_type =~ /2gbsparse/i) {
+		$destination_disk_type = 'sparse2Gb';
+	}
+	
+	# Check the disk type argument, the string must match exactly or the copy will fail
+	my @valid_disk_types = qw( eagerZeroedThick flatMonolithic preallocated raw rdm rdmp sparse2Gb sparseMonolithic thick thick2Gb thin );
+	if (!grep(/^$destination_disk_type$/, @valid_disk_types)) {
+		notify($ERRORS{'WARNING'}, 0, "disk type argument is not valid: '$destination_disk_type', it must exactly match (case sensitive) one of the following strings:\n" . join("\n", @valid_disk_types));
+		return;
+	}
+	
 	my $destination_adapter_type = shift;
 	
 	# If the adapter type was not specified, retrieve it from the source vmdk file
@@ -465,13 +478,6 @@ sub copy_virtual_disk {
 		return;
 	}
 	
-	# Check the disk type argument, the string must match exactly or the copy will fail
-	my @valid_disk_types = qw( eagerZeroedThick flatMonolithic preallocated raw rdm rdmp sparse2Gb sparseMonolithic thick thick2Gb thin );
-	if (!grep(/^$destination_disk_type$/, @valid_disk_types)) {
-		notify($ERRORS{'WARNING'}, 0, "disk type argument is not valid: '$destination_disk_type', it must exactly match (case sensitive) one of the following strings:\n" . join("\n", @valid_disk_types));
-		return;
-	}
-	
 	# Get a virtual disk manager object
 	my $service_content = Vim::get_service_content() || return;
 	if (!$service_content->{virtualDiskManager}) {
@@ -490,7 +496,7 @@ sub copy_virtual_disk {
 	);
 	
 	# Get the source vmdk file info so the source adapter and disk type can be displayed
-	my $source_info = $self->get_file_info($source_path) || return;
+	my $source_info = $self->_get_file_info($source_path) || return;
 	notify($ERRORS{'DEBUG'}, 0, "source file info:\n" . format_data($source_info));
 	my @file_names = keys(%{$source_info});
 	my $info_file_name = $file_names[0];
@@ -590,7 +596,7 @@ sub move_virtual_disk {
 	
 	# Create a datacenter object
 	my $datacenter = Vim::find_entity_view(view_type => 'Datacenter');
-	if (!$virtual_disk_manager) {
+	if (!$datacenter) {
 		notify($ERRORS{'WARNING'}, 0, "failed to create vSphere SDK datacenter object");
 		return;
 	}
@@ -610,7 +616,7 @@ sub move_virtual_disk {
 	# Check if an error occurred
 	if (my $fault = $@) {
 		# Get the source file info
-		my $source_file_info = $self->get_file_info($source_path)->{$source_path};
+		my $source_file_info = $self->_get_file_info($source_path)->{$source_path};
 		
 		# 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) {
@@ -632,6 +638,36 @@ sub move_virtual_disk {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 set_file_permissions
+
+ Parameters  : 
+ Returns     : boolean
+ Description : 
+
+=cut
+
+sub set_file_permissions {
+	my $self = shift;
+	if (ref($self) !~ /VCL::Module/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	# 
+	my $service_content = Vim::get_service_content() || return;
+	if (!$service_content->{authorizationManager}) {
+		notify($ERRORS{'WARNING'}, 0, "unable to set file permissions, authorization manager is not available through the vSphere SDK");
+		return;
+	}
+	my $authorization_manager = Vim::get_view(mo_ref => $service_content->{authorizationManager}) || return;
+	notify($ERRORS{'DEBUG'}, 0, "created vSphere SDK authorization manager object");
+	
+	my $permissions = $authorization_manager->RetrieveEntityPermissions();
+
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 create_nfs_datastore
 
  Parameters  : $datastore_name, $remote_host, $remote_path
@@ -661,15 +697,15 @@ sub create_nfs_datastore {
 	# Assemble a datastore device string, used to check if existing datastore is pointing to the same remote host and path
 	my $datastore_device = "$remote_host:$remote_path";
 	
-	# Get the existing datastore summaries
-	my $datastore_summaries = $self->_get_datastore_summaries();
-	for my $check_datastore_name (keys(%$datastore_summaries)) {
-		my $check_datastore_type = $datastore_summaries->{$check_datastore_name}{type};
+	# Get the existing datastore info
+	my $datastore_info = $self->_get_datastore_info();
+	for my $check_datastore_name (keys(%$datastore_info)) {
+		my $check_datastore_type = $datastore_info->{$check_datastore_name}{type};
 		
 		# Make sure a non-NFS datastore with the same name doesn't alreay exist
 		if ($check_datastore_type !~ /nfs/i) {
 			if ($check_datastore_name eq $datastore_name) {
-				notify($ERRORS{'WARNING'}, 0, "datastore named $datastore_name already exists on VM host but its type is not NFS:\n" . format_data($datastore_summaries->{$check_datastore_name}));
+				notify($ERRORS{'WARNING'}, 0, "datastore named $datastore_name already exists on VM host but its type is not NFS:\n" . format_data($datastore_info->{$check_datastore_name}));
 				return;
 			}
 			else {
@@ -680,9 +716,9 @@ sub create_nfs_datastore {
 		
 		# Get the existing datastore device string, format is:
 		# 10.25.0.245:/install/vmtest/datastore
-		my $check_datastore_device = $datastore_summaries->{$check_datastore_name}{datastore}{value};
+		my $check_datastore_device = $datastore_info->{$check_datastore_name}{datastore}{value};
 		if (!$check_datastore_device) {
-			notify($ERRORS{'WARNING'}, 0, "unable to retrieve datastore device string from datastore summary:\n" . format_data($datastore_summaries->{$check_datastore_name}));
+			notify($ERRORS{'WARNING'}, 0, "unable to retrieve datastore device string from datastore info:\n" . format_data($datastore_info->{$check_datastore_name}));
 			next;
 		}
 		
@@ -777,7 +813,7 @@ sub get_virtual_disk_controller_type {
 	}
 	
 	# Get the vmdk file info
-	my $vmdk_file_info = $self->get_file_info($vmdk_file_path)->{$vmdk_file_path};
+	my $vmdk_file_info = $self->_get_file_info($vmdk_file_path)->{$vmdk_file_path};
 	if (!$vmdk_file_info) {
 		notify($ERRORS{'WARNING'}, 0, "unable to retrieve info for file: $vmdk_file_path");
 		return;
@@ -841,7 +877,7 @@ sub get_virtual_disk_type {
 	}
 	
 	# Get the vmdk file info
-	my $vmdk_file_info = $self->get_file_info($vmdk_file_path)->{$vmdk_file_path};
+	my $vmdk_file_info = $self->_get_file_info($vmdk_file_path)->{$vmdk_file_path};
 	if (!$vmdk_file_info) {
 		notify($ERRORS{'WARNING'}, 0, "unable to retrieve info for file: $vmdk_file_path");
 		return;
@@ -888,7 +924,7 @@ sub get_virtual_disk_hardware_version {
 	}
 	
 	# Get the vmdk file info
-	my $vmdk_file_info = $self->get_file_info($vmdk_file_path)->{$vmdk_file_path};
+	my $vmdk_file_info = $self->_get_file_info($vmdk_file_path)->{$vmdk_file_path};
 	if (!$vmdk_file_info) {
 		notify($ERRORS{'WARNING'}, 0, "unable to retrieve info for file: $vmdk_file_path");
 		return;
@@ -1032,11 +1068,17 @@ sub is_restricted {
 		return;
 	}
 	
+	my $service_content = Vim::get_service_content();
+	if (!$service_content) {
+		notify($ERRORS{'WARNING'}, 0, "unable to vSphere SDK service content object, assuming access to the VM host via the vSphere SDK is restricted");
+		return 1;
+	}
+	
 	# Get a fileManager object
-	my $file_manager = Vim::get_view(mo_ref => Vim::get_service_content()->{fileManager}) || return;
+	my $file_manager = Vim::get_view(mo_ref => $service_content->{fileManager}) || return;
 	if (!$file_manager) {
 		notify($ERRORS{'WARNING'}, 0, "unable to determine if access to the VM host via the vSphere SDK is restricted due to the license, failed to retrieve file manager object");
-		return;
+		return 1;
 	}
 	
 	# Override the die handler because MakeDirectory may call it
@@ -1059,6 +1101,14 @@ sub is_restricted {
 	}
 	
 	notify($ERRORS{'OK'}, 0, "access to the VM host via the vSphere SDK is NOT restricted due to the license");
+	
+	# Attempt to get a virtual disk manager object
+	# This is required to copy virtual disks and perform other operations
+	if (!$service_content->{virtualDiskManager}) {
+		notify($ERRORS{'OK'}, 0, "access to the VM host is restricted, virtual disk manager is not available through the vSphere SDK");
+		return 1;
+	}
+	
 	return 0;
 }
 
@@ -1594,7 +1644,7 @@ sub get_file_size {
 	my $computer_name = $self->data->get_computer_short_name() || return;
 	
 	# Get the file info
-	my $file_info = $self->get_file_info($file_path);
+	my $file_info = $self->_get_file_info($file_path);
 	if (!defined($file_info)) {
 		notify($ERRORS{'WARNING'}, 0, "unable to get file size, failed to get file info for: $file_path");
 		return;
@@ -1660,7 +1710,7 @@ sub find_files {
 	$base_directory_path = $self->_get_normal_path($base_directory_path) || return;
 	
 	# Get the file info
-	my $file_info = $self->get_file_info("$base_directory_path/$search_pattern", $search_subdirectories);
+	my $file_info = $self->_get_file_info("$base_directory_path/$search_pattern", $search_subdirectories);
 	if (!defined($file_info)) {
 		notify($ERRORS{'WARNING'}, 0, "unable to find files, failed to get file info for: $base_directory_path/$search_pattern");
 		return;
@@ -1718,12 +1768,12 @@ sub get_available_space {
 	
 	my $computer_node_name = $self->data->get_computer_node_name() || return;
 	
-	# Get the datastore summary hash
-	my $datastore_summaries = $self->_get_datastore_summaries() || return;
+	# Get the datastore info hash
+	my $datastore_info = $self->_get_datastore_info() || return;
 	
-	my $available_bytes = $datastore_summaries->{$datastore_name}{freeSpace};
+	my $available_bytes = $datastore_info->{$datastore_name}{freeSpace};
 	if (!defined($available_bytes)) {
-		notify($ERRORS{'WARNING'}, 0, "datastore $datastore_name freeSpace key does not exist in datastore summaries:\n" . format_data($datastore_summaries));
+		notify($ERRORS{'WARNING'}, 0, "datastore $datastore_name freeSpace key does not exist in datastore info:\n" . format_data($datastore_info));
 		return;
 	}
 	
@@ -1801,11 +1851,11 @@ sub initialize {
 		$result = 'undefined' if !defined($result);
 		
 		if (!$result || $@) {
-			notify($ERRORS{'DEBUG'}, 0, "unable to connect to VM host: $host_url, username: '$vmhost_username', error:\n$@");
+			notify($ERRORS{'DEBUG'}, 0, "unable to connect to VM host: $host_url, username: '$vmhost_username', password: '$vmhost_password', error:\n$@");
 			undef $@;
 		}
 		else {
-			notify($ERRORS{'DEBUG'}, 0, "connected to VM host: $host_url");
+			notify($ERRORS{'DEBUG'}, 0, "connected to VM host: $host_url, username: '$vmhost_username'");
 			return 1;
 		}
 	}
@@ -1816,7 +1866,7 @@ sub initialize {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 get_file_info
+=head2 _get_file_info
 
  Parameters  : $file_path
  Returns     : hash reference
@@ -1838,7 +1888,7 @@ sub initialize {
 
 =cut
 
-sub get_file_info {
+sub _get_file_info {
 	my $self = shift;
 	if (ref($self) !~ /VCL::Module/i) {
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
@@ -1977,35 +2027,6 @@ sub get_file_info {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 _get_datastore_names
-
- Parameters  : none
- Returns     : array
- Description : Returns an array containing the names of the datastores on the VM
-               host.
-
-=cut
-
-sub _get_datastore_names {
-	my $self = shift;
-	if (ref($self) !~ /VCL::Module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the datastore summary information
-	my $datastore_summaries = $self->_get_datastore_summaries();
-	if (!$datastore_summaries) {
-		notify($ERRORS{'WARNING'}, 0, "failed to retrieve datastore names, unable to retrieve datastore summary information from the VM host");
-		return;
-	}
-	
-	# The datastore names are the hash keys
-	return sort keys %$datastore_summaries;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 _get_datastore_object
 
  Parameters  : $datastore_name
@@ -2050,39 +2071,34 @@ sub _get_datastore_object {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 _get_datastore_summaries
+=head2 _get_datastore_info
 
  Parameters  : none
  Returns     : hash reference
  Description : Finds all datastores on the ESX host and returns a hash reference
-               containing the datastore summary information. The keys of the
-               hash are the datastore names. Example:
+               containing the datastore information. The keys of the hash are
+               the datastore names. Example:
                
-               my $datastore_summaries = $self->_get_datastore_summaries();
-               $datastore_summaries->{datastore1}{accessible} = '1'
-               $datastore_summaries->{datastore1}{capacity} = '31138512896'
-               $datastore_summaries->{datastore1}{datastore}{type} = 'Datastore'
-               $datastore_summaries->{datastore1}{datastore}{value} = '4bcf0efe-c426acc4-c7e1-001a644d1cc0'
-               $datastore_summaries->{datastore1}{freeSpace} = '30683430912'
-               $datastore_summaries->{datastore1}{name} = 'datastore1'
-               $datastore_summaries->{datastore1}{type} = 'VMFS'
-               $datastore_summaries->{datastore1}{uncommitted} = '0'
-               $datastore_summaries->{datastore1}{url} = '/vmfs/volumes/4bcf0efe-c426acc4-c7e1-001a644d1cc0'
+               my $datastore_info = $self->_get_datastore_info();
+               $datastore_info->{datastore1}{accessible} = '1'
+               $datastore_info->{datastore1}{capacity} = '31138512896'
+               $datastore_info->{datastore1}{datastore}{type} = 'Datastore'
+               $datastore_info->{datastore1}{datastore}{value} = '4bcf0efe-c426acc4-c7e1-001a644d1cc0'
+               $datastore_info->{datastore1}{freeSpace} = '30683430912'
+               $datastore_info->{datastore1}{name} = 'datastore1'
+               $datastore_info->{datastore1}{type} = 'VMFS'
+               $datastore_info->{datastore1}{uncommitted} = '0'
+               $datastore_info->{datastore1}{url} = '/vmfs/volumes/4bcf0efe-c426acc4-c7e1-001a644d1cc0'
 
 =cut
 
-sub _get_datastore_summaries {
+sub _get_datastore_info {
 	my $self = shift;
 	if (ref($self) !~ /VCL::Module/i) {
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
 		return;
 	}
 	
-	# Return previously retrieved data if it is defined
-	if ($self->{datastore_summaries}) {
-		return $self->{datastore_summaries};
-	}
-	
 	# Get the host view
 	my $host_view = VIExt::get_host_view(1);
 	
@@ -2091,7 +2107,7 @@ sub _get_datastore_summaries {
 	
 	# Loop through the datastore managed object references
 	# Get a datastore view, add the view's summary to the return hash
-	my %datastore_summaries;
+	my $datastore_info;
 	for my $datastore_mo_ref (@datastore_mo_refs) {
 		my $datastore_view = Vim::get_view(mo_ref => $datastore_mo_ref);
 		my $datastore_name = $datastore_view->summary->name;
@@ -2104,593 +2120,10 @@ sub _get_datastore_summaries {
 			$datastore_view->summary->{normal_path} = $datastore_url;
 		}
 		
-		$datastore_summaries{$datastore_name} = $datastore_view->summary;
-	}
-	
-	# Store the data in this object so it doesn't need to be retrieved again
-	$self->{datastore_summaries} = \%datastore_summaries;
-   return $self->{datastore_summaries};
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_datastore_path
-
- Parameters  : $path
- Returns     : string
- Description : Converts a normal path to a datastore path. The path returned
-               will never have any trailing slashes or spaces.
-               '/vmfs/volumes/datastore1/folder/file.txt' --> '[datastore1] folder/file.txt'
-
-=cut
-
-sub _get_datastore_path {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path_argument = shift;
-	if (!$path_argument) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	my $datastore_name = $self->_get_datastore_name($path_argument);
-	if (!$datastore_name) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine datastore path, failed to determine datastore name: $path_argument");
-		return;
-	}
-	
-	my $relative_datastore_path = $self->_get_relative_datastore_path($path_argument);
-	if (!defined($relative_datastore_path)) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine datastore path, failed to determine relative datastore path: $path_argument");
-		return;
-	}
-	
-	if ($relative_datastore_path) {
-		return "[$datastore_name] $relative_datastore_path";
-	}
-	else {
-		return "[$datastore_name]";
-	}
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_datastore_root_normal_path
-
- Parameters  : $path
- Returns     : string
- Description : Parses the path argument and determines its datastore root path
-               in normal form.
-               '/vmfs/volumes/datastore1/folder/file.txt' --> '/vmfs/volumes/datastore1'
-					'[datastore1] folder/file.txt' --> '/vmfs/volumes/datastore1'
-
-=cut
-
-sub _get_datastore_root_normal_path {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path = shift;
-	if (!$path) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	my $datastore_name = $self->_get_datastore_name($path);
-	if (!$datastore_name) {
-		notify($ERRORS{'WARNING'}, 0, "failed to determine datastore root normal path, unable to determine datastore name: $path");
-		return;
-	}
-	
-	# Get the datastore summary information
-	my $datastore_summaries = $self->_get_datastore_summaries();
-	if (!$datastore_summaries) {
-		notify($ERRORS{'WARNING'}, 0, "failed to determine datastore root normal path, unable to retrieve datastore summaries");
-		return;
-	}
-	
-	return $datastore_summaries->{$datastore_name}{normal_path};
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_datastore_root_url_path
-
- Parameters  : $path
- Returns     : string
- Description : Parses the path argument and determines its datastore root path
-               in normal form.
-               '/vmfs/volumes/datastore1/folder/file.txt' --> '/vmfs/volumes/895cdc05-11c0ee8f'
-					'[datastore1] folder/file.txt' --> '/vmfs/volumes/895cdc05-11c0ee8f'
-
-=cut
-
-sub _get_datastore_root_url_path {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path = shift;
-	if (!$path) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	my $datastore_name = $self->_get_datastore_name($path);
-	if (!$datastore_name) {
-		notify($ERRORS{'WARNING'}, 0, "failed to determine datastore root URL path, unable to determine datastore name: $path");
-		return;
-	}
-	
-	# Get the datastore summary information
-	my $datastore_summaries = $self->_get_datastore_summaries();
-	if (!$datastore_summaries) {
-		notify($ERRORS{'WARNING'}, 0, "failed to determine datastore root URL path, unable to retrieve datastore summaries");
-		return;
-	}
-	
-	return $datastore_summaries->{$datastore_name}{url};
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_normal_path
-
- Parameters  : $path
- Returns     : string
- Description : Converts a datastore path to a normal path. The path returned
-               will never have any trailing slashes or spaces.
-               '[datastore1] folder/file.txt' --> '/vmfs/volumes/datastore1/folder/file.txt'
-               '[datastore1]' --> '/vmfs/volumes/datastore1'
-
-=cut
-
-sub _get_normal_path {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path_argument = shift;
-	if (!$path_argument) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	if ($path_argument !~ /\[.+\]/ && $path_argument !~ /^\/vmfs\/volumes\//i) {
-		return normalize_file_path($path_argument);
-	}
-	
-	my $datastore_root_normal_path = $self->_get_datastore_root_normal_path($path_argument);
-	if (!$datastore_root_normal_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine normal path, failed to determine datastore root normal path: $path_argument");
-		return;
-	}
-	
-	my $relative_datastore_path = $self->_get_relative_datastore_path($path_argument);
-	if (!defined($relative_datastore_path)) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine normal path, failed to determine relative datastore path: $path_argument");
-		return;
-	}
-	
-	if ($relative_datastore_path) {
-		return "$datastore_root_normal_path/$relative_datastore_path";
-	}
-	else {
-		return $datastore_root_normal_path;
-	}
-	
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_datastore_name
-
- Parameters  : $path
- Returns     : string
- Description : Returns the datastore name from the path argument.
-               '/vmfs/volumes/datastore1/folder/file.txt' --> 'datastore1'
-					'[datastore1] folder/file.txt' --> 'datastore1'
-
-=cut
-
-sub _get_datastore_name {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path = shift;
-	if (!$path) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	$path = normalize_file_path($path);
-	
-	# Get the datastore summary information
-	my $datastore_summaries = $self->_get_datastore_summaries();
-	my @datastore_normal_paths;
-	
-	# Loop through the datastores, check if the path begins with the datastore path
-	for my $datastore_name (keys(%{$datastore_summaries})) {
-		my $datastore_normal_path = $datastore_summaries->{$datastore_name}{normal_path};
-		my $datastore_url = $datastore_summaries->{$datastore_name}{url};
-		
-		if ($path =~ /^(\[$datastore_name\]|$datastore_normal_path|$datastore_url)(\s|\/|$)/) {
-			return $datastore_name;
-		}
-		
-		# Path does not begin with datastore path, add datastore path to array for warning message
-		push @datastore_normal_paths, ("'[$datastore_name]'", "'$datastore_normal_path'", "'$datastore_url'");
-	}
-	
-	notify($ERRORS{'WARNING'}, 0, "unable to determine datastore name from path: '$path', path does not begin with any of the datastore paths:\n" . join("\n", @datastore_normal_paths));
-	return;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_parent_directory_normal_path
-
- Parameters  : $path
- Returns     : string
- Description : Returns the parent directory of the path argument in normal form.
-               '/vmfs/volumes/nfs datastore/vmwarewinxp-base234-v12/*.vmdk' --> '/vmfs/volumes/nfs datastore/vmwarewinxp-base234-v12'
-               '/vmfs/volumes/nfs datastore/vmwarewinxp-base234-v12/' --> '/vmfs/volumes/nfs datastore'
-
-=cut
-
-sub _get_parent_directory_normal_path {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path_argument = shift;
-	if (!$path_argument) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	if ($path_argument !~ /\[.+\]/ && $path_argument !~ /^\/vmfs\/volumes\//i) {
-		# Remove the last component of the path - after the last '/'
-		$path_argument =~ s/[^\/\]]*$//g;
-	
-		return normalize_file_path($path_argument);
-	}
-	
-	my $parent_directory_datastore_path = $self->_get_parent_directory_datastore_path($path_argument);
-	if (!$parent_directory_datastore_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine parent directory normal path, parent directory datastore path could not be determined on which the normal path is based: '$path_argument'");
-		return;
-	}
-	
-	my $parent_directory_normal_path = $self->_get_normal_path($parent_directory_datastore_path);
-	if (!$parent_directory_normal_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine parent directory normal path, parent directory datastore path could not be converted to a normal path: '$parent_directory_datastore_path'");
-		return;
-	}
-	
-	return $parent_directory_normal_path;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_parent_directory_datastore_path
-
- Parameters  : $path
- Returns     : string
- Description : Returns the parent directory path for the path argument in
-               datastore format.
-               '/vmfs/volumes/nfs datastore/vmwarewinxp-base234-v12/*.vmdk ' --> '[nfs datastore] vmwarewinxp-base234-v12'
-
-=cut
-
-sub _get_parent_directory_datastore_path {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path_argument = shift;
-	if (!$path_argument) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	my $datastore_path = $self->_get_datastore_path($path_argument);
-	if (!$datastore_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine parent directory datastore path, path argument could not be converted to a datastore path: '$path_argument'");
-		return;
-	}
-	
-	if ($datastore_path =~ /^\[.+\]$/) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine parent directory datastore path, path argument is the root path of a datastore: '$path_argument'");
-		return;
-	}
-	
-	# Remove the last component of the path - after the last '/'
-	$datastore_path =~ s/[^\/\]]*$//g;
-	
-	return normalize_file_path($datastore_path);
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_file_name
-
- Parameters  : $path
- Returns     : string
- Description : Returns the file name or leftmost section of the path argument.
-               '/vmfs/volumes/nfs datastore/vmwarewinxp-base234-v12/*.vmdk ' --> '*.vmdk'
-
-=cut
-
-sub _get_file_name {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
+		$datastore_info->{$datastore_name} = $datastore_view->summary;
 	}
 	
-	# Get the path argument
-	my $path_argument = shift;
-	if (!$path_argument) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	my $datastore_path = $self->_get_datastore_path($path_argument);
-	if (!$datastore_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine file name, path argument could not be converted to a datastore path: '$path_argument'");
-		return;
-	}
-	
-	if ($datastore_path =~ /^\[.+\]$/) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine file name, path argument is the root path of a datastore: '$path_argument'");
-		return;
-	}
-	
-	# Extract the last component of the path - after the last '/'
-	my ($file_name) = $datastore_path =~ /([^\/\]]+)$/;
-	
-	return normalize_file_path($file_name);
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_file_base_name
-
- Parameters  : $path
- Returns     : string
- Description : Returns the file name of the path argument without the file
-               extension.
-               '/vmfs/volumes/nfs datastore/vmwarewinxp-base234-v12/image_55-v0.vmdk ' --> 'image_55-v0'
-
-=cut
-
-sub _get_file_base_name {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path_argument = shift;
-	if (!$path_argument) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	my $file_name = $self->_get_file_name($path_argument);
-	if (!$file_name) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine file base name, file name could not be determined from path argument: '$path_argument'");
-		return;
-	}
-	
-	# Remove the file extension - everything before the first '.' in the file name
-	my ($file_base_name) = $file_name =~ /^([^\.]*)/;
-	
-	return $file_base_name;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _get_relative_datastore_path
-
- Parameters  : $path
- Returns     : string
- Description : Returns the relative datastore path for the path argument.
-               '/vmfs/volumes/datastore1/folder/file.txt' --> 'folder/file.txt'
-               '[datastore1] folder/file.txt' --> 'folder/file.txt'
-
-=cut
-
-sub _get_relative_datastore_path {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	# Get the path argument
-	my $path_argument = shift;
-	if (!$path_argument) {
-		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
-		return;
-	}
-	
-	my $datastore_name = $self->_get_datastore_name($path_argument);
-	if (!$datastore_name) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine relative datastore path, failed to determine datastore name: $path_argument");
-		return;
-	}
-	
-	my $datastore_root_normal_path = $self->_get_datastore_root_normal_path($path_argument);
-	if (!$datastore_root_normal_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine relative datastore path, failed to determine the normal root path for the datastore: $path_argument");
-		return;
-	}
-	
-	my $datastore_root_url_path = $self->_get_datastore_root_url_path($path_argument);
-	if (!$datastore_root_normal_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine relative datastore path, failed to determine the normal root path for the datastore: $path_argument");
-		return;
-	}
-	
-	my ($datastore_path, $relative_datastore_path) = $path_argument =~ /^(\[$datastore_name\]|$datastore_root_normal_path|$datastore_root_url_path)(.*)/;
-	
-	if (!$datastore_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine relative datastore path: '$path_argument', path argument does not begin with any of the following:\n'[$datastore_name]'\n'$datastore_root_url_path'\n'$datastore_root_normal_path'");
-		return;
-	}
-	
-	$relative_datastore_path = '' if !$relative_datastore_path;
-	
-	# Remove slashes or spaces from the beginning and end of the relative datastore path
-	$relative_datastore_path =~ s/(^[\/\s]*|[\/\s]*$)//g;
-	
-	return $relative_datastore_path;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 _check_datastore_paths
-
- Parameters  : @check_paths (optional)
- Returns     : boolean
- Description : Checks each of the vSphere.pm subroutines which parse a file path
-					argument. This subroutine returns false if any subroutine returns
-					undefined. The file paths passed to each subroutine that is
-					checked may be specified as arguments to _check_datastore_paths.
-					If no arguments are specified, several default paths will be
-					checked.
-
-=cut
-
-sub _check_datastore_paths {
-	my $self = shift;
-	if (ref($self) !~ /module/i) {
-		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
-		return;
-	}
-	
-	my @check_paths = @_;
-	
-	# Check to make sure all of the vmdk file path components can be retrieved
-	my $undefined_string = "<undefined>";
-	
-	# Assemble a string of all of the components
-	my $check_paths_string = "====================\n";
-	
-	my @datastore_names = $self->_get_datastore_names();
-	if (!@datastore_names) {
-		notify($ERRORS{'WARNING'}, 0, "datastore names could not be retrieved");
-	}
-	$check_paths_string .= "datastore names:\n" . join("\n", @datastore_names) . "\n";
-	
-	my $datastore_summaries = $self->_get_datastore_summaries();
-	if (!$datastore_summaries) {
-		notify($ERRORS{'WARNING'}, 0, "datastore summary information could not be retrieved");
-		return;
-	}
-	notify($ERRORS{'DEBUG'}, 0, "datastore summary information:\n" . format_data($datastore_summaries));
-	
-	my @check_subroutines = (
-		'_get_datastore_name',
-		'_get_datastore_path',
-		'_get_normal_path',
-		'_get_datastore_root_normal_path',
-		'_get_datastore_root_url_path',
-		'_get_parent_directory_datastore_path',
-		'_get_parent_directory_normal_path',
-		'_get_relative_datastore_path',
-		'_get_file_name',
-		'_get_file_base_name',
-	);
-	
-	my $max_sub_name_length = max (map { length } @check_subroutines);
-	
-	if (!@check_paths) {
-		#for my $datastore_name (sort keys %$datastore_summaries) {
-		#	my $datastore_normal_path = $datastore_summaries->{$datastore_name}{normal_path};
-		#	my $datastore_url_path = $datastore_summaries->{$datastore_name}{url};
-		#	push @check_paths, (
-		#		"[$datastore_name] ",
-		#		"[$datastore_name] /",
-		#		"[$datastore_name] test/test file.txt ",
-		#		"$datastore_normal_path/test dir/test file.txt ",
-		#		"$datastore_normal_path/test dir/ ",
-		#		"$datastore_url_path/test dir/test file.txt ",
-		#		"$datastore_url_path/test dir/ ",
-		#		"$datastore_url_path/test.txt ",
-		#		"[invalid datastore] file.txt",
-		#	);
-		#}
-		
-		push @check_paths, (
-			$self->get_vmx_file_path(),
-			$self->get_vmx_directory_path(),
-			$self->get_vmx_base_directory_path(),
-			$self->get_vmdk_file_path(),
-			$self->get_vmdk_directory_path(),
-			$self->get_vmdk_base_directory_path(),
-			$self->get_vmdk_directory_path_persistent(),
-			$self->get_vmdk_directory_path_nonpersistent(),
-			$self->get_vmdk_file_path_persistent(),
-			$self->get_vmdk_file_path_nonpersistent(),
-		);
-	}
-	
-	for my $check_path (@check_paths) {
-		$check_paths_string .= "----------\n";
-		$check_paths_string .= "'$check_path'\n";
-		
-		for my $check_subroutine (@check_subroutines) {
-			my $result = eval "\$self->$check_subroutine(\$check_path)";
-			
-			$check_paths_string .= "$check_subroutine: ";
-			$check_paths_string .= " " x ($max_sub_name_length - length($check_subroutine));
-			
-			if (defined($result)) {
-				$check_paths_string .= "'$result'\n";
-			}
-			else {
-				$check_paths_string .= "$undefined_string\n";
-			}
-		}
-	}
-	
-	notify($ERRORS{'OK'}, 0, "retrieved datastore path components:\n$check_paths_string");
-	
-	if ($check_paths_string =~ /$undefined_string/) {
-		return;
-	}
-	else {
-		return 1;
-	}
+	return $datastore_info;
 }
 
 #/////////////////////////////////////////////////////////////////////////////