Author: arkurth
Date: Wed May 6 14:07:44 2015
New Revision: 1677997
URL: http://svn.apache.org/r1677997
Log:
VCL-844
Reworked much of VMware.pm::migrat_vm to overcome issues with VMs which use
dedicated vmdk files - mainly for server requests.
Added optional type argument to OS.pm::find_files and
vSphere_SDK.pm::find_files.
Moved recently created SSH key subroutines from OS.pm to Linux.pm. They do not
work as-is on Windows. Reworked new SSH subroutines in VMware.pm. Most of this
code has been generalized and now exists in Linux.pm.
Added VMware.pm::add_ssh_host_key_to_known_hosts. SSH/SCP would hang on host to
host operations without any warning. This should allow host-host communication
to work without any manual changes.
Added caching to VIM_SSH.pm::_get_vm_id. This subroutine was inefficiently
being called numerous times for basic operations such as register_vm. The
cached VM ID is deleted when a VM is unregistered.
Updated vSphere_SDK.pm::initialize to attempt to load VIExt (vSphere SDK) after
checking if vmprofile username and password are defined. If not defined,
initialize returns immediately. This prevents unnecessary warnings from
appearing in vcld.log.
Added code to vSphere_SDK.pm::initialize to attempt to use the result of
determine_remote_connection_target.
Added vSphere_SDK.pm::get_vm_virtual_disk_file_paths to match VIM_SSH.pm. This
is now used in VMware.pm::delete_vm. Reworked delete_vm. It was not deleting
the directory containing the .vmdk for server reservations under some
circumstances.
Renamed VMware.pm::_get_vmx_file_path_computer_name to
_get_file_path_computer_name. Updated it to attempt to determine a computer
name from any path, not just a .vmx file path. This allows a VM's working
directory path to be passed to it. Updated VMware.pm::is_vmdk_directory_shared
to call _get_file_path_computer_name as an extra security check.
VCL-853
Updated vSphere_SDK.pm::_get_resource_pool_view to return the root pool if a
pool isn't configured in the VM profile and multiple pools are found on this
host.
Modified:
vcl/trunk/managementnode/lib/VCL/Module/OS.pm
vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1677997&r1=1677996&r2=1677997&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Wed May 6 14:07:44 2015
@@ -3319,11 +3319,20 @@ sub copy_file_from {
=head2 find_files
- Parameters : $base_directory_path, $file_pattern, $search_subdirectories
(optional)
+ Parameters : $base_directory_path, $file_pattern, $search_subdirectories
(optional), $type (optional)
Returns : array
Description : Finds files under the base directory and any subdirectories path
matching the file pattern. The search is not case sensitive. An
array is returned containing matching file paths.
+
+ Subdirectories will be searched if the $search_subdirectories
+ argument is true or not supplied.
+
+ If the $type argument is supplied, it must be one of the
+ following:
+ f - Only search for files (default behavior)
+ d - Only search for directories
+ * - Search for files and directories
=cut
@@ -3335,7 +3344,7 @@ sub find_files {
}
# Get the arguments
- my ($base_directory_path, $file_pattern, $search_subdirectories) = @_;
+ my ($base_directory_path, $file_pattern, $search_subdirectories, $type)
= @_;
if (!$base_directory_path || !$file_pattern) {
notify($ERRORS{'WARNING'}, 0, "base directory path and file
pattern arguments were not specified");
return;
@@ -3343,6 +3352,25 @@ sub find_files {
$search_subdirectories = 1 if !defined($search_subdirectories);
+ my $type_string;
+ $type = 'f' unless defined $type;
+ if ($type =~ /^f$/i) {
+ $type = 'f';
+ $type_string = 'files';
+ }
+ elsif ($type =~ /^d$/i) {
+ $type = 'd';
+ $type_string = 'directories';
+ }
+ elsif ($type =~ /^\*$/i) {
+ $type = undef;
+ $type_string = 'files and directories';
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unsupported type argument:
'$type'");
+ return;
+ }
+
# Normalize the arguments
$base_directory_path = normalize_file_path($base_directory_path);
$file_pattern = normalize_file_path($file_pattern);
@@ -3360,17 +3388,17 @@ sub find_files {
COMMAND: for my $find_command (@find_commands) {
# Run the find command
- my $command = "$find_command \"$base_directory_path\" -iname
\"$file_pattern\" -type f";
+ my $command = "$find_command \"$base_directory_path\" -iname
\"$file_pattern\"";
+ $command .= " -type $type" if $type;
if (!$search_subdirectories) {
$command .= " -maxdepth 1";
}
- #notify($ERRORS{'DEBUG'}, 0, "attempting to find files on
$computer_node_name, base directory path: '$base_directory_path', pattern:
$file_pattern, command: $command");
-
+ #notify($ERRORS{'DEBUG'}, 0, "attempting to find $type_string
on $computer_node_name, base directory path: '$base_directory_path', pattern:
$file_pattern, command: $command");
my ($exit_status, $output) = $self->execute($command, 0);
if (!defined($output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to run command to
find files on $computer_node_name, base directory path: '$base_directory_path',
pattern: $file_pattern, command:\n$command");
+ notify($ERRORS{'WARNING'}, 0, "failed to run command to
find $type_string on $computer_node_name, base directory path:
'$base_directory_path', pattern: $file_pattern, command:\n$command");
return;
}
elsif (grep(/find:.*No such file or directory/i, @$output)) {
@@ -3383,7 +3411,7 @@ sub find_files {
next;
}
elsif (grep(/find: /i, @$output)) {
- notify($ERRORS{'WARNING'}, 0, "error occurred
attempting to find files on $computer_node_name\nbase directory path:
$base_directory_path\npattern: $file_pattern\ncommand: $command\noutput:\n" .
join("\n", @$output));
+ notify($ERRORS{'WARNING'}, 0, "error occurred
attempting to find $type_string on $computer_node_name\nbase directory path:
$base_directory_path\npattern: $file_pattern\ncommand: $command\noutput:\n" .
join("\n", @$output));
return;
}
@@ -3394,8 +3422,8 @@ sub find_files {
my $file_count = scalar(@files);
- notify($ERRORS{'DEBUG'}, 0, "files found under
$base_directory_path matching '$file_pattern': $file_count");
- #notify($ERRORS{'DEBUG'}, 0, "files found: $file_count, base
directory: '$base_directory_path', pattern: '$file_pattern'\ncommand:
'$command', output:\n" . join("\n", @$output));
+ notify($ERRORS{'DEBUG'}, 0, "$type_string found under
$base_directory_path matching pattern '$file_pattern': $file_count");
+ #notify($ERRORS{'DEBUG'}, 0, "$type_string found: $file_count,
base directory: '$base_directory_path', pattern: '$file_pattern'\ncommand:
'$command', output:\n" . join("\n", @$output));
return @files;
}
@@ -3450,7 +3478,7 @@ sub get_file_checksum {
=head2 get_tools_file_paths
- Parameters : $pattern
+ Parameters : $pattern (optional)
Returns : boolean
Description : Scans the tools directory on the management node for any files
which are intended for the OS of the reservation image. The OS
@@ -4095,182 +4123,6 @@ sub get_cluster_info_file_path {
return $self->{cluster_info_file_path};
}
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 generate_ssh_key_files
-
- Parameters : $private_key_file_path, $type (optional), $bits (optional),
$comment (optional), $passphrase, $options (optional)
- Returns : boolean
- Description : Calls ssh-keygen to generate an SSH private key file.
-
-=cut
-
-sub generate_ssh_key_files {
- my $self = shift;
- if (ref($self) !~ /VCL::Module::OS/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
- }
-
- my ($private_key_file_path, $type, $bits, $comment, $passphrase,
$options) = @_;
- if (!$private_key_file_path) {
- notify($ERRORS{'WARNING'}, 0, "private key file path argument
was not specified");
- return;
- }
- $type = 'rsa' unless $type;
- $passphrase = '' unless $passphrase;
-
- my $computer_name = $self->data->get_computer_short_name();
-
- # Make sure the file does not already exist
- if ($self->file_exists($private_key_file_path)) {
- notify($ERRORS{'WARNING'}, 0, "failed to generate SSH key, file
already exists on $computer_name: $private_key_file_path");
- return;
- }
-
- my $command = "ssh-keygen -t $type -f \"$private_key_file_path\" -N
\"$passphrase\"";
- $command .= " -b $bits" if defined($bits);
- $comment .= " $options" if defined($options);
-
- if (defined($comment)) {
- $comment =~ s/\\*(["])/\\"$1/g;
- $command .= " -C \"$comment\"";;
- }
-
- my ($exit_status, $output) = $self->mn_os->execute($command);
- if (!defined($output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to execute command to
generate SSH key on $computer_name: $command");
- return;
- }
- elsif ($exit_status ne '0') {
- notify($ERRORS{'WARNING'}, 0, "failed to generate SSH key on
$computer_name, exit status: $exit_status, command:\n$command\noutput:\n" .
join("\n", @$output));
- return;
- }
- else {
- notify($ERRORS{'OK'}, 0, "generated SSH key on $computer_name:
$private_key_file_path, command: $command");
- return 1;
- }
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 generate_ssh_public_key_string
-
- Parameters : $private_key_file_path, $comment (optional)
- Returns : boolean
- Description : Calls ssh-keygen to retrieve the corresponding SSH public key
- from a private key file.
-
-=cut
-
-sub generate_ssh_public_key_string {
- my $self = shift;
- if (ref($self) !~ /VCL::Module::OS/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
- }
-
- my ($private_key_file_path, $comment) = @_;
- if (!$private_key_file_path) {
- notify($ERRORS{'WARNING'}, 0, "private key file path argument
was not specified");
- return;
- }
-
- my $computer_name = $self->data->get_computer_short_name();
-
- # Make sure the private key file exists
- if (!$self->file_exists($private_key_file_path)) {
- notify($ERRORS{'WARNING'}, 0, "unable to generate SSH public
key, private key file does not exist on $computer_name:
$private_key_file_path");
- return;
- }
-
- my $command = "ssh-keygen -y -f \"$private_key_file_path\"";
- my ($exit_status, $output) = $self->mn_os->execute($command);
- if (!defined($output)) {
- notify($ERRORS{'WARNING'}, 0, "failed to execute command to
generate SSH public key string from $private_key_file_path on $computer_name");
- return;
- }
- elsif ($exit_status ne '0') {
- notify($ERRORS{'WARNING'}, 0, "failed to generate SSH public
key string from $private_key_file_path on $computer_name, exit status:
$exit_status, command:\n$command\noutput:\n" . join("\n", @$output));
- return;
- }
-
- my ($ssh_public_key_string) = grep(/^ssh-.*/, @$output);
- if ($ssh_public_key_string) {
- if ($comment) {
- if ($ssh_public_key_string !~ /=/) {
- $ssh_public_key_string .= "==";
- }
- $ssh_public_key_string .= " $comment";
- }
- notify($ERRORS{'OK'}, 0, "generated SSH public key string from
$private_key_file_path on $computer_name: $ssh_public_key_string");
- return $ssh_public_key_string;
- }
- else {
- notify($ERRORS{'OK'}, 0, "failed to generate SSH public key
string from $private_key_file_path on $computer_name, output does not contain a
line beginning with 'ssh-', command:\n$command\noutput:\n" . join("\n",
@$output));
- return;
- }
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 create_ssh_public_key_file
-
- Parameters : $private_key_file_path, $public_key_file_path, $comment
(optional)
- Returns : boolean
- Description : Calls ssh-keygen to retrieve the corresponding SSH public key
- from a private key file and generates a file containing the
- public key.
-
-=cut
-
-sub create_ssh_public_key_file {
- my $self = shift;
- if (ref($self) !~ /VCL::Module::OS/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
- }
-
- my ($private_key_file_path, $public_key_file_path, $comment) = @_;
- if (!$private_key_file_path) {
- notify($ERRORS{'WARNING'}, 0, "private key file path argument
was not specified");
- return;
- }
- if (!$public_key_file_path) {
- notify($ERRORS{'WARNING'}, 0, "public key file path argument
was not specified");
- return;
- }
-
- my $computer_name = $self->data->get_computer_short_name();
-
- # Make sure the private key file exists
- if (!$self->file_exists($private_key_file_path)) {
- notify($ERRORS{'WARNING'}, 0, "failed to generate SSH public
key file, private key file does not exist on $computer_name:
$private_key_file_path");
- return;
- }
-
- # Make sure the public key file does not exist
- if ($self->file_exists($public_key_file_path)) {
- notify($ERRORS{'WARNING'}, 0, "failed to create SSH public key
file, public key file already exists on $computer_name: $public_key_file_path");
- return;
- }
-
- my $public_key_string =
$self->generate_ssh_public_key_string($private_key_file_path, $comment);
- if (!$public_key_string) {
- notify($ERRORS{'WARNING'}, 0, "failed to create SSH public key
file: $public_key_file_path, public key string could not be retrieved from
private key file: $private_key_file_path");
- return;
- }
-
- if ($self->create_text_file($public_key_file_path, $public_key_string))
{
- notify($ERRORS{'DEBUG'}, 0, "created SSH public key file:
$public_key_file_path");
- return 1;
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to create SSH public key
file: $public_key_file_path");
- return;
- }
-}
-
#///////////////////////////////////////////////////////////////////////////
1;
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1677997&r1=1677996&r2=1677997&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Wed May 6 14:07:44 2015
@@ -57,6 +57,7 @@ use VCL::utils;
use English qw( -no_match_vars );
use Net::Netmask;
use File::Basename;
+use File::Temp qw( tempfile mktemp );
##############################################################################
@@ -5174,7 +5175,8 @@ sub command_exists {
my $computer_node_name = $self->data->get_computer_node_name();
- my ($exit_status, $output) = $self->execute("which $shell_command", 0);
+ my $command = "which $shell_command";
+ my ($exit_status, $output) = $self->execute($command, 0);
if (!defined($output)) {
notify($ERRORS{'WARNING'}, 0, "failed to execute command to
determine if the '$shell_command' shell command exists on $computer_node_name");
return;
@@ -5185,7 +5187,7 @@ sub command_exists {
return 1;
}
else {
- notify($ERRORS{'DEBUG'}, 0, "'$shell_command' command does NOT
exist on $computer_node_name");
+ notify($ERRORS{'DEBUG'}, 0, "'$shell_command' command does NOT
exist on $computer_node_name, command: $command\noutput:\n" . join("\n",
@$output));
$self->{command_exists}{$shell_command} = 0;
return 0;
}
@@ -5853,6 +5855,324 @@ sub is_display_manager_running {
}
}
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 generate_ssh_private_key_file
+
+ Parameters : $private_key_file_path, $type (optional), $bits (optional),
$comment (optional), $passphrase, $options (optional)
+ Returns : boolean
+ Description : Calls ssh-keygen or dropbearkey to generate an SSH private key
+ file.
+
+=cut
+
+sub generate_ssh_private_key_file {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
+
+ my ($private_key_file_path, $type, $bits, $comment, $passphrase,
$options) = @_;
+ if (!$private_key_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "private key file path argument
was not specified");
+ return;
+ }
+ $type = 'rsa' unless $type;
+ $passphrase = '' unless $passphrase;
+
+ if (defined($comment)) {
+ $comment =~ s/\\*(["])/\\"$1/g;
+ }
+
+ my $computer_name = $self->data->get_computer_short_name();
+
+ # Make sure the file does not already exist
+ if ($self->file_exists($private_key_file_path)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to generate SSH key, file
already exists on $computer_name: $private_key_file_path");
+ return;
+ }
+
+ if ($self->command_exists('ssh-keygen')) {
+ if
($self->_generate_ssh_private_key_file_helper($private_key_file_path, $type,
$bits, $comment, $passphrase, $options, 'ssh-keygen')) {
+ return 1;
+ }
+ }
+ if ($self->command_exists('dropbearkey')) {
+ if
($self->_generate_ssh_private_key_file_helper($private_key_file_path, $type,
$bits, $comment, $passphrase, $options, 'dropbearkey')) {
+ return 1;
+ }
+ }
+
+ if (ref($self) =~ /ManagementNode/) {
+ notify($ERRORS{'WARNING'}, 0, "failed to generate SSH key on
$computer_name: $private_key_file_path");
+ return;
+ }
+
+ my $mn_temp_file_path = mktemp($computer_name . 'XXXXXX');
+ notify($ERRORS{'DEBUG'}, 0, "attempting to create SSH private key file
on this management node ($mn_temp_file_path) and copy it to $computer_name
($private_key_file_path)");
+ my $result =
$self->mn_os->generate_ssh_private_key_file($mn_temp_file_path, $type, $bits,
$comment, $passphrase, $options);
+ if (!$result) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create SSH private key
file on this management node and copy it to $private_key_file_path on
$computer_name");
+ $self->mn_os->delete_file($mn_temp_file_path);
+ return;
+ }
+
+ if (!$self->copy_file_to($mn_temp_file_path, $private_key_file_path)) {
+ notify($ERRORS{'WARNING'}, 0, "create SSH private key file on
this management node but failed to copy it to $private_key_file_path on
$computer_name");
+ $self->mn_os->delete_file($mn_temp_file_path);
+ return;
+ }
+ else {
+ $self->mn_os->delete_file($mn_temp_file_path);
+ notify($ERRORS{'OK'}, 0, "created SSH private key file on this
management and copied it to $private_key_file_path on $computer_name");
+ return 1;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _generate_ssh_private_key_file_helper
+
+ Parameters : $private_key_file_path, $type, $bits, $comment, $passphrase,
$options, $utility
+ Returns : boolean
+ Description : Calls ssh-keygen to generate an SSH private key file.
+
+=cut
+
+sub _generate_ssh_private_key_file_helper {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
+
+ my ($private_key_file_path, $type, $bits, $comment, $passphrase,
$options, $utility) = @_;
+ if (!defined($utility)) {
+ notify($ERRORS{'WARNING'}, 0, "utility argument was not
supplied");
+ return;
+ }
+
+ my $computer_name = $self->data->get_computer_short_name();
+
+ my $command;
+ if ($utility eq 'ssh-keygen') {
+ $command = "ssh-keygen -t $type -f \"$private_key_file_path\"
-N \"$passphrase\"";
+ $command .= " -b $bits" if (defined($bits) && length($bits));
+ $comment .= " $options" if (defined($options) &&
length($options));
+ $command .= " -C \"$comment\"" if (defined($comment) &&
length($comment));
+ }
+ elsif ($utility eq 'dropbearkey') {
+ $command = "dropbearkey -t $type -f \"$private_key_file_path\"";
+ $command .= " -s $bits" if (defined($bits) && length($bits));
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "invalid utility argument
provided: '$utility', it must either be 'ssh-keygen' or 'dropbearkey'");
+ return;
+ }
+
+ my ($exit_status, $output) = $self->execute($command);
+ if (!defined($output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute command to
generate SSH key using $utility on $computer_name: $command");
+ return;
+ }
+ elsif ($exit_status ne '0') {
+ notify($ERRORS{'WARNING'}, 0, "failed to generate SSH key using
$utility on $computer_name, exit status: $exit_status,
command:\n$command\noutput:\n" . join("\n", @$output));
+ return;
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "generated SSH key using $utility on
$computer_name: $private_key_file_path, command: $command");
+ return 1;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 generate_ssh_public_key_file
+
+ Parameters : $private_key_file_path, $public_key_file_path, $comment
(optional)
+ Returns : boolean
+ Description : Calls ssh-keygen to retrieve the corresponding SSH public key
+ from a private key file and generates a file containing the
+ public key.
+
+=cut
+
+sub generate_ssh_public_key_file {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
+
+ my ($private_key_file_path, $public_key_file_path, $comment) = @_;
+ if (!$private_key_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "private key file path argument
was not specified");
+ return;
+ }
+ if (!$public_key_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "public key file path argument
was not specified");
+ return;
+ }
+
+ my $computer_name = $self->data->get_computer_short_name();
+
+ # Make sure the private key file exists
+ if (!$self->file_exists($private_key_file_path)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to generate SSH public
key file, private key file does not exist on $computer_name:
$private_key_file_path");
+ return;
+ }
+
+ # Make sure the public key file does not exist
+ if ($self->file_exists($public_key_file_path)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create SSH public key
file, public key file already exists on $computer_name: $public_key_file_path");
+ return;
+ }
+
+ my $public_key_string =
$self->get_ssh_public_key_string($private_key_file_path, $comment);
+ if (!$public_key_string) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create SSH public key
file: $public_key_file_path, public key string could not be retrieved from
private key file: $private_key_file_path");
+ return;
+ }
+
+ if ($self->create_text_file($public_key_file_path, $public_key_string))
{
+ notify($ERRORS{'DEBUG'}, 0, "created SSH public key file:
$public_key_file_path");
+ return 1;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to create SSH public key
file: $public_key_file_path");
+ return;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_ssh_public_key_string
+
+ Parameters : $private_key_file_path, $comment (optional)
+ Returns : boolean
+ Description : Extracts the SSH public key from a private key file.
+
+=cut
+
+sub get_ssh_public_key_string {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
+
+ my ($private_key_file_path, $comment) = @_;
+ if (!$private_key_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "private key file path argument
was not specified");
+ return;
+ }
+
+ my $computer_name = $self->data->get_computer_short_name();
+
+ # Make sure the private key file exists
+ if (!$self->file_exists($private_key_file_path)) {
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve SSH public
key, private key file does not exist on $computer_name:
$private_key_file_path");
+ return;
+ }
+
+ my $public_key_string;
+ if ($self->command_exists('ssh-keygen')) {
+ $public_key_string =
$self->_get_ssh_public_key_string_helper($private_key_file_path, 'ssh-keygen');
+ }
+ if (!$public_key_string && $self->command_exists('dropbearkey')) {
+ $public_key_string =
$self->_get_ssh_public_key_string_helper($private_key_file_path, 'dropbearkey');
+ }
+ if ($public_key_string) {
+ if ($comment) {
+ $public_key_string =~ s/(ssh-[^\s]+\s[^\s=]+).*$/$1==
$comment/g;
+ }
+ return $public_key_string;
+ }
+
+ if (ref($self) =~ /ManagementNode/) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve SSH public
key from private key file on $computer_name: $private_key_file_path");
+ return;
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "attempting to copy SSH private key
file $private_key_file_path from $computer_name and extract the public key on
this management node");
+ }
+
+ my ($mn_temp_file_handle, $mn_temp_file_path) = tempfile(SUFFIX =>
'.key', UNLINK => 1);
+ if (!$self->copy_file_from($private_key_file_path, $mn_temp_file_path))
{
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve SSH public
key from private key file on $computer_name: $private_key_file_path, failed to
copy temp file to management node");
+ $self->mn_os->delete_file($mn_temp_file_path);
+ return;
+ }
+ $self->mn_os->set_file_permissions($mn_temp_file_path, '0400');
+
+ $public_key_string =
$self->mn_os->get_ssh_public_key_string($mn_temp_file_path, $comment);
+ $self->mn_os->delete_file($mn_temp_file_path);
+ return $public_key_string;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 _get_ssh_public_key_string_helper
+
+ Parameters : $private_key_file_path, $utility
+ Returns : boolean
+ Description :
+
+=cut
+
+sub _get_ssh_public_key_string_helper {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
+
+ my ($private_key_file_path, $utility) = @_;
+ if (!$private_key_file_path) {
+ notify($ERRORS{'WARNING'}, 0, "private key file path argument
was not specified");
+ return;
+ }
+ elsif (!$utility) {
+ notify($ERRORS{'WARNING'}, 0, "utility argument (ssh-keygen or
dropbearkey) was not specified");
+ return;
+ }
+
+ my $computer_name = $self->data->get_computer_short_name();
+
+ my $command;
+ if ($utility eq 'ssh-keygen') {
+ $command = "ssh-keygen -y -f \"$private_key_file_path\"";
+ }
+ elsif ($utility eq 'dropbearkey') {
+ $command = "/bin/dropbearkey -f \"$private_key_file_path\" -y";
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "invalid utility argument
provided: '$utility', it must either be 'ssh-keygen' or 'dropbearkey'");
+ return;
+ }
+
+ my ($exit_status, $output) = $self->execute($command);
+ if (!defined($output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute command to
retrieve SSH public key string using $utility from $private_key_file_path on
$computer_name");
+ return;
+ }
+ elsif ($exit_status ne 0) {
+ notify($ERRORS{'WARNING'}, 0, "failed to retrieve SSH public
key string using $utility from $private_key_file_path on $computer_name, exit
status: $exit_status, command:\n$command\noutput:\n" . join("\n", @$output));
+ return;
+ }
+
+ my ($ssh_public_key_string) = grep(/^ssh-.*/, @$output);
+ if ($ssh_public_key_string) {
+ notify($ERRORS{'OK'}, 0, "retrieved SSH public key string using
$utility from $private_key_file_path on
$computer_name:\n$ssh_public_key_string");
+ return $ssh_public_key_string;
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "failed to retrieved SSH public key
string using $utility from $private_key_file_path on $computer_name, output
does not contain a line beginning with 'ssh-', command:\n$command\noutput:\n" .
join("\n", @$output));
+ return;
+ }
+}
+
##/////////////////////////////////////////////////////////////////////////////
1;
__END__
Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
URL:
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm?rev=1677997&r1=1677996&r2=1677997&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
(original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm Wed
May 6 14:07:44 2015
@@ -532,6 +532,8 @@ sub _get_vm_id {
return;
}
+ return $self->{vm_id}{$vmx_file_path} if $self->{vm_id}{$vmx_file_path};
+
# Get the VM IDs and vmx paths
my $vm_list = $self->_get_vm_list();
if (!defined($vm_list)) {
@@ -540,7 +542,10 @@ sub _get_vm_id {
}
for my $vm_id (keys %$vm_list) {
- return $vm_id if ($vm_list->{$vm_id} && $vmx_file_path eq
$vm_list->{$vm_id});
+ if ($vm_list->{$vm_id} && $vmx_file_path eq $vm_list->{$vm_id})
{
+ $self->{vm_id}{$vmx_file_path} = $vm_id;
+ return $vm_id;
+ }
}
notify($ERRORS{'WARNING'}, 0, "unable to determine VM ID, vmx file is
not registered: $vmx_file_path, registered VMs:\n" . format_data($vm_list));
@@ -1484,6 +1489,10 @@ sub vm_unregister {
my $vim_cmd_arguments = "vmsvc/unregister $vm_id";
my ($exit_status, $output) = $self->_run_vim_cmd($vim_cmd_arguments);
+
+ # Delete cached .vmx - VM ID mapping if previously retrieved
+ delete $self->{vm_id}{$vmx_file_path};
+
return if !$output;
# Expected output if the VM is not registered:
@@ -2845,7 +2854,7 @@ sub _get_vm_virtual_disk_file_layout {
my $virtual_disk_file_layout = $self->_parse_vim_cmd_output($output);
if ($virtual_disk_file_layout) {
- notify($ERRORS{'DEBUG'}, 0, "retrieved virtual disk file layout
for VM $vm_id ($vmx_file_path)\n" . format_data($virtual_disk_file_layout));
+ #notify($ERRORS{'DEBUG'}, 0, "retrieved virtual disk file
layout for VM $vm_id ($vmx_file_path)\n" .
format_data($virtual_disk_file_layout));
return $virtual_disk_file_layout;
}
else {
@@ -2859,7 +2868,7 @@ sub _get_vm_virtual_disk_file_layout {
=head2 get_vm_virtual_disk_file_paths
Parameters : $vmx_file_path
- Returns : array reference
+ Returns : array
Description : Retrieves a VM's virtual disk file layout and returns an array
reference. Each top-level array element represent entire virtual
disk and contains an array reference containing the virtual