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