0

I have a perl script in which i want to first check if it possible to ssh into the server before i actually do ssh. So if it possible to ssh, then go ahead and ssh into that server, otherwise handle this exception appropriately.

So i have this script that goes through a textfile with a list of databases, and tries to ssh into each server to perform a bash command that checks if the server is performing MySQL SST or not:

    #!/usr/bin/perl -w

use strict;
use warnings;

use 5.010;
use DBI;
use Encode;
use IO::File;
use JSON;
use utf8;

BEGIN {
    binmode STDERR, ':utf8';
    binmode STDIN, ':utf8';
    binmode STDOUT, ':utf8';
}

my $time = localtime();
my $file = '/opt/db-servers/db.txt';
open my $info, $file or die "Could not open $file: $!";

while( my $hostname = <$info>)  {
    chomp( $hostname );
    my $xtrabk_check = `ssh $hostname ps -ef |grep mysql | grep wsrep_sst_xtrabackup-v2`;
    my $role_check = `ssh $hostname ps -ef |grep mysql | grep donor`;
    my $error_log = `ssh $hostname ps -ef |grep mysql`;
        if ( $xtrabk_check ne "" ){
            if ( $role_check ne "" ){
                my $cmd ="curl -vs -o /dev/null -X POST --data-urlencode 'payload={\"channel\": \"#db-wsrep-status-log\", \"username\": \"db-wsrep-status-log\", \"text\": \"$time: $hostname: --role Donor \n```$error_log```\", \"icon_emoji\": \":scorpion:\"}' 2>&1 /dev/null https://hooks.slack.com/services/GVadasdd/B6LSMF5GV/BIApnzoIldfdsrw343wf";
                system($cmd);
            }
            else {
                my $cmd ="curl -vs -o /dev/null -X POST --data-urlencode 'payload={\"channel\": \"#db-wsrep-status-log\", \"username\": \"db-wsrep-status-log\", \"text\": \"$time: $hostname: State transfer in progress, setting sleep higher mysqld \n```$error_log```\", \"icon_emoji\": \":scorpion:\"}' 2>&1 https://hooks.slack.com/services/GVadasdd/B6LSMF5GV/BIApnzoIldfdsrw343wf";
                system($cmd);
            }
       }
}
close $info;

So probably before performing the three lines below, i want to be able to know if that server is down (hence cannot ssh into it) or not (then ssh into it with the commands below):

my $xtrabk_check = `ssh $hostname ps -ef |grep mysql | grep wsrep_sst_xtrabackup-v2`;
    my $role_check = `ssh $hostname ps -ef |grep mysql | grep donor`;
    my $error_log = `ssh $hostname ps -ef |grep mysql`;

How can i go about achieving this? By the way, the slack URL have been altered so security worries there.

I have added suggested code below, but still not seem to be working:

    ...
    while( my $hostname = <$info>)  {
    chomp( $hostname );
    my $ssh_ping = `$ssh_cmd\'@\'$hostname true`;
    if ( `$ssh_ping true`){
    my $xtrabk_check = `ssh $hostname ps -ef |grep mysql | grep wsrep_sst_xtrabackup-v2`;
    my $role_check = `ssh $hostname ps -ef |grep mysql | grep donor`;
    my $error_log = `ssh $hostname ps -ef |grep mysql`;
        if ( $xtrabk_check ne "" ){
            if ( $role_check ne "" ){
                my $cmd ="curl -vs -o /dev/null -X POST --data-urlencode 'payload={\"channel\": \"#db-wsrep-status-log\", \"username\": \"db-wsrep-status-log\", \"text\": \"$time: $hostname: --role Donor \n```$error_log```\", \"icon_emoji\": \":scorpion:\"}' 2>&1 /dev/null https://hooks.slack.com/services/GVadasdd/B6LSMF5GV/BIApnzoIldfdsrw343wf";
                system($cmd);
            }
            else {
                my $cmd ="curl -vs -o /dev/null -X POST --data-urlencode 'payload={\"channel\": \"#db-wsrep-status-log\", \"username\": \"db-wsrep-status-log\", \"text\": \"$time: $hostname: State transfer in progress, setting sleep higher mysqld \n```$error_log```\", \"icon_emoji\": \":scorpion:\"}' 2>&1 https://hooks.slack.com/services/GVadasdd/B6LSMF5GV/BIApnzoIldfdsrw343wf";
                system($cmd);
            } 
       }
    } #end $ssh_ping if
} #end while
2
  • 6
    The simplest way to see if you can SSH is to SSH. ssh $hostname true, for example, and check the exit status. BTW, consider saving the output of ssh $hostname ps -ef and parsing it instead of running it thrice.
    – muru
    Oct 17, 2017 at 7:01
  • 2
    As muru says do a single ssh and collect the output into a variable for further processing such as if($v =~ m/mysql/){...}. You might like to add -o ConnectTimeout=20, for example, to the ssh if you want to not hang too long for slightly dead servers. Also -o BatchMode=yes is useful in scripts to ensure the ssh never tries to go interactive when things get broken.
    – meuh
    Oct 17, 2017 at 17:04

1 Answer 1

1

You can do something like this :

`ssh $hostname true`;

if ($? == 0) {
    ...;
} else {
    die "ssh failed";
}
3
  • I have updated the script adding some suggested lines. Please check updated par of the code above. Oct 19, 2017 at 4:45
  • POST edited accordingly Oct 19, 2017 at 18:08
  • The true command actually returns 0 (in Bash 0 is true, >0 is false).
    – sborsky
    Oct 19, 2017 at 22:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.