From 6f4df4ed2202b23760640c6838de9f125176729e Mon Sep 17 00:00:00 2001 From: Digimer Date: Fri, 23 Feb 2018 00:58:47 -0700 Subject: [PATCH] * Changed 'database::X::ping_before_connect' to 'database::X::ping' and made the value be the actual timeout to wait for pings when trying to connect to a database. Signed-off-by: Digimer --- Anvil/Tools/Database.pm | 49 +++++++++++++++++++++++------------------ Anvil/Tools/System.pm | 20 ++++++++++++++++- anvil.conf | 31 +++++++++++++++++++++++--- notes | 6 +++++ share/words.xml | 2 +- 5 files changed, 82 insertions(+), 26 deletions(-) diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index b7a2bd76..36b6e8ab 100755 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -551,20 +551,22 @@ sub configure_pgsql This method tries to connect to all databases it knows of. To define databases for a machine to connect to, load a configuration file with the following parameters; - database::1::host = an-striker01.alteeve.com - database::1::port = 5432 - database::1::name = scancore - database::1::user = admin - database::1::password = Initial1 - database::1::ping_before_connect = 1 + database::1::host = an-striker01.alteeve.com + database::1::port = 5432 + database::1::name = scancore + database::1::user = admin + database::1::password = Initial1 + database::1::ping = 0.25 + + database::2::host = an-striker02.alteeve.com + database::2::port = 5432 + database::2::name = scancore + database::2::user = admin + database::2::password = Initial1 + database::2::ping = 0.25 + +Please see the comments in /etc/anvil/anvil.conf for more information on how to use the above variables. - database::2::host = an-striker02.alteeve.com - database::2::port = 5432 - database::2::name = scancore - database::2::user = admin - database::2::password = Initial1 - database::2::ping_before_connect = 1 - The C<< 1 >> and C<< 2 >> are the IDs of the given databases. They can be any number and do not need to be sequential, they just need to be unique. This module will return the number of databases that were successfully connected to. This makes it convenient to check and exit if no databases are available using a check like; @@ -679,9 +681,9 @@ sub connect }}); # If not set, we will always ping before connecting. - if ((not exists $anvil->data->{database}{$id}{ping_before_connect}) or (not defined $anvil->data->{database}{$id}{ping_before_connect})) + if ((not exists $anvil->data->{database}{$id}{ping}) or (not defined $anvil->data->{database}{$id}{ping})) { - $anvil->data->{database}{$id}{ping_before_connect} = 1; + $anvil->data->{database}{$id}{ping} = 1; } # Make sure the user didn't specify the same target twice. @@ -713,17 +715,22 @@ sub connect password => $anvil->Log->secure ? $password : "--", }}); + ### TODO: Can we do a telnet port ping with a short timeout instead of a shell ping call? + # Assemble my connection string my $db_connect_string = "$driver:dbname=$name;host=$host;port=$port"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { - db_connect_string => $db_connect_string, - "database::${id}::ping_before_connect" => $anvil->data->{database}{$id}{ping_before_connect}, + db_connect_string => $db_connect_string, + "database::${id}::ping" => $anvil->data->{database}{$id}{ping}, }}); - #if ($anvil->data->{database}{$id}{ping_before_connect}) - if (0) + if ($anvil->data->{database}{$id}{ping}) { # Can I ping? - my ($pinged) = $anvil->System->ping({ping => $host, count => 1}); + my ($pinged) = $anvil->System->ping({ + ping => $host, + count => 1, + timeout => $anvil->data->{database}{$id}{ping}, + }); my $ping_time = tv_interval ($start_time, [gettimeofday]); print "[".$ping_time."] - Pinged: [$host:$port:$name:$user]\n"; @@ -731,7 +738,7 @@ sub connect $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { pinged => $pinged }}); if (not $pinged) { - # Didn't ping and 'database::::ping_before_connect' not set. Record this + # Didn't ping and 'database::::ping' not set. Record this # in the failed connections array. $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => "log_0063", variables => { host => $port ? $host.":".$port : $host, diff --git a/Anvil/Tools/System.pm b/Anvil/Tools/System.pm index d9558c69..04f10a6b 100755 --- a/Anvil/Tools/System.pm +++ b/Anvil/Tools/System.pm @@ -840,6 +840,10 @@ B: See C<< System->remote_call >> for additional information on specifying This is the host name or IP address of a remote machine that you want to run the ping on. This is used to test a remote machine's access to a given ping target. +=head3 timeout (optional, default '1') + +This is how long we will wait for a ping to return, in seconds. Any real number is allowed (C<< 1 >> (one second), C<< 0.25 >> (1/4 second), etc). If set to C<< 0 >>, we will wait for the ping command to exit without limit. + =cut sub ping { @@ -862,6 +866,7 @@ sub ping my $ping = $parameter->{ping} ? $parameter->{ping} : ""; my $port = $parameter->{port} ? $parameter->{port} : ""; my $target = $parameter->{target} ? $parameter->{target} : ""; + my $timeout = $parameter->{timeout} ? $parameter->{timeout} : 1; # This sets the 'timeout' delay. $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count, fragment => $fragment, @@ -872,6 +877,14 @@ sub ping target => $target, }}); + # Was timeout specified as a simple integer? + if (($timeout !~ /^\d+$/) && ($timeout !~ /^\d+\.\d+$/)) + { + # The timeout was invalid, switch it to 1 + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { timeout => $timeout }}); + $timeout = 1; + } + # If the payload was set, take 28 bytes off to account for ICMP overhead. if ($payload) { @@ -881,7 +894,12 @@ sub ping # Build the call. Note that we use 'timeout' because if there is no connection and the hostname is # used to ping and DNS is not available, it could take upwards of 30 seconds time timeout otherwise. - my $shell_call = $anvil->data->{path}{exe}{timeout}." 1 ".$anvil->data->{path}{exe}{'ping'}." -W 1 -n $ping -c 1"; + my $shell_call = ""; + if ($timeout) + { + $shell_call = $anvil->data->{path}{exe}{timeout}." $timeout "; + } + $shell_call .= $anvil->data->{path}{exe}{'ping'}." -W 1 -n $ping -c 1"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { shell_call => $shell_call }}); if (not $fragment) { diff --git a/anvil.conf b/anvil.conf index 233df5dc..10c9aad1 100644 --- a/anvil.conf +++ b/anvil.conf @@ -1,19 +1,44 @@ -# This is the main Striker (and ScanCore) configuration file. +### This is the main Striker (and ScanCore) configuration file. # +# Database connections; +# +# Each Anvil! database is defined below using an incrementing counter as the second variable. The value of +# the second variable is not important, so long as it is unique. Generally, it's a simple incrementing +# intger. +# +# There are six variables for each database definition; +# host = This is the (resolvable) host name or IP address of the peer database. +# port = This is the TCP port used to connect to the database. By default, it is 5432 +# name = This is the name of the database itself. By default (and almost always), it is 'scancore'. +# user = This is the user that owns the database. By default (and almost always), it is 'admin'. +# password = This is the password used to connect to the database. +# NOTE: Do not directly change the database password. Please use 'anvil-update-password' so that +# the WebUI, database, nodes and peers are all kept in sync. +# ping = If set, this will cause a ping to be made against the database server before the actual +# connection is attempted. This can be useful when peer dashboards are offline for extended +# periods of time. The value can be any real number and will be used as the timeout for the actual +# ping. If the peer dashboard is on the same subnet, a value of '0.25' (250ms) should be a good +# balance between giving the peer a chance to reply and not waiting too long when it is offline. +# If the peer is remote, you will want to set this to '1' (1000ms) or higher. +# +# Setting this to '0' disables pinging before connecting entirely. In this case, if the peer is +# offline, it will take about 3 seconds on average for the connection attempt to timeout. This +# might be necessary if the peer dashboard is behind a firewall/router or otherwise can't respond +# to ICMP pings. database::1::host = 192.168.122.201 database::1::port = 5432 database::1::name = scancore database::1::user = admin database::1::password = Initial1 -database::1::ping_before_connect = 1 +database::1::ping = 1 database::2::host = 192.168.122.202 database::2::port = 5432 database::2::name = scancore database::2::user = admin database::2::password = Initial1 -database::2::ping_before_connect = 1 +database::2::ping = 1 # This is the schema for the ScanCore database. sys::database::schema = /usr/sbin/anvil/anvil.sql diff --git a/notes b/notes index 97d9d64e..1da5175a 100644 --- a/notes +++ b/notes @@ -479,3 +479,9 @@ pcs resource manage srv01-c7 ==== Unrelated Notes; + + +17:03 <@kgaillot> digimer: quick skim looks good. for metadata, refers to OCF version, so 1.0; your RA version goes in . also on-fail/interval/depth are pacemaker properties, not part of the ocf + metadata +17:05 <@kgaillot> digimer: also be aware that probes (monitor w/0 interval) can be done on nodes that aren't intended to run the resource, so it should return not running in that case (eg if necessary files don't exist). really this is + an issue that should be handled on the pacemaker side but it isn't currently diff --git a/share/words.xml b/share/words.xml index 1325f61c..3438634d 100644 --- a/share/words.xml +++ b/share/words.xml @@ -114,7 +114,7 @@ Connecting to Database with configuration ID: [#!variable!id!#] Database user: [#!variable!user!#] already exists with ID: [#!variable!id!#]. users_home() was asked to find the home directory for the user: [#!variable!user!#], but was unable to do so.]]> SSH session opened without a password to: [#!variable!target!#]. - The database: [#!variable!host!# -> #!variable!name!#] with the ID: [#!variable!id!#] did not respond to pings and 'database::#!variable!id!#::ping_before_connect' is not set to '0' in '#!data!path::configs::striker.conf!#', skipping it. + The database: [#!variable!host!# -> #!variable!name!#] with the ID: [#!variable!id!#] did not respond to pings and 'database::#!variable!id!#::ping' is not set to '0' in '#!data!path::configs::striker.conf!#', skipping it. [ Warning ] - The database: [#!variable!name!#] on host: [#!variable!host!#] with ID: [#!variable!id!#] can not be used, skipping it. The database connection error was: