the-bastion/bin/plugin/open/alive
Stéphane Lesimple 345a1f951f fix: don't exit with fping host is unreachable
As ping can return unknown exit codes for unknown cases,
just never bail out to avoid taking bad decisions,
as we retry each second maximum, there's no DoS risk
2023-12-05 10:02:52 +01:00

78 lines
2.1 KiB
Perl
Executable file

#! /usr/bin/env perl
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
use common::sense;
use Time::HiRes ();
use File::Basename;
use lib dirname(__FILE__) . '/../../../lib/perl';
use OVH::Result;
use OVH::Bastion;
use OVH::Bastion::Plugin qw( :DEFAULT help );
my $remainingOptions = OVH::Bastion::Plugin::begin(
argv => \@ARGV,
header => "ping until host is alive",
options => {},
helptext => <<'EOF',
Ping a host and exit as soon as it answers
This command can be used to monitor a host that is expected to go back online soon.
Note that if you want to ssh to it afterwards, you can simply use the ``--wait`` main option.
Usage: --osh SCRIPT_NAME [--host] HOSTNAME
--host HOSTNAME hostname or IP to ping
EOF
);
# be nice and try to guessify a user@host as first param
# if user said --osh alive usah@mymachine.example.org
if ( not $host
and not $ip
and not $user
and ref $remainingOptions eq 'ARRAY'
and @$remainingOptions == 1
and $remainingOptions->[0] =~ /^([a-zA-Z0-9_-]+\@)?([a-zA-Z0-9][a-zA-Z0-9.-]{1,})$/)
{
$user = $1;
$host = $2;
$user =~ s/\@$//;
}
#
# code
#
my $fnret;
if (not $host) {
help();
osh_exit 'ERR_MISSING_PARAMETER', "Missing required host parameter";
}
osh_info "Waiting for $host to be alive...";
my $startedat = Time::HiRes::gettimeofday();
my $firstLoop = 1;
my @command = qw{ fping -- };
push @command, $host;
while (1) {
$fnret = OVH::Bastion::execute(cmd => \@command, noisy_stdout => 1, noisy_stderr => 1);
if ($fnret->err eq 'ERR_EXEC_FAILED') {
if ($firstLoop) {
# maybe fping doesn't work, fallback to ping
@command = qw{ ping -c 1 -w 1 -- };
push @command, $host;
$firstLoop = 0;
next; # restart the loop to exec ping
}
osh_exit $fnret; # we tried both ping and fping :(
}
$fnret or osh_exit $fnret;
if ($fnret->value->{'sysret'} == 0) {
my $delay = int(Time::HiRes::gettimeofday() - $startedat);
osh_info "Alive after waiting for $delay seconds, exiting!";
osh_ok {waited_for => $delay + 0};
}
sleep 1;
}
osh_exit 'ERR_INTERNAL';