in managementnode/lib/VCL/Module/OS.pm [3174:3300]
sub execute {
my @original_arguments = @_;
my ($argument) = @_;
my ($computer_name, $command, $display_output, $timeout_seconds, $max_attempts, $port, $user, $password, $identity_key, $ignore_error);
my $self;
# Check if this subroutine was called as an object method
if (ref($argument) && ref($argument) =~ /VCL::Module/) {
# Subroutine was called as an object method ($self->execute)
$self = shift;
($argument) = @_;
#notify($ERRORS{'DEBUG'}, 0, "called as an object method: " . ref($self));
# Get the computer name from the reservation data
$computer_name = $self->data->get_computer_node_name();
if (!$computer_name) {
notify($ERRORS{'WARNING'}, 0, "called as an object method, failed to retrieve computer name from reservation data");
return;
}
#notify($ERRORS{'DEBUG'}, 0, "retrieved computer name from reservation data: $computer_name");
}
my $no_persistent_connection = 0;
# Check the argument type
if (ref($argument)) {
if (ref($argument) eq 'HASH') {
#notify($ERRORS{'DEBUG'}, 0, "first argument is a hash reference:\n" . format_data($argument));
$computer_name = $argument->{node} if (!$computer_name);
$command = $argument->{command};
$display_output = $argument->{display_output};
$timeout_seconds = $argument->{timeout_seconds};
$max_attempts = $argument->{max_attempts};
$port = $argument->{port};
$user = $argument->{user};
$password = $argument->{password};
$identity_key = $argument->{identity_key};
$ignore_error = $argument->{ignore_error};
$no_persistent_connection = $argument->{no_persistent_connection};
}
else {
notify($ERRORS{'WARNING'}, 0, "invalid argument reference type passed: " . ref($argument) . ", if a reference is passed as the argument it may only be a hash or VCL::Module reference");
return;
}
}
else {
# Argument is not a reference, computer name must be the first argument unless this subroutine was called as an object method
# If called as an object method, $computer_name will already be populated
if (!$computer_name) {
$computer_name = shift;
#notify($ERRORS{'DEBUG'}, 0, "first argument is a scalar, should be the computer name: $computer_name, remaining arguments:\n" . format_data(\@_));
}
else {
#notify($ERRORS{'DEBUG'}, 0, "first argument should be the command:\n" . format_data(\@_));
}
# Get the remaining arguments
($command, $display_output, $timeout_seconds, $max_attempts, $port, $user, $password, $identity_key, $ignore_error) = @_;
}
if (!$computer_name) {
notify($ERRORS{'WARNING'}, 0, "computer name could not be determined");
return;
}
if (!$command) {
notify($ERRORS{'WARNING'}, 0, "command argument was not specified");
return;
}
# TESTING: use the new subroutine if $ENV{execute_new} is set and the command isn't one that's known to fail with the new subroutine
if ($ENV->{execute_new} && !$no_persistent_connection) {
my @excluded_commands = $command =~ /(vmkfstools|qemu-img|Convert-VHD|scp|shutdown|reboot)/i;
if (@excluded_commands) {
notify($ERRORS{'DEBUG'}, 0, "not using execute_new, command: $command\nexcluded commands matched:\n" . join("\n", @excluded_commands));
}
else {
return execute_new(@original_arguments);
}
}
# If 'ssh_user' key is set in this object, use it
# This allows OS modules to specify the username to use
if ($self && $self->{ssh_user}) {
#notify($ERRORS{'DEBUG'}, 0, "\$self->{ssh_user} is defined: $self->{ssh_user}");
$user = $self->{ssh_user};
}
elsif (!$port) {
$user = 'root';
}
# If 'ssh_port' key is set in this object, use it
# This allows OS modules to specify the port to use
if ($self && $self->{ssh_port}) {
#notify($ERRORS{'DEBUG'}, 0, "\$self->{ssh_port} is defined: $self->{ssh_port}");
$port = $self->{ssh_port};
}
elsif (!$port) {
$port = 22;
}
my $arguments = {
node => $computer_name,
command => $command,
identity_paths => $identity_key,
user => $user,
port => $port,
output_level => $display_output,
max_attempts => $max_attempts,
timeout_seconds => $timeout_seconds,
};
# Run the command via SSH
my ($exit_status, $output) = run_ssh_command($arguments);
if (defined($exit_status) && defined($output)) {
if ($display_output) {
notify($ERRORS{'DEBUG'}, 0, "executed command: '$command', exit status: $exit_status, output:\n" . join("\n", @$output));
}
return ($exit_status, $output);
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to run command on $computer_name: $command") if $display_output;
return;
}
}