Modified: incubator/vcl/trunk/managementnode/lib/VCL/image.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/image.pm?rev=987623&r1=987622&r2=987623&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/image.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/image.pm Fri Aug 20 20:06:13 2010
@@ -65,6 +65,7 @@ use 5.008000;
 use strict;
 use warnings;
 use diagnostics;
+use English '-no_match_vars';
 
 use VCL::utils;
 
@@ -106,8 +107,9 @@ sub process {
        my $managementnode_shortname   = 
$self->data->get_management_node_short_name();
        my $sysadmin_mail_address      = 
$self->data->get_management_node_sysadmin_email();
 
-       # Notify administrators that image creation is starting
-       my $body = <<"END";
+       if ($sysadmin_mail_address) {
+               # Notify administrators that image creation is starting
+               my $body = <<"END";
 VCL Image Creation Started
 
 Request ID: $request_id
@@ -129,8 +131,9 @@ Computer name: $computer_shortname
 
 Use Sysprep: $imagemeta_sysprep
 END
-       mail($sysadmin_mail_address, "VCL IMAGE Creation Started: $image_name", 
$body, $affiliation_helpaddress);
-
+               mail($sysadmin_mail_address, "VCL IMAGE Creation Started: 
$image_name", $body, $affiliation_helpaddress);
+       }
+       
        # Make sure image does not exist in the repository
        my $image_already_exists = $self->provisioner->does_image_exist();
        if ($image_already_exists) {
@@ -460,6 +463,321 @@ END
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 setup
+
+ Parameters  : none
+ Returns     : 
+ Description : This subroutine is used when vcld is run in setup mode. It
+               presents a menu for the image module.
+
+=cut
+
+sub setup {
+       my $self = shift;
+       unless (ref($self) && $self->isa('VCL::Module')) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       push @{$ENV{setup_path}}, 'Image';
+       
+       my @operation_choices = (
+               'Capture Base Image',
+       );
+       
+       my @setup_path = @{$ENV{setup_path}};
+       OPERATION: while (1) {
+               @{$ENV{setup_path}} = @setup_path;
+               
+               print '-' x 76 . "\n";
+               
+               print "Choose an operation:\n";
+               my $operation_choice_index = 
setup_get_array_choice(@operation_choices);
+               last if (!defined($operation_choice_index));
+               my $operation_name = 
$operation_choices[$operation_choice_index];
+               print "\n";
+               
+               push @{$ENV{setup_path}}, $operation_name;
+               
+               if ($operation_name =~ /capture/i) {
+                       $self->setup_capture_base_image();
+               }
+       }
+       
+       pop @{$ENV{setup_path}};
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 setup_capture_base_image
+
+ Parameters  : none
+ Returns     : 
+ Description : This subroutine is used when vcld is run in setup mode. It
+               inserts the database entries necessary to capture a base image.
+               Several questions are presented to the user via the command 
line.
+
+=cut
+
+sub setup_capture_base_image {
+       my $self = shift;
+       unless (ref($self) && $self->isa('VCL::Module')) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       # Get the management node id, needed to insert a reservation row later 
on
+       my $management_node_id = $self->data->get_management_node_id();
+       if (!$management_node_id) {
+               print "ERROR: failed to determine the management node ID\n";
+               return;
+       }
+       
+       # Get the user who the reservation and image will belong to
+       my $user_id;
+       my $username;
+       while (!$user_id) {
+               my $user_identifier = setup_get_input_string("Enter the VCL 
login name or ID of the user who will own the image:", 'admin');
+               return if (!defined($user_identifier));
+               my $user_info = get_user_info($user_identifier);
+               if (!$user_info) {
+                       print "User was not found: $user_identifier\n";
+               }
+               else {
+                       $user_id = (keys %$user_info)[0];
+                       $username = $user_info->{$user_id}{unityid};
+               }
+       }
+       print "\nUser who will own the image: $username (ID: $user_id)\n\n";
+       
+       # Determine the computer ID
+       my $computer_id;
+       my %computer_info;
+       while (!$computer_id) {
+               my $computer_identifier = setup_get_input_string("Enter the 
hostname or IP address of the computer to be captured:");
+               return if (!defined($computer_identifier));
+               
+               # Search the computer table for a match
+               my @computer_ids = get_computer_ids($computer_identifier);
+               if (!...@computer_ids) {
+                       print "No VCL computers were found with the name or IP 
address: $computer_identifier\n";
+                       next;
+               }
+               
+               # Get information from the database for all of the computers 
found
+               for my $computer_id (@computer_ids) {
+                       $computer_info{$computer_id} = 
get_computer_info($computer_id)->{computer};
+                       if (!$computer_info{$computer_id}) {
+                               print "ERROR: unable to retrieve information 
for computer ID: $computer_id\n";
+                               return;
+                       }
+               }
+       
+               if (scalar(@computer_ids) > 1) {
+                       print "Multiple VCL computers were found with the name 
or IP address: '$computer_identifier' (@computer_ids)\n\n";
+                       print "Choose a computer:\n";
+                       $computer_id = setup_get_hash_choice(\%computer_info, 
'hostname');
+                       return if (!defined($computer_id));
+               }
+               else {
+                       $computer_id = (keys %computer_info)[0];
+               }
+       }
+       
+       my $computer_hostname = $computer_info{$computer_id}{hostname};
+       my $computer_state_name = $computer_info{$computer_id}{state}{name};
+       my $computer_provisioning_module_name = 
$computer_info{$computer_id}{provisioning}{module}{name};
+       
+       my $install_type;
+       if ($computer_provisioning_module_name =~ /vm/i) {
+               $install_type = 'vmware';
+       }
+       else {
+               $install_type = 'partimage';
+       }
+       
+       print "\nComputer to be captured: $computer_hostname (ID: 
$computer_id)\n";
+       print "Provisioning module: $computer_provisioning_module_name\n";
+       print "Install type: $install_type\n";
+       print "\n";
+       
+       # Make sure the computer state is valid
+       if ($computer_state_name =~ /(maintenance|deleted)/i) {
+               print "ERROR: state of $computer_hostname is 
$computer_state_name\n";
+               return;
+       }
+       
+       
+       # Get the OS table contents from the database
+       my $os_info = get_os_info();
+       if (!$os_info) {
+               print "ERROR: failed to retrieve OS info from the database\n";
+               return;
+       }
+
+       # Loop through the OS table info
+       for my $os_id (keys %$os_info) {
+               # Remove keys which don't match the selected computer type
+               # Remove keys where the name begins with esx - deprecated OS 
type
+               if ($os_info->{$os_id}{installtype} ne $install_type || 
$os_info->{$os_id}{name} =~ /^vmwareesx/i) {
+                       delete $os_info->{$os_id};
+               }
+       }
+
+       print "Select the OS to be captured (install type: $install_type):\n";
+       my $os_id = setup_get_hash_choice($os_info, 'prettyname');
+       return if (!defined($os_id));
+       my $os_prettyname = $os_info->{$os_id}{prettyname};
+       my $os_module_perl_package = $os_info->{$os_id}{module}{perlpackage};
+       my $os_type = $os_info->{$os_id}{type};
+       print "\nSelected OS: $os_prettyname\n\n";
+       
+       # If Windows, ask if Sysprep should be used
+       my $use_sysprep = 1;
+       if ($os_type =~ /windows/i) {
+               my @yes_no_choices = (
+                       'Yes',
+                       'No',
+               );
+               
+               print "Use Sysprep:\n";
+               my $sysprep_choice_index = 
setup_get_array_choice(@yes_no_choices);
+               last if (!defined($sysprep_choice_index));
+               my $use_sysprep_choice = $yes_no_choices[$sysprep_choice_index];
+               print "\nUse Sysprep: $use_sysprep_choice\n\n";
+               
+               if ($use_sysprep_choice =~ /no/i) {
+                       $use_sysprep = 0;
+               }
+       }
+       
+       my $image_prettyname;
+       while (!$image_prettyname) {
+               $image_prettyname = setup_get_input_string("Enter the name of 
the image to be captured:");
+               return if (!defined($image_prettyname));
+               #if ($image_prettyname =~ //) {
+               #       print "Image name is not valid: $image_prettyname\n";
+               #       $image_prettyname = 0;
+               #}
+       }
+       
+       my $image_name = $image_prettyname;
+       $image_name =~ s/[\s\W]//g;
+       $image_name = $os_info->{$os_id}{name} . "-$image_name-v0";
+       
+       my $insert_imagemeta_statement = <<EOF;
+INSERT INTO imagemeta
+(sysprep)
+VALUES
+('$use_sysprep')
+EOF
+       
+       my $imagemeta_id = database_execute($insert_imagemeta_statement);
+       if (!defined($imagemeta_id)) {
+               print "ERROR: failed to insert into imagemeta table\n";
+               return;
+       }
+       
+       
+       my $insert_image_statement = <<EOF;
+INSERT INTO image (name, prettyname, ownerid, platformid, OSid, imagemetaid, 
deleted, lastupdate, size, architecture, basedoffrevisionid)
+VALUES ('$image_name', '$image_prettyname', '$user_id', '1', $os_id, 
$imagemeta_id, '1', NOW( ), '1450', 'x86', '4')
+EOF
+       
+       my $image_id = database_execute($insert_image_statement);
+       if (!defined($image_id)) {
+               print "ERROR: failed to insert into image table\n";
+               return;
+       }
+       
+       # Add the newly inserted image ID to the image name
+       $image_name =~ s/-v0$/$image_id-v0/;
+       
+       # Upadate the name in the image table
+       my $update_image_statement = <<EOF;
+UPDATE image
+SET name = '$image_name'
+WHERE
+id = $image_id
+EOF
+       if (!database_execute($update_image_statement)) {
+               print "ERROR: failed to update the image table with the correct 
image name: $image_name\n";
+               return;
+       }
+       
+       
+       my $insert_imagerevision_statement = <<EOF;
+INSERT INTO imagerevision
+(imageid, revision, userid, datecreated, deleted, production, imagename)
+VALUES
+($image_id, '0', '$user_id', NOW( ), '1', '1', '$image_name')
+EOF
+
+       my $imagerevision_id = 
database_execute($insert_imagerevision_statement);
+       if (!defined($imagerevision_id)) {
+               print "ERROR: failed to insert into imagerevision table\n";
+               return;
+       }
+
+       my $insert_resource_statement = <<EOF;
+INSERT INTO resource
+(resourcetypeid, subid)
+VALUES ('13', '$image_id')
+EOF
+
+       my $resource_id = database_execute($insert_resource_statement);
+       if (!defined($resource_id)) {
+               print "ERROR: failed to insert into resource table\n";
+               return;
+       }
+       
+       print "\nAdded new image to database: '$image_prettyname'\n";
+       print "   image.name: $image_name\n";
+       print "   image.id: $image_id\n";
+       print "   imagerevision.id: $imagerevision_id\n";
+       print "   imagemeta.id: $imagemeta_id\n";
+       print "   resource.id: $resource_id\n\n";
+       
+       
+       my ($request_id, $reservation_id) = insert_request($management_node_id, 
'image', 'image', 0, $username, $computer_id, $image_id, $imagerevision_id, 0, 
60);
+       if (!defined($request_id) || !defined($reservation_id)) {
+               print "ERROR: failed to insert new imaging request\n";
+               return;
+       }
+       
+       my $message = <<EOF;
+Inserted imaging request to the database:
+request ID: $request_id
+reservation ID: $reservation_id
+
+This process will now display the contents of the vcld.log file if the vcld
+daemon is running. If you do not see many lines of additional output, exit this
+process, start the vcld daemon, and monitor the image capture process by 
running
+the command:
+tail -f $LOGFILE | grep '$request_id:$reservation_id'
+
+EOF
+       
+       print '-' x 76 . "\n";
+       print "$message";
+       print '-' x 76 . "\n";
+       
+       # Pipe the command output to a file handle
+       # The open function returns the pid of the process
+       if (open(COMMAND, "tail -f $LOGFILE 2>&1 |")) {
+               # Capture the output of the command
+               
+               while (my $output = <COMMAND>) {
+                       print $output if ($output =~ /$reservation_id/);
+               }
+       }
+       
+       exit;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=987623&r1=987622&r2=987623&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Fri Aug 20 20:06:13 2010
@@ -108,8 +108,10 @@ our @EXPORT = qw(
   format_number
   get_affiliation_info
   get_block_request_image_info
+  get_caller_trace
   get_computer_current_state_name
   get_computer_grp_members
+  get_computer_ids
   get_computer_info
   get_computers_controlled_by_MN
   get_current_file_name
@@ -127,12 +129,14 @@ our @EXPORT = qw(
   get_management_predictive_info
   get_module_info
   get_next_image_default
+  get_os_info
   get_production_imagerevision_info
   get_request_by_computerid
   get_request_end
   get_request_info
   get_resource_groups
   get_managable_resource_groups
+  get_user_info
   get_vmhost_info
   get_user_info
   getdynamicaddress
@@ -8243,6 +8247,50 @@ EOF
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_computer_ids
+
+ Parameters  : $computer_identifier
+ Returns     : array
+ Description : Queries the computer table for computers matching the
+               $computer_identifier argument. The argument may contain either
+               the computer's hostname or IP address. An array containing the
+               computer IDs is returned.
+
+=cut
+
+sub get_computer_ids {
+       my ($computer_identifier) = @_;
+
+       if(!defined($computer_identifier)){
+               notify($ERRORS{'WARNING'}, $LOGFILE, "computer identifier 
argument was not supplied");
+               return;
+       }
+
+       my $select_statement = <<EOF;
+SELECT
+*
+FROM
+computer
+WHERE
+hostname LIKE '$computer_identifier'
+OR hostname LIKE '$computer_identifier.%'
+OR IPaddress = '$computer_identifier'
+OR privateIPaddress = '$computer_identifier'
+EOF
+
+       my @selected_rows = database_select($select_statement);
+       if (!...@selected_rows) {
+               notify($ERRORS{'DEBUG'}, 0, "no computers were found matching 
identifier: $computer_identifier");
+               return ();
+       }
+
+       my @computer_ids = map { $_->{id} } @selected_rows;
+       notify($ERRORS{'DEBUG'}, 0, "found computers matching identifier: 
$computer_identifier, IDs: @computer_ids");
+       return sort @computer_ids;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 insert_request
 
  Parameters  : $managementnode_id, $request_state_name, 
$request_laststate_name, $end_minutes_in_future, $user_unityid, $computer_id, 
$image_id, $imagerevision_id
@@ -9549,6 +9597,64 @@ sub get_module_info {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_user_info
+
+ Parameters  : $user_identifier
+ Returns     : hash reference
+ Description : Retrieves information from the database for the user specified 
by
+               the $user_identifier argument. The $user_identifier argument can
+               either be a user ID or login name.
+
+=cut
+
+sub get_user_info {
+       my ($user_identifier) = @_;
+       if (!defined($user_identifier)) {
+               notify($ERRORS{'WARNING'}, 0, "user identifier argument was not 
specified");
+               return;
+       }
+       
+       my $select_statement = <<EOF;
+SELECT
+*
+FROM
+user
+WHERE
+EOF
+       
+       if ($user_identifier =~ /^\d+$/) {
+               $select_statement .= "id = $user_identifier";
+       }
+       else {
+               $select_statement .= "unityid = '$user_identifier'";
+       }
+       
+       # Call the database select subroutine
+       my @selected_rows = database_select($select_statement);
+
+       # Check to make sure rows were returned
+       if (!...@selected_rows) {
+               notify($ERRORS{'WARNING'}, 0, "unable to retrieve rows from 
user table");
+               return;
+       }
+       
+       # Transform the array of database rows into a hash
+       my %info_hash;
+       for my $row (@selected_rows) {
+               my $user_id = $row->{id};
+               
+               for my $key (keys %$row) {
+                       my $value = $row->{$key};
+                       $info_hash{$user_id}{$key} = $value;
+               }
+       }
+       
+       notify($ERRORS{'DEBUG'}, 0, "retrieved user info:\n" . 
format_data(\%info_hash));
+       return \%info_hash;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 get_current_package_name
 
  Parameters  : None
@@ -10080,6 +10186,58 @@ sub setup_print_wrap {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_os_info
+
+ Parameters  : none
+ Returns     : hash reference
+ Description : Returns the contents of the OS table as a hash reference. The
+               hash keys are the OS IDs.
+
+=cut
+
+sub get_os_info {
+       # Create the select statement
+       my $select_statement = <<EOF;
+SELECT
+OS.*,
+module.name AS module_name,
+module.prettyname AS module_prettyname,
+module.perlpackage AS module_perlpackage
+FROM
+OS,
+module
+WHERE
+OS.moduleid = module.id
+EOF
+       
+       # Call the database select subroutine
+       my @selected_rows = database_select($select_statement);
+       
+       my %info;
+       
+       for my $row (@selected_rows) {
+               my $os_id = $row->{id};
+               
+               foreach my $key (keys %$row) {
+                       my $value = $row->{$key};
+                       
+                       (my $original_key = $key) =~ s/^.+_//;
+       
+                       if ($key =~ /module_/) {
+                                $info{$os_id}{module}{$original_key} = $value;
+                       }
+                       else {
+                               $info{$os_id}{$original_key} = $value;
+                       }
+               }
+       }
+       
+       notify($ERRORS{'DEBUG'}, 0, "retrieved OS info:\n" . 
format_data(\%info));
+       return \%info;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 


Reply via email to