Author: arkurth
Date: Wed Aug  3 18:43:06 2011
New Revision: 1153606

URL: http://svn.apache.org/viewvc?rev=1153606&view=rev
Log:
VCL-350
Added snapshot support to the VMware code. Added VMware.pm::snapshot() 
subroutine and create_snapshot subroutines in the helper modules.

Changed default virtual disk mode to persistent instead of 
independent-persistent or independent-nonpersistent. A snapshot is created 
after the VM is registered but before it is powered on. This causes changes to 
be written to a delta file in the directory where the vmx resides. This 
eliminates the need to create a full copy of the vmdk for imaging and long-term 
reservations. Imaging and long-term reservations now use this mode. A full copy 
of the vmdk is only created for server requests. Added 
DataStructure.pm::is_server_request subroutine to tell if a request is a server 
request or not.

Changed all things named nonpersistent to shared, and persistent to dedicated 
to avoid confusion.

Other
Added some missing block request values to DataStructure.pm.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
    
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.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/Module/Provisioning/VMware/vmware_cmd.pm
    incubator/vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1153606&r1=1153605&r2=1153606&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm Wed Aug  3 
18:43:06 2011
@@ -105,7 +105,7 @@ $SUBROUTINE_MAPPINGS{blockrequest_name} 
 $SUBROUTINE_MAPPINGS{blockrequest_image_id}           = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{imageid}';
 $SUBROUTINE_MAPPINGS{blockrequest_number_machines}    = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{numMachines}';
 $SUBROUTINE_MAPPINGS{blockrequest_group_id}           = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{groupid}';
-$SUBROUTINE_MAPPINGS{blockrequest_group_name}         = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{groupname}';
+$SUBROUTINE_MAPPINGS{blockrequest_group_name}         = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{usergroup}{name}';
 $SUBROUTINE_MAPPINGS{blockrequest_repeating}          = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{repeating}';
 $SUBROUTINE_MAPPINGS{blockrequest_owner_id}           = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{ownerid}';
 $SUBROUTINE_MAPPINGS{blockrequest_admin_group_id}     = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{admingroupid}';
@@ -114,6 +114,13 @@ $SUBROUTINE_MAPPINGS{blockrequest_expire
 $SUBROUTINE_MAPPINGS{blockrequest_processing}         = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{processing}';
 $SUBROUTINE_MAPPINGS{blockrequest_mode}               = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{MODE}';
 
+$SUBROUTINE_MAPPINGS{blockrequest_blocktimes_id}       = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{BLOCKTIMES_ID}';
+
+$SUBROUTINE_MAPPINGS{blockrequest_owner_email}                   = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{owner}{email}';
+$SUBROUTINE_MAPPINGS{blockrequest_owner_affiliation_helpaddress} = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{owner}{affiliation}{helpaddress}';
+
+$SUBROUTINE_MAPPINGS{blockrequest_image_prettyname} = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{image}{prettyname}';
+
 $SUBROUTINE_MAPPINGS{blocktime_id} = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{blockTimes}{BLOCKTIME_ID}{id}';
 #$SUBROUTINE_MAPPINGS{blocktime_blockrequest_id} = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{blockTimes}{BLOCKTIME_ID}{blockRequestid}';
 $SUBROUTINE_MAPPINGS{blocktime_start}     = 
'$self->blockrequest_data->{BLOCKREQUEST_ID}{blockTimes}{BLOCKTIME_ID}{start}';
@@ -230,6 +237,7 @@ $SUBROUTINE_MAPPINGS{computer_provisioni
 
 $SUBROUTINE_MAPPINGS{vmhost_computer_id} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computerid}';
 $SUBROUTINE_MAPPINGS{vmhost_hostname}   = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{hostname}';
+$SUBROUTINE_MAPPINGS{vmhost_short_name}   = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{SHORTNAME}';
 $SUBROUTINE_MAPPINGS{vmhost_id}         = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{id}';
 $SUBROUTINE_MAPPINGS{vmhost_image_id} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{imageid}';
 $SUBROUTINE_MAPPINGS{vmhost_image_name} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{image}{name}';
@@ -2132,6 +2140,29 @@ sub is_blockrequest {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 is_server_request
+
+ Parameters  : None.
+ Returns     : 
+ Description : This subroutine determines whether or not the DataStructure
+               contains data for a server request.
+
+=cut
+
+sub is_server_request {
+       my $self = shift;
+       
+       # Check if subroutine was called as an object method
+       unless (ref($self) && $self->isa('VCL::DataStructure')) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called 
as a VCL::DataStructure module object method");
+               return;
+       }
+       
+       return $self->get_server_request_id() ? 1 : 0;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 get_management_node_public_default_gateway
 
  Parameters  : None

Modified: 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm?rev=1153606&r1=1153605&r2=1153606&view=diff
==============================================================================
--- 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
 (original)
+++ 
incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
 Wed Aug  3 18:43:06 2011
@@ -1666,6 +1666,131 @@ sub get_network_names {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 create_snapshot
+
+ Parameters  : $vmx_file_path, $name (optional)
+ Returns     : boolean
+ Description : Creates a snapshot of the VM.
+
+=cut
+
+sub create_snapshot {
+       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 file path argument
+       my $vmx_file_path = shift;
+       if (!$vmx_file_path) {
+               notify($ERRORS{'WARNING'}, 0, "vmx file path argument was not 
supplied");
+               return;
+       }
+       
+       my $snapshot_name = shift || ("VCL: " . convert_to_datetime());
+       
+       # Get the VM ID
+       my $vm_id = $self->_get_vm_id($vmx_file_path);
+       if (!defined($vm_id)) {
+               notify($ERRORS{'WARNING'}, 0, "unable to create snapshot 
because VM ID could not be determined");
+               return;
+       }
+       
+       my $vim_cmd_arguments = "vmsvc/snapshot.create $vm_id '$snapshot_name'";
+       my ($exit_status, $output) = $self->_run_vim_cmd($vim_cmd_arguments);
+       return if !$output;
+       
+       notify($ERRORS{'DEBUG'}, 0, "create snapshot output:\n" . join("\n", 
@$output));
+       
+       if (grep(/failed|invalid/i, @$output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to create snapshot of VM 
$vmx_file_path, VIM command arguments: '$vim_cmd_arguments', output:\n" . 
join("\n", @$output));
+               return;
+       }
+       
+       # Get the task ID
+       my @task_ids = $self->_get_task_ids($vmx_file_path, 'createSnapshot');
+       if (!@task_ids) {
+               notify($ERRORS{'WARNING'}, 0, "unable to retrieve the ID of the 
task created to create snapshot");
+               return;
+       }
+       
+       # Wait for the task to complete
+       if ($self->_wait_for_task($task_ids[0])) {
+               notify($ERRORS{'OK'}, 0, "created snapshot of VM: 
$vmx_file_path, snapshot name: $snapshot_name");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to create snapshot VM: 
$vmx_file_path, the vim task did not complete successfully, vim-cmd 
$vim_cmd_arguments output:\n" . join("\n", @$output));
+               return;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 snapshot_exists
+
+ Parameters  : $vmx_file_path
+ Returns     : boolean
+ Description : Determines if a snapshot exists for the VM.
+
+=cut
+
+sub snapshot_exists {
+       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 file path argument
+       my $vmx_file_path = shift;
+       if (!$vmx_file_path) {
+               notify($ERRORS{'WARNING'}, 0, "vmx file path argument was not 
supplied");
+               return;
+       }
+       
+       # Get the VM ID
+       my $vm_id = $self->_get_vm_id($vmx_file_path);
+       if (!defined($vm_id)) {
+               notify($ERRORS{'WARNING'}, 0, "unable to determine if snapshot 
exists because VM ID could not be determined");
+               return;
+       }
+       
+       my $vim_cmd_arguments = "vmsvc/snapshot.get $vm_id";
+       my ($exit_status, $output) = $self->_run_vim_cmd($vim_cmd_arguments);
+       return if !$output;
+       
+       notify($ERRORS{'DEBUG'}, 0, "snapshot.get output:\n" . join("\n", 
@$output));
+       
+       if (grep(/failed|invalid/i, @$output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to determine if snapshot 
exists for VM $vmx_file_path, VIM command arguments: '$vim_cmd_arguments', 
output:\n" . join("\n", @$output));
+               return;
+       }
+       
+       # Expected output if shapshot exists:
+       # Get Snapshot:
+       # |-ROOT
+       # --Snapshot Name        : 1311966951
+       # --Snapshot Desciption  :
+       # --Snapshot Created On  : 7/29/2011 19:15:59
+       # --Snapshot State       : powered off
+       
+       # Expected output if snapshot does not exist:
+       # Get Snapshot:
+
+       if (grep(/-ROOT/, @$output)) {
+               notify($ERRORS{'DEBUG'}, 0, "snapshot exists for VM 
$vmx_file_path");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'DEBUG'}, 0, "snapshot does NOT exist for VM 
$vmx_file_path");
+               return 0;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 DESTROY
 
  Parameters  : none


Reply via email to