You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2015/04/22 21:59:25 UTC

svn commit: r1675483 [3/3] - in /vcl/trunk/managementnode/lib/VCL: DataStructure.pm Module.pm Module/Provisioning/VMware/VIM_SSH.pm Module/Provisioning/VMware/VMware.pm utils.pm

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) {