| #!/usr/bin/perl -w |
| ############################################################################### |
| # $Id$ |
| ############################################################################### |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You under the Apache License, Version 2.0 |
| # (the "License"); you may not use this file except in compliance with |
| # the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| ############################################################################### |
| |
| =head1 NAME |
| |
| VCL::Module::OS::Linux::init::SysV.pm |
| |
| =head1 DESCRIPTION |
| |
| This module provides VCL support for the SysV-style Linux init daemon used in |
| distributions such as: |
| Red Hat Enterprise Linux 5.x, 6.x |
| CentOS 5.x, 6.x |
| |
| =cut |
| |
| ############################################################################### |
| package VCL::Module::OS::Linux::init::SysV; |
| |
| # Specify the lib path using FindBin |
| use FindBin; |
| use lib "$FindBin::Bin/../../../../.."; |
| |
| # Configure inheritance |
| use base qw(VCL::Module::OS::Linux::init); |
| |
| # Specify the version of this module |
| our $VERSION = '2.5'; |
| |
| # Specify the version of Perl to use |
| use 5.008000; |
| |
| use strict; |
| use warnings; |
| use diagnostics; |
| |
| use VCL::utils; |
| |
| ############################################################################### |
| |
| =head1 CLASS VARIABLES |
| |
| =cut |
| |
| =head2 $INIT_DAEMON_ORDER |
| |
| Data type : integer |
| Value : 50 |
| Description : Determines the order in which Linux init daemon modules are used |
| if an OS supports multiple init daemons. Lower values are used |
| first. SysV has a higher value than other init modules because it |
| is older than other, newer init daemons. The newer init daemon |
| modules should be tried first. |
| |
| =cut |
| |
| our $INIT_DAEMON_ORDER = 50; |
| |
| =head2 @REQUIRED_COMMANDS |
| |
| Data type : array |
| Values : chkconfig, service |
| Description : List of commands used within this module to configure and control |
| SysV services. This module will not be used if any of these |
| commands are unavailable on the computer. |
| |
| =cut |
| |
| our @REQUIRED_COMMANDS = ('chkconfig', 'service'); |
| |
| ############################################################################### |
| |
| =head1 OBJECT METHODS |
| |
| =cut |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_service_names |
| |
| Parameters : none |
| Returns : array |
| Description : Calls 'chkconfig --list' to retrieve the list of services |
| controlled by SysV on the computer. |
| |
| =cut |
| |
| sub get_service_names { |
| 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 $computer_node_name = $self->data->get_computer_node_name(); |
| |
| my $command = "chkconfig --list"; |
| my ($exit_status, $output) = $self->os->execute($command, 0); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to list SysV services on $computer_node_name"); |
| return; |
| } |
| |
| # Format out chkconfig --list output lines: |
| # Note: This output shows SysV services only and does not include native |
| # systemd services. SysV configuration data might be overridden by native |
| # ... |
| # sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off |
| my %service_name_hash; |
| for my $line (@$output) { |
| my ($service_name) = $line =~ /^([^\s\t]+)[\s\t]+\d/; |
| $service_name_hash{$service_name} = 1 if $service_name; |
| } |
| my @service_names = sort(keys %service_name_hash); |
| notify($ERRORS{'DEBUG'}, 0, "retrieved SysV service names from $computer_node_name: " . join(", ", @service_names)); |
| return @service_names; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 enable_service |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'chkconfig <$service_name> on' to configure the service to |
| start automatically. Does not start the service. |
| |
| =cut |
| |
| sub enable_service { |
| 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 0; |
| } |
| |
| my $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| # Enable the service |
| my $command = "chkconfig $service_name on"; |
| my ($exit_status, $output) = $self->os->execute($command, 0); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to enable '$service_name' service on $computer_node_name: $command"); |
| return; |
| } |
| elsif (grep(/(error reading information|No such file)/i, @$output)) { |
| # Output if the service doesn't exist: 'error reading information on service httpdx: No such file or directory' |
| notify($ERRORS{'WARNING'}, 0, "'$service_name' service does not exist on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/(failed|warn|error)/i, @$output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to enable '$service_name' service on $computer_node_name, exit status: $exit_status, output:\n" . join("\n", @$output)); |
| return; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "enabled '$service_name' service on $computer_node_name"); |
| } |
| |
| return 1; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 disable_service |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'chkconfig <$service_name> off' to prevent the service from |
| starting automatically. Does not stop the service. |
| |
| =cut |
| |
| sub disable_service { |
| 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 0; |
| } |
| |
| my $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| # Disable the service |
| my $command = "chkconfig $service_name off"; |
| my ($exit_status, $output) = $self->os->execute($command, 0); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to disable '$service_name' service on $computer_node_name: $command"); |
| return; |
| } |
| elsif (grep(/(error reading information|No such file)/i, @$output)) { |
| # Output if the service doesn't exist: 'error reading information on service httpdx: No such file or directory' |
| notify($ERRORS{'WARNING'}, 0, "'$service_name' service does not exist on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/(failed|warn|error)/i, @$output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to disable '$service_name' service on $computer_node_name, exit status: $exit_status, output:\n" . join("\n", @$output)); |
| return; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "disabled '$service_name' service on $computer_node_name"); |
| } |
| |
| return 1; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 service_enabled |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'chkconfig --list <$service_name>' to determine if a |
| service is enabled. |
| |
| =cut |
| |
| sub service_enabled { |
| 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 0; |
| } |
| |
| my $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| my $command = "chkconfig --list $service_name"; |
| my ($exit_status, $output) = $self->os->execute($command, 0); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to determine if '$service_name' service is enabled on $computer_node_name: $command"); |
| return; |
| } |
| elsif (grep(/(error reading information|No such file)/i, @$output)) { |
| # Output if the service does not exist: 'error reading information on service httpdx: No such file or directory' |
| notify($ERRORS{'WARNING'}, 0, "'$service_name' service does not exist on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/^$service_name\s+.*3:on/i, @$output)) { |
| # Output if the service is enabled: '<service name> 0:off 1:off 2:on 3:on 4:on 5:on 6:off' |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service is enabled on $computer_node_name"); |
| return 1; |
| } |
| elsif (grep(/^$service_name\s+.*3:off/i, @$output)) { |
| # Output if the service is disabled: '<service name> 0:off 1:off 2:off 3:off 4:off 5:off 6:off' |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service is not enabled on $computer_node_name"); |
| return 0; |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "failed to determine if '$service_name' service is enabled on $computer_node_name, exit status: $exit_status, output:\n" . join("\n", @$output)); |
| return; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 service_running |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'service <$service_name> status' to determine if a |
| service is running. |
| |
| =cut |
| |
| sub service_running { |
| 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 0; |
| } |
| |
| my $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| # Enable the service |
| my $command = "service $service_name status"; |
| my ($exit_status, $output) = $self->os->execute($command, 0); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to determine if '$service_name' service is running on $computer_node_name: $command"); |
| return; |
| } |
| elsif (grep(/(error reading information|No such file)/i, @$output)) { |
| # Output if the service does not exist: 'error reading information on service httpdx: No such file or directory' |
| notify($ERRORS{'WARNING'}, 0, "'$service_name' service does not exist on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/(is running)/i, @$output)) { |
| # Output if the service is running: '<service name> is running' |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service is running on $computer_node_name, output:\n" . join("\n", @$output)); |
| return 1; |
| } |
| elsif (grep(/(is not running|no\s.*process)/i, @$output)) { |
| # Output if the service is not running: '<service name> is not running' |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service is not running on $computer_node_name, output:\n" . join("\n", @$output)); |
| return 0; |
| } |
| elsif ($exit_status == 0) { |
| notify($ERRORS{'DEBUG'}, 0, "unable to determine if '$service_name' service is running on $computer_node_name based on output but exit status of $command is $exit_status, assuming service is running, output:\n" . join("\n", @$output)); |
| return 1; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "unable to determine if '$service_name' service is running on $computer_node_name based on output but exit status of $command is $exit_status, assuming service is NOT running, output:\n" . join("\n", @$output)); |
| return 0; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 add_service |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'chkconfig --add <$service_name>' to add the service |
| specified by the argument. The service file must already reside |
| in /etc/rc.d/init.d/. |
| |
| =cut |
| |
| sub add_service { |
| 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 $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| # Add the service |
| my $command = "chkconfig --add $service_name"; |
| my ($exit_status, $output) = $self->os->execute($command); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to add '$service_name' service on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/(error|No such file)/i, @$output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to add '$service_name' service on $computer_node_name, exit status: $exit_status, command: '$command', output:\n" . join("\n", @$output)); |
| return; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "added '$service_name' service on $computer_node_name"); |
| return 1; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 delete_service |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'chkconfig --del <$service_name>' to delete the service |
| specified by the argument. Deletes the service file from |
| /etc/rc.d/init.d/. |
| |
| =cut |
| |
| sub delete_service { |
| 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 $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| # Delete the service |
| my $command = "chkconfig --del $service_name"; |
| my ($exit_status, $output) = $self->os->execute($command); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to delete '$service_name' service on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/(error reading information|No such file)/i, @$output)) { |
| # Output if the service doesn't exist: 'error reading information on service xxx: No such file or directory' |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service does not exist on $computer_node_name"); |
| } |
| elsif ($exit_status ne '0') { |
| notify($ERRORS{'WARNING'}, 0, "failed to delete '$service_name' service on $computer_node_name, exit status: $exit_status, command: '$command', output:\n" . join("\n", @$output)); |
| return; |
| } |
| |
| # Delete the service configuration file |
| my $service_file_path = "/etc/rc.d/init.d/$service_name"; |
| if (!$self->os->delete_file($service_file_path)) { |
| return; |
| } |
| |
| notify($ERRORS{'DEBUG'}, 0, "deleted '$service_name' service on $computer_node_name"); |
| return 1; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 start_service |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'service <$service_name> start' to start the service. |
| |
| =cut |
| |
| sub start_service { |
| 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 $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| my $command = "service $service_name start"; |
| my ($exit_status, $output) = $self->os->execute($command); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to start '$service_name' service on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/(error reading information|No such file)/i, @$output)) { |
| # Output if the service doesn't exist: 'error reading information on service xxx: No such file or directory' |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service does not exist on $computer_node_name"); |
| } |
| elsif (grep(/Starting $service_name:.*FAIL/i, @$output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to start '$service_name' service on $computer_node_name, exit status: $exit_status, command: '$command', output:\n" . join("\n", @$output)); |
| return; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "started '$service_name' service on $computer_node_name"); |
| return 1; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 stop_service |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'service <$service_name> stop' to start the service. |
| |
| =cut |
| |
| sub stop_service { |
| 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 $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| my $command = "service $service_name status ; service $service_name stop"; |
| my ($exit_status, $output) = $self->os->execute($command); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to stop '$service_name' service on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/(error reading information|No such file)/i, @$output)) { |
| # Output if the service doesn't exist: 'error reading information on service xxx: No such file or directory' |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service does not exist on $computer_node_name"); |
| return 1; |
| } |
| elsif (grep(/is stopped/i, @$output)) { |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service is already stopped on $computer_node_name"); |
| return 1; |
| } |
| elsif (grep(/Stopping $service_name:.*FAIL/i, @$output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to stop '$service_name' service on $computer_node_name, exit status: $exit_status, command: '$command', output:\n" . join("\n", @$output)); |
| return; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "stopped '$service_name' service on $computer_node_name, output:\n" . join("\n", @$output)); |
| return 1; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 restart_service |
| |
| Parameters : $service_name |
| Returns : boolean |
| Description : Calls 'service <$service_name> restart' to start the service. |
| |
| =cut |
| |
| sub restart_service { |
| 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 $service_name = shift; |
| if (!$service_name) { |
| notify($ERRORS{'WARNING'}, 0, "service name argument was not supplied"); |
| return; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| my $command = "service $service_name restart"; |
| my ($exit_status, $output) = $self->os->execute($command, 0); |
| if (!defined($output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to execute command to restart '$service_name' service on $computer_node_name"); |
| return; |
| } |
| elsif (grep(/(error reading information|No such file)/i, @$output)) { |
| # Output if the service doesn't exist: 'error reading information on service xxx: No such file or directory' |
| notify($ERRORS{'DEBUG'}, 0, "'$service_name' service does not exist on $computer_node_name"); |
| } |
| elsif (grep(/Starting $service_name:.*FAIL/i, @$output)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to restart '$service_name' service on $computer_node_name, exit status: $exit_status, command: '$command', output:\n" . join("\n", @$output)); |
| return; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "restarted '$service_name' service on $computer_node_name, output:\n" . join("\n", @$output)); |
| return 1; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 add_ext_sshd_service |
| |
| Parameters : none |
| Returns : boolean |
| Description : Adds the ext_sshd service to the computer. Generates and |
| configures /etc/rc.d/init.d/ext_sshd based off of the existing |
| /etc/rc.d/init.d/sshd file. Adds the ext_sshd service and |
| configures it to start automatically. |
| |
| =cut |
| |
| sub add_ext_sshd_service { |
| 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 0; |
| } |
| |
| my $computer_node_name = $self->data->get_computer_node_name(); |
| |
| my $sshd_service_file_path = '/etc/rc.d/init.d/sshd'; |
| my $sshd_service_file_path_original = '/etc/rc.d/init.d/sshd_original'; |
| my $ext_sshd_service_file_path = '/etc/rc.d/init.d/ext_sshd'; |
| my $ext_sshd_config_file_path = '/etc/ssh/external_sshd_config'; |
| |
| # Get the contents of the sshd service startup file already on the computer |
| my @sshd_service_file_lines = $self->os->get_file_contents($sshd_service_file_path); |
| if (!@sshd_service_file_lines) { |
| notify($ERRORS{'WARNING'}, 0, "failed to retrieve contents of $sshd_service_file_path from $computer_node_name"); |
| return; |
| } |
| |
| my $sshd_service_file_contents_original = join("\n", @sshd_service_file_lines); |
| my $sshd_service_file_contents_updated = $sshd_service_file_contents_original; |
| my $ext_sshd_service_file_contents = $sshd_service_file_contents_original; |
| |
| # Replace: OpenSSH --> externalOpenSSH |
| $ext_sshd_service_file_contents =~ s|( OpenSSH)| external$1|g; |
| |
| # Replace: openssh-daemon --> external-openssh-daemon |
| $ext_sshd_service_file_contents =~ s| (openssh-daemon)| external-$1|g; |
| |
| # Replace: sshd --> ext_sshd, exceptions: |
| # /bin/sshd |
| # /sshd_config |
| # Note: pattern in look-behind assertion (?<!) must all be same length |
| $ext_sshd_service_file_contents =~ s*(?<!(bin|pty)/)sshd(?!_config)*ext_sshd*g; |
| |
| # Replace: sshd_config --> external_sshd_config |
| $ext_sshd_service_file_contents =~ s|(?:ext_)?(sshd_config)|external_$1|g; |
| |
| # Add config file path argument to '$SSHD $OPTIONS' |
| $ext_sshd_service_file_contents =~ s|(\$SSHD)\s+(\$OPTIONS)|$1 -f $ext_sshd_config_file_path $2|g; |
| |
| # Replace: |
| # 'pidfileofproc $SSHD' --> 'pidfileofproc $prog' |
| # 'killproc $SSHD' --> 'killproc $prog' |
| # 'status $SSHD' --> 'status $prog' |
| $ext_sshd_service_file_contents =~ s/(pidfileofproc|killproc|status)\s+\$SSHD/$1 \$prog/g; |
| |
| # Update the sshd file as well or else 'service sshd status' will always report sshd is running if ext_sshd is running |
| # The status line has to be: 'status -p $PID_FILE openssh-daemon' |
| $sshd_service_file_contents_updated =~ s/(status)\s+.*/$1 -p \$PID_FILE openssh-daemon/g; |
| |
| # Check if any changes were made to the original sshd file |
| if ($sshd_service_file_contents_updated ne $sshd_service_file_contents_original) { |
| # Save a copy of the original sshd file if the backup doesn't already exist |
| if (!$self->os->file_exists($sshd_service_file_path_original)) { |
| $self->os->copy_file($sshd_service_file_path, $sshd_service_file_path_original); |
| } |
| |
| if (!$self->os->create_text_file($sshd_service_file_path, $sshd_service_file_contents_updated)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to update sshd service file on $computer_node_name: $sshd_service_file_path"); |
| } |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "sshd service file on $computer_node_name does not need to be updated"); |
| } |
| |
| if (!$self->os->create_text_file($ext_sshd_service_file_path, $ext_sshd_service_file_contents)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to create ext_sshd service file on $computer_node_name: $ext_sshd_service_file_path"); |
| return; |
| } |
| |
| if (!$self->os->set_file_permissions($ext_sshd_service_file_path, '755')) { |
| notify($ERRORS{'WARNING'}, 0, "failed to set permissions on ext_sshd service file to 755 on $computer_node_name: $ext_sshd_service_file_path"); |
| return; |
| } |
| |
| # Add the service |
| return unless $self->add_service('ext_sshd'); |
| |
| return $self->enable_service('ext_sshd'); |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| 1; |
| __END__ |
| |
| =head1 SEE ALSO |
| |
| L<http://cwiki.apache.org/VCL/> |
| |
| =cut |