Author: arkurth
Date: Wed Oct 5 18:22:54 2011
New Revision: 1179363
URL: http://svn.apache.org/viewvc?rev=1179363&view=rev
Log:
VCL-30
Updated SQL query utils.pm::get_connect_methods subroutine in utils.pm and
renamed it to get_connect_method_info to match other subroutines. Updated
OS.pm::process_connect_methods to handle the results returned by
get_connect_method_info.
Updated Linux.pm::enable_firewall_port to accept the same arguments and scope
format as Windows.pm::enable_firewall_port.
VCL-503
Added OS.pm::execute_new. This isn't currently called by anything and will
eventually replace OS.pm::execute. It uses Net::SSH::Expect to keep an SSH
connection open and then commands are issued to this connection. This speeds
things up. There are commented out "return...execute_new" lines at the
beginning of OS.pm::execute and in utils.pm::run_ssh_command. Uncommenting
these lines will cause the new subroutine to be used.
Other
Added OS type information to the hash returned by get_image_info. Added
OS.pm::get_management_node_identity_key_paths subroutine so that the
comma-separated value is parsed consistently.
Modified:
incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
Modified: incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1179363&r1=1179362&r2=1179363&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm Wed Oct 5
18:22:54 2011
@@ -2319,6 +2319,28 @@ sub get_management_node_public_dns_serve
#/////////////////////////////////////////////////////////////////////////////
+=head2 get_management_node_identity_key_paths
+
+ Parameters : None
+ Returns : If successful: array containing paths to SSH identity keys
+ If failed: false
+ Description : Returns an array containing the paths to SSH identity keys
+ configured for the management node.
+
+=cut
+
+sub get_management_node_identity_key_paths {
+ my $keys_string = $ENV{management_node_info}{keys};
+ if (!$keys_string) {
+ notify($ERRORS{'WARNING'}, 0, "no identity key paths are
configured for the management node");
+ return ();
+ }
+
+ return split(/\s*[,;]\s*/, $keys_string);
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 get_computer_state_name
Parameters : computer name (optional
Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1179363&r1=1179362&r2=1179363&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Wed Oct 5 18:22:54
2011
@@ -52,6 +52,8 @@ use strict;
use warnings;
use diagnostics;
use English '-no_match_vars';
+use Net::SSH::Expect;
+
use VCL::utils;
##############################################################################
@@ -547,7 +549,7 @@ sub wait_for_response {
my $end_time = time();
my $duration = ($end_time - $start_time);
- #insertloadlog($reservation_id, $computer_id, "osrespond",
"$computer_node_name is responding to SSH after $duration seconds");
+ # insertloadlog($reservation_id, $computer_id, "osrespond",
"$computer_node_name is responding to SSH after $duration seconds");
notify($ERRORS{'OK'}, 0, "$computer_node_name is responding to SSH
after $duration seconds");
return 1;
}
@@ -1577,6 +1579,7 @@ sub create_text_file {
=cut
sub execute {
+#return execute_new(@_);
my $self = shift;
unless (ref($self) && $self->isa('VCL::Module')) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called
as an object method");
@@ -1615,6 +1618,177 @@ sub execute {
#/////////////////////////////////////////////////////////////////////////////
+=head2 execute_new
+
+ Parameters : $computer_name (conditional), $command, $display_output,
$timeout_seconds, $max_attempts, $port, $user, $password
+ Returns : array ($exit_status, $output)
+ Description : Executes a command on the computer via SSH.
+
+=cut
+
+sub execute_new {
+ my $argument = shift;
+ my ($computer_name, $command, $display_output, $timeout_seconds,
$max_attempts, $port, $user, $password);
+
+ if (!ref($argument) || $argument->isa('VCL::Module')) {
+ if ($argument->isa('VCL::Module')) {
+ $computer_name =
$argument->data->get_computer_node_name();
+ }
+ else {
+ $computer_name = $argument;
+ }
+ ($command, $display_output, $timeout_seconds, $max_attempts,
$port, $user, $password) = @_;
+ }
+ else {
+ $computer_name = $argument->{node};
+ $command = $argument->{command};
+ $display_output = $argument->{display_output};
+ $timeout_seconds = $argument->{timeout};
+ $max_attempts = $argument->{max_attempts};
+ $port = $argument->{port};
+ $user = $argument->{user};
+ $password = $argument->{password};
+ }
+
+ 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;
+ }
+
+ $display_output = 0 unless $display_output;
+ $timeout_seconds = 60 unless $timeout_seconds;
+ $max_attempts = 1 unless $max_attempts;
+ $port = 22 unless $port;
+ $user = 'root' unless $user;
+
+ # Override the die handler
+ local $SIG{__DIE__} = sub{};
+
+ my $ssh;
+ my $attempt = 0;
+ my $attempt_delay = 5;
+ my $attempt_string = '';
+
+ ATTEMPT: while ($attempt < $max_attempts) {
+ if ($attempt > 0) {
+ $attempt_string = "attempt $attempt/$max_attempts: ";
+ $ssh->close() if $ssh;
+
+ notify($ERRORS{'DEBUG'}, 0, $attempt_string . "sleeping
for $attempt_delay seconds before making next attempt");
+ sleep $attempt_delay;
+ }
+
+ $attempt++;
+ $attempt_string = "attempt $attempt/$max_attempts: " if
($attempt > 1);
+
+
+ if (!$ENV{net_ssh_expect}{$computer_name}) {
+ eval {
+ $ssh = Net::SSH::Expect->new(
+ host => $computer_name,
+ user => $user,
+ port => $port,
+ raw_pty => 1,
+ no_terminal => 1,
+ ssh_option => '-o
StrictHostKeyChecking=no',
+ timeout => 3,
+ );
+
+ if ($ssh) {
+ notify($ERRORS{'DEBUG'}, 0, "created "
. ref($ssh) . " object to control $computer_name");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed
to create Net::SSH::Expect object to control $computer_name, $!");
+ next ATTEMPT;
+ }
+
+ if ($ssh->run_ssh()) {
+ notify($ERRORS{'DEBUG'}, 0, ref($ssh) .
" object forked SSH process to control $computer_name");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, ref($ssh)
. " object failed to fork SSH process to control $computer_name, $!");
+ next ATTEMPT;
+ }
+
+ #$ssh->exec("stty -echo");
+ #$ssh->exec("stty raw -echo");
+
+ # Set the timeout counter behaviour:
+ # If true, sets the timeout to "inactivity
timeout"
+ # If false sets it to "absolute timeout"
+ #$ssh->restart_timeout_upon_receive(1);
+ };
+ if ($EVAL_ERROR) {
+ if ($EVAL_ERROR =~ /^(\w+) at \//) {
+ notify($ERRORS{'DEBUG'}, 0,
$attempt_string . "$1 error occurred initializing Net::SSH::Expect object for
$computer_name");
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0,
$attempt_string . "error occurred initializing Net::SSH::Expect object for
$computer_name");
+ }
+ next ATTEMPT;
+ }
+ }
+ else {
+ $ssh = $ENV{net_ssh_expect}{$computer_name};
+
+ # Delete the stored SSH object to make sure it isn't
saved if the command fails
+ # The SSH object will be added back to %ENV if the
command completes successfully
+ delete $ENV{net_ssh_expect}{$computer_name};
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, $attempt_string . "executing
command on $computer_name: '$command', timeout: $timeout_seconds seconds") if
($display_output);
+ $ssh->send($command . ' 2>&1 ; echo exitstatus:$?');
+
+ my $ssh_wait_status;
+ eval {
+ $ssh_wait_status = $ssh->waitfor('exitstatus:[0-9]+',
$timeout_seconds);
+ };
+
+ if ($EVAL_ERROR) {
+ if ($EVAL_ERROR =~ /^(\w+) at \//) {
+ notify($ERRORS{'DEBUG'}, 0, $attempt_string .
"$1 error occurred executing command on $computer_name: '$command'");
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, $attempt_string .
"error occurred executing command on $computer_name: '$command'\nerror:
$EVAL_ERROR");
+ }
+ next ATTEMPT;
+ }
+ elsif (!$ssh_wait_status) {
+ notify($ERRORS{'DEBUG'}, 0, $attempt_string . "command
timed out after $timeout_seconds seconds on $computer_name: '$command'");
+ next ATTEMPT;
+ }
+
+ my $output = $ssh->before() || '';
+ $output =~ s/(^\s+)|(\s+$)//g;
+
+ my $exit_status_string = $ssh->match() || '';
+ my ($exit_status) = $exit_status_string =~ /(\d)+/;
+ if (!$exit_status_string || !defined($exit_status)) {
+ my $all_output = $ssh->read_all() || '';
+ notify($ERRORS{'WARNING'}, 0, $attempt_string . "failed
to determine exit status from string: '$exit_status_string',
output:\n$all_output");
+ next ATTEMPT;
+ }
+
+ my @output_lines = split(/[\r\n]+/, $output);
+
+ notify($ERRORS{'OK'}, 0, "executed command on $computer_name:
'$command', exit status: $exit_status, output:\n$output") if ($display_output);
+
+ # Save the SSH object for later use
+ $ENV{net_ssh_expect}{$computer_name} = $ssh;
+
+ return ($exit_status, \@output_lines);
+ }
+
+ notify($ERRORS{'WARNING'}, 0, $attempt_string . "failed to execute
command on $computer_name: '$command'") if ($display_output);
+ return;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
=head2 get_os_type
Parameters : None
@@ -1661,43 +1835,51 @@ sub get_os_type {
#/////////////////////////////////////////////////////////////////////////////
+=head2 manage_server_access
+
+ Parameters : None
+ Returns :
+ Description :
+
+=cut
+
sub manage_server_access {
my $self = shift;
- if (ref($self) !~ /VCL::Module/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
- }
-
- my $computer_node_name = $self->data->get_computer_node_name() ||
return;
- my $reservation_id = $self->data->get_reservation_id();
- my $server_request_id = $self->data->get_server_request_id();
- my $server_request_admingroupid =
$self->data->get_server_request_admingroupid();
- my $server_request_logingroupid =
$self->data->get_server_request_logingroupid();
-
- #Build list of users.
- #If in admin group set admin flag
- #If in both login and admin group, only use admin setting
- #Check if user is in reserverationaccounts table, add user if needed
- #Check if user exists on server, add if needed
+ if (ref($self) !~ /VCL::Module/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
+
+ my $computer_node_name = $self->data->get_computer_node_name()
|| return;
+ my $reservation_id = $self->data->get_reservation_id();
+ my $server_request_id = $self->data->get_server_request_id();
+ my $server_request_admingroupid =
$self->data->get_server_request_admingroupid();
+ my $server_request_logingroupid =
$self->data->get_server_request_logingroupid();
+
+ # Build list of users.
+ # If in admin group set admin flag
+ # If in both login and admin group, only use admin setting
+ # Check if user is in reserverationaccounts table, add user if needed
+ # Check if user exists on server, add if needed
my @userlist_admin;
my @userlist_login;
my %user_hash;
my $ssh_allow_list;
- if ( $server_request_admingroupid ) {
+ if ($server_request_admingroupid) {
@userlist_admin =
getusergroupmembers($server_request_admingroupid);
}
- if ( $server_request_logingroupid ) {
+ if ($server_request_logingroupid) {
@userlist_login =
getusergroupmembers($server_request_logingroupid);
}
notify($ERRORS{'OK'}, 0, " admin list= @userlist_admin");
notify($ERRORS{'OK'}, 0, " login list= @userlist_login");
-
- if ( scalar @userlist_admin > 0 ) {
+
+ if (scalar @userlist_admin > 0) {
foreach my $str (@userlist_admin) {
my ($username,$uid,$vcl_user_id) = split(/:/, $str);
$user_hash{$uid}{"username"} = $username;
@@ -1707,7 +1889,7 @@ sub manage_server_access {
notify($ERRORS{'OK'}, 0, "adding admin $uid for
$username ");
}
}
- if ( scalar @userlist_login > 0 ) {
+ if (scalar @userlist_login > 0) {
foreach my $str (@userlist_login) {
notify($ERRORS{'OK'}, 0, "admin str= $str");
my ($username, $uid,$vcl_user_id) = split(/:/, $str);
@@ -1724,18 +1906,18 @@ sub manage_server_access {
}
}
- #Collect users in reservationaccounts table
+ # Collect users in reservationaccounts table
my %res_accounts = get_reservation_accounts($reservation_id);
my $not_standalone_list = "";
my $standalone = 0;
if(defined($ENV{management_node_info}{NOT_STANDALONE}) &&
$ENV{management_node_info}{NOT_STANDALONE}){
- $not_standalone_list =
$ENV{management_node_info}{NOT_STANDALONE};
- }
+ $not_standalone_list =
$ENV{management_node_info}{NOT_STANDALONE};
+ }
foreach my $userid (sort keys %user_hash) {
next if (!($userid));
if(!exists($res_accounts{$userid})){
- #check affiliation
+ # check affiliation
notify($ERRORS{'OK'}, 0, "checking affiliation for
$userid");
my $affiliation_name =
get_user_affiliation($user_hash{$userid}{vcl_user_id});
if(defined($affiliation_name)) {
@@ -1744,7 +1926,7 @@ sub manage_server_access {
$standalone = 1;
}
}
- #IF standalone - generate password
+ # IF standalone - generate password
if($standalone) {
$user_hash{$userid}{"passwd"} = getpw();
}
@@ -1792,10 +1974,9 @@ sub manage_server_access {
=head2 process_connect_methods
- Parameters : None
- Returns : If successful: 1
- If failed: 0
- Description : starts and open port for available connection methods
+ Parameters : none
+ Returns : boolean
+ Description : Processes the connect methods configured for the image revision.
=cut
@@ -1806,84 +1987,111 @@ sub process_connect_methods {
return;
}
- my $mode = shift;
- if (!$mode) {
- notify($ERRORS{'OK'}, 0, "Mode variable not passed in as an
argument");
- return 0;
- }
-
- my $computer_node_name = $self->data->get_computer_node_name();
- my $connect_methods = $self->data->get_connect_methods();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $imagerevision_id = $self->data->get_imagerevision_id();
- foreach my $CMid (sort keys %{$connect_methods} ) {
- notify($ERRORS{'OK'}, 0, "id= $$connect_methods{$CMid}{id}")
if(defined ($$connect_methods{$CMid}{id}) );
- notify($ERRORS{'OK'}, 0, "description=
$$connect_methods{$CMid}{description}") if(defined
($$connect_methods{$CMid}{description}) );
- notify($ERRORS{'OK'}, 0, "port==
$$connect_methods{$CMid}{port}") if(defined ($$connect_methods{$CMid}{port}) );
- notify($ERRORS{'OK'}, 0, "servicename=
$$connect_methods{$CMid}{servicename}") if(defined
($$connect_methods{$CMid}{servicename}) );
- notify($ERRORS{'OK'}, 0, "startupscript=
$$connect_methods{$CMid}{startupscript}") if(defined
($$connect_methods{$CMid}{startupscript}) );
- notify($ERRORS{'OK'}, 0, "autoprov=
$$connect_methods{$CMid}{autoprovisioned}") if(defined
($$connect_methods{$CMid}{autoprovisioned}) );
- my $description = $$connect_methods{$CMid}{description};
- my $port = $$connect_methods{$CMid}{port};
-
- my $service_started = 0;
- notify($ERRORS{'OK'}, 0, "checking if servicename exists ");
- if( defined ($$connect_methods{$CMid}{servicename}) &&
$$connect_methods{$CMid}{servicename} ) {
- # does service exist
- my $servicename = $$connect_methods{$CMid}{servicename};
- notify($ERRORS{'OK'}, 0, "trying to start servicename
$servicename ");
- if( $self->can("service_exists")) {
- if($self->service_exists($servicename)) {
- if( $self->can("start_service")) {
- if(
$self->start_service($servicename) ) {
- notify($ERRORS{'OK'},
0, "Service $servicename started");
- $service_started = 1;
- }
- else {
-
notify($ERRORS{'WARNING'}, 0, "Service $servicename failed to start");
- }
+ # Retrieve the connect method info hash
+ my $connect_method_info = get_connect_method_info($imagerevision_id);
+ if (!$connect_method_info) {
+ notify($ERRORS{'WARNING'}, 0, "no connect methods are
configured for image revision $imagerevision_id");
+ }
+
+ my $remote_ip = $self->data->get_reservation_remote_ip();
+ if (!$remote_ip) {
+ notify($ERRORS{'WARNING'}, 0, "reservation remote IP address is
not defined, connect methods will be available from any IP address");
+ $remote_ip = '0.0.0.0/0.0.0.0';
+ }
+
+ CONNECT_METHOD: for my $connect_method_id (sort keys
%{$connect_method_info} ) {
+ notify($ERRORS{'DEBUG'}, 0, "processing connect method:\n" .
format_data($connect_method_info->{$connect_method_id}));
+
+ my $name =
$connect_method_info->{$connect_method_id}{name};
+ my $description =
$connect_method_info->{$connect_method_id}{description};
+ my $protocol =
$connect_method_info->{$connect_method_id}{protocol} || 'TCP';
+ my $port =
$connect_method_info->{$connect_method_id}{port};
+ my $service_name =
$connect_method_info->{$connect_method_id}{servicename};
+ my $startup_script =
$connect_method_info->{$connect_method_id}{startupscript};
+ my $install_script =
$connect_method_info->{$connect_method_id}{installscript};
+ my $disabled =
$connect_method_info->{$connect_method_id}{connectmethodmap}{disabled};
+
+ if ($disabled) {
+ # TODO: Add code to disable the service, close the
firewall port, etc
+ notify($ERRORS{'OK'}, 0, "skipping '$name' connect
method configuration, it should be disabled on $computer_node_name");
+ }
+ else {
+ # Attempt to start and configure the connect method
+ my $service_started = 0;
+
+ # Attempt to start the service if the service name has
been defined for the connect method
+ if ($service_name) {
+ # Check if service exists
+ notify($ERRORS{'DEBUG'}, 0, "checking if
'$service_name' service exists for '$name' connect method on
$computer_node_name");
+ if ($self->service_exists($service_name)) {
+ notify($ERRORS{'DEBUG'}, 0, "attempting
to start '$service_name' service for '$name' connect method on
$computer_node_name");
+ if
($self->start_service($service_name)) {
+ notify($ERRORS{'OK'}, 0,
"'$service_name' started on $computer_node_name");
+ $service_started = 1;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0,
"failed to start '$service_name' service for '$name' connect method on
$computer_node_name");
}
}
+ #elsif ($install_script) {
+ # notify($ERRORS{'DEBUG'}, 0,
"'$service_name' service for '$name' connect method does not exist on
$computer_node_name, attempting to execute connect method install script");
+ # my ($install_exit_status,
$install_output) = $self->execute($install_script, 1, 600, 1);
+ # if (!defined($install_output)) {
+ # notify($ERRORS{'WARNING'}, 0,
"failed to run command to execute install script for '$name' connect method on
$computer_node_name, command: '$install_script'");
+ # }
+ # else {
+ # notify($ERRORS{'OK'}, 0,
"executed install script for '$name' connect method on $computer_node_name,
command: '$install_script', exit status: $install_exit_status, output:\n" .
join("\n", @$install_output));
+ #
+ # if
($self->service_exists($service_name)) {
+ # if
($self->start_service($service_name)) {
+ #
notify($ERRORS{'OK'}, 0, "'$service_name' started on $computer_node_name");
+ #
$service_started = 1;
+ # }
+ # else {
+ #
notify($ERRORS{'WARNING'}, 0, "failed to start '$service_name' service after
executing install script for '$name' connect method on $computer_node_name");
+ # }
+ # }
+ # else {
+ #
notify($ERRORS{'WARNING'}, 0, "'$service_name' service does NOT exist after
executing install script for '$name' connect method on $computer_node_name");
+ # }
+ # }
+ #}
else {
- notify($ERRORS{'WARNING'}, 0, "Service
$servicename does not exist on $computer_node_name");
+ notify($ERRORS{'WARNING'}, 0,
"'$service_name' service for '$name' connect method does NOT exist on
$computer_node_name, connect method install script is not defined");
}
}
- else {
- notify($ERRORS{'WARNING'}, 0, "service_exists
not implemented by OS module" . ref($self));
- }
- }
-
- if ( !$service_started && defined
($$connect_methods{$CMid}{startupscript} ) ) {
- notify($ERRORS{'OK'}, 0, "startupscript exists and
service NOT started ");
- #Service command did not work or does not exist
- # Try to use startup script
- my $cmd = $$connect_methods{$CMid}{startupscript} . "
start";
- notify($ERRORS{'OK'}, 0, "service not started, attempt
to run $cmd ");
- if( $self->can("execute") ) {
- if( $self->execute($cmd, 1) ){
- $service_started = 1;
- }
- }
- else {
- notify($ERRORS{'OK'}, 0, "execute routing not
available by module" . ref($self) );
+ # Run the startup script if the service is not started
+ if (!$service_started && defined($startup_script)) {
+ notify($ERRORS{'DEBUG'}, 0, "attempting to run
startup script '$startup_script' for '$name' connect method on
$computer_node_name");
+ my ($startup_exit_status, $startup_output) =
$self->execute($startup_script, 1);
+ if (!defined($startup_output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed
to run command to execute startup script '$startup_script' for '$name' connect
method on $computer_node_name, command: '$startup_script'");
+ }
+ elsif ($startup_exit_status == 0){
+ notify($ERRORS{'OK'}, 0, "executed
startup script '$startup_script' for '$name' connect method on
$computer_node_name, command: '$startup_script', exit status:
$startup_exit_status, output:\n" . join("\n", @$startup_output));
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed
to execute startup script '$startup_script' for '$name' connect method on
$computer_node_name, command: '$startup_script', exit status:
$startup_exit_status, output:\n" . join("\n", @$startup_output));
+ }
}
- }
-
- if ( $service_started ) {
- #open firewall port
- notify($ERRORS{'OK'}, 0, "service started ");
- if($self->can("enable_firewall_port")) {
- notify($ERRORS{'OK'}, 0, "trying to enable
firewall port $port on $computer_node_name ");
- if(!$self->enable_firewall_port($port)) {
- notify($ERRORS{'CRITICAL'}, 0, "Failed
to enable firewall Connect Method $CMid $description on $computer_node_name");
+
+ # Open the firewall port
+ if (defined($port)) {
+ notify($ERRORS{'DEBUG'}, 0, "attempting to open
firewall port $port on $computer_node_name for '$name' connect method");
+ if ($self->enable_firewall_port($protocol,
$port, "$remote_ip/24", 1)) {
+ notify($ERRORS{'OK'}, 0, "opened
firewall port $port on $computer_node_name for '$name' connect method");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed
to open firewall port $port on $computer_node_name for '$name' connect method");
}
}
}
- else {
- notify($ERRORS{'WARNING'}, 0, "Connect Method $CMid
$description failed to start on $computer_node_name");
- }
}
-
+
return 1;
}
@@ -1901,10 +2109,10 @@ sub process_connect_methods {
sub is_user_connected {
my $self = shift;
- if (ref($self) !~ /VCL::Module/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
- }
+ if (ref($self) !~ /VCL::Module/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
my $time_limit = shift;
if ( !$time_limit ) {
notify($ERRORS{'WARNING'}, 0, "time_limit variable not passed
as an argument");
@@ -1912,7 +2120,7 @@ sub is_user_connected {
}
my $request_id = $self->data->get_request_id();
- my $computer_node_name = $self->data->get_computer_node_name();
+ my $computer_node_name = $self->data->get_computer_node_name();
my $request_state_name = $self->data->get_request_state_name();
my $user_unityid = $self->data->get_user_login_id();
my $computer_ip_address = $self->data->get_computer_ip_address();
@@ -1920,41 +2128,41 @@ sub is_user_connected {
my $connect_methods = $self->data->get_connect_methods();
my $start_time = time();
- my $time_exceeded = 0;
- my $break = 0;
- my $ret_val = "no";
-
- # Figure out number of loops for log messages
- my $maximum_loops = $time_limit * 2;
- my $loop_count = 0;
+ my $time_exceeded = 0;
+ my $break = 0;
+ my $ret_val = "no";
+
+ # Figure out number of loops for log messages
+ my $maximum_loops = $time_limit * 2;
+ my $loop_count = 0;
while (!$break) {
- $loop_count++;
+ $loop_count++;
- notify($ERRORS{'OK'}, 0, "checking for connection by
$user_unityid on $computer_node_name, attempt $loop_count ");
+ notify($ERRORS{'OK'}, 0, "checking for connection by
$user_unityid on $computer_node_name, attempt $loop_count ");
- if (is_request_deleted($request_id)) {
- notify($ERRORS{'OK'}, 0, "user has deleted request");
- $break = 1;
- $ret_val = "deleted";
- return $ret_val;
- }
+ if (is_request_deleted($request_id)) {
+ notify($ERRORS{'OK'}, 0, "user has deleted request");
+ $break = 1;
+ $ret_val = "deleted";
+ return $ret_val;
+ }
$time_exceeded = time_exceeded($start_time, $time_limit);
- if ($time_exceeded) {
- notify($ERRORS{'OK'}, 0, "$time_limit minute time
limit exceeded begin cleanup process");
- #time_exceeded, begin cleanup process
- $break = 1;
- if ($request_state_name =~ /reserved/) {
- notify($ERRORS{'OK'}, 0, "user never logged in
returning nologin");
- $ret_val = "nologin";
- }
- else {
- $ret_val = "timeout";
- }
- return $ret_val;
- } ## end if ($time_exceeded)
- else { #time not exceeded check for connection
+ if ($time_exceeded) {
+ notify($ERRORS{'OK'}, 0, "$time_limit minute time limit
exceeded begin cleanup process");
+ # time_exceeded, begin cleanup process
+ $break = 1;
+ if ($request_state_name =~ /reserved/) {
+ notify($ERRORS{'OK'}, 0, "user never logged in
returning nologin");
+ $ret_val = "nologin";
+ }
+ else {
+ $ret_val = "timeout";
+ }
+ return $ret_val;
+ } ## end if ($time_exceeded)
+ else { # time not exceeded check for connection
foreach my $CMid (sort keys %{$connect_methods} ) {
if($self->can("check_connection_on_port")) {
if(defined($$connect_methods{$CMid}{port}) && $$connect_methods{$CMid}{port}) {
@@ -1974,8 +2182,8 @@ sub is_user_connected {
}
}
notify($ERRORS{'DEBUG'}, 0, "sleeping for 20 seconds");
- sleep 20;
- }
+ sleep 20;
+ }
return $ret_val;
}
Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1179363&r1=1179362&r2=1179363&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Wed Oct 5
18:22:54 2011
@@ -3044,41 +3044,42 @@ EOF
=cut
sub service_exists {
- my $self = shift;
- if (ref($self) !~ /linux/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
- }
-
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
-
- my $service_name = shift;
- if (!$service_name) {
- notify($ERRORS{'WARNING'}, 0, "service name was not passed as
an argument");
- return;
- }
-
+ my $self = shift;
+ if (ref($self) !~ /linux/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ my $service_name = shift;
+ if (!$service_name) {
+ notify($ERRORS{'WARNING'}, 0, "service name was not passed as
an argument");
+ return;
+ }
+
my $command = "/sbin/chkconfig --list $service_name";
- my ($status, $output) = run_ssh_command($computer_node_name,
$management_node_keys, $command, '', '', 1);
- if (defined($output) && grep(/error reading information on service/i,
@{$output})) {
- notify($ERRORS{'DEBUG'}, 0, "service does not exist:
$service_name");
- return 0;
- }
- elsif (defined($status) && $status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "service exists: $service_name");
- }
- elsif (defined($status)) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine if service
exists: $service_name, exit status: $status, output:\n@{$output}");
- return;
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to
determine if service exists");
- return;
- }
-
- return 1;
+ my ($exit_status, $output) = run_ssh_command($computer_node_name,
$management_node_keys, $command, '', '', 1);
+ if (!defined($output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute command to
determine if '$service_name' service exists on $computer_node_name");
+ return;
+ }
+ elsif (grep(/error reading information on service/i, @$output)) {
+ notify($ERRORS{'DEBUG'}, 0, "'$service_name' service does not
exist on $computer_node_name");
+ return 0;
+ }
+ elsif ($exit_status == 0 || grep(/not referenced in any runlevel/i,
@$output)) {
+ # chkconfig may display the following if the service exists but
has not been added:
+ # service ext_sshd supports chkconfig, but is not referenced in
any runlevel (run 'chkconfig --add ext_sshd')
+ notify($ERRORS{'DEBUG'}, 0, "'$service_name' service exists but
is not referenced in any runlevel");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine if
'$service_name' service exists, exit status: $exit_status, output:\n" .
join("\n", @$output));
+ return;
+ }
+ return 1;
}
#/////////////////////////////////////////////////////////////////////////////
@@ -3381,9 +3382,9 @@ sub get_total_memory {
=head2 enable_firewall_port
- Parameters : none
- Returns : 1 successful, 0 failed
- Description : updates iptables for given port for collect IPaddress range
and mode
+ Parameters : $protocol, $port, $scope (optional), $overwrite_existing
(optional), $name (optional), $description (optional)
+ Returns : boolean
+ Description : Updates iptables for given port for collect IPaddress range
and mode
=cut
@@ -3394,56 +3395,42 @@ sub enable_firewall_port {
return;
}
- my $port = shift;
- if(!$port) {
- notify($ERRORS{'CRITICAL'}, 0, "Input variable port was not
passed in as an argument");
- return 0;
- }
-
- my $mode = shift;
- if(!$mode) {
- notify($ERRORS{'DEBUG'}, 0, "firewall mode not passed in as an
argument setting to loose");
- $mode = "medium";
+ my ($protocol, $port, $scope_argument, $overwrite_existing, $name,
$description) = @_;
+ if (!defined($protocol) || !defined($port)) {
+ notify($ERRORS{'WARNING'}, 0, "protocol and port arguments were
not supplied");
+ return;
}
my $computer_node_name = $self->data->get_computer_node_name();
- my $remote_ip = $self->data->get_reservation_remote_ip();
- my $scope;
- my $command;
-
- if ( $mode =~ /loose/i ) {
- $command = "/sbin/iptables -I INPUT 1 -m state --state
NEW,RELATED,ESTABLISHED -m tcp -p tcp --dport $port -j ACCEPT";
- }
- elsif($mode =~ /medium/i) {
- $scope = "$remote_ip/16";
- $command = "/sbin/iptables -I INPUT 1 -s $scope -m state
--state NEW,RELATED,ESTABLISHED -m tcp -p tcp --dport $port -j ACCEPT";
- }
- elsif( $mode =~ /tight/i) {
- $scope = "$remote_ip/24";
- $command = "/sbin/iptables -I INPUT 1 -s $scope -m state
--state NEW,RELATED,ESTABLISHED -m tcp -p tcp --dport $port -j ACCEPT";
- }
- elsif( $mode =~ /locked/i) {
- $command = "/sbin/iptables -I INPUT 1 -s $remote_ip -m state
--state NEW,RELATED,ESTABLISHED -m tcp -p tcp --dport $port -j ACCEPT";
- }
-
- #copy original config
- my $cp_iptables_config = "cp /etc/sysconfig/iptables
/etc/sysconfig/iptables_pre_$port";
- my ($status_cp, $output_cp) = $self->execute($cp_iptables_config);
- if (defined $status_cp && $status_cp == 0) {
- notify($ERRORS{'DEBUG'}, 0, "executed command
$cp_iptables_config on $computer_node_name");
+ $protocol = lc($protocol);
+
+ my $command = "/sbin/iptables -I INPUT 1 -m state --state
NEW,RELATED,ESTABLISHED -m $protocol -p $protocol --dport $port -j ACCEPT";
+
+ if ($scope_argument) {
+ $command .= " -s $scope_argument";
+ }
+
+ # Make backup copy of original iptables configuration
+ my $iptables_backup_file_path = "/etc/sysconfig/iptables_pre_$port";
+ if ($self->copy_file("/etc/sysconfig/iptables",
$iptables_backup_file_path)) {
+ notify($ERRORS{'DEBUG'}, 0, "backed up original iptables file
to: '$iptables_backup_file_path'");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to back up original
iptables file to: '$iptables_backup_file_path'");
}
# Add rule
+ notify($ERRORS{'DEBUG'}, 0, "attempting to execute command on
$computer_node_name: '$command'");
my ($status, $output) = $self->execute($command);
if (defined $status && $status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "executed command $command on
$computer_node_name");
+ notify($ERRORS{'DEBUG'}, 0, "executed command on
$computer_node_name: '$command'");
}
else {
- notify($ERRORS{'WARNING'}, 0, "output from iptables:" .
join("\n", @$output));
+ notify($ERRORS{'WARNING'}, 0, "output from iptables:\n" .
join("\n", @$output));
}
- #Save rules to sysconfig/iptables -- incase of reboot
+ # Save rules to sysconfig/iptables -- incase of reboot
my $iptables_save_cmd = "/sbin/iptables-save > /etc/sysconfig/iptables";
my ($status_save, $output_save) = $self->execute($iptables_save_cmd);
if (defined $status_save && $status_save == 0) {
Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1179363&r1=1179362&r2=1179363&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Wed Oct 5 18:22:54 2011
@@ -117,6 +117,7 @@ our @EXPORT = qw(
get_computer_ids
get_computer_info
get_computers_controlled_by_MN
+ get_connect_method_info
get_current_file_name
get_current_package_name
get_current_subroutine_name
@@ -4645,8 +4646,8 @@ sub get_request_info {
my $computer_info = get_computer_info($computer_id, 1);
$request_info{reservation}{$reservation_id}{computer} =
$computer_info;
- my $connect_methods = get_connect_methods($image_id,
$imagerevision_id);
- $request_info{reservation}{$reservation_id}{connect_methods} =
$connect_methods;
+ my $connect_method_info =
get_connect_method_info($imagerevision_id);
+ $request_info{reservation}{$reservation_id}{connect_methods} =
$connect_method_info;
} # Close loop through selected rows
@@ -4797,7 +4798,7 @@ sub get_request_info {
$request_info{reservation}{$reservation_id}{computer}{SHORTNAME} =
$computer_shortname;
# Add the managementnode info to the hash
- my $management_node_id =
$request_info{reservation}{$reservation_id}{managementnodeid};
+ my $management_node_id =
$request_info{reservation}{$reservation_id}{managementnodeid};
my $management_node_info =
get_management_node_info($management_node_id);
if (!$management_node_info) {
notify($ERRORS{'WARNING'}, 0, "failed to retrieve
management node info");
@@ -5061,6 +5062,7 @@ sub get_image_info {
'image',
'platform',
'OS',
+ 'OStype',
'module',
);
@@ -5084,12 +5086,14 @@ FROM
image,
platform,
OS,
+OStype,
module
WHERE
platform.id = image.platformid
AND OS.id = image.OSid
AND module.id = OS.moduleid
+AND OS.type = OStype.name
AND
EOF
@@ -5132,7 +5136,7 @@ EOF
if ($table eq $tables[0]) {
$image_info->{$column} = $value;
}
- elsif ($table eq 'module') {
+ elsif ($table =~ /^(module|OStype)$/) {
$image_info->{OS}{$table}{$column} = $value;
}
else {
@@ -5586,6 +5590,8 @@ sub run_ssh_command {
$timeout_seconds = 0 if (!$timeout_seconds);
$identity_paths = $ENV{management_node_info}{keys} if (!defined
$identity_paths || length($identity_paths) == 0);
+#return VCL::Module::OS::execute($node, $command, $output_level,
$timeout_seconds, $max_attempts, $port, $user);
+
# TODO: Add ssh path to config file and set global variable
# Locate the path to the ssh binary
my $ssh_path;
@@ -9564,8 +9570,7 @@ sub xmlrpc_call {
"password: $XMLRPC_PASS\n" .
"arguments: " . join(", ", @arguments) . "\n" .
"fault code: " . $response->code . "\n" .
- "fault string: " . $response->string .
- format_data($response)
+ "fault string: " . $response->string
);
$ENV{rpc_xml_error} = $response->string;
return;
@@ -10667,83 +10672,119 @@ sub kill_child_processes {
#/////////////////////////////////////////////////////////////////////////////
-=head2 get_connect_method
+=head2 get_connect_method_info
- Parameters : reservationid
+ Parameters : $imagerevision_id
Returns : hash reference
- Description : Returns the contents of connect method for reservationid.
+ Description : Returns the connect methods for the image revision specified as
+ the argument.
=cut
-sub get_connect_methods {
+sub get_connect_method_info {
+ my ($imagerevision_id) = @_;
+ if (!defined($imagerevision_id)) {
+ notify($ERRORS{'WARNING'}, 0, "imagerevision ID argument was
not supplied");
+ return;
+ }
+
+ my $imagerevision_info = get_imagerevision_info($imagerevision_id);
+
+ notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve connect method
info:\n" .
+ "imagerevision: $imagerevision_id - " .
$imagerevision_info->{imagename} . "\n" .
+ "OS: " . $imagerevision_info->{image}{OS}{id} . " - " .
$imagerevision_info->{image}{OS}{name} . "\n" .
+ "OS type: " . $imagerevision_info->{image}{OS}{OStype}{id} . "
- " . $imagerevision_info->{image}{OS}{OStype}{name}
+ );
+
+ # Get a hash ref containing the database column names
+ my $database_table_columns = get_database_table_columns();
+
+ my @tables = (
+ 'connectmethod',
+ 'connectmethodmap'
+ );
+
+ # Construct the select statement
+ my $select_statement = "SELECT DISTINCT\n";
+
+ # Get the column names for each table and add them to the select
statement
+ for my $table (@tables) {
+ my @columns = @{$database_table_columns->{$table}};
+ for my $column (@columns) {
+ $select_statement .= "$table.$column AS
'$table-$column',\n";
+ }
+ }
+
+ # Remove the comma after the last column line
+ $select_statement =~ s/,$//;
+
+ # Complete the select statement
+ $select_statement .= <<EOF;
+FROM
+connectmethod,
+connectmethodmap,
+imagerevision
- my ($imageid, $imagerevisionid) = @_;
- my ($calling_package, $calling_filename, $calling_line, $calling_sub)
= caller(0);
+LEFT JOIN image ON (image.id = imagerevision.imageid)
+LEFT JOIN OS ON (OS.id = image.OSid)
+LEFT JOIN OStype ON (OStype.name = OS.type)
- if (!defined($imagerevisionid)) {
- notify($ERRORS{'WARNING'}, 0, "$calling_sub $calling_package
missing mandatory variable: imagerevisionid ");
- return 0;
- }
-
- if (!defined($imageid)) {
- notify($ERRORS{'WARNING'}, 0, "$calling_sub $calling_package
missing mandatory variable: imageid ");
- return 0;
- }
-
- my $select_statement = "
- SELECT DISTINCT
- c.id AS CM_id,
- c.description AS CM_description,
- c.port AS CM_port,
- c.servicename AS CM_servicename,
- c.startupscript AS CM_startupscript,
- cm.autoprovisioned AS CM_autoprovisioned,
- cm.disabled AS CM_disabled
- FROM
- connectmethod c,
- connectmethodmap cm,
- image i
- LEFT JOIN OS o ON (o.id = i.OSid)
- LEFT JOIN OStype ot ON (ot.name = o.type)
- WHERE
- i.id = $imageid AND
- cm.connectmethodid = c.id AND
- cm.autoprovisioned IS NULL AND
- (cm.OStypeid = ot.id OR
- cm.OSid = o.id OR
- cm.imagerevisionid = $imagerevisionid)
- ORDER BY cm.disabled, c.description";
+WHERE
+connectmethodmap.connectmethodid = connectmethod.id
+AND imagerevision.id = $imagerevision_id
+AND connectmethodmap.autoprovisioned IS NOT NULL
+AND (
+ connectmethodmap.OStypeid = OStype.id
+ OR connectmethodmap.OSid = OS.id
+ OR connectmethodmap.imagerevisionid = imagerevision.id
+)
- # Call the database select subroutine
- # This will return an array of one or more rows based on the select
statement
- my @selected_rows = database_select($select_statement);
+ORDER BY
+connectmethod.id,
+connectmethodmap.imagerevisionid,
+connectmethodmap.OSid,
+connectmethodmap.OStypeid,
+connectmethodmap.disabled
+EOF
- my @ret_array;
- my %connect_info;
+ # Call the database select subroutine
+ my @selected_rows = database_select($select_statement);
- # Check to make sure 1 or more rows were returned
- if (scalar @selected_rows > 0) {
- # It contains a hash
- for (@selected_rows) {
- my %connectMethod = %{$_};
- next if($connectMethod{CM_disabled});
- my $CMid = $connectMethod{CM_id};
- $connect_info{$CMid}{"id"} = $CMid;
- $connect_info{$CMid}{"description"} =
$connectMethod{CM_description};
- $connect_info{$CMid}{"port"} = $connectMethod{CM_port};
- $connect_info{$CMid}{"servicename"} =
$connectMethod{CM_servicename};
- $connect_info{$CMid}{"startupscript"} =
$connectMethod{CM_startupscript};
- $connect_info{$CMid}{"autoprovisioned"} =
$connectMethod{CM_autoprovisioned};
+ # Transform the array of database rows into a hash
+ my $connect_method_info = {};
+
+ for my $row (@selected_rows) {
+ notify($ERRORS{'DEBUG'}, 0, $row->{"connectmethod-name"} . ": "
.
+ "connectmethodid=" . $row->{"connectmethod-id"} . ", " .
+ "OStypeid=" . ($row->{"connectmethodmap-OStypeid"} || 'NULL') .
", " .
+ "OSid=" . ($row->{"connectmethodmap-OSid"} || 'NULL') . ", " .
+ "imagerevisionid=" .
($row->{"connectmethodmap-imagerevisionid"} || 'NULL') . ", " .
+ "disabled=" . $row->{"connectmethodmap-disabled"});
+
+ my $connectmethod_id = $row->{'connectmethod-id'};
+
+ # Loop through all the columns returned
+ for my $key (keys %$row) {
+ next if $key eq 'connectmethod-connecttext';
- notify($ERRORS{'OK'}, 0, "CONNECT METHOD CMid= $CMid
description= $connect_info{$CMid}{description}");
-
- }
-
- return \%connect_info;
- }
-
- return();
+ my $value = $row->{$key};
+
+ # Split the table-column names
+ my ($table, $column) = $key =~ /^([^-]+)-(.+)/;
+
+ # Add the values for the primary table to the hash
+ # Add values for other tables under separate keys
+ if ($table eq $tables[0]) {
+
$connect_method_info->{$connectmethod_id}{$column} = $value;
+ }
+ else {
+
$connect_method_info->{$connectmethod_id}{$table}{$column} = $value;
+ }
+ }
+ }
+ notify($ERRORS{'DEBUG'}, 0, "retrieved connect method info:\n" .
format_data($connect_method_info));
+ return $connect_method_info;
}
#/////////////////////////////////////////////////////////////////////////////