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 2009/12/14 21:30:58 UTC
svn commit: r890470 -
/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
Author: arkurth
Date: Mon Dec 14 20:30:34 2009
New Revision: 890470
URL: http://svn.apache.org/viewvc?rev=890470&view=rev
Log:
VCL-279
Added call_post_load_custom() sub to Linux.pm. It checks if /etc/init.d/post_load_custom exists and executes it after an image is loaded. This allows an image creator to easily add a custom script which automatically executes on image load. This functionality already exists for Windows.
Added $NODE_CONFIGURATION_DIRECTORY class variable to Linux.pm to match Windows.pm.
Also added subroutine headers to Linux.pm where they were missing but did not populate the information.
Modified:
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
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=890470&r1=890469&r2=890470&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Mon Dec 14 20:30:34 2009
@@ -56,6 +56,38 @@
##############################################################################
+=head1 CLASS VARIABLES
+
+=cut
+
+=head2 $NODE_CONFIGURATION_DIRECTORY
+
+ Data type : String
+ Description : Location on computer on which an image has been loaded where
+ configuration files reside.
+
+=cut
+
+our $NODE_CONFIGURATION_DIRECTORY = '/root/VCL';
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_node_configuration_directory
+
+ Parameters : None.
+ Returns : String containing filesystem path
+ Description : Retrieves the $NODE_CONFIGURATION_DIRECTORY variable value the
+ OS. This is the path on the computer's hard drive where image
+ configuration files and scripts are copied.
+
+=cut
+
+sub get_node_configuration_directory {
+ return $NODE_CONFIGURATION_DIRECTORY;
+}
+
+##############################################################################
+
=head1 OBJECT METHODS
=cut
@@ -198,7 +230,6 @@
my $clear_extsshd = "sed -ie \"/^AllowUsers .*/d\" /etc/ssh/external_sshd_config";
if (run_ssh_command($computer_node_name, $management_node_keys, $clear_extsshd, "root")) {
notify($ERRORS{'DEBUG'}, 0, "cleared AllowUsers directive from external_sshd_config");
- return 1;
}
else {
notify($ERRORS{'CRITICAL'}, 0, "failed to clear AllowUsers from external_sshd_config");
@@ -209,11 +240,26 @@
if ($self->clear_private_keys()) {
notify($ERRORS{'OK'}, 0, "cleared known identity keys");
}
+
+ # Check if post_load_custom script exists and execute it
+ if (!$self->call_post_load_custom()) {
+ notify($ERRORS{'WARNING'}, 0, "failed to execute post_load_custom script");
+ }
return 1;
} ## end sub post_load
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 clear_private_keys
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
sub clear_private_keys {
my $self = shift;
unless (ref($self) && $self->isa('VCL::Module')) {
@@ -238,6 +284,17 @@
}
}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_static_public_address
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
sub set_static_public_address {
my $self = shift;
if (ref($self) !~ /linux/i) {
@@ -455,6 +512,16 @@
return $GATEWAY;
}
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 logoff_user
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
sub logoff_user {
my $self = shift;
if (ref($self) !~ /linux/i) {
@@ -957,7 +1024,18 @@
return 1;
-}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 is_connected
+
+ Parameters :
+ Returns :
+ Description :
+
+=cut
+
sub is_connected {
my $self = shift;
if (ref($self) !~ /linux/i) {
@@ -990,6 +1068,176 @@
#/////////////////////////////////////////////////////////////////////////////
+=head2 call_post_load_custom
+
+ Parameters : none
+ Returns : If successfully ran post_load_custom script: 1
+ If post_load_custom script does not exist: 1
+ If error occurred: false
+ Description : Checks if /etc/init.d/post_load_custom script exists on the
+ Linux node and attempts to run it. This script can be created by
+ the image creator and will run when the image is loaded.
+
+=cut
+
+sub call_post_load_custom {
+ 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;
+ }
+
+ # Check if post_load_custom exists
+ my $post_load_custom_path = '/etc/init.d/post_load_custom';
+ if ($self->filesystem_entry_exists($post_load_custom_path)) {
+ notify($ERRORS{'DEBUG'}, 0, "post_load_custom script exists: $post_load_custom_path");
+ }
+ else {
+ notify($ERRORS{'OK'}, 0, "post_load_custom script does NOT exist: $post_load_custom_path");
+ return 1;
+ }
+
+ # Get the node configuration directory, make sure it exists, create if necessary
+ my $node_log_directory = $self->get_node_configuration_directory() . '/Logs';
+ if (!$self->create_directory($node_log_directory)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create node log file directory: $node_log_directory");
+ return;
+ }
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ # Assemble the log file path
+ my $post_load_custom_log_path = $node_log_directory . "/post_load_custom.log";
+
+ # Assemble the command
+ my $post_load_custom_command;
+ # Make sure the script is readable and executable
+ $post_load_custom_command .= "chmod +rx \"$post_load_custom_path\"";
+ # Redirect the script output to the log file path
+ $post_load_custom_command .= " && \"$post_load_custom_path\" >> \"$post_load_custom_log_path\" 2>&1";
+
+ # Execute the command
+ my ($post_load_custom_exit_status, $post_load_custom_output) = run_ssh_command($computer_node_name, $management_node_keys, $post_load_custom_command, '', '', 1);
+ if (defined($post_load_custom_exit_status) && $post_load_custom_exit_status == 0) {
+ notify($ERRORS{'OK'}, 0, "executed $post_load_custom_path, exit status: $post_load_custom_exit_status");
+ }
+ elsif (defined($post_load_custom_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "$post_load_custom_path returned a non-zero exit status: $post_load_custom_exit_status, output:\n@{$post_load_custom_output}");
+ return 0;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to execute $post_load_custom_path");
+ return;
+ }
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 create_directory
+
+ Parameters : directory path
+ Returns : If successful: true
+ If failed: false
+ Description : Creates a directory on the Linux node. If a multi-level
+ directory path is specified, parent directories are also created
+ if they do not exist.
+
+=cut
+
+sub create_directory {
+ my $self = shift;
+ if (ref($self) !~ /module/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ # Make sure path argument was specified
+ my $path = shift;
+ if (!$path) {
+ notify($ERRORS{'WARNING'}, 0, "directory path argument was not specified");
+ return;
+ }
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ # Assemble the mkdir command and execute it
+ my $mkdir_command = "mkdir -p \"$path\" && ls -d \"$path\"";
+ my ($mkdir_exit_status, $mkdir_output) = run_ssh_command($computer_node_name, $management_node_keys, $mkdir_command, '', '', 1);
+ if (defined($mkdir_output) && grep(/ls: /, @$mkdir_output)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create directory on $computer_node_name: $path, exit status: $mkdir_exit_status, output:\n@{$mkdir_output}");
+ return;
+ }
+ elsif (defined($mkdir_exit_status)) {
+ notify($ERRORS{'OK'}, 0, "directory created on $computer_node_name: $path, output:\n@{$mkdir_output}");
+ return 1;
+ }
+ elsif (defined($mkdir_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create directory on $computer_node_name: $path, exit status: $mkdir_exit_status, output:\n@{$mkdir_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to delete file on $computer_node_name: $path");
+ return;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 filesystem_entry_exists
+
+ Parameters : filesystem path
+ Returns : If entry exists: 1
+ If entry does not exist: 0
+ If error occurred: undefined
+ Description : Checks if a filesystem entry (file or directory) exists on the
+ Linux node.
+
+=cut
+
+sub filesystem_entry_exists {
+ my $self = shift;
+ if (ref($self) !~ /module/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ # Get the path from the subroutine arguments and make sure it was passed
+ my $path = shift;
+ if (!$path) {
+ notify($ERRORS{'WARNING'}, 0, "unable to detmine if file exists, path was not specified as an argument");
+ return;
+ }
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ # Assemble the dir command and execute it
+ my $ls_command = "ls -l \"$path\"";
+ my ($ls_exit_status, $ls_output) = run_ssh_command($computer_node_name, $management_node_keys, $ls_command, '', '', 1);
+ if (defined($ls_output) && grep(/no such file/i, @$ls_output)) {
+ notify($ERRORS{'DEBUG'}, 0, "filesystem entry does NOT exist on $computer_node_name: $path");
+ return 0;
+ }
+ elsif ((defined($ls_exit_status) && $ls_exit_status == 0) || (defined($ls_output) && grep(/$path/i, @$ls_output))) {
+ notify($ERRORS{'DEBUG'}, 0, "filesystem entry exists on $computer_node_name: $path, dir output:\n" . join("\n", @$ls_output));
+ return 1;
+ }
+ elsif ($ls_exit_status) {
+ notify($ERRORS{'WARNING'}, 0, "failed to determine if filesystem entry exists on $computer_node_name: $path, exit status: $ls_exit_status, output:\n@{$ls_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to determine if filesystem entry exists on $computer_node_name: $path");
+ return;
+ }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
1;
__END__