Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1675483&r1=1675482&r2=1675483&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Wed Apr 22 19:59:24 2015
@@ -63,7 +63,7 @@ use Fcntl qw(:DEFAULT :flock);
 use FindBin;
 use Getopt::Long;
 use Carp;
-use Term::ANSIColor;
+use Term::ANSIColor 2.00 qw(:constants :pushpop color colored);
 use Text::Wrap;
 use English;
 use List::Util qw(min max);
@@ -237,6 +237,7 @@ our @EXPORT = qw(
        setup_confirm
        setup_get_array_choice
        setup_get_hash_choice
+       setup_get_hash_multiple_choice
        setup_get_input_file_path
        setup_get_input_string
        setup_get_menu_choice
@@ -264,6 +265,7 @@ our @EXPORT = qw(
        update_computer_public_ip_address
        update_computer_ram
        update_computer_state
+       update_computer_vmhost_id
        update_connectlog
        update_currentimage
        update_image_name
@@ -2894,7 +2896,7 @@ sub get_request_info {
                return;
        }
        
-       # Use cached info by default
+       # Don't use cached info by default
        if (!$no_cache) {
                $no_cache = 1;
        }
@@ -3957,7 +3959,15 @@ EOF
                return;
        }
        elsif (scalar @selected_rows > 1) {
-               notify($ERRORS{'WARNING'}, 0, scalar @selected_rows . " rows 
were returned from database select statement:\n$select_statement");
+               my $vmhost_string;
+               for my $row (@selected_rows) {
+                       $vmhost_string .= "VM host ID: " . $row->{'vmhost-id'};
+                       $vmhost_string .= ", computer ID: " . 
$row->{'vmhost-computerid'};
+                       $vmhost_string .= ", VM profile ID: " . 
$row->{'vmprofile-id'};
+                       $vmhost_string .= ", VM profile name: " . 
$row->{'vmprofile-profilename'};
+                       $vmhost_string .= "\n";
+               }
+               notify($ERRORS{'WARNING'}, 0, scalar @selected_rows . " rows 
were returned from database select 
statement:\n$select_statement\nrows:\n$vmhost_string");
                return;
        }
 
@@ -5085,6 +5095,50 @@ EOF
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 update_computer_vmhost_id
+
+ Parameters  : $computer_id, $vmhost_id
+ Returns     : boolean
+ Description : Updates the computer.vmhostid value of the computer specified by
+               the argument.
+
+=cut
+
+sub update_computer_vmhost_id {
+       my ($computer_id, $vmhost_id) = @_;
+       
+       if (!defined($computer_id)) {
+               notify($ERRORS{'WARNING'}, 0, "computer ID argument was not 
specified");
+               return;
+       }
+       if (!defined($vmhost_id)) {
+               notify($ERRORS{'WARNING'}, 0, "VM host ID argument was not 
specified");
+               return;
+       }
+
+       # Construct the update statement
+       my $update_statement = <<EOF;
+UPDATE
+computer
+SET
+vmhostid = '$vmhost_id'
+WHERE
+id = $computer_id
+EOF
+
+       # Call the database execute subroutine
+       if (database_execute($update_statement)) {
+               notify($ERRORS{'OK'}, 0, "updated VM host ID of computer 
$computer_id in database: $vmhost_id");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to update VM host ID of 
of computer $computer_id in database: $vmhost_id");
+               return;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 get_request_end
 
  Parameters  : $request_id
@@ -10242,9 +10296,245 @@ sub setup_get_hash_choice {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 setup_get_hash_multiple_choice
+
+ Parameters  : $hash_ref, $argument_hash_ref (optional)
+ Returns     : $hash_key
+ Description : Given a hash reference structure, constructs a menu and 
retrieves
+               user input.
+               
+               An optional hash reference can be supplied containing 
information
+               to control how the menu is displayed. The hash may contain the
+               following keys:
+               * title - A string which will be displayed above the menu.
+               * display_keys - An array reference containing strings. Each
+                 array element may be a string enclosed in curly brackets. This
+                 allows the menu items to be composed from any data elements
+                 contained within the hash reference.
+               
+               Example:
+               {
+                  'title' => "Select VMs to be migrated off of 
$source_vmhost_computer_name",
+                  'display_keys' => ['{SHORTNAME}', ' - ', 
'{currentimagerevision}{imagename}'],
+               }
+               
+               This would result in menu entry names being assembled from:
+               $hash_ref->{SHORTNAME} - 
$hash_ref->{currentimagerevision}{imagename}
+
+=cut
+
+sub setup_get_hash_multiple_choice {
+       my $hash_ref = shift;
+       if (!defined($hash_ref)) {
+               notify($ERRORS{'WARNING'}, 0, "hash reference argument was not 
supplied");
+               return;
+       }
+       elsif (!ref($hash_ref)) {
+               notify($ERRORS{'WARNING'}, 0, "1st argument is not a reference, 
it must be a hash reference:\n$hash_ref");
+               return;
+       }
+       elsif (ref($hash_ref) ne 'HASH') {
+               notify($ERRORS{'WARNING'}, 0, "1st argument is a " . 
ref($hash_ref) . " reference, it must be a hash reference:\n" . 
format_data($hash_ref));
+               return;
+       }
+       
+       my $arguments = shift;
+       if (defined($arguments)) {
+               if (!ref($arguments)) {
+                       notify($ERRORS{'WARNING'}, 0, "2nd argument is not a 
reference, it must be a hash reference:\n$arguments");
+                       return;
+               }
+               elsif (ref($arguments) ne 'HASH') {
+                       notify($ERRORS{'WARNING'}, 0, "2nd argument is a " . 
ref($arguments) . " reference, it must be a hash reference:\n" . 
format_data($arguments));
+                       return;
+               }
+       }
+       else {
+               $arguments = {};
+       }
+       
+       my $title = $arguments->{title};
+       my @display_keys = (defined($arguments->{display_keys}) ? 
@{$arguments->{display_keys}} : ());
+       
+       my $entry_hash = {};
+       my $max_entry_length = 0;
+       for my $key (sort keys %$hash_ref) {
+               my $entry_display_name;
+               
+               for my $display_key (@display_keys) {
+                       if ($display_key =~ /^{.+}$/) {
+                               my $hash_path = 
"\$hash_ref->{$key}$display_key";
+                               notify($ERRORS{'DEBUG'}, 0, "retrieving hash 
value: $hash_path");
+                               my $value = eval $hash_path;
+                               if ($EVAL_ERROR) {
+                                       notify($ERRORS{'WARNING'}, 0, "error 
encountered evaluating hash path: '$hash_path'\n$EVAL_ERROR");
+                                       return;
+                               }
+                               elsif (!defined($value)) {
+                                       notify($ERRORS{'WARNING'}, 0, "unable 
to determine entry display name, hash does not contain key: '$hash_path'\," . 
format_data($hash_ref->{$key}));
+                                       return;
+                               }
+                               else {
+                                       notify($ERRORS{'DEBUG'}, 0, "retrieved 
entry display name component: $hash_path = '$value'");
+                                       $entry_display_name .= $value;
+                               }
+                       }
+                       else {
+                               notify($ERRORS{'DEBUG'}, 0, "adding text to 
entry display name: '$display_key'");
+                               $entry_display_name .= $display_key;
+                       }
+               }
+               
+               if (defined($entry_hash->{$entry_display_name})) {
+                       notify($ERRORS{'WARNING'}, 0, "duplicate entry display 
names: '$entry_display_name', appending hash key: '$entry_display_name 
{$key}'");
+                       $entry_display_name = "$entry_display_name {$key}";
+               }
+               else {
+                       notify($ERRORS{'DEBUG'}, 0, "choice entry name for hash 
key $key: '$entry_display_name'");
+               }
+               
+               $entry_hash->{$entry_display_name}{key} = $key;
+               $entry_hash->{$entry_display_name}{selected} = 0;
+               $entry_hash->{$entry_display_name}{entry_display_name} = 
$entry_display_name;
+               
+               my $entry_display_name_length = length($entry_display_name);
+               $max_entry_length = $entry_display_name_length if 
($entry_display_name_length > $max_entry_length);
+       }
+       
+       my $entry_index_hash = {};
+       my $i = 1;
+       for my $entry_display_name (sort keys %$entry_hash) {
+               $entry_index_hash->{$i} = $entry_hash->{$entry_display_name};
+               $entry_index_hash->{$i}{entry_index} = $i;
+               $i++;
+       }
+
+       my $entry_count = scalar(keys %$entry_hash);
+       my $entry_count_length = length($entry_count);
+       my $no_print_entries = 0;
+       
+       # Adjust $max_entry_length to include:
+       # [_]_x._
+       $max_entry_length = $max_entry_length + 6 + $entry_count_length;
+       
+       while (1) {
+               print "\n";
+               if (defined($title)) {
+                       my $title_length = length($title);
+                       my $title_pad_string = '';
+                       if ($max_entry_length > $title_length) {
+                               $title_pad_string = ' ' x ($max_entry_length - 
$title_length);
+                       }
+                       print colored("$title$title_pad_string", 'BOLD 
UNDERLINE');
+                       print "\n";
+               }
+               my $selection_made = 0;
+               #if (!$no_print_entries) {
+                       for my $entry_index (sort {$a<=>$b} keys 
%$entry_index_hash) {
+                               my $entry_display_name = 
$entry_index_hash->{$entry_index}{entry_display_name};
+                               my $selected = 
$entry_index_hash->{$entry_index}{selected};
+                               $selection_made = 1 if $selected;
+                               
+                               my $selection_string = '[';
+                               if ($selected) {
+                                       $selection_string .= '*';
+                               }
+                               else {
+                                       $selection_string .= ' ';
+                               }
+                               $selection_string .= '] ';
+                               
+                               my $entry_index_length = length($entry_index);
+                               my $entry_pad_length = ($entry_count_length - 
$entry_index_length);
+                               my $entry_pad_string = ' ' x $entry_pad_length;
+                               
+                               $selection_string .= "$entry_index. 
$entry_pad_string";
+                               $selection_string .= "$entry_display_name";
+                               if ($selected) {
+                                       print colored($selection_string, 
'BOLD');
+                               }
+                               else {
+                                       print $selection_string;
+                               }
+                               print "\n";
+                       }
+               #}
+               
+               #print "\n[" . join("/", @{$ENV{setup_path}}) . "]\n" if 
defined($ENV{setup_path});
+               my $option_pad_string = ' ' x ($entry_count_length - 1);
+               
+               print "\n";
+               print "[1";
+               print "-$entry_count" if ($entry_count > 1);
+               print "] - toggle selection (mutiple may be entered)\n";
+               print "  $option_pad_string\[a] - select all\n";
+               print "  $option_pad_string\[n] - select none\n";
+               print "  $option_pad_string\[i] - invert selected\n";
+               print "  $option_pad_string\[d] - done making selections\n";
+               print "  $option_pad_string\[c] - cancel\n";
+               print "Make a selection";
+               print " [d]" if $selection_made;
+               print ": ";
+               my $choice = <STDIN>;
+               chomp $choice;
+               
+               $no_print_entries = 0;
+               
+               if ($choice =~ /^c$/i) {
+                       return;
+               }
+               elsif ($choice =~ /^d$/i || $selection_made && 
!length($choice)) {
+                       last;
+               }
+               elsif ($choice =~ /^a$/i) {
+                       for my $entry_index (keys %$entry_index_hash) {
+                               $entry_index_hash->{$entry_index}{selected} = 1;
+                       }
+                       next;
+               }
+               elsif ($choice =~ /^n$/i) {
+                       for my $entry_index (keys %$entry_index_hash) {
+                               $entry_index_hash->{$entry_index}{selected} = 0;
+                       }
+                       next;
+               }
+               elsif ($choice =~ /^i$/i) {
+                       for my $entry_index (keys %$entry_index_hash) {
+                               $entry_index_hash->{$entry_index}{selected} = 
!$entry_index_hash->{$entry_index}{selected};
+                       }
+                       next;
+               }
+               else {
+                       my @selected_entry_indexes = split(/[\s,]+/, $choice);
+                       for my $selected_entry_index (@selected_entry_indexes) {
+                               if ($selected_entry_index !~ /^\d+$/ || 
$selected_entry_index < 1 || $selected_entry_index > $entry_count) {
+                                       print colored("*** Choice ignored: 
$selected_entry_index, it must be an integer between 1 and $entry_count ***", 
'YELLOW ON_RED');
+                                       print "\n";
+                                       $no_print_entries = 1;
+                                       next;
+                               }
+                               else {
+                                       
$entry_index_hash->{$selected_entry_index}{selected} = 
!$entry_index_hash->{$selected_entry_index}{selected};
+                               }
+                       }
+               }
+       }
+       
+       my @selected_keys;
+       for my $entry_index (sort {$a<=>$b} keys %$entry_index_hash) {
+               if ($entry_index_hash->{$entry_index}{selected}) {
+                       push @selected_keys, 
$entry_index_hash->{$entry_index}{key};
+               }
+       }
+       
+       return @selected_keys;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 setup_get_array_choice
 
- Parameters  : @choices, $print_choices
+ Parameters  : @choices
  Returns     : integer
  Description : Lists the elements in the @choices argument as a menu and 
accepts
                user input to select one of the elements. The array index
@@ -10253,7 +10543,7 @@ sub setup_get_hash_choice {
 =cut
 
 sub setup_get_array_choice {
-       my (@choices, $print_choices) = @_;
+       my (@choices) = @_;
        
        if (@choices) {
                notify($ERRORS{'DEBUG'}, 0, "choices argument:\n" . join("\n", 
@choices));
@@ -10264,12 +10554,15 @@ sub setup_get_array_choice {
        }
        
        my $choice_count = scalar(@choices);
+       my $choice_count_length = length($choice_count);
        
        while (1) {
-               if (!defined($print_choices) || $print_choices) {
-                       for (my $i=1; $i<=$choice_count; $i++) {
-                               print "$i. $choices[$i-1]\n";
-                       }
+               for (my $i=1; $i<=$choice_count; $i++) {
+                       my $choice_length = length($i);
+                       my $pad = ($choice_count_length - $choice_length);
+                       print "$i. ";
+                       print " " x $pad;
+                       print "$choices[$i-1]\n";
                }
                
                print "\n[" . join("/", @{$ENV{setup_path}}) . "]\n" if 
defined($ENV{setup_path});
@@ -10313,6 +10606,10 @@ sub setup_get_choice {
                print ", 'c' to cancel): ";
                
                my $choice = <STDIN>;
+               if (!defined($choice)) {
+                       return;
+               }
+               
                chomp $choice;
                
                if ($choice =~ /^c$/i) {


Reply via email to