github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/scripts/m3dbnode_bootstrapped.sh (about) 1 #!/bin/ash 2 # shellcheck shell=dash 3 4 # Checks for node health: 5 # 1. Is there a topology? If not, exit healthy. 6 # 2. Is the host in the topology? If not, exit healthy. 7 # 3. Is there a namespace? If not, exit healthy. 8 # 4. If 1-3 true, check if host reports bootstrapped and exit healthy if so 9 # (fail otherwise). 10 11 set -o pipefail 12 13 COORDINATOR_PORT=${COORDINATOR_PORT:-7201} 14 DBNODE_PORT=${DBNODE_PORT:-9002} 15 COORD_PLACEMENT_ENDPOINT="http://localhost:${COORDINATOR_PORT}/api/v1/services/m3db/placement" 16 COORD_NAMESPACE_ENDPOINT="http://localhost:${COORDINATOR_PORT}/api/v1/services/m3db/namespace" 17 DBNODE_ENDPOINT="http://localhost:${DBNODE_PORT}/health" 18 19 HOSTNAME=${HOSTNAME:-$(hostname)} 20 21 COORD_TMPFILE=$(mktemp) 22 DBNODE_TMPFILE=$(mktemp) 23 24 cleanup() { 25 rm -f "$COORD_TMPFILE" "$DBNODE_TMPFILE" 26 } 27 28 trap cleanup EXIT 29 30 curl --max-time 60 -sSf -o "$COORD_TMPFILE" "$COORD_PLACEMENT_ENDPOINT" 31 RES=$? 32 33 # Curl exits 22 for 400+ status code. Note this leaves us vulnerable to saying 34 # bootstrapped if our script makes a bad request and must use caution when 35 # modifying the script or the coordinator placement endpoint. 36 if [ "$RES" -eq 22 ]; then 37 COORD_OUTPUT=$(cat "$COORD_TMPFILE") 38 echo "Received 4xx from coordinator $COORD_PLACEMENT_ENDPOINT: $COORD_OUTPUT" 39 exit 0 40 fi 41 42 # jq -e will exit 1 if the last value was null (or false) 43 jq -e ".placement.instances | .[\"${HOSTNAME}\"]" < "$COORD_TMPFILE" >/dev/null 44 RES=$? 45 46 if [ "$RES" -ne 0 ]; then 47 echo "Host not present in topology" 48 exit 0 49 fi 50 51 curl --max-time 60 -sSf -o "$COORD_TMPFILE" "$COORD_NAMESPACE_ENDPOINT" 52 RES=$? 53 54 if [ "$RES" -eq 22 ]; then 55 echo "Received 4xx from namespace endpoint $COORD_NAMESPACE_ENDPOINT" 56 exit 0 57 fi 58 59 # If there IS a placement but NO namespace, then the dbnode will respond 60 # connection refused (until https://github.com/m3db/m3/issues/996 is addressed) 61 # and the health script would fail hereafter. However, if there's no namespaces 62 # then we want to consider the node healthy because it just doesn't have 63 # anything to do. So before we ask the dbnode for its health, check if there's 64 # no namespaces to begin with, and if so exit 0. 65 NS_COUNT=$(jq '.registry.namespaces | length' < "$COORD_TMPFILE") 66 if [ "$NS_COUNT" -eq 0 ]; then 67 echo "No namespaces in cluster" 68 exit 0 69 fi 70 71 curl --max-time 60 -sSf -o "$DBNODE_TMPFILE" "$DBNODE_ENDPOINT" 72 RES=$? 73 74 if [ "$RES" -ne 0 ]; then 75 echo "Received exit code $RES from curl health $DBNODE_ENDPOINT" 76 exit 1 77 fi 78 79 BOOTSTRAPPED=$(jq .bootstrapped < "$DBNODE_TMPFILE") 80 if [ "$BOOTSTRAPPED" != "true" ]; then 81 echo "Not bootstrapped ($BOOTSTRAPPED)" 82 exit 1 83 fi 84 85 echo "Host bootstrapped" 86 exit 0