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/08/20 22:06:13 UTC
svn commit: r987623 [1/2] - in /incubator/vcl/trunk/managementnode/lib/VCL:
Module/OS/Windows.pm Module/Provisioning/VMware/VMware.pm
Module/Provisioning/VMware/vSphere_SDK.pm image.pm utils.pm
Author: arkurth
Date: Fri Aug 20 20:06:13 2010
New Revision: 987623
URL: http://svn.apache.org/viewvc?rev=987623&view=rev
Log:
VCL-164
Added setup and setup_capture_base_image subroutines to image.pm which allows the base image creation steps to be automated via a command-line interface when vcld is run with the -setup argument. Added get_computer_ids, get_os_info, and get_user_info subroutines to utils.pm which are called by image.pm::setup.
Removed call to enable DHCP in Windows.pm::pre_capture and added a switch to Windows.pm::shutdown allowing the caller to specify whether or not DHCP should be disabled immediately before shutting down the computer. This allows a base image to be captured which has been configured with a static address.
VCL-298
Updated VMware.pm. Split up prepare_vmx subroutine to create another subroutine which only removes existing VMs which were created for the VM assigned to the reservation.
Reworked VMware.pm::capture to display more meaningful error and warning messages.
Reworked most of the get_vmx...path and get_vmdk...path subroutines to display more meaningful error and warning messages.
Updated vSphere.pm::copy_virtual_disk to retrieve the adapter type from the source vmdk rather than using lsiLogic as the default value if the argument was not specified.
Modified:
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
incubator/vcl/trunk/managementnode/lib/VCL/image.pm
incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=987623&r1=987622&r2=987623&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Fri Aug 20 20:06:13 2010
@@ -226,16 +226,6 @@ sub pre_capture {
return 0;
}
-#=item *
-#
-# Disable IPv6
-#
-#=cut
-#
-# if (!$self->disable_ipv6()) {
-# notify($ERRORS{'WARNING'}, 0, "unable to disable IPv6");
-# }
-
=item *
Disable dynamic DNS
@@ -335,17 +325,6 @@ sub pre_capture {
if (!$self->clean_hard_drive()) {
notify($ERRORS{'WARNING'}, 0, "unable to clean unnecessary files the hard drive");
}
-
-=item *
-
- Configure the network adapters to use DHCP
-
-=cut
-
- if (!$self->enable_dhcp()) {
- notify($ERRORS{'WARNING'}, 0, "unable to enable DHCP on the public and private interfaces");
- return 0;
- }
=item *
@@ -3078,14 +3057,40 @@ sub shutdown {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
+
+ # Get the argument that determines whether or not to disable DHCP before shutting down computer
+ my $disable_dhcp = shift;
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
- notify($ERRORS{'DEBUG'}, 0, "$computer_node_name will be shut down");
-
+
+ my $system32_path = $self->get_system32_path();
+ my $shutdown_command = "/bin/cygstart.exe cmd.exe /c \"";
+
+ if ($disable_dhcp) {
+ notify($ERRORS{'DEBUG'}, 0, "enabling DHCP and shutting down $computer_node_name");
+
+ my $private_interface_name = $self->get_private_interface_name();
+ my $public_interface_name = $self->get_public_interface_name();
+ if (!$private_interface_name || !$public_interface_name) {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine private and public interface names, failed to enable DHCP and shut down $computer_node_name");
+ return;
+ }
+
+ $shutdown_command .= "$system32_path/netsh.exe interface ip set address name=\\\"$private_interface_name\\\" source=dhcp & ";
+ $shutdown_command .= "$system32_path/netsh.exe interface ip set dnsservers name=\\\"$private_interface_name\\\" source=dhcp & ";
+
+ $shutdown_command .= "$system32_path/netsh.exe interface ip set address name=\\\"$public_interface_name\\\" source=dhcp & ";
+ $shutdown_command .= "$system32_path/netsh.exe interface ip set dnsservers name=\\\"$public_interface_name\\\" source=dhcp & ";
+
+ $shutdown_command .= "$system32_path/route.exe DELETE 0.0.0.0 MASK 0.0.0.0 & ";
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "shutting down $computer_node_name");
+ }
+
# Initiate the shutdown.exe command to reboot the computer
- my $shutdown_command = 'cmd.exe /c "' . $self->get_system32_path() . '/shutdown.exe -s -t 0 -f"';
+ $shutdown_command .= "$system32_path/shutdown.exe -s -t 0 -f\"";
my $attempt_count = 0;
my $attempt_limit = 12;
@@ -3097,30 +3102,28 @@ sub shutdown {
}
my ($shutdown_exit_status, $shutdown_output) = run_ssh_command($computer_node_name, $management_node_keys, $shutdown_command);
- if (defined($shutdown_exit_status) && $shutdown_exit_status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "attempt $attempt_count/$attempt_limit: executed shutdown command on $computer_node_name");
-
- # Wait maximum of 3 minutes for the computer to become unresponsive
- if ($self->wait_for_no_ping(180)) {
- notify($ERRORS{'OK'}, 0, "attempt $attempt_count/$attempt_limit: computer has become unresponsive after shutdown command was issued");
- return 1;
- }
- else {
- # Computer never stopped responding to ping
- notify($ERRORS{'WARNING'}, 0, "attempt $attempt_count/$attempt_limit: $computer_node_name never became unresponsive after shutdown command was issued, attempting power off");
- }
+ if (!defined($shutdown_output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to shutdown $computer_node_name");
+ last;
}
- elsif (defined($shutdown_output) && grep(/processing another action/i, @$shutdown_output)) {
+ elsif (grep(/(processing another action)/i, @$shutdown_output)) {
notify($ERRORS{'WARNING'}, 0, "attempt $attempt_count/$attempt_limit: failed to execute shutdown command on $computer_node_name, exit status: $shutdown_exit_status, output:\n@{$shutdown_output}");
next;
}
- elsif (defined($shutdown_output)) {
- notify($ERRORS{'WARNING'}, 0, "attempt $attempt_count/$attempt_limit: failed to execute shutdown command on $computer_node_name, exit status: $shutdown_exit_status, output:\n@{$shutdown_output}");
- }
else {
- notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to shutdown $computer_node_name");
+ notify($ERRORS{'DEBUG'}, 0, "attempt $attempt_count/$attempt_limit: executed shutdown command on $computer_node_name");
+ last;
}
- last;
+ }
+
+ # Wait maximum of 3 minutes for the computer to become unresponsive
+ if ($self->wait_for_no_ping(180)) {
+ notify($ERRORS{'OK'}, 0, "attempt $attempt_count/$attempt_limit: computer has become unresponsive after shutdown command was issued");
+ return 1;
+ }
+ else {
+ # Computer never stopped responding to ping
+ notify($ERRORS{'WARNING'}, 0, "$computer_node_name did not become unresponsive after shutdown command was issued, attempting power off");
}
# Call provisioning module's power_off() subroutine
@@ -3291,7 +3294,7 @@ sub prepare_post_load {
# Shut down computer unless end_state argument was passed with a value other than 'off'
if ($end_state eq 'off') {
- if (!$self->shutdown()) {
+ if (!$self->shutdown(1)) {
notify($ERRORS{'WARNING'}, 0, "failed to shut down computer");
return;
}
@@ -4671,6 +4674,9 @@ sub get_network_configuration {
}
}
+
+
+
notify($ERRORS{'DEBUG'}, 0, 'saving network configuration in $self->{network_configuration}');
$self->{network_configuration} = \%network_configuration;
}
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=987623&r1=987622&r2=987623&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 Aug 20 20:06:13 2010
@@ -324,6 +324,12 @@ sub load {
insertloadlog($reservation_id, $computer_id, "startload", "$computer_name $image_name");
+ # Remove existing VMs which were created for the reservation computer
+ if (!$self->remove_existing_vms()) {
+ notify($ERRORS{'WARNING'}, 0, "failed to remove existing VMs created for computer $computer_name on VM host: $vmhost_hostname");
+ return;
+ }
+
# Check if the .vmdk files exist, copy them if necessary
if (!$self->prepare_vmdk()) {
notify($ERRORS{'WARNING'}, 0, "failed to prepare vmdk file for $computer_name on VM host: $vmhost_hostname");
@@ -391,17 +397,27 @@ sub capture {
}
# 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) {
- notify($ERRORS{'WARNING'}, 0, "unable to capture image, failed to determine the vmx file path being used by $computer_name");
+ my $vmx_file_path_capture = $self->get_active_vmx_file_path();
+ if (!$vmx_file_path_capture) {
+ notify($ERRORS{'WARNING'}, 0, "failed to determine the vmx file path actively being used by $computer_name");
return;
}
# Set the vmx file path in this object so that it overrides the default value that would normally be constructed
- $self->set_vmx_file_path($vmx_file_path) || return;
+ if (!$self->set_vmx_file_path($vmx_file_path_capture)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to set the vmx file to the path that was determined to be in use by the VM being captured: $vmx_file_path_capture");
+ return;
+ }
+
+ # Get the vmx directory path of the VM being captured
+ my $vmx_directory_path_capture = $self->get_vmx_directory_path();
+ if (!$vmx_directory_path_capture) {
+ notify($ERRORS{'WARNING'}, 0, "failed to determine the vmx directory path of the VM being captured");
+ return;
+ }
# Get the information contained within the vmx file
- my $vmx_info = $self->get_vmx_info($vmx_file_path);
+ my $vmx_info = $self->get_vmx_info($vmx_file_path_capture);
notify($ERRORS{'DEBUG'}, 0, "vmx info for VM to be captured:\n" . format_data($vmx_info));
# Get the vmdk info from the vmx info
@@ -415,13 +431,13 @@ sub capture {
return;
}
- # Get the vmdk file path from the vmx information
- my $vmdk_file_path = $vmx_info->{vmdk}{$vmdk_identifiers[0]}{vmdk_file_path};
- if (!$vmdk_file_path) {
- notify($ERRORS{'WARNING'}, 0, "vmdk file path was not found in the vmx info:\n" . format_data($vmx_info));
+ # Get the vmdk file path to be captured from the vmx information
+ my $vmdk_file_path_capture = $vmx_info->{vmdk}{$vmdk_identifiers[0]}{vmdk_file_path};
+ if (!$vmdk_file_path_capture) {
+ notify($ERRORS{'WARNING'}, 0, "vmdk file path to be captured was not found in the vmx file info:\n" . format_data($vmx_info));
return;
}
- notify($ERRORS{'DEBUG'}, 0, "vmdk file path used by the VM: $vmdk_file_path");
+ notify($ERRORS{'DEBUG'}, 0, "vmdk file path used by the VM to be captured: $vmdk_file_path_capture");
# Get the vmdk mode from the vmx information and make sure it's persistent
my $vmdk_mode = $vmx_info->{vmdk}{$vmdk_identifiers[0]}{mode};
@@ -429,70 +445,96 @@ sub capture {
notify($ERRORS{'WARNING'}, 0, "vmdk mode was not found in the vmx info:\n" . format_data($vmx_info));
return;
}
- elsif ($vmdk_mode !~ /(independent-)?persistent/i) {
- notify($ERRORS{'WARNING'}, 0, "vmdk mode is not persistent: $vmdk_mode");
+ elsif ($vmdk_mode !~ /^(independent-)?persistent/i) {
+ notify($ERRORS{'WARNING'}, 0, "mode of vmdk '$vmdk_file_path_capture': $vmdk_mode, the mode must be persistent in order to be captured");
return;
}
- notify($ERRORS{'DEBUG'}, 0, "vmdk mode is valid: $vmdk_mode");
+ notify($ERRORS{'DEBUG'}, 0, "mode of vmdk to be captured is valid: $vmdk_mode");
# Set the vmdk file path in this object so that it overrides the default value that would normally be constructed
- $self->set_vmdk_file_path($vmdk_file_path) || return;
+ if (!$self->set_vmdk_file_path($vmdk_file_path_capture)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to set the vmdk file to the path that was determined to be in use by the VM being captured: $vmdk_file_path_capture");
+ return;
+ }
# Construct the vmdk file path where the captured image will be saved to
- my $vmdk_renamed_file_path = "$vmhost_profile_datastore_path/$image_name/$image_name.vmdk";
+ my $vmdk_file_path_renamed = "$vmhost_profile_datastore_path/$image_name/$image_name.vmdk";
# Make sure the vmdk file path for the captured image doesn't already exist
- if ($vmdk_file_path ne $vmdk_renamed_file_path && $self->vmhost_os->file_exists($vmdk_renamed_file_path)) {
- notify($ERRORS{'WARNING'}, 0, "vmdk file for captured image already exists: $vmdk_renamed_file_path");
+ # Do this before calling pre_capture and shutting down the VM
+ if ($vmdk_file_path_capture ne $vmdk_file_path_renamed && $self->vmhost_os->file_exists($vmdk_file_path_renamed)) {
+ notify($ERRORS{'WARNING'}, 0, "vmdk file that captured image will be renamed to already exists: $vmdk_file_path_renamed");
return;
}
# Write the details about the new image to ~/currentimage.txt
- write_currentimage_txt($self->data) || return;
+ if (!write_currentimage_txt($self->data)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create the currentimage.txt file on the VM being captured");
+ return;
+ }
# Call the OS module's pre_capture() subroutine if implemented
- if ($self->os->can("pre_capture")) {
- $self->os->pre_capture({end_state => 'off'}) || return;
+ if ($self->os->can("pre_capture") && !$self->os->pre_capture({end_state => 'off'})) {
+ notify($ERRORS{'WARNING'}, 0, "failed to complete OS module's pre_capture tasks");
+ return;
}
# Power off the VM if it's not already off
- my $vm_power_state = $self->api->get_vm_power_state($vmx_file_path) || return;
- if ($vm_power_state !~ /off/i) {
- $self->api->vm_power_off($vmx_file_path) || return;
-
- # Sleep for 5 seconds to make sure the power off is complete
- sleep 5;
+ my $vm_power_state = $self->api->get_vm_power_state($vmx_file_path_capture);
+ if (!defined($vm_power_state)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve the power state of the VM being captured after the OS module's pre_capture tasks were completed");
+ return;
+ }
+ elsif ($vm_power_state !~ /off/i) {
+ if ($self->api->vm_power_off($vmx_file_path_capture)) {
+ # Sleep for 5 seconds to make sure the power off is complete
+ sleep 5;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to power off the VM being captured after the OS module's pre_capture tasks were completed, VM power state: $vm_power_state");
+ return;
+ }
}
# Rename the vmdk files on the VM host and change the vmdk directory name to the image name
- # This ensures that the vmdk and vmx files now reside in different directories
- # so that the vmdk files can't be deleted when the vmx directory is deleted later on
- if ($vmdk_file_path ne $vmdk_renamed_file_path) {
- $self->rename_vmdk($vmdk_file_path, $vmdk_renamed_file_path) || return;
- $self->set_vmdk_file_path($vmdk_renamed_file_path) || return;
+ if ($vmx_file_path_capture ne $vmdk_file_path_renamed) {
+ if (!$self->rename_vmdk($vmdk_file_path_capture, $vmdk_file_path_renamed)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to rename the vmdk files after the VM was powered off: '$vmdk_file_path_capture' --> '$vmdk_file_path_renamed'");
+ return;
+ }
+
+ if (!$self->set_vmdk_file_path($vmdk_file_path_renamed)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to set the vmdk file to the path after renaming the vmdk files: $vmdk_file_path_renamed");
+ return;
+ }
}
else {
- notify($ERRORS{'DEBUG'}, 0, "vmdk file does not need to be renamed: $vmdk_file_path");
+ notify($ERRORS{'DEBUG'}, 0, "vmdk file does not need to be renamed: $vmx_file_path_capture");
}
+ # Get the renamed vmdk directory path
+ my $vmdk_directory_path_renamed = $self->get_vmdk_directory_path();
+
# Check if the VM host is using local or network-based disk to store vmdk files
# Don't have to do anything else for network disk because the vmdk directory has already been renamed
if ($vmprofile_vmdisk eq "localdisk") {
- # Get the vmdk directory path
- my $vmdk_directory_path = $self->get_vmdk_directory_path() || return;
-
# Copy the vmdk directory from the VM host to the image repository
- my @vmdk_copy_paths = $self->vmhost_os->find_files($vmdk_directory_path, '*.vmdk');
+ my @vmdk_copy_paths = $self->vmhost_os->find_files($vmdk_directory_path_renamed, '*.vmdk');
if (!@vmdk_copy_paths) {
- notify($ERRORS{'WARNING'}, 0, "unable to find vmdk file paths on VM host to copy back to the managment node, vmdk directory path: $vmdk_directory_path, pattern: *.vmdk");
+ notify($ERRORS{'WARNING'}, 0, "failed to find the renamed vmdk files on VM host to copy back to the managment node's image repository");
return;
}
- my $repository_directory_path = $self->get_repository_vmdk_directory_path() || return;
+ # Get the image repository directory path on this management node
+ my $repository_directory_path = $self->get_repository_vmdk_directory_path();
+ if (!$repository_directory_path) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve management node's image repository path");
+ return;
+ }
# Loop through the files, copy each to the management node's repository directory
for my $vmdk_copy_path (@vmdk_copy_paths) {
- my ($vmdk_copy_name) = $vmdk_copy_path =~ /([^\/]+)$/g;
+ 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 the VM host to the management node:\n '$vmdk_copy_path' --> '$repository_directory_path/$vmdk_copy_name'");
return;
@@ -500,19 +542,40 @@ sub capture {
}
# Delete the vmdk directory on the VM host
- $self->vmhost_os->delete_file($vmdk_directory_path) || return;
+ if ($vmdk_directory_path_renamed eq $vmx_directory_path_capture) {
+ notify($ERRORS{'DEBUG'}, 0, "renamed vmdk directory will not be deleted yet because it matches the vmx directory path and the VM has not been unregistered yet: $vmdk_directory_path_renamed");
+ }
+ else {
+ if ($self->vmhost_os->delete_file($vmdk_directory_path_renamed)) {
+ notify($ERRORS{'OK'}, 0, "deleted the vmdk directory after files were copied to the image repository: $vmdk_directory_path_renamed");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to delete the vmdk directory after files were copied to the image repository: $vmdk_directory_path_renamed");
+ }
+ }
}
+
# Unregister the VM
- $self->api->vm_unregister($vmx_file_path) || return;
+ if ($self->api->vm_unregister($vmx_file_path_capture)) {
+ notify($ERRORS{'OK'}, 0, "unregistered the VM being captured: $vmx_file_path_capture");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to unregister the VM being captured: $vmx_file_path_capture");
+ }
+
# Delete the vmx directory
- if ($self->get_vmx_directory_path() ne $self->get_vmdk_directory_path()) {
- $self->vmhost_os->delete_file($self->get_vmx_directory_path()) || return;
+ if ($vmprofile_vmdisk eq "networkdisk" && $vmx_directory_path_capture eq $vmdk_directory_path_renamed) {
+ notify($ERRORS{'DEBUG'}, 0, "vmx directory will not be deleted because the VM disk mode is '$vmprofile_vmdisk' and the vmx directory path is the same as the vmdk directory path for the captured image: '$vmdk_directory_path_renamed'");
}
else {
- notify($ERRORS{'WARNING'}, 0, "vmx directory not deleted because it matches the vmdk directory, this should never happen: " . $self->get_vmdk_directory_path());
- return;
+ if ($self->vmhost_os->delete_file($vmx_directory_path_capture)) {
+ notify($ERRORS{'OK'}, 0, "deleted the vmx directory after the image was captured: $vmx_directory_path_capture");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to delete the vmx directory that was captured: $vmx_directory_path_capture");
+ }
}
return 1;
@@ -935,70 +998,24 @@ sub get_vmhost_api_object {
#/////////////////////////////////////////////////////////////////////////////
-=head2 prepare_vmx
+=head2 remove_existing_vms
Parameters : none
Returns : boolean
- Description : Creates a .vmx file on the VM host configured for the
- reservation. Checks if a VM for the same VCL computer entry is
- already registered. If the VM is already registered, it is
- unregistered and the files for the existing VM are deleted.
+ Description :
=cut
-sub prepare_vmx {
+sub remove_existing_vms {
my $self = shift;
if (ref($self) !~ /vmware/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
- # Get the required data to configure the .vmx file
- my $image_id = $self->data->get_image_id() || return;
- my $imagerevision_id = $self->data->get_imagerevision_id() || return;
- my $image_project = $self->data->get_image_project() || return;
- my $computer_id = $self->data->get_computer_id() || return;
- my $vmx_file_name = $self->get_vmx_file_name() || return;
- my $vmx_file_path = $self->get_vmx_file_path() || return;
- my $vmx_directory_name = $self->get_vmx_directory_name() || return;
- my $vmx_directory_path = $self->get_vmx_directory_path() || return;
- my $vmdk_file_path = $self->get_vmdk_file_path() || return;
- my $computer_name = $self->data->get_computer_short_name() || return;
- my $image_name = $self->data->get_image_name() || return;
- my $vm_ram = $self->get_vm_ram() || return;
- my $vm_cpu_count = $self->data->get_image_minprocnumber() || 1;
- my $vm_ethernet_adapter_type = $self->get_vm_ethernet_adapter_type() || return;
- my $vm_eth0_mac = $self->data->get_computer_eth0_mac_address() || return;
- my $vm_eth1_mac = $self->data->get_computer_eth1_mac_address() || return;
- my $virtual_switch_0 = $self->data->get_vmhost_profile_virtualswitch0() || return;
- my $virtual_switch_1 = $self->data->get_vmhost_profile_virtualswitch1() || return;
- my $vm_disk_adapter_type = $self->get_vm_disk_adapter_type() || return;
- my $vm_hardware_version = $self->get_vm_virtual_hardware_version() || return;
- my $vm_persistent = $self->is_vm_persistent();
- my $guest_os = $self->get_vm_guest_os() || return;
-
- ## Figure out how much additional space is required for the vmx directory for the VM for this reservation
- ## This is the number of additional bytes which have not already been allocated the VM will likely use
- #my $vm_additional_vmx_bytes_required = $self->get_vm_additional_vmx_bytes_required();
- #return if !defined($vm_additional_vmx_bytes_required);
- #
- ## Get the number of bytes available on the device where the base vmx directory resides
- #my $host_vmx_bytes_available = $self->vmhost_os->get_available_space($self->get_vmx_base_directory_path());
- #return if !defined($host_vmx_bytes_available);
- #
- ## Check if there is enough space available for the VM's vmx files
- #if ($vm_additional_vmx_bytes_required > $host_vmx_bytes_available) {
- # my $vmx_deficit_bytes = ($vm_additional_vmx_bytes_required - $host_vmx_bytes_available);
- # my $vmx_deficit_mb = format_number($vmx_deficit_bytes / 1024 / 1024);
- # notify($ERRORS{'WARNING'}, 0, "not enough space is available for the vmx files on the VM host, deficit: $vmx_deficit_bytes bytes ($vmx_deficit_mb MB)");
- #}
- #else {
- # notify($ERRORS{'DEBUG'}, 0, "enough space is available for the vmx files on the VM host");
- #}
+ my $computer_name = $self->data->get_computer_short_name() || return;
- # Get a hash containing info about all the .vmx files that exist on the VM host
# Check the VMs on the host to see if any match the computer assigned to this reservation
-
# Get an array containing the existing vmx file paths on the VM host
my @vmx_file_paths = $self->get_vmx_file_paths();
@@ -1020,6 +1037,7 @@ sub prepare_vmx {
}
# Loop through the existing vmx file paths found, check if it matches the VM for this reservation
+ my $vmx_base_directory_path = $self->get_vmx_base_directory_path();
for my $vmx_file_path (@vmx_file_paths) {
# Parse the vmx file name from the path
my ($vmx_directory_name, $vmx_file_name) = $vmx_file_path =~ /([^\/]+)\/([^\/]+\.vmx)$/i;
@@ -1028,6 +1046,14 @@ sub prepare_vmx {
next;
}
+ # Ignore file if it does not begin with the base directory path
+ # get_vmx_file_paths() will return all vmx files it finds under the base directory path and all registered vmx files
+ # It's possible for a vmx file to be registered that resided on some other datastore
+ if ($vmx_file_path !~ /^$vmx_base_directory_path/) {
+ notify($ERRORS{'DEBUG'}, 0, "ignoring existing vmx file '$vmx_file_path' because it does not begin with the base directory path: '$vmx_base_directory_path'");
+ next;
+ }
+
# Check if the vmx directory name matches the pattern:
# <computer_short_name>_<image id>-v<imagerevision revision>
# <computer_short_name>_<image id>-v<imagerevision revision>_<request id>
@@ -1047,10 +1073,75 @@ sub prepare_vmx {
}
}
else {
- notify($ERRORS{'DEBUG'}, 0, "ignoring existing vmx file: $vmx_file_path");
+ notify($ERRORS{'DEBUG'}, 0, "ignoring existing vmx directory: $vmx_directory_name");
next;
}
}
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 prepare_vmx
+
+ Parameters : none
+ Returns : boolean
+ Description : Creates a .vmx file on the VM host configured for the
+ reservation. Checks if a VM for the same VCL computer entry is
+ already registered. If the VM is already registered, it is
+ unregistered and the files for the existing VM are deleted.
+
+=cut
+
+sub prepare_vmx {
+ my $self = shift;
+ if (ref($self) !~ /vmware/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ # Get the required data to configure the .vmx file
+ my $image_id = $self->data->get_image_id() || return;
+ my $imagerevision_id = $self->data->get_imagerevision_id() || return;
+ my $image_project = $self->data->get_image_project() || return;
+ my $computer_id = $self->data->get_computer_id() || return;
+ my $vmx_file_name = $self->get_vmx_file_name() || return;
+ my $vmx_file_path = $self->get_vmx_file_path() || return;
+ my $vmx_directory_name = $self->get_vmx_directory_name() || return;
+ my $vmx_directory_path = $self->get_vmx_directory_path() || return;
+ my $vmdk_file_path = $self->get_vmdk_file_path() || return;
+ my $computer_name = $self->data->get_computer_short_name() || return;
+ my $image_name = $self->data->get_image_name() || return;
+ my $vm_ram = $self->get_vm_ram() || return;
+ my $vm_cpu_count = $self->data->get_image_minprocnumber() || 1;
+ my $vm_ethernet_adapter_type = $self->get_vm_ethernet_adapter_type() || return;
+ my $vm_eth0_mac = $self->data->get_computer_eth0_mac_address() || return;
+ my $vm_eth1_mac = $self->data->get_computer_eth1_mac_address() || return;
+ my $virtual_switch_0 = $self->data->get_vmhost_profile_virtualswitch0() || return;
+ my $virtual_switch_1 = $self->data->get_vmhost_profile_virtualswitch1() || return;
+ my $vm_disk_adapter_type = $self->get_vm_disk_adapter_type() || return;
+ my $vm_hardware_version = $self->get_vm_virtual_hardware_version() || return;
+ my $vm_persistent = $self->is_vm_persistent();
+ my $guest_os = $self->get_vm_guest_os() || return;
+
+ ## Figure out how much additional space is required for the vmx directory for the VM for this reservation
+ ## This is the number of additional bytes which have not already been allocated the VM will likely use
+ #my $vm_additional_vmx_bytes_required = $self->get_vm_additional_vmx_bytes_required();
+ #return if !defined($vm_additional_vmx_bytes_required);
+ #
+ ## Get the number of bytes available on the device where the base vmx directory resides
+ #my $host_vmx_bytes_available = $self->vmhost_os->get_available_space($self->get_vmx_base_directory_path());
+ #return if !defined($host_vmx_bytes_available);
+ #
+ ## Check if there is enough space available for the VM's vmx files
+ #if ($vm_additional_vmx_bytes_required > $host_vmx_bytes_available) {
+ # my $vmx_deficit_bytes = ($vm_additional_vmx_bytes_required - $host_vmx_bytes_available);
+ # my $vmx_deficit_mb = format_number($vmx_deficit_bytes / 1024 / 1024);
+ # notify($ERRORS{'WARNING'}, 0, "not enough space is available for the vmx files on the VM host, deficit: $vmx_deficit_bytes bytes ($vmx_deficit_mb MB)");
+ #}
+ #else {
+ # notify($ERRORS{'DEBUG'}, 0, "enough space is available for the vmx files on the VM host");
+ #}
# Create the .vmx directory on the host
if (!$self->vmhost_os->create_directory($vmx_directory_path)) {
@@ -1117,6 +1208,8 @@ sub prepare_vmx {
"config.version" => "8",
+ "disk.locking" => "false",
+
"displayName" => "$display_name",
"ethernet0.address" => "$vm_eth0_mac",
@@ -1183,6 +1276,25 @@ sub prepare_vmx {
));
}
+ if ($vm_hardware_version >= 7) {
+ %vmx_parameters = (%vmx_parameters, (
+ "pciBridge0.present" => "TRUE",
+ "pciBridge4.present" => "TRUE",
+ "pciBridge4.virtualDev" => "pcieRootPort",
+ "pciBridge4.functions" => "8",
+ "pciBridge5.present" => "TRUE",
+ "pciBridge5.virtualDev" => "pcieRootPort",
+ "pciBridge5.functions" => "8",
+ "pciBridge6.present" => "TRUE",
+ "pciBridge6.virtualDev" => "pcieRootPort",
+ "pciBridge6.functions" => "8",
+ "pciBridge7.present" => "TRUE",
+ "pciBridge7.virtualDev" => "pcieRootPort",
+ "pciBridge7.functions" => "8",
+ "vmci0.present" => "TRUE",
+ ));
+ }
+
# Add additional Ethernet interfaces if the image project name is not vcl
if ($image_project !~ /^vcl$/i) {
notify($ERRORS{'DEBUG'}, 0, "image project is: $image_project, checking if additional network adapters should be configured");
@@ -1280,10 +1392,24 @@ sub prepare_vmdk {
my $image_name = $self->data->get_image_name() || return;
my $vmhost_hostname = $self->data->get_vmhost_hostname() || return;
+ my $is_vm_persistent = $self->is_vm_persistent();
+
# Check if the first .vmdk file exists on the host
if ($self->vmhost_os->file_exists($host_vmdk_file_path)) {
- notify($ERRORS{'DEBUG'}, 0, "vmdk file exists on VM host: $host_vmdk_file_path");
- return $self->check_vmdk_disk_type();
+
+ if ($is_vm_persistent) {
+ notify($ERRORS{'DEBUG'}, 0, "VM is persistent and vmdk file already exists on VM host: $host_vmdk_file_path, vmdk file will be deleted and a new copy will be used");
+ exit;
+ if (!$self->vmhost_os->delete_file($host_vmdk_file_path)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to deleted existing vmdk file: ");
+ return;
+ }
+ }
+ else {
+ # vmdk file exists and not persistent
+ # No copying necessary, proceed to check the disk type
+ return $self->check_vmdk_disk_type();
+ }
}
else {
notify($ERRORS{'DEBUG'}, 0, "vmdk file does NOT exist on VM host: $host_vmdk_file_path");
@@ -1311,7 +1437,7 @@ sub prepare_vmdk {
#}
# Check if the VM is persistent, if so, attempt to copy files locally from the nonpersistent directory if they exist
- if ($self->is_vm_persistent()) {
+ if ($is_vm_persistent) {
if ($self->api->can('copy_virtual_disk') && $self->api->copy_virtual_disk($host_vmdk_file_path_nonpersistent, $host_vmdk_file_path)) {
notify($ERRORS{'OK'}, 0, "copied vmdk files from nonpersistent to persistent directory on VM host");
@@ -1419,8 +1545,7 @@ sub check_vmdk_disk_type {
my $vmdk_file_path = $self->get_vmdk_file_path() || return;
# Check if the API object implements the required subroutines
- unless ($self->api->can("get_virtual_disk_type")
- && $self->api->can("copy_virtual_disk")) {
+ unless ($self->api->can("get_virtual_disk_type") && $self->api->can("copy_virtual_disk")) {
notify($ERRORS{'DEBUG'}, 0, "skipping vmdk disk type check because required subroutines are not implemented by the API object");
return 1;
}
@@ -1448,8 +1573,6 @@ sub check_vmdk_disk_type {
my $vmdk_file_prefix = $self->get_vmdk_file_prefix() || return;
my $thin_vmdk_file_path = "$vmdk_directory_path/thin_$vmdk_file_prefix.vmdk";
- my $vm_disk_adapter_type = $self->get_vm_disk_adapter_type() || return;
-
if ($self->vmhost_os->file_exists($thin_vmdk_file_path)) {
notify($ERRORS{'DEBUG'}, 0, "thin virtual disk already exists: $thin_vmdk_file_path");
}
@@ -1457,7 +1580,7 @@ sub check_vmdk_disk_type {
notify($ERRORS{'DEBUG'}, 0, "attempting to create a copy of the virtual disk using the thin virtual disk type: $thin_vmdk_file_path");
# Attempt to create a thin copy of the virtual disk
- if ($self->api->copy_virtual_disk($vmdk_file_path, $thin_vmdk_file_path, 'thin', $vm_disk_adapter_type)) {
+ if ($self->api->copy_virtual_disk($vmdk_file_path, $thin_vmdk_file_path, 'thin')) {
notify($ERRORS{'DEBUG'}, 0, "created a copy of the virtual disk using the thin virtual disk type: $thin_vmdk_file_path");
}
else {
@@ -1490,14 +1613,50 @@ sub check_vmdk_disk_type {
#/////////////////////////////////////////////////////////////////////////////
+=head2 get_vmx_file_path
+
+ Parameters : none
+ Returns : string
+ Description : Returns the path to the vmx file being used for the reservation.
+ Example:
+ /vmfs/volumes/local-datastore/vclv1-29_vmwarewin7-Test75321-v0/vclv1-29_vmwarewin7-Test75321-v0.vmx
+
+=cut
+
+sub get_vmx_file_path {
+ my $self = shift;
+ if (ref($self) !~ /vmware/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ return $ENV{vmx_file_path} if $ENV{vmx_file_path};
+
+ my $vmx_base_directory_path = $self->get_vmx_base_directory_path();
+ if (!$vmx_base_directory_path) {
+ notify($ERRORS{'WARNING'}, 0, "unable to construct vmx file path, vmx base directory path could not be determined");
+ return;
+ }
+
+ my $vmx_directory_name = $self->get_vmx_directory_name();
+ if (!$vmx_directory_name) {
+ notify($ERRORS{'WARNING'}, 0, "unable to construct vmx file path, vmx directory name could not be determined");
+ return;
+ }
+
+ return "$vmx_base_directory_path/$vmx_directory_name/$vmx_directory_name.vmx";
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 get_vmx_base_directory_path
Parameters : none
Returns : string
Description : Returns the path on the VM host under which the vmx directory is
- located. Example:
- vmx file path: /vmfs/volumes/nfs-vmpath/vm1-6-987-v0/vm1-6-987-v0.vmx
- vmx base directory path: /vmfs/volumes/nfs-vmpath
+ located.
+ Example:
+ /vmfs/volumes/local-datastore
=cut
@@ -1510,25 +1669,29 @@ sub get_vmx_base_directory_path {
my $vmx_base_directory_path;
- my $vmhost_profile_vmpath = normalize_file_path($self->data->get_vmhost_profile_vmpath());
- if ($vmhost_profile_vmpath) {
- $vmhost_profile_vmpath =~ s/\\//g;
- $vmx_base_directory_path = $vmhost_profile_vmpath;
- }
- else {
- my $vmhost_profile_datastore_path = normalize_file_path($self->data->get_vmhost_profile_datastore_path());
- if ($vmhost_profile_datastore_path) {
- $vmx_base_directory_path = $vmhost_profile_datastore_path;
+ # Check if vmx_file_path environment variable has been set
+ # If set, parse the path to return the directory name preceding the vmx file name and directory name
+ # /<vmx base directory path>/<vmx directory name>/<vmx file name>
+ if ($ENV{vmx_file_path}) {
+ ($vmx_base_directory_path) = $ENV{vmx_file_path} =~ /(.+)\/[^\/]+\/[^\/]+.vmx$/i;
+ if ($vmx_base_directory_path) {
+ return $vmx_base_directory_path;
}
else {
- notify($ERRORS{'WARNING'}, 0, "unable to determine the vmdk base directory, could not determine VM path or datastore path from the database");
+ notify($ERRORS{'WARNING'}, 0, "vmx base directory path could not be determined from vmx file path: '$ENV{vmx_file_path}'");
return;
}
}
- # Remove any trailing slashes
- $vmx_base_directory_path =~ s/\/$//g;
- return $vmx_base_directory_path;
+ # Get the vmprofile.vmpath
+ # If this is not set, use vmprofile.datastorepath
+ $vmx_base_directory_path = $self->data->get_vmhost_profile_vmpath() || $self->data->get_vmhost_profile_datastore_path();
+ if (!$vmx_base_directory_path) {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine the vmdk base directory path, failed to retrieve either the VM path or datastore path for the VM profile");
+ return;
+ }
+
+ return normalize_file_path($vmx_base_directory_path);
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1540,8 +1703,8 @@ sub get_vmx_base_directory_path {
Description : Returns the name of the directory in which the .vmx file is
located. The name differs depending on whether or not the VM
is persistent.
- If not persistent: <computer name>_<image ID>-<revision>
- If persistent: <computer name>_<image ID>-<revision>_<request ID>
+ If not persistent: <computer name>_<image name>
+ If persistent: <computer name>_<image name>_<request ID>
=cut
@@ -1553,44 +1716,106 @@ sub get_vmx_directory_name {
}
my $vmx_directory_name;
-
+
+ # Check if vmx_file_path environment variable has been set
+ # If set, parse the path to return the directory name preceding the vmx file name
+ # /<vmx base directory path>/<vmx directory name>/<vmx file name>
if ($ENV{vmx_file_path}) {
- my $vmx_base_directory_path = $self->get_vmx_base_directory_path() || return;
- ($vmx_directory_name) = $ENV{vmx_file_path} =~ /^$vmx_base_directory_path\/(.+)\/[^\/]+.vmx$/;
- return $vmx_directory_name;
+ ($vmx_directory_name) = $ENV{vmx_file_path} =~ /([^\/]+)\/[^\/]+.vmx$/i;
+ if ($vmx_directory_name) {
+ return $vmx_directory_name;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "vmx directory name could not be determined from vmx file path: '$ENV{vmx_file_path}'");
+ return;
+ }
+ }
+
+ if ($self->is_vm_persistent()) {
+ return $self->get_vmx_directory_name_persistent();
+ }
+ else {
+ return $self->get_vmx_directory_name_nonpersistent();
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_vmx_directory_name_persistent
+
+ Parameters : none
+ Returns : string
+ Description : Returns the name of the directory in which the .vmx file is
+ located if the VM is persistent. Example:
+ <computer name>_<image name>
+
+=cut
+
+sub get_vmx_directory_name_persistent {
+ my $self = shift;
+ if (ref($self) !~ /vmware/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ my $vmx_directory_name_nonpersistent = $self->get_vmx_directory_name_nonpersistent();
+ if (!$vmx_directory_name_nonpersistent) {
+ notify($ERRORS{'WARNING'}, 0, "unable to assemble the persistent vmx directory name, failed to retrieve the nonpersistent vmx directory name on which the persistent vmx directory name is based");
+ return;
+ }
+
+ my $request_id = $self->data->get_request_id();
+ if (!defined($request_id)) {
+ notify($ERRORS{'WARNING'}, 0, "unable to assemble the persistent vmx directory name, failed to retrieve request ID");
+ return;
}
- # Get the computer name, image ID, and revision number
+ return "$vmx_directory_name_nonpersistent\_$request_id";
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_vmx_directory_name_nonpersistent
+
+ Parameters : none
+ Returns : string
+ Description : Returns the name of the directory in which the .vmx file is
+ located if the VM is not persistent.
+ Example:
+ <computer name>_<image name>_<request ID>
+
+=cut
+
+sub get_vmx_directory_name_nonpersistent {
+ my $self = shift;
+ if (ref($self) !~ /vmware/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ # Get the computer name
my $computer_short_name = $self->data->get_computer_short_name();
if (!$computer_short_name) {
- notify($ERRORS{'WARNING'}, 0, "unable to retrieve computer short name");
+ notify($ERRORS{'WARNING'}, 0, "unable to assemble the nonpersistent vmx directory name, failed to retrieve computer short name");
return;
}
+
+ # Get the image ID
my $image_id = $self->data->get_image_id();
if (!defined($image_id)) {
- notify($ERRORS{'WARNING'}, 0, "unable to retrieve image ID");
+ notify($ERRORS{'WARNING'}, 0, "unable to assemble the nonpersistent vmx directory name, failed to retrieve image ID");
return;
}
- my $imagerevision_revision = $self->data->get_imagerevision_revision();
- if (!defined($imagerevision_revision)) {
- notify($ERRORS{'WARNING'}, 0, "unable to retrieve imagerevision revision");
+
+ # Get the image revision number
+ my $image_revision = $self->data->get_imagerevision_revision();
+ if (!defined($image_revision)) {
+ notify($ERRORS{'WARNING'}, 0, "unable to assemble the nonpersistent vmx directory name, failed to retrieve image revision");
return;
}
# Assemble the directory name
- $vmx_directory_name = "$computer_short_name\_$image_id-v$imagerevision_revision";
-
- # If persistent, append the request ID
- if ($self->is_vm_persistent()) {
- my $request_id = $self->data->get_request_id();
- if (!defined($request_id)) {
- notify($ERRORS{'WARNING'}, 0, "unable to retrieve request ID");
- return;
- }
- $vmx_directory_name .= "\_$request_id";
- }
-
- return $vmx_directory_name;
+ return "$computer_short_name\_$image_id-v$image_revision";
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1613,10 +1838,22 @@ sub get_vmx_directory_path {
return;
}
- my $vmx_base_directory_path = $self->get_vmx_base_directory_path() || return;
- my $vmx_directory_name = $self->get_vmx_directory_name() || return;
+ # Get the vmx file path
+ my $vmx_file_path = $self->get_vmx_file_path();
+ if (!$vmx_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "vmx directory path could not be determined because vmx file path could not be retrieved");
+ return;
+ }
- return "$vmx_base_directory_path/$vmx_directory_name";
+ # Parse the vmx file path, return the path preceding the vmx file name
+ my ($vmx_directory_path) = $vmx_file_path =~ /(.+)\/[^\/]+.vmx$/i;
+ if ($vmx_directory_path) {
+ return $vmx_directory_path;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "vmx directory path could not be determined from vmx file path: '$vmx_file_path'");
+ return;
+ }
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1638,37 +1875,181 @@ sub get_vmx_file_name {
return;
}
- if ($ENV{vmx_file_path}) {
- my ($vmx_file_name) = $ENV{vmx_file_path} =~ /([^\/]+.vmx)$/g;
+ # Get the vmx file path
+ my $vmx_file_path = $self->get_vmx_file_path();
+ if (!$vmx_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "vmx directory path could not be determined because vmx file path could not be retrieved");
+ return;
}
- my $vmx_directory_name = $self->get_vmx_directory_name() || return;
- return "$vmx_directory_name.vmx";
+ # Parse the vmx file path, return the path preceding the vmx file name
+ my ($vmx_file_name) = $vmx_file_path =~ /\/([^\/]+.vmx)$/i;
+ if ($vmx_file_name) {
+ return $vmx_file_name;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "vmx file name could not be determined from vmx file path: '$vmx_file_path'");
+ return;
+ }
}
#/////////////////////////////////////////////////////////////////////////////
-=head2 get_vmx_file_path
+=head2 set_vmx_file_path
+
+ Parameters : $vmx_file_path
+ Returns : boolean
+ Description : Sets the vmx path into %ENV so that the default values are
+ overridden when the various get_vmx_ subroutines are called. This
+ is useful when a base image is being captured. The vmx file does
+ not need to be in the expected directory nor does it need to be
+ named anything particular. The code locates the vmx file and then
+ saves the non-default path in this object so that capture works
+ regardless of the vmx path/name.
+
+=cut
+
+sub set_vmx_file_path {
+ my $self = shift;
+ if (ref($self) !~ /vmware/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ # Get the vmx file path argument
+ my $vmx_file_path_argument = shift;
+ if (!$vmx_file_path_argument) {
+ notify($ERRORS{'WARNING'}, 0, "vmx file path argument was not supplied");
+ return;
+ }
+
+ $vmx_file_path_argument = normalize_file_path($vmx_file_path_argument);
+
+ # Make sure the vmx file path format is valid
+ if ($vmx_file_path_argument !~ /^\/.+\/.+\/[^\/]+\.vmx$/i) {
+ notify($ERRORS{'WARNING'}, 0, "unable to override vmx file path because the path format is invalid: '$vmx_file_path_argument'");
+ return;
+ }
+
+ $ENV{vmx_file_path} = $vmx_file_path_argument;
+
+ # Check all of the vmx file path components
+ if ($self->check_file_paths('vmx')) {
+ # Set the vmx_file_path environment variable
+ notify($ERRORS{'OK'}, 0, "set overridden vmx file path: '$vmx_file_path_argument'");
+ return 1;
+ }
+ else {
+ delete $ENV{vmx_file_path};
+ notify($ERRORS{'WARNING'}, 0, "failed to set overridden vmx file path: '$vmx_file_path_argument'");
+ return;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_vmdk_file_path
Parameters : none
Returns : string
- Description : Returns the path to the .vmx file. Example:
- vmx file path: /vmfs/volumes/nfs-vmpath/vm1-6-987-v0/vm1-6-987-v0.vmx
+ Description : Returns the path of the vmdk file. Example:
+ vmdk file path: /vmfs/volumes/nfs-datastore/vmwarewinxp-base234-v12/vmwarewinxp-base234-v12.vmdk
=cut
-sub get_vmx_file_path {
+sub get_vmdk_file_path {
+ my $self = shift;
+ if (ref($self) !~ /vmware/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ return $ENV{vmdk_file_path} if $ENV{vmdk_file_path};
+
+ if ($self->is_vm_persistent()) {
+ return $self->get_vmdk_file_path_persistent();
+ }
+ else {
+ return $self->get_vmdk_file_path_nonpersistent();
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_vmdk_file_path_persistent
+
+ Parameters : none
+ Returns : string
+ Description : Returns the vmdk file path for a persistent VM. This is
+ useful when checking the image size on a VM host using
+ network-based disks. It returns the vmdk file path that would be
+ used for nonperistent VMs.
+
+=cut
+
+sub get_vmdk_file_path_persistent {
+ my $self = shift;
+ if (ref($self) !~ /vmware/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ # Get the vmprofile.datastorepath
+ my $vmdk_base_directory_path = $self->data->get_vmhost_profile_datastore_path();
+ if (!$vmdk_base_directory_path) {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine the persistent vmdk file path, failed to retrieve datastore path for the VM profile");
+ return;
+ }
+
+ my $vmdk_directory_name_persistent = $self->get_vmdk_directory_name_persistent();
+ if (!$vmdk_directory_name_persistent) {
+ notify($ERRORS{'WARNING'}, 0, "unable to construct vmdk file path, vmdk directory name could not be determined");
+ 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");
+ return;
+ }
+
+ return "$vmdk_base_directory_path/$vmdk_directory_name_persistent/$image_name.vmdk";
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_vmdk_file_path_nonpersistent
+
+ Parameters : none
+ Returns : string
+ Description : Returns the vmdk file path for a nonpersistent VM. This is
+ useful when checking the image size on a VM host using
+ network-based disks. It returns the vmdk file path that would be
+ used for nonperistent VMs.
+
+=cut
+
+sub get_vmdk_file_path_nonpersistent {
my $self = shift;
if (ref($self) !~ /vmware/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
- return $ENV{vmx_file_path} if $ENV{vmx_file_path};
+ # Get the vmprofile.datastorepath
+ my $vmdk_base_directory_path = $self->data->get_vmhost_profile_datastore_path();
+ if (!$vmdk_base_directory_path) {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine the nonpersistent vmdk file path, failed to retrieve datastore path for the VM profile");
+ return;
+ }
- my $vmx_directory_path = $self->get_vmx_directory_path() || return;
- my $vmx_file_name = $self->get_vmx_file_name() || return;
- return "$vmx_directory_path/$vmx_file_name";
+ my $vmdk_directory_name_nonpersistent = $self->get_vmdk_directory_name_nonpersistent();
+ if (!$vmdk_directory_name_nonpersistent) {
+ notify($ERRORS{'WARNING'}, 0, "unable to construct vmdk file path, vmdk directory name could not be determined");
+ return;
+ }
+
+ return "$vmdk_base_directory_path/$vmdk_directory_name_nonpersistent/$vmdk_directory_name_nonpersistent.vmdk";
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1691,24 +2072,30 @@ sub get_vmdk_base_directory_path {
return;
}
- # Check if $ENV{vmdk_file_path} is set, parse this path if it is set
- if (my $vmdk_file_path = $ENV{vmdk_file_path}) {
- my ($vmdk_base_directory_path) = $vmdk_file_path =~ /^(.+)\/[^\/]+\/[^\/]+\.vmdk$/g;
- if (!$vmdk_base_directory_path) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine vmdk base directory path from vmdk file path: $vmdk_file_path");
- return;
+ my $vmdk_base_directory_path;
+
+ # Check if vmdk_file_path environment variable has been set
+ # If set, parse the path to return the directory name preceding the vmdk file name and directory name
+ # /<vmdk base directory path>/<vmdk directory name>/<vmdk file name>
+ if ($ENV{vmdk_file_path}) {
+ ($vmdk_base_directory_path) = $ENV{vmdk_file_path} =~ /(.+)\/[^\/]+\/[^\/]+.vmdk$/i;
+ if ($vmdk_base_directory_path) {
+ return $vmdk_base_directory_path;
}
- return $vmdk_base_directory_path;
- }
- else {
- # Get the VM host profile datastore path
- my $vmhost_profile_datastore_path = normalize_file_path($self->data->get_vmhost_profile_datastore_path());
- if (!$vmhost_profile_datastore_path) {
- notify($ERRORS{'WARNING'}, 0, "unable to retrieve VM host profile datastore path");
+ else {
+ notify($ERRORS{'WARNING'}, 0, "vmdk base directory path could not be determined from vmdk file path: '$ENV{vmdk_file_path}'");
return;
}
- return $vmhost_profile_datastore_path;
}
+
+ # Get the vmprofile.datastorepath
+ $vmdk_base_directory_path = $self->data->get_vmhost_profile_datastore_path();
+ if (!$vmdk_base_directory_path) {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine the vmdk base directory path, failed to retrieve either the datastore path for the VM profile");
+ return;
+ }
+
+ return normalize_file_path($vmdk_base_directory_path);
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1735,6 +2122,20 @@ sub get_vmdk_directory_name {
return;
}
+ # Check if vmdk_file_path environment variable has been set
+ # If set, parse the path to return the directory name preceding the vmdk file name
+ # /<vmdk base directory path>/<vmdk directory name>/<vmdk file name>
+ if ($ENV{vmdk_file_path}) {
+ my ($vmdk_directory_name) = $ENV{vmdk_file_path} =~ /([^\/]+)\/[^\/]+.vmdk$/i;
+ if ($vmdk_directory_name) {
+ return $vmdk_directory_name;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "vmdk directory name could not be determined from vmdk file path: '$ENV{vmdk_file_path}'");
+ return;
+ }
+ }
+
if ($self->is_vm_persistent()) {
return $self->get_vmdk_directory_name_persistent();
}
@@ -1762,19 +2163,15 @@ sub get_vmdk_directory_name_persistent {
return;
}
- if ($ENV{vmdk_file_path}) {
- my $vmdk_base_directory_path = $self->get_vmdk_base_directory_path() || return;
- my ($vmdk_directory_name) = $ENV{vmdk_file_path} =~ /^$vmdk_base_directory_path\/(.+)\/[^\/]+.vmdk$/;
- if ($vmdk_directory_name) {
- return $vmdk_directory_name;
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "unable to parse vmdk directory name from vmdk file path: $ENV{vmdk_file_path}");
- return;
- }
+ # Use the same name that's used for the persistent vmx directory name
+ my $vmdk_directory_name_persistent = $self->get_vmx_directory_name_persistent();
+ if ($vmdk_directory_name_persistent) {
+ return $vmdk_directory_name_persistent;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine persistent vmdk directory name because persistent vmx directory name could not be retrieved");
+ return;
}
-
- return $self->get_vmx_directory_name();
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1796,25 +2193,15 @@ sub get_vmdk_directory_name_nonpersisten
return;
}
- if ($ENV{vmdk_file_path}) {
- my $vmdk_base_directory_path = $self->get_vmdk_base_directory_path() || return;
- my ($vmdk_directory_name) = $ENV{vmdk_file_path} =~ /^$vmdk_base_directory_path\/(.+)\/[^\/]+.vmdk$/;
-
- if ($vmdk_directory_name) {
- return $vmdk_directory_name;
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "unable to parse vmdk directory name from vmdk file path: $ENV{vmdk_file_path}");
- return;
- }
- }
-
+ # Use the image name for the vmdk directory name
my $image_name = $self->data->get_image_name();
- if (!$image_name) {
- notify($ERRORS{'WARNING'}, 0, "unable determine vmdk directory name because unable to retrieve image name");
+ if ($image_name) {
+ return $image_name;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable determine vmdk nonpersistent vmdk directory name because image name could not be retrieved");
return;
}
- return $image_name;
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1837,19 +2224,60 @@ sub get_vmdk_directory_path {
return;
}
- my $vmdk_base_directory_path = $self->get_vmdk_base_directory_path();
+ # Check if vmdk_file_path environment variable has been set
+ # If set, parse the path to return the directory name preceding the vmdk file name
+ # /<vmdk base directory path>/<vmdk directory name>/<vmdk file name>
+ if ($ENV{vmdk_file_path}) {
+ my ($vmdk_directory_path) = $ENV{vmdk_file_path} =~ /(.+)\/[^\/]+.vmdk$/i;
+ if ($vmdk_directory_path) {
+ return $vmdk_directory_path;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "vmdk directory name could not be determined from vmdk file path: '$ENV{vmdk_file_path}'");
+ return;
+ }
+ }
+
+ if ($self->is_vm_persistent()) {
+ return $self->get_vmdk_directory_path_persistent();
+ }
+ else {
+ return $self->get_vmdk_directory_path_nonpersistent();
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_vmdk_directory_path_persistent
+
+ Parameters : none
+ Returns : string
+ Description : Returns the directory path under which the .vmdk files are
+ located for persistent VMs.
+
+=cut
+
+sub get_vmdk_directory_path_persistent {
+ my $self = shift;
+ if (ref($self) !~ /vmware/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ # Get the vmprofile.datastorepath
+ my $vmdk_base_directory_path = $self->data->get_vmhost_profile_datastore_path();
if (!$vmdk_base_directory_path) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine vmdk directory path because vmdk base directory path could not be determined");
+ notify($ERRORS{'WARNING'}, 0, "unable to determine the persistent vmdk base directory path, failed to retrieve datastore path for the VM profile");
return;
}
- my $vmdk_directory_name = $self->get_vmdk_directory_name() || return;
- if (!$vmdk_directory_name) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine vmdk directory path because vmdk directory 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 persistent vmdk directory path because persistent vmdk directory name could not be determined");
return;
}
- return "$vmdk_base_directory_path/$vmdk_directory_name";
+ return "$vmdk_base_directory_path/$vmdk_directory_name_persistent";
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1870,19 +2298,20 @@ sub get_vmdk_directory_path_nonpersisten
return;
}
- my $vmdk_base_directory_path = $self->get_vmdk_base_directory_path() || return;
+ # Get the vmprofile.datastorepath
+ my $vmdk_base_directory_path = $self->data->get_vmhost_profile_datastore_path();
if (!$vmdk_base_directory_path) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine nonpersistent vmdk directory path because vmdk base directory path could not be determined");
+ notify($ERRORS{'WARNING'}, 0, "unable to determine the nonpersistent vmdk base directory path, failed to retrieve datastore path for the VM profile");
return;
}
- my $vmdk_directory_name = $self->get_vmdk_directory_name_nonpersistent() || return;
- if (!$vmdk_directory_name) {
+ my $vmdk_directory_name_nonpersistent = $self->get_vmdk_directory_name_nonpersistent();
+ if (!$vmdk_directory_name_nonpersistent) {
notify($ERRORS{'WARNING'}, 0, "unable to determine nonpersistent vmdk directory path because nonpersistent vmdk directory name could not be determined");
return;
}
- return "$vmdk_base_directory_path/$vmdk_directory_name";
+ return "$vmdk_base_directory_path/$vmdk_directory_name_nonpersistent";
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1905,13 +2334,22 @@ sub get_vmdk_file_prefix {
return;
}
- if ($ENV{vmdk_file_path}) {
- my ($vmdk_file_prefix) = $ENV{vmdk_file_path} =~ /([^\/]+).vmdk$/g;
- return $vmdk_file_prefix;
+ # Get the vmdk file path
+ my $vmdk_file_path = $self->get_vmdk_file_path();
+ if (!$vmdk_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "vmdk directory path could not be determined because vmdk file path could not be retrieved");
+ return;
}
- my $image_name = $self->data->get_image_name() || return;
- return $image_name;
+ # Parse the vmdk file path, return the path preceding the vmdk file name
+ my ($vmdk_file_name) = $vmdk_file_path =~ /\/([^\/]+)\.vmdk$/i;
+ if ($vmdk_file_name) {
+ return $vmdk_file_name;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "vmdk file name could not be determined from vmdk file path: '$vmdk_file_path'");
+ return;
+ }
}
#/////////////////////////////////////////////////////////////////////////////
@@ -1933,61 +2371,133 @@ sub get_vmdk_file_name {
return;
}
- my $vmdk_file_prefix = $self->get_vmdk_file_prefix() || return;
- if (!$vmdk_file_prefix) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine vmdk file name because vmdk file prefix could not be determined");
+ # Get the vmdk file path
+ my $vmdk_file_path = $self->get_vmdk_file_path();
+ if (!$vmdk_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "vmdk directory path could not be determined because vmdk file path could not be retrieved");
return;
}
- return "$vmdk_file_prefix.vmdk";
+ # Parse the vmdk file path, return the path preceding the vmdk file name
+ my ($vmdk_file_name) = $vmdk_file_path =~ /\/([^\/]+\.vmdk)$/i;
+ if ($vmdk_file_name) {
+ return $vmdk_file_name;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "vmdk file name could not be determined from vmdk file path: '$vmdk_file_path'");
+ return;
+ }
}
#/////////////////////////////////////////////////////////////////////////////
-=head2 get_vmdk_file_path_nonpersistent
+=head2 set_vmdk_file_path
- Parameters : none
- Returns : string
- Description : Returns the vmdk file path for a nonpersistent VM. This is
- useful when checking the image size on a VM host using
- network-based disks. It returns the vmdk file path that would be
- used for nonperistent VMs.
+ Parameters : $vmx_file_path
+ Returns :
+ Description : Sets the vmdk path into %ENV so that the default values are
+ overridden when the various get_vmdk_... subroutines are called.
+ This is useful for base image imaging reservations if the
+ code detects the vmdk path is not in the expected place.
=cut
-sub get_vmdk_file_path_nonpersistent {
+sub set_vmdk_file_path {
my $self = shift;
if (ref($self) !~ /vmware/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
- my $vmdk_directory_path_nonpersistent = $self->get_vmdk_directory_path_nonpersistent() || return;
- my $vmdk_file_name = $self->get_vmdk_file_name() || return;
- return "$vmdk_directory_path_nonpersistent/$vmdk_file_name";
+ # Get the vmdk file path argument
+ my $vmdk_file_path_argument = shift;
+ if (!$vmdk_file_path_argument) {
+ notify($ERRORS{'WARNING'}, 0, "vmdk file path argument was not supplied");
+ return;
+ }
+
+ $vmdk_file_path_argument = normalize_file_path($vmdk_file_path_argument);
+
+ # Make sure the vmdk file path format is valid
+ if ($vmdk_file_path_argument !~ /^\/.+\/.+\/[^\/]+\.vmdk$/i) {
+ notify($ERRORS{'WARNING'}, 0, "unable to override vmdk file path because the path format is invalid: '$vmdk_file_path_argument'");
+ return;
+ }
+
+ $ENV{vmdk_file_path} = $vmdk_file_path_argument;
+
+ # Check all of the vmdk file path components
+ if ($self->check_file_paths('vmdk')) {
+ # Set the vmdk_file_path environment variable
+ notify($ERRORS{'OK'}, 0, "set overridden vmdk file path: '$vmdk_file_path_argument'");
+ return 1;
+ }
+ else {
+ delete $ENV{vmdk_file_path};
+ notify($ERRORS{'WARNING'}, 0, "failed to set overridden vmdk file path: '$vmdk_file_path_argument'");
+ return;
+ }
}
#/////////////////////////////////////////////////////////////////////////////
-=head2 get_vmdk_file_path
+=head2 check_file_paths
Parameters : none
- Returns : string
- Description : Returns the path of the vmdk file. Example:
- vmdk file path: /vmfs/volumes/nfs-datastore/vmwarewinxp-base234-v12/vmwarewinxp-base234-v12.vmdk
+ Returns :
+ Description :
=cut
-sub get_vmdk_file_path {
+sub check_file_paths {
my $self = shift;
- if (ref($self) !~ /vmware/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ unless (ref($self) && $self->isa('VCL::Module')) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module module object method");
return;
}
- my $vmdk_directory_path = $self->get_vmdk_directory_path() || return;
- my $vmdk_file_name = $self->get_vmdk_file_name() || return;
- return "$vmdk_directory_path/$vmdk_file_name";
+ my $file_type = shift || 'all';
+
+ # 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;
+
+ if ($file_type !~ /vmdk/i) {
+ $check_paths_string .= "vmx file path: '" . ($self->get_vmx_file_path() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmx directory path: '" . ($self->get_vmx_directory_path() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmx base directory path: '" . ($self->get_vmx_base_directory_path() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmx directory name: '" . ($self->get_vmx_directory_name() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmx file name: '" . ($self->get_vmx_file_name() || $undefined_string) . "'\n";
+ $check_paths_string .= "persistent vmx directory name: '" . ($self->get_vmx_directory_name_persistent() || $undefined_string) . "'\n";
+ $check_paths_string .= "nonpersistent vmx directory name: '" . ($self->get_vmx_directory_name_nonpersistent() || $undefined_string) . "'\n";
+ }
+
+ if ($file_type !~ /vmx/i) {
+ $check_paths_string .= "vmdk file path: '" . ($self->get_vmdk_file_path() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmdk directory path: '" . ($self->get_vmdk_directory_path() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmdk base directory path: '" . ($self->get_vmdk_base_directory_path() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmdk directory name: '" . ($self->get_vmdk_directory_name() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmdk file name: '" . ($self->get_vmdk_file_name() || $undefined_string) . "'\n";
+ $check_paths_string .= "vmdk file prefix: '" . ($self->get_vmdk_file_prefix() || $undefined_string) . "'\n";
+ $check_paths_string .= "persistent vmdk file path: '" . ($self->get_vmdk_file_path_persistent() || $undefined_string) . "'\n";
+ $check_paths_string .= "persistent vmdk directory path: '" . ($self->get_vmdk_directory_path_persistent() || $undefined_string) . "'\n";
+ $check_paths_string .= "persistent vmdk directory name: '" . ($self->get_vmdk_directory_name_persistent() || $undefined_string) . "'\n";
+ $check_paths_string .= "nonpersistent vmdk file path: '" . ($self->get_vmdk_file_path_nonpersistent() || $undefined_string) . "'\n";
+ $check_paths_string .= "nonpersistent vmdk directory path: '" . ($self->get_vmdk_directory_path_nonpersistent() || $undefined_string) . "'\n";
+ $check_paths_string .= "nonpersistent vmdk directory name: '" . ($self->get_vmdk_directory_name_nonpersistent() || $undefined_string) . "'\n";
+ }
+
+ if ($check_paths_string =~ /$undefined_string/) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve $file_type file path components:\n$check_paths_string");
+ return;
+ }
+ else {
+ # Set the vmdk_file_path environment variable
+ notify($ERRORS{'OK'}, 0, "successfully retrieved $file_type file path components:\n$check_paths_string");
+ return 1;
+ }
}
#/////////////////////////////////////////////////////////////////////////////
@@ -2699,9 +3209,16 @@ sub get_vmx_file_paths {
my $vmx_base_directory_path = $self->get_vmx_base_directory_path() || return;
- my @vmx_paths = $self->vmhost_os->find_files($vmx_base_directory_path, "*.vmx");
- notify($ERRORS{'DEBUG'}, 0, "found " . scalar(@vmx_paths) . " vmx files on VM host");
- return @vmx_paths;
+ # Get a list of all the vmx files under the normal vmx base directory
+ my @found_vmx_paths = $self->vmhost_os->find_files($vmx_base_directory_path, "*.vmx");
+
+ # Get a list of the registered VMs in case a VM is registered and the vmx file does not reside under the normal vmx base directory
+ my @registered_vmx_paths = $self->api->get_registered_vms();
+
+ my %vmx_file_paths = map { $_ => 1 } (@found_vmx_paths, @registered_vmx_paths);
+ notify($ERRORS{'DEBUG'}, 0, "found " . scalar(keys %vmx_file_paths) . " unique vmx files on VM host:\n" . join("\n", sort keys %vmx_file_paths));
+
+ return sort keys %vmx_file_paths;
}
#/////////////////////////////////////////////////////////////////////////////
@@ -3019,167 +3536,6 @@ sub get_vm_additional_vmx_bytes_required
#/////////////////////////////////////////////////////////////////////////////
-=head2 set_vmx_file_path
-
- Parameters : $vmx_file_path
- Returns : boolean
- Description : Sets the vmx path into %ENV so that the default values are
- overridden when the various get_vmx_ subroutines are called. This
- is useful when a base image is being captured. The vmx file does
- not need to be in the expected directory nor does it need to be
- named anything particular. The code locates the vmx file and then
- saves the non-default path in this object so that capture works
- regardless of the vmx path/name.
-
-=cut
-
-sub set_vmx_file_path {
- my $self = shift;
- if (ref($self) !~ /vmware/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
- return;
- }
-
- # Get the vmx file path argument
- my $vmx_file_path = shift;
- if (!$vmx_file_path) {
- notify($ERRORS{'WARNING'}, 0, "vmx file path argument was not supplied");
- return;
- }
-
- delete $ENV{vmx_file_path};
-
- if ($vmx_file_path ne $self->get_vmx_file_path()) {
- notify($ERRORS{'DEBUG'}, 0, "vmx file path will be overridden, it does not match the expected path:
- argument: $vmx_file_path
- expected: " . $self->get_vmx_file_path());
- }
- else {
- return 1;
- }
-
- # Make sure the vmx file path begins with the vmx base directory
- my $vmx_base_directory_path = $self->get_vmx_base_directory_path() || return;
- if ($vmx_file_path !~ /^$vmx_base_directory_path/) {
- notify($ERRORS{'WARNING'}, 0, "unable to override vmx file path $vmx_file_path, it does not begin with the vmx base directory path: $vmx_base_directory_path");
- return;
- }
-
- # Make sure the vmx file path ends with .vmx
- if ($vmx_file_path !~ /\.vmx$/) {
- notify($ERRORS{'WARNING'}, 0, "unable to override vmx file path $vmx_file_path, it does not end with .vmx");
- return;
- }
-
- # Make sure the vmx file path contains a file name
- if ($vmx_file_path !~ /\/[^\/]+\.vmx$/) {
- notify($ERRORS{'WARNING'}, 0, "unable to override vmx file path $vmx_file_path, it does not contain a file name");
- return;
- }
-
- # Make sure the vmx file path contains an intermediate path
- if ($vmx_file_path !~ /^$vmx_base_directory_path\/.+\/[^\/]+\.vmx$/) {
- notify($ERRORS{'WARNING'}, 0, "unable to override vmx file path $vmx_file_path, it does not contain an intermediate path");
- return;
- }
-
- $ENV{vmx_file_path} = $vmx_file_path;
- notify($ERRORS{'OK'}, 0, "set overridden vmx location:\n" .
- "vmx file path: $vmx_file_path\n" .
- "vmx base directory path: " . $self->get_vmx_base_directory_path() . "\n" .
- "vmx directory name: " . $self->get_vmx_directory_name() . "\n" .
- "vmx directory path: " . $self->get_vmx_directory_path() . "\n" .
- "vmx file name: " . $self->get_vmx_file_name() . "\n" .
- "vmx file path: " . $self->get_vmx_file_path());
-
- return 1;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 set_vmdk_file_path
-
- Parameters : $vmx_file_path
- Returns :
- Description : Sets the vmdk path into %ENV so that the default values are
- overridden when the various get_vmdk_... subroutines are called.
- This is useful for base image imaging reservations if the
- code detects the vmdk path is not in the expected place.
-
-=cut
-
-sub set_vmdk_file_path {
- my $self = shift;
- if (ref($self) !~ /vmware/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
- return;
- }
-
- # Get the vmdk file path argument
- my $vmdk_file_path_argument = shift;
- if (!$vmdk_file_path_argument) {
- notify($ERRORS{'WARNING'}, 0, "vmdk file path argument was not supplied");
- return;
- }
-
- delete $ENV{vmdk_file_path};
-
- if ($vmdk_file_path_argument ne $self->get_vmdk_file_path()) {
- notify($ERRORS{'DEBUG'}, 0, "vmdk file path will be overridden, it does not match the expected path:
- argument: $vmdk_file_path_argument
- expected: " . $self->get_vmdk_file_path());
- }
- else {
- notify($ERRORS{'DEBUG'}, 0, "vmdk file path does not need to overridden, it matches the expected path: $vmdk_file_path_argument");
- return 1;
- }
-
- # Make sure the vmdk file path ends with .vmdk
- if ($vmdk_file_path_argument !~ /\.vmdk$/) {
- notify($ERRORS{'WARNING'}, 0, "unable to override vmdk file path $vmdk_file_path_argument, it does not end with .vmdk");
- return;
- }
-
- # Make sure the vmdk file path contains a file name
- if ($vmdk_file_path_argument !~ /\/[^\/]+\.vmdk$/) {
- notify($ERRORS{'WARNING'}, 0, "unable to override vmdk file path $vmdk_file_path_argument, it does not contain a file name");
- return;
- }
-
- $ENV{vmdk_file_path} = $vmdk_file_path_argument;
-
- my $vmdk_file_path = $self->get_vmdk_file_path() || 'UNAVAILABLE';
- my $vmdk_base_directory_path = $self->get_vmdk_base_directory_path() || 'UNAVAILABLE';
- my $vmdk_directory_name = $self->get_vmdk_directory_name() || 'UNAVAILABLE';
- my $vmdk_directory_path = $self->get_vmdk_directory_path() || 'UNAVAILABLE';
- my $vmdk_file_name = $self->get_vmdk_file_name() || 'UNAVAILABLE';
-
- if (grep(/UNAVAILABLE/, ($vmdk_file_path, $vmdk_base_directory_path, $vmdk_directory_name, $vmdk_directory_path, $vmdk_file_name))) {
- notify($ERRORS{'WARNING'}, 0, "failed to override vmdk location, some path components are unavailable:\n" .
- "vmdk file path argument: $vmdk_file_path_argument\n" .
- "vmdk file path: $vmdk_file_path\n" .
- "vmdk base directory path: $vmdk_base_directory_path\n" .
- "vmdk directory name: $vmdk_directory_name\n" .
- "vmdk directory path: $vmdk_directory_path\n" .
- "vmdk file name: $vmdk_file_name\n" .
- "vmdk file path: $vmdk_file_path");
- return;
- }
-
- notify($ERRORS{'OK'}, 0, "set overridden vmdk location:\n" .
- "vmdk file path argument: $vmdk_file_path_argument\n" .
- "vmdk file path: $vmdk_file_path\n" .
- "vmdk base directory path: $vmdk_base_directory_path\n" .
- "vmdk directory name: $vmdk_directory_name\n" .
- "vmdk directory path: $vmdk_directory_path\n" .
- "vmdk file name: $vmdk_file_name\n" .
- "vmdk file path: $vmdk_file_path");
-
- return 1;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
=head2 rename_vmdk
Parameters : $source_vmdk_file_path, $destination_vmdk_file_path
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=987623&r1=987622&r2=987623&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 Aug 20 20:06:13 2010
@@ -368,11 +368,7 @@ sub get_vm_power_state {
Description : Copies a virtual disk (set of vmdk files). This subroutine allows
a virtual disk to be converted to a different disk type or
adapter type. The source and destination vmdk file path arguments
- are required. The adapter type argument is optional and may be
- one of the following values:
- -busLogic (default)
- -ide
- -lsiLogic
+ are required.
The disk type argument is optional and may be one of the
following values:
@@ -423,6 +419,16 @@ sub get_vm_power_state {
-not usable for disk creation
-thin (default)
-space required for thin-provisioned virtual disk is allocated and zeroed on demand as the space is used
+
+ The adapter type argument is optional and may be one of the
+ following values:
+ -busLogic
+ -ide
+ -lsiLogic
+
+ If the adapter type argument is not specified an attempt will be
+ made to retrieve it from the source vmdk file. If this fails,
+ lsiLogic will be used.
=cut
@@ -440,7 +446,17 @@ 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';
- my $destination_adapter_type = shift || 'busLogic';
+ my $destination_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';
+ }
+ }
# Check the adapter type argument, the string must match exactly or the copy will fail
my @valid_adapter_types = qw( busLogic lsiLogic ide );
@@ -518,7 +534,7 @@ sub copy_virtual_disk {
my $bits_per_second = ($source_file_size_bytes * 8 / $duration_seconds);
my $mb_per_second = ($source_file_size_bytes / $duration_seconds / 1024 / 1024);
my $mbit_per_second = ($source_file_size_bytes * 8 / $duration_seconds / 1024 / 1024);
- my $gbit_per_minute = ($source_file_size_bytes * 8 / $duration_seconds / 1024 / 1024 * 60);
+ my $gbyte_per_minute = ($source_file_size_bytes / $duration_seconds / 1024 / 1024 / 1024 * 60);
notify($ERRORS{'OK'}, 0, "copied vmdk: '$source_path' --> '$destination_path'" .
"source file bytes: " . format_number($source_file_size_bytes) . "\n" .
@@ -527,7 +543,7 @@ sub copy_virtual_disk {
"b/s: " . format_number($bits_per_second) . "\n" .
"MB/s: " . format_number($mb_per_second, 2) . "\n" .
"Mb/s: " . format_number($mbit_per_second, 2) . "\n" .
- "Gb/m: " . format_number($gbit_per_minute, 2));
+ "GB/m: " . format_number($gbyte_per_minute, 2));
return 1;
}
@@ -1514,7 +1530,6 @@ sub file_exists {
# Get and check the file path argument
my $file_path = $self->get_datastore_path(shift) || return;
- notify($ERRORS{'DEBUG'}, 0, "checking if file exists: $file_path");
# Check if the path argument is the root of a datastore
if ($file_path =~ /^\[(.+)\]$/) {