taler-mdb-network-check.sh (5482B)
1 #!/bin/bash 2 # 3 # This file is part of TALER 4 # Copyright (C) 2023, 2024 Taler Systems SA 5 # 6 # TALER is free software; you can redistribute it and/or modify 7 # it under the terms of the GNU General Public License as 8 # published by the Free Software Foundation; either version 3, or 9 # (at your option) any later version. 10 # 11 # TALER is distributed in the hope that it will be useful, but 12 # WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 # GNU General Public License for more details. 15 # 16 # You should have received a copy of the GNU General Public 17 # License along with TALER; see the file COPYING. If not, see 18 # <http://www.gnu.org/licenses/> 19 # 20 # Author: Christian Grothoff 21 # 22 # Script to test for network connectivity, and if 23 # successful launch some "main" application. If 24 # the network goes down, stop the "main" application 25 # and show an error message. 26 # 27 28 set -eu 29 30 EXIT_STATUS=0 31 CHILD_PID=-1 32 ERROR_PID=-1 33 34 # Exit, with error message (hard failure) 35 function exit_fail() { 36 echo " FAILURE:" "$@" >&2 37 EXIT_STATUS=1 38 exit "$EXIT_STATUS" 39 } 40 41 CONF="$HOME/.config/taler.conf" 42 43 # Parse command-line options 44 while getopts ':c:f:h' OPTION; do 45 case "$OPTION" in 46 c) 47 CONF="$OPTARG" 48 ;; 49 f) 50 FAIL_PROG="$OPTARG" 51 ;; 52 h) 53 echo 'Supported options:' 54 # shellcheck disable=SC2016 55 echo ' -c $CONF -- set configuration' 56 # shellcheck disable=SC2016 57 echo ' -f $CMD -- command to run to display failures' 58 ;; 59 ?) 60 exit_fail "Unrecognized command line option" 61 ;; 62 esac 63 done 64 shift $((OPTIND - 1)) 65 66 WORKER="$@" 67 68 dig -h > /dev/null || exit_fail "'dig' is required" 69 70 if [[ ${FAIL_PROG:-} = "" ]] 71 then 72 FAIL_PROG=$(taler-config -c "$CONF" -s taler-mdb -o "FAIL_HELPER") 73 fi 74 75 # Cleanup to run whenever we exit 76 function cleanup() 77 { 78 echo "network-check terminating!" >&2 79 80 if [ "$ERROR_PID" != "-1" ] 81 then 82 kill -TERM "$ERROR_PID" 83 wait "$ERROR_PID" 84 ERROR_PID="-1" 85 fi 86 if [ "$CHILD_PID" != "-1" ] 87 then 88 kill -TERM "$CHILD_PID" 89 wait "$CHILD_PID" 90 CHILD_PID="-1" 91 fi 92 for n in $(jobs -p) 93 do 94 kill "$n" 2> /dev/null || true 95 done 96 wait 97 exit "$EXIT_STATUS" 98 } 99 100 # Function called with the short-hand of a detected 101 # Failure. Stop our child (if any) and show it. 102 function show_failure() 103 { 104 echo "Showing failure $1" 105 if [ "$ERROR_PID" != "-1" ] 106 then 107 kill -TERM "$ERROR_PID" 108 wait 109 ERROR_PID="-1" 110 fi 111 if [ "$CHILD_PID" != "-1" ] 112 then 113 kill -TERM "$CHILD_PID" 114 wait 115 CHILD_PID="-1" 116 fi 117 ${FAIL_PROG} "$1" >&2 & 118 ERROR_PID=$! 119 } 120 121 122 # Install cleanup handler (except for kill -9) 123 trap cleanup EXIT 124 125 # shellcheck disable=SC2120 126 function check_network() 127 { 128 DEF_BACKEND=$(taler-config -c "$CONF" -s "taler-mdb" -o "BACKEND_BASE_URL") 129 BACKEND_HOSTNAME=$(echo "$DEF_BACKEND" | awk -F/ '{print $3}') 130 BACKEND_AUTH=$(taler-config -c "$CONF" -s "taler-mdb" -o "BACKEND_AUTHORIZATION") 131 132 DNS_HOST=$(grep nameserver /etc/resolv.conf | grep -v '^#' | head -n1 | awk '{print $2}') 133 if ! ping -c1 "$DNS_HOST" &> /dev/null 134 then 135 show_failure no-ip 136 return 137 fi 138 if ! dig "$BACKEND_HOSTNAME" &> /dev/null 139 then 140 show_failure backend-dns-resolution-failure 141 return 142 fi 143 if ! ping -c1 "$BACKEND_HOSTNAME" &> /dev/null 144 then 145 show_failure backend-unreachable 146 return 147 fi 148 149 if echo "$DEF_BACKEND" | grep "https://" > /dev/null 150 then 151 if ! wget --no-check-certificate "${DEF_BACKEND}config" -O /dev/null &> /dev/null 152 then 153 show_failure backend-no-webserver 154 return 155 fi 156 if ! wget "${DEF_BACKEND}config" -O /dev/null &> /dev/null 157 then 158 show_failure backend-x509-cert-bad 159 return 160 fi 161 else 162 if ! wget "${DEF_BACKEND}config" -O /dev/null &> /dev/null 163 then 164 show_failure backend-no-webserver 165 return 166 fi 167 fi 168 169 HAVE_PRODUCT=0 170 for PS in $(taler-config -c "$CONF" -S | grep "product-" | head -n1) 171 do 172 URL=$(taler-config -c "$CONF" -s "$PS" -o "INSTANCE" 2> /dev/null || echo "$DEF_BACKEND") 173 AUTH=$(taler-config -c "$CONF" -s "$PS" -o "BACKEND_AUTHORIZATION" 2> /dev/null || echo "$BACKEND_AUTH") 174 175 if ! wget --header "Authorization: $AUTH" "${URL}private/orders" -O /dev/null &> /dev/null 176 then 177 echo "Failed to access backend for product '$PS'" >&2 178 else 179 HAVE_PRODUCT=1 180 fi 181 done 182 if [ "$HAVE_PRODUCT" = 0 ] 183 then 184 show_failure backend-auth-failure 185 return 186 fi 187 188 echo "Network OK" 189 if [ "$ERROR_PID" != "-1" ] 190 then 191 kill -TERM "$ERROR_PID" 192 wait 193 ERROR_PID="-1" 194 fi 195 196 if [ "$CHILD_PID" = "-1" ] 197 then 198 echo "Starting child using $WORKER" 199 # shellcheck disable=SC2068 200 $WORKER & 201 CHILD_PID=$! 202 fi 203 } 204 205 206 # Check network status 207 while true 208 do 209 echo "Checking network status" 210 check_network 211 sleep 30 212 if ! ps "$ERROR_PID" &> /dev/null 213 then 214 wait "${ERROR_PID}" 215 ERROR_PID="-1" 216 fi 217 if ! ps "$CHILD_PID" &> /dev/null 218 then 219 wait "${CHILD_PID}" 220 CHILD_PID="-1" 221 fi 222 done