sub capture()

in managementnode/lib/VCL/Module/Provisioning/vbox.pm [455:604]


sub capture { ## This is going to need to be implemented before the module is complete, but at the moment the focus is on complete VM provisioning.
	my $self = shift;
	if (ref($self) !~ /vbox/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return 0;
	}
	my $request_id         = $self->data->get_request_id;
	my $request_state_name = $self->data->get_request_state_name();
	my $reservation_id     = $self->data->get_reservation_id;
	my $management_node_keys     = $self->data->get_management_node_keys();

	my $requestedimagename = $self->data->get_image_name;

	my $datastorepath     = $self->data->get_vmhost_profile_datastore_path;

	my $image_id       = $self->data->get_image_id;
	my $image_os_name  = $self->data->get_image_os_name;
	my $image_os_type  = $self->data->get_image_os_type;
	my $image_name     = $self->data->get_image_name();

	my $computer_id        = $self->data->get_computer_id;
	my $computer_shortname = $self->data->get_computer_short_name;
	my $computer_nodename  = $computer_shortname;
	my $computer_hostname  = $self->data->get_computer_hostname;
	my $computer_type      = $self->data->get_computer_type;
	
	my $vmhost_vmpath           = $self->data->get_vmhost_profile_vmpath;
	my $vmprofile_vmdisk        = $self->data->get_vmhost_profile_vmdisk;
	my $vmprofile_datastorepath = $self->data->get_vmhost_profile_datastore_path;
	my $vmhost_hostname         = $self->data->get_vmhost_hostname;
	my $host_type               = $self->data->get_vmhost_type;
	my $vmhost_imagename        = $self->data->get_vmhost_image_name;

	my $image_repository_path   = $self->_get_image_repository_path();
	my $hostnodename = $vmhost_hostname;
	# Assemble a consistent prefix for notify messages
	my $notify_prefix = "req=$request_id, res=$reservation_id:";
	my $image_filename;


	# Print some preliminary information
	notify($ERRORS{'OK'}, 0, "$notify_prefix new name: $image_name");
	notify($ERRORS{'OK'}, 0, "$notify_prefix computer_name: $computer_shortname");
	notify($ERRORS{'OK'}, 0, "$notify_prefix vmhost_hostname: $vmhost_hostname");

	my @sshcmd;

	# Check if pre_capture() subroutine has been implemented by the OS module
	if ($self->os->can("pre_capture")) {
		# Call OS pre_capture() - it should perform all OS steps necessary to capture an image
		# pre_capture() should shut down the computer when it is done
		notify($ERRORS{'OK'}, 0, "calling OS module's pre_capture() subroutine");

		if (!$self->os->pre_capture({end_state => 'off'})) {
			notify($ERRORS{'WARNING'}, 0, "OS module pre_capture() failed");
			return 0;
		}

		# Get the power status, make sure computer is off
		my $power_status = $self->power_status();
		notify($ERRORS{'DEBUG'}, 0, "retrieved power status: $power_status");
		if ($power_status eq 'off') {
			notify($ERRORS{'OK'}, 0, "verified $computer_nodename power is off");
		}
		elsif ($power_status eq 'on') {
			notify($ERRORS{'WARNING'}, 0, "$computer_nodename power is still on, turning computer off");

			# Attempt to power off computer
			if ($self->power_off()) {
				notify($ERRORS{'OK'}, 0, "$computer_nodename was powered off");
			}
			else {
				notify($ERRORS{'WARNING'}, 0, "failed to power off $computer_nodename");
				return 0;
			}
		}
		else {
			notify($ERRORS{'WARNING'}, 0, "failed to determine power status of $computer_nodename");
			return 0;
		}
	}
	
	if ($vmprofile_vmdisk =~ /(local|dedicated)/) {
		# copy vdi files
		# confirm they were copied

		undef @sshcmd;
		@sshcmd = run_ssh_command($hostnodename, $management_node_keys, "ls $datastorepath/*_IMAGING_$computer_shortname", "root");
		for my $l (@{$sshcmd[1]}) {
			if ($l =~ /\/(.*_IMAGING_$computer_shortname)/) {
				$image_filename = $l;
				notify($ERRORS{'OK'}, 0, "Image filename is: $image_filename");
			}
		} ## end for my $l (@{$sshcmd[1]})

		notify($ERRORS{'OK'}, 0, "attemping to copy vdi file to $image_repository_path");
		if (run_scp_command("$hostnodename:\"$image_filename\"", "$image_repository_path\/$image_name", $management_node_keys)) {

		# set file premissions on images to 644
		# to allow for other management nodes to fetch image if neccessary
		# useful in a large distributed framework
		if (open(CHMOD, "/bin/chmod -R 644 $image_repository_path\/$image_name 2>&1 |")) {
			close(CHMOD);
			notify($ERRORS{'DEBUG'}, 0, "$notify_prefix recursive update file permssions 644 on $image_repository_path\/$image_name");
		}
		undef @sshcmd;
		@sshcmd = run_ssh_command($hostnodename, $management_node_keys, "VBoxManage closemedium disk $datastorepath/$image_filename --delete", "root");
		return 1;
		} ## end if (run_scp_command("$hostnodename:\"$vmhost_vmpath/$vmx_directory/*.vmdk\""...
		else {
			notify($ERRORS{'CRITICAL'}, 0, "failed to copy .vdi file to image repository");
			return 0;
		}
		
		if ($request_state_name !~ /^(image)$/) {
			notify($ERRORS{'OK'}, 0, "VM will NOT be deleted because the request state is '$request_state_name'");
		}
		else {
			# Image has been captured, remove the VM
			$self->control_vm("remove");
		}
	} elsif ($vmprofile_vmdisk =~ /shared/) { ## end if ($vmprofile_vmdisk =~ /(local|dedicated)/)
		
		if (open(FILELIST, "/bin/ls $image_repository_path/*_IMAGING_$computer_shortname 2>&1 |")) {
			my @filelist = <FILELIST>;
			close(FILELIST);
			my $size = 0;
			foreach my $f (@filelist) {
				if ($f =~ /\/(.*_IMAGING_$computer_shortname)/) {
					$image_filename = $f;
					$image_filename =~ s/(\r|\n)//g;
					notify($ERRORS{'OK'}, 0, "Image filename is: $image_filename");
				}
			}	
		} 
		
		if (open(MV, "/bin/mv $image_filename $image_repository_path\/$image_name 2>&1 |")) {
			close(MV);
			notify($ERRORS{'OK'}, 0, "renamed $image_filename to $image_repository_path\/$image_name");
			if (open(CHMOD, "/bin/chmod -R 644 $image_repository_path\/$image_name 2>&1 |")) {
				close(CHMOD);
				notify($ERRORS{'DEBUG'}, 0, "$notify_prefix recursive update file permssions 644 on $image_repository_path\/$image_name");
			}
			#undef @sshcmd;
			#@sshcmd = run_ssh_command($hostnodename, $management_node_keys, "VBoxManage closemedium disk $datastorepath/$image_filename --delete", "root");
			return 1;
		}
	}

} ## end sub capture