colo-node-onfree.sh 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #!/usr/bin/env bash
  2. # These variable must be set before the main body is called
  3. SOLANA_LOCK_FILE="${SOLANA_LOCK_FILE:?}"
  4. SECONDARY_DISK_MOUNT_POINT="${SECONDARY_DISK_MOUNT_POINT:?}"
  5. SSH_AUTHORIZED_KEYS="${SSH_AUTHORIZED_KEYS:?}"
  6. FORCE_DELETE="${FORCE_DELETE:?}"
  7. RC=false
  8. if [[ -f "${SOLANA_LOCK_FILE}" ]]; then
  9. exec 9<>"${SOLANA_LOCK_FILE}"
  10. flock -x -n 9 || ( echo "Failed to acquire lock!" 1>&2 && exit 1 )
  11. # shellcheck disable=SC1090
  12. . "${SOLANA_LOCK_FILE}"
  13. if [[ "${SOLANA_LOCK_USER}" = "${SOLANA_USER}" || -n "${FORCE_DELETE}" ]]; then
  14. # Begin running process cleanup
  15. CLEANUP_PID=$$
  16. CLEANUP_PIDS=()
  17. CLEANUP_PPIDS=()
  18. get_pids() {
  19. CLEANUP_PIDS=()
  20. CLEANUP_PPIDS=()
  21. declare line maybe_ppid maybe_pid
  22. while read -r line; do
  23. read -r maybe_ppid maybe_pid _ _ _ _ _ _ _ _ <<<"${line}"
  24. CLEANUP_PIDS+=( "${maybe_pid}" )
  25. CLEANUP_PPIDS+=( "${maybe_ppid}" )
  26. done < <(ps jxh | sort -rn -k2,2)
  27. }
  28. CLEANUP_PROC_CHAINS=()
  29. resolve_chains() {
  30. CLEANUP_PROC_CHAINS=()
  31. declare i pid ppid handled n
  32. for i in "${!CLEANUP_PIDS[@]}"; do
  33. pid=${CLEANUP_PIDS[${i}]}
  34. ppid=${CLEANUP_PPIDS[${i}]}
  35. handled=false
  36. for j in "${!CLEANUP_PROC_CHAINS[@]}"; do
  37. if grep -q "^${ppid}\b" <<<"${CLEANUP_PROC_CHAINS[${j}]}"; then
  38. CLEANUP_PROC_CHAINS[${j}]="${pid} ${CLEANUP_PROC_CHAINS[${j}]}"
  39. handled=true
  40. break
  41. elif grep -q "\b${pid}\$" <<<"${CLEANUP_PROC_CHAINS[${j}]}"; then
  42. CLEANUP_PROC_CHAINS[${j}]+=" ${ppid}"
  43. handled=true
  44. # Don't break, we may be the parent of may proc chains
  45. fi
  46. done
  47. if ! ${handled}; then
  48. n=${#CLEANUP_PROC_CHAINS[@]}
  49. CLEANUP_PROC_CHAINS[${n}]="${pid} ${ppid}"
  50. fi
  51. done
  52. }
  53. # Kill screen sessions
  54. while read -r SID; do
  55. screen -S "${SID}" -X quit
  56. done < <(screen -wipe 2>&1 | sed -e 's/^\s\+\([^[:space:]]\+\)\s.*/\1/;t;d')
  57. # Kill tmux sessions
  58. tmux kill-server &> /dev/null
  59. # Kill other processes
  60. for SIG in INT TERM KILL; do
  61. get_pids
  62. if [[ ${#CLEANUP_PIDS[@]} -eq 0 ]]; then
  63. break
  64. else
  65. resolve_chains
  66. for p in "${CLEANUP_PROC_CHAINS[@]}"; do
  67. if ! grep -q "\b${CLEANUP_PID}\b" <<<"${p}"; then
  68. read -ra TO_KILL <<<"${p}"
  69. N=${#TO_KILL[@]}
  70. ROOT_PPID="${TO_KILL[$((N-1))]}"
  71. if [[ 1 -ne ${ROOT_PPID} ]]; then
  72. LAST_PID_IDX=$((N-2))
  73. for I in $(seq 0 ${LAST_PID_IDX}); do
  74. pid="${TO_KILL[${I}]}"
  75. kill "-${SIG}" "${pid}" &>/dev/null
  76. done
  77. fi
  78. fi
  79. done
  80. get_pids
  81. if [[ ${#CLEANUP_PIDS[@]} -gt 0 ]]; then
  82. sleep 5
  83. fi
  84. fi
  85. done
  86. # End running process cleanup
  87. # Begin filesystem cleanup
  88. git clean -qxdff
  89. rm -f /solana-scratch/* /solana-scratch/.[^.]*
  90. cat > "${HOME}/.ssh/authorized_keys" <<EOAK
  91. ${SSH_AUTHORIZED_KEYS}
  92. EOAK
  93. EXTERNAL_CONFIG_DIR="${SECONDARY_DISK_MOUNT_POINT}/config/"
  94. if [[ -d "${EXTERNAL_CONFIG_DIR}" ]]; then
  95. rm -rf "${EXTERNAL_CONFIG_DIR}"
  96. fi
  97. # End filesystem cleanup
  98. RC=true
  99. else
  100. echo "Invalid user: expected \"${SOLANA_LOCK_USER}\" got \"${SOLANA_USER}\"" 1>&2
  101. fi
  102. exec 9>&-
  103. fi
  104. ${RC}