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 2011/08/04 19:02:26 UTC
svn commit: r1153929 - in
/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware:
VMware.pm vSphere_SDK.pm
Author: arkurth
Date: Thu Aug 4 17:02:25 2011
New Revision: 1153929
URL: http://svn.apache.org/viewvc?rev=1153929&view=rev
Log:
VCL-470
Added code contributed by Aaron Coburn included in the Jira issue to add a vSphere_SDK.pm::get_total_space subroutine.
VCL-471
Updated VMware.pm::_get_parent_directory_normal_path() to allow non-datastore paths to be specified. This solves a problem where a path residing on the management node is passed, but the subroutine fails.
VCL-450
Fixed a problem where vSphere_SDK.pm::copy_virtual_disk failed because the vmdk adapter type is not listed in the typical info if a snapshot has been created.
Updated vSphere.pm to cache most of the SDK object types it uses including host, vm, datastore. This prevents the code from having to fetch a new object every time, greatly increasing speed. This also reduced a lot of duplicated code.
Fixed problem in VMware.pm::node_status. It was not accounting for VMs loaded before the snapshot functionality was added which were using nonpersistent mode.
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=1153929&r1=1153928&r2=1153929&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 Thu Aug 4 17:02:25 2011
@@ -1008,6 +1008,7 @@ sub node_status {
my $reservation_id = $self->data->get_reservation_id();
my $computer_name = $self->data->get_computer_node_name();
my $image_name = $self->data->get_image_name();
+ my $request_forimaging = $self->data->get_request_forimaging();
notify($ERRORS{'DEBUG'}, 0, "attempting to check the status of computer $computer_name, image: $image_name");
@@ -1068,7 +1069,8 @@ sub node_status {
}
# If the VM is dedicated, check if the vmdk of the VM already loaded is shared or dedicated
- if ($self->is_vm_dedicated()) {
+ my $is_vm_dedicated = $self->is_vm_dedicated();
+ if ($request_forimaging || $is_vm_dedicated) {
# Determine the vmx file path actively being used by the VM
my $vmx_file_path = $self->get_active_vmx_file_path();
if (!$vmx_file_path) {
@@ -1102,7 +1104,6 @@ sub node_status {
notify($ERRORS{'WARNING'}, 0, "vmdk file path was not found in the vmx file info, returning 'RELOAD':\n" . format_data($vmx_info));
return $status;
}
- notify($ERRORS{'DEBUG'}, 0, "vmdk file path used by the VM already loaded: $vmdk_file_path");
# Get the vmdk mode from the vmx information and make sure it is not nonpersistent
my $vmdk_mode = $vmx_info->{vmdk}{$vmdk_identifiers[0]}{mode};
@@ -1111,17 +1112,22 @@ sub node_status {
return $status;
}
+ notify($ERRORS{'DEBUG'}, 0, "vmdk file path used by the VM already loaded: $vmdk_file_path, mode: $vmdk_mode");
+
+ # Can't use if nonpersistent
if ($vmdk_mode =~ /nonpersistent/i) {
notify($ERRORS{'OK'}, 0, "VM already loaded may NOT be used, vmdk mode: '$vmdk_mode', returning 'RELOAD'");
return $status;
}
- if ($self->is_vmdk_shared($vmdk_file_path)) {
- notify($ERRORS{'OK'}, 0, "VM already loaded may NOT be used, the vmdk appears to be shared");
- return $status;
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "VM already loaded may be used, the vmdk does NOT appear to be shared");
+ if ($is_vm_dedicated) {
+ if ($self->is_vmdk_shared($vmdk_file_path)) {
+ notify($ERRORS{'OK'}, 0, "VM already loaded may NOT be used, the vmdk appears to be shared");
+ return $status;
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "VM already loaded may be used, the vmdk does NOT appear to be shared");
+ }
}
}
@@ -3082,9 +3088,9 @@ sub get_reference_vmx_file_path {
return $ENV{reference_vmx_file_path} if defined($ENV{reference_vmx_file_path});
- my $vmdk_directory_path = $self->get_vmdk_directory_path();
- if (!$vmdk_directory_path) {
- notify($ERRORS{'WARNING'}, 0, "unable to construct reference vmx file path, vmdk directory path could not be determined");
+ my $vmdk_directory_path_shared = $self->get_vmdk_directory_path_shared();
+ if (!$vmdk_directory_path_shared) {
+ notify($ERRORS{'WARNING'}, 0, "unable to construct reference vmx file path, shared vmdk directory path could not be determined");
return;
}
@@ -3094,7 +3100,7 @@ sub get_reference_vmx_file_path {
return;
}
- $ENV{reference_vmx_file_path} = "$vmdk_directory_path/$reference_vmx_file_name";
+ $ENV{reference_vmx_file_path} = "$vmdk_directory_path_shared/$reference_vmx_file_name";
notify($ERRORS{'DEBUG'}, 0, "determined reference vmx file path: $ENV{reference_vmx_file_path}");
return $ENV{reference_vmx_file_path};
}
@@ -6019,7 +6025,7 @@ sub get_datastore_info {
return;
}
else {
- notify($ERRORS{'DEBUG'}, 0, "retrieved datastore info from VM host:\n" . join("\n", sort keys(%$datastore_info)));
+ notify($ERRORS{'DEBUG'}, 0, "retrieved datastore info from VM host:\n" . join(", ", sort keys(%$datastore_info)));
$self->{datastore_info} = $datastore_info;
return $datastore_info;
}
@@ -6366,6 +6372,13 @@ sub _get_parent_directory_normal_path {
return;
}
+ # If this is a normal path - remove the part after the last '/'
+ if ($path_argument !~ /\[.+\]/) {
+ $path_argument =~ s/[^\/]*\/?$//g;
+ return $self->_get_normal_path($path_argument);
+ }
+
+ # Datastore path was passed, call datastore sub and return normal path
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'");
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=1153929&r1=1153928&r2=1153929&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 Aug 4 17:02:25 2011
@@ -122,12 +122,12 @@ sub vm_register {
# Get the vmx path argument and convert it to a datastore path
my $vmx_path = $self->_get_datastore_path(shift) || return;
- my $host_view = VIExt::get_host_view(1) || return;
- my $datacenter = Vim::find_entity_view (view_type => 'Datacenter') || return;
+ my $host_view = $self->_get_host_view() || return;
+ my $datacenter = $self->_get_datacenter_view() || return;
my $vm_folder = Vim::get_view(mo_ref => $datacenter->{vmFolder}) || return;
my $resource_pool = Vim::find_entity_view(view_type => 'ResourcePool') || return;
- # Override the die handler because fileManager may call it
+ # Override the die handler
local $SIG{__DIE__} = sub{};
my $vm_mo_ref;
@@ -181,12 +181,7 @@ sub vm_unregister {
# Override the die handler
local $SIG{__DIE__} = sub{};
- my $vm;
- eval { $vm = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'config.files.vmPathName' => $vmx_path}); };
- if (!$vm) {
- notify($ERRORS{'DEBUG'}, 0, "VM is not registered: $vmx_path");
- return 1;
- }
+ my $vm = $self->_get_vm_view($vmx_path) || return;
# Make sure the VM is powered off or unregister will fail
$self->vm_power_off($vmx_path) || return;
@@ -197,6 +192,9 @@ sub vm_unregister {
return;
}
+ # Delete the cached VM object
+ delete $self->{vm_view_objects}{$vmx_path};
+
notify($ERRORS{'DEBUG'}, 0, "unregistered VM: $vmx_path");
return 1;
}
@@ -226,12 +224,7 @@ sub vm_power_on {
# Override the die handler
local $SIG{__DIE__} = sub{};
- my $vm;
- eval { $vm = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'config.files.vmPathName' => $vmx_path}); };
- if (!$vm) {
- notify($ERRORS{'WARNING'}, 0, "unable to power on VM because it is not registered: $vmx_path");
- return;
- }
+ my $vm = $self->_get_vm_view($vmx_path) || return;
eval { $vm->PowerOnVM(); };
if ($@) {
@@ -273,15 +266,10 @@ sub vm_power_off {
# Get the vmx path argument and convert it to a datastore path
my $vmx_path = $self->_get_datastore_path(shift) || return;
- # Override the die handler because fileManager may call it
+ # Override the die handler
local $SIG{__DIE__} = sub{};
- my $vm;
- eval { $vm = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'config.files.vmPathName' => $vmx_path}); };
- if (!$vm) {
- notify($ERRORS{'WARNING'}, 0, "unable to power off VM because it is not registered: $vmx_path");
- return;
- }
+ my $vm = $self->_get_vm_view($vmx_path) || return;
eval { $vm->PowerOffVM(); };
if ($@) {
@@ -326,15 +314,10 @@ sub get_vm_power_state {
# Get the vmx path argument and convert it to a datastore path
my $vmx_path = $self->_get_datastore_path(shift) || return;
- # Override the die handler because fileManager may call it
+ # Override the die handler
local $SIG{__DIE__} = sub{};
- my $vm;
- eval { $vm = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'config.files.vmPathName' => $vmx_path}); };
- if (!$vm) {
- notify($ERRORS{'WARNING'}, 0, "unable to retrieve power state of VM because it is not registered: $vmx_path");
- return;
- }
+ my $vm = $self->_get_vm_view($vmx_path) || return;
my $power_state = $vm->runtime->powerState->val;
@@ -457,40 +440,28 @@ sub copy_virtual_disk {
return;
}
- my $destination_adapter_type = shift;
+ my $adapter_type = shift;
# If the adapter type was not specified, retrieve it from the source vmdk file
- if (!$destination_adapter_type) {
- $destination_adapter_type = $self->get_virtual_disk_controller_type($source_path);
- if (!$destination_adapter_type) {
- notify($ERRORS{'WARNING'}, 0, "destination adapter type argument was not specifed and unable to retrieve adapter type from source vmdk file: $source_path, using lsiLogic");
- $destination_adapter_type = 'lsiLogic';
+ if (!$adapter_type) {
+ $adapter_type = $self->get_vm_disk_adapter_type($source_path);
+ if (!$adapter_type) {
+ notify($ERRORS{'WARNING'}, 0, "adapter type argument was not specifed and unable to retrieve adapter type from source vmdk file: $source_path, using lsiLogic");
+ $adapter_type = 'lsiLogic';
}
}
- # Check the adapter type argument, the string must match exactly or the copy will fail
- my @valid_adapter_types = qw( busLogic lsiLogic ide );
- if (!grep(/^$destination_adapter_type$/, @valid_adapter_types)) {
- notify($ERRORS{'WARNING'}, 0, "adapter type argument is not valid: '$destination_adapter_type', it must exactly match (case sensitive) one of the following strings:\n" . join("\n", @valid_adapter_types));
- 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 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;
+ my $virtual_disk_manager = $self->_get_virtual_disk_manager_view() || return;
# Get the destination partent directory path and create the directory
my $destination_directory_path = $self->_get_parent_directory_datastore_path($destination_path) || return;
$self->create_directory($destination_directory_path) || return;
# Create a virtual disk spec object
- my $virtual_disk_spec = VirtualDiskSpec->new(adapterType => $destination_adapter_type,
+ my $virtual_disk_spec = VirtualDiskSpec->new(adapterType => $adapter_type,
diskType => $destination_disk_type,
);
@@ -500,10 +471,9 @@ sub copy_virtual_disk {
my @file_names = keys(%{$source_info});
my $info_file_name = $file_names[0];
- my $source_adapter_type = $source_info->{$info_file_name}{controllerType};
- 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/) {
+ my $source_disk_type = $source_info->{$info_file_name}{diskType} || 'unknown';
+ my $source_file_size_bytes = $source_info->{$info_file_name}{fileSize} || 'unknown';
+ if ($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 on VM host $vmhost_name: '$source_path', file info:\n" . format_data($source_info));
return;
}
@@ -513,7 +483,7 @@ sub copy_virtual_disk {
# Attempt to copy the file
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
+ adapter type: $adapter_type
disk type: $source_disk_type --> $destination_disk_type
source file size: " . format_number($source_file_size_bytes));
@@ -590,27 +560,10 @@ sub move_virtual_disk {
$self->create_directory($destination_parent_directory_path) || return;
# Check if a virtual disk manager object is available
- my $service_content = Vim::get_service_content() || return;
-
- # 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 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 on VM host $vmhost_name");
- return;
- }
+ my $virtual_disk_manager = $self->_get_virtual_disk_manager_view() || 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 on VM host $vmhost_name");
- return;
- }
+ my $datacenter = $self->_get_datacenter_view() || return;
# Override the die handler
local $SIG{__DIE__} = sub{};
@@ -835,7 +788,7 @@ sub get_virtual_disk_controller_type {
# Check if the controllerType key exists in the vmdk file info
if (!defined($vmdk_file_info->{controllerType}) || !$vmdk_file_info->{controllerType}) {
- notify($ERRORS{'WARNING'}, 0, "unable to retrieve controllerType value from file info: $vmdk_file_path\n" . format_data($vmdk_file_info));
+ notify($ERRORS{'DEBUG'}, 0, "unable to retrieve controllerType value from file info: $vmdk_file_path\n" . format_data($vmdk_file_info));
return;
}
@@ -980,7 +933,7 @@ sub get_vmware_product_name {
my $vmhost_hostname = $self->data->get_vmhost_hostname();
# Get the host view
- my $host_view = VIExt::get_host_view(1);
+ my $host_view = $self->_get_host_view();
my $product_name = $host_view->config->product->fullName;
if ($product_name) {
@@ -1017,7 +970,7 @@ sub get_vmware_product_version {
my $vmhost_hostname = $self->data->get_vmhost_hostname();
# Get the host view
- my $host_view = VIExt::get_host_view(1);
+ my $host_view = $self->_get_host_view();
my $product_version = $host_view->config->product->version;
if ($product_version) {
@@ -1049,7 +1002,7 @@ sub get_network_names {
}
# Get the host view
- my $host_view = VIExt::get_host_view(1);
+ my $host_view = $self->_get_host_view();
# Retrieve the network info, check if each network is accessible
my @network_names;
@@ -1160,8 +1113,7 @@ sub create_directory {
my $vmhost_hostname = $self->data->get_vmhost_hostname();
# Get a fileManager object
- my $service_content = Vim::get_service_content() || return;
- my $file_manager = Vim::get_view(mo_ref => $service_content->{fileManager}) || return;
+ my $file_manager = $self->_get_file_manager_view() || return;
# Override the die handler because MakeDirectory may call it
local $SIG{__DIE__} = sub{};
@@ -1226,10 +1178,9 @@ sub delete_file {
}
# Get a fileManager object
- my $service_content = Vim::get_service_content() || return;
- my $file_manager = Vim::get_view(mo_ref => $service_content->{fileManager}) || return;
+ my $file_manager = $self->_get_file_manager_view() || return;
- # Override the die handler because fileManager may call it
+ # Override the die handler
local $SIG{__DIE__} = sub{};
# Attempt to delete the file
@@ -1282,11 +1233,10 @@ sub copy_file {
$self->create_directory($destination_directory_path) || return;
# Get a fileManager object
- my $service_content = Vim::get_service_content() || return;
- my $file_manager = Vim::get_view(mo_ref => $service_content->{fileManager}) || return;
- my $datacenter = Vim::find_entity_view(view_type => 'Datacenter') || return;
+ my $file_manager = $self->_get_file_manager_view() || return;
+ my $datacenter = $self->_get_datacenter_view() || return;
- # Override the die handler because fileManager may call it
+ # Override the die handler
local $SIG{__DIE__} = sub{};
# Attempt to copy the file
@@ -1540,11 +1490,10 @@ sub move_file {
$self->create_directory($destination_directory_path) || return;
# Get a fileManager and Datacenter object
- my $service_content = Vim::get_service_content() || return;
- my $file_manager = Vim::get_view(mo_ref => $service_content->{fileManager}) || return;
- my $datacenter = Vim::find_entity_view(view_type => 'Datacenter') || return;
+ my $file_manager = $self->_get_file_manager_view() || return;
+ my $datacenter = $self->_get_datacenter_view() || return;
- # Override the die handler because fileManager may call it
+ # Override the die handler
local $SIG{__DIE__} = sub{};
# Attempt to copy the file
@@ -1753,6 +1702,50 @@ sub find_files {
}
#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_total_space
+
+ Parameters : $path
+ Returns : integer
+ Description : Returns the total size (in bytes) of the volume specified by the
+ argument.
+
+=cut
+
+sub get_total_space {
+ 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 path argument
+ my $path = shift;
+ if (!$path) {
+ notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
+ return;
+ }
+
+ # Get the datastore name
+ my $datastore_name = $self->_get_datastore_name($path) || return;
+
+ my $vmhost_hostname = $self->data->get_vmhost_hostname();
+
+ # Get the datastore info hash
+ my $datastore_info = $self->_get_datastore_info() || return;
+
+ my $total_bytes = $datastore_info->{$datastore_name}{capacity};
+ if (!defined($total_bytes)) {
+ notify($ERRORS{'WARNING'}, 0, "datastore $datastore_name capacity key does not exist in datastore info:\n" . format_data($datastore_info));
+ return;
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, "capacity of $datastore_name datastore on $vmhost_hostname: " . get_file_size_info_string($total_bytes));
+ return $total_bytes;
+}
+
+
+#/////////////////////////////////////////////////////////////////////////////
=head2 get_available_space
@@ -1783,7 +1776,7 @@ sub get_available_space {
my $vmhost_hostname = $self->data->get_vmhost_hostname();
# Get the datastore info hash
- my $datastore_info = $self->_get_datastore_info() || return;
+ my $datastore_info = $self->_get_datastore_info(1) || return;
my $available_bytes = $datastore_info->{$datastore_name}{freeSpace};
if (!defined($available_bytes)) {
@@ -1791,7 +1784,7 @@ sub get_available_space {
return;
}
- notify($ERRORS{'DEBUG'}, 0, "space available in $datastore_name datastore on $vmhost_hostname: " . format_number($available_bytes) . " bytes");
+ notify($ERRORS{'DEBUG'}, 0, "space available in $datastore_name datastore on $vmhost_hostname: " . get_file_size_info_string($available_bytes));
return $available_bytes;
}
@@ -1996,7 +1989,7 @@ sub _get_file_info {
query => [@file_queries],
);
- # Override the die handler because fileManager may call it
+ # Override the die handler
local $SIG{__DIE__} = sub{};
# Searches the folder specified by the datastore path and all subfolders based on the searchSpec
@@ -2056,12 +2049,168 @@ sub _get_file_info {
}
}
- #notify($ERRORS{'DEBUG'}, 0, "retrieved info for " . scalar(keys(%file_info)) . " matching files:\n" . format_data(\%file_info));
+ notify($ERRORS{'DEBUG'}, 0, "retrieved info for " . scalar(keys(%file_info)) . " matching files:\n" . format_data(\%file_info));
return \%file_info;
}
#/////////////////////////////////////////////////////////////////////////////
+=head2 _get_host_view
+
+ Parameters :
+ Returns : vSphere SDK host object
+ Description : Retrieves a host object.
+
+=cut
+
+sub _get_host_view {
+ 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 $self->{host_view_object} if $self->{host_view_object};
+
+ # Get the host view
+ $self->{host_view_object} = VIExt::get_host_view(1);
+ return $self->{host_view_object};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_datacenter_view
+
+ Parameters :
+ Returns : vSphere SDK datacenter view object
+ Description : Retrieves a vSphere SDK datacenter view object.
+
+=cut
+
+sub _get_datacenter_view {
+ 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 $self->{datacenter_view_object} if $self->{datacenter_view_object};
+
+ # Get the host view
+ my $datacenter = Vim::find_entity_view(view_type => 'Datacenter');
+ if (!$datacenter) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve datacenter view object");
+ return;
+ }
+ else {
+ $self->{datacenter_view_object} = $datacenter;
+ return $self->{datacenter_view_object};
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_vm_view
+
+ Parameters : $vmx_file_path (optional)
+ Returns :
+ Description :
+
+=cut
+
+sub _get_vm_view {
+ 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 vmx path argument and convert it to a datastore path
+ my $vmx_path = shift || $self->get_vmx_file_path();
+ $vmx_path = $self->_get_datastore_path($vmx_path);
+
+ # Override the die handler
+ local $SIG{__DIE__} = sub{};
+
+ my $vm_view;
+ eval { $vm_view = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'config.files.vmPathName' => $vmx_path}); };
+ if (!$vm_view) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve view object for VM: $vmx_path");
+ return;
+ }
+
+ $self->{vm_view_objects}{$vmx_path} = $vm_view;
+ return $self->{vm_view_objects}{$vmx_path};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_virtual_disk_manager_view
+
+ Parameters :
+ Returns : vSphere SDK virtual disk manager view object
+ Description : Retrieves a vSphere SDK virtual disk manager view object.
+
+=cut
+
+sub _get_virtual_disk_manager_view {
+ 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 $self->{virtual_disk_manager_object} if $self->{virtual_disk_manager_object};
+
+ # Get a virtual disk manager object
+ my $service_content = Vim::get_service_content() || return;
+ if (!$service_content->{virtualDiskManager}) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve virtual disk manager object, it is not available via the vSphere SDK");
+ return;
+ }
+
+ my $virtual_disk_manager = Vim::get_view(mo_ref => $service_content->{virtualDiskManager});
+ if (!$virtual_disk_manager) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve virtual disk manager object");
+ return;
+ }
+
+ $self->{virtual_disk_manager_object} = $virtual_disk_manager;
+ return $self->{virtual_disk_manager_object};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_file_manager_view
+
+ Parameters :
+ Returns : vSphere SDK file manager view object
+ Description : Retrieves a vSphere SDK file manager view object.
+
+=cut
+
+sub _get_file_manager_view {
+ 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 $self->{file_manager_object} if $self->{file_manager_object};
+
+ my $service_content = Vim::get_service_content() || return;
+ my $file_manager = Vim::get_view(mo_ref => $service_content->{fileManager});
+ if (!$file_manager) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve file manager object");
+ return;
+ }
+
+ $self->{file_manager_object} = $file_manager;
+ return $self->{file_manager_object};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 _get_datastore_object
Parameters : $datastore_name
@@ -2079,14 +2228,16 @@ sub _get_datastore_object {
}
# Get the datastore name argument
- my $datastore_name = shift;
- if (!$datastore_name) {
+ my $datastore_name_argument = shift;
+ if (!$datastore_name_argument) {
notify($ERRORS{'WARNING'}, 0, "datastore name argument was not specified");
return;
}
+ return $self->{datastore_objects}{$datastore_name_argument} if ($self->{datastore_objects}{$datastore_name_argument});
+
# Get the host view
- my $host_view = VIExt::get_host_view(1);
+ my $host_view = $self->_get_host_view();
# Get an array containing datastore managed object references
my @datastore_mo_refs = @{$host_view->datastore};
@@ -2096,11 +2247,13 @@ sub _get_datastore_object {
my @datastore_names_found;
for my $datastore_mo_ref (@datastore_mo_refs) {
my $datastore = Vim::get_view(mo_ref => $datastore_mo_ref);
- return $datastore if ($datastore_name eq $datastore->summary->name);
- push @datastore_names_found, $datastore->summary->name;
+ my $datastore_name = $datastore->summary->name;
+ $self->{datastore_objects}{$datastore_name} = $datastore;
}
- notify($ERRORS{'WARNING'}, 0, "failed to find datastore named $datastore_name, datastore names found:\n" . join("\n", @datastore_names_found));
+ return $self->{datastore_objects}{$datastore_name_argument} if ($self->{datastore_objects}{$datastore_name_argument});
+
+ notify($ERRORS{'WARNING'}, 0, "failed to find datastore named $datastore_name_argument, datastore names found:\n" . join("\n", keys(%{$self->{datastore_objects}})));
return;
}
@@ -2134,10 +2287,14 @@ sub _get_datastore_info {
return;
}
+ # If the datastore info was previously retrieved, return the cached data unless an argument was specified
+ my $no_cache = shift;
+ return $self->{datastore_info} if (!$no_cache && $self->{datastore_info});
+
my $vmhost_hostname = $self->data->get_vmhost_hostname();
# Get the host view
- my $host_view = VIExt::get_host_view(1);
+ my $host_view = $self->_get_host_view();
# Get an array containing datastore managed object references
my @datastore_mo_refs = @{$host_view->datastore};
@@ -2173,6 +2330,8 @@ sub _get_datastore_info {
$datastore_info->{$datastore_name} = $datastore_view->summary;
}
+ #notify($ERRORS{'DEBUG'}, 0, "retrieved datastore info:\n" . format_data($datastore_info));
+ $self->{datastore_info} = $datastore_info;
return $datastore_info;
}
@@ -2201,12 +2360,7 @@ sub create_snapshot {
# Override the die handler
local $SIG{__DIE__} = sub{};
- my $vm;
- eval { $vm = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'config.files.vmPathName' => $vmx_path}); };
- if (!$vm) {
- notify($ERRORS{'WARNING'}, 0, "unable to create snapshop because VM is not registered: $vmx_path");
- return;
- }
+ my $vm = $self->_get_vm_view($vmx_path) || return;
eval { $vm->CreateSnapshot(name => $snapshot_name,
memory => 0,
@@ -2243,18 +2397,13 @@ sub snapshot_exists {
# Get the vmx path argument and convert it to a datastore path
my $vmx_path = $self->_get_datastore_path(shift) || return;
- # Override the die handler because fileManager may call it
+ # Override the die handler
local $SIG{__DIE__} = sub{};
- my $vm;
- eval { $vm = Vim::find_entity_view(view_type => 'VirtualMachine', filter => {'config.files.vmPathName' => $vmx_path}); };
- if (!$vm) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine if snapshot exists because VM is not registered: $vmx_path");
- return;
- }
+ my $vm = $self->_get_vm_view($vmx_path) || return;
if (defined($vm->snapshot)) {
- notify($ERRORS{'DEBUG'}, 0, "snapshot exists for VM: $vmx_path");
+ notify($ERRORS{'DEBUG'}, 0, "snapshot exists for VM: $vmx_path\n" . format_data($vm->snapshot));
return 1;
}
else {