bash-common.sh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #!/bin/bash
  2. #
  3. # Common functions for bash scripts.
  4. #
  5. # Set variables used for color displays.
  6. if [ -z $TERM ] || [ $TERM == "dumb" ]
  7. then # non-interactive
  8. NORMAL=""
  9. BOLDCYAN=""
  10. BOLDYELLOW=""
  11. BOLDRED=""
  12. else # interactive
  13. NORMAL=$(tput sgr0)
  14. BOLDCYAN=$(tput setaf 6; tput bold)
  15. BOLDYELLOW=$(tput setaf 3; tput bold)
  16. BOLDRED=$(tput setaf 1; tput bold)
  17. fi
  18. # Color display functions.
  19. function cyan {
  20. echo -e "$BOLDCYAN$*$NORMAL"
  21. }
  22. function red {
  23. echo -e "$BOLDRED$*$NORMAL"
  24. }
  25. function yellow {
  26. echo -e "$BOLDYELLOW$*$NORMAL"
  27. }
  28. # Displays informative message.
  29. function information { cyan "$@"; }
  30. # Displays warning message.
  31. function warning { yellow "$@"; }
  32. # Displays error message.
  33. function error { red "ERROR: $@" 1>&2; }
  34. # Displays error message and aborts.
  35. function fail { [ $# -eq 0 ] || error "$@"; exit 1; }
  36. # Retries a command a fixed number of times with a fixed linear backoff.
  37. function retry {
  38. local command=$*
  39. local max_attempts=20 # Maximum number of attempts
  40. local sleep_time=30 # Seconds between attempts
  41. local attempt=1
  42. until $command; do
  43. ((attempt++))
  44. if [ $attempt -gt $max_attempts ]; then
  45. echo "The command has failed after $max_attempts attempts."
  46. return 1
  47. fi
  48. echo "The command failed. Attempt $attempt/$max_attempts will start in $sleep_time seconds."
  49. sleep $sleep_time
  50. done
  51. }
  52. # Detect CYGWIN.
  53. function iscygwin {
  54. if [ $(uname -s | grep "CYGWIN") ]; then
  55. true
  56. else
  57. false
  58. fi
  59. }
  60. # Function used to invoke Windows batch files.
  61. # It removes cygwinisms from the PATH and the environment first
  62. # and does some argument pre-processing.
  63. # It also seems to fix the space problem.
  64. # Author: Igor Pechtchanski
  65. # http://cygwin.com/ml/cygwin/2004-09/msg00150.html
  66. function cywgin_cmd {
  67. ( local c="`cygpath -w \"$1\"`";
  68. shift;
  69. local cmd=`cygpath -u $COMSPEC`;
  70. local args="";
  71. while [ $# != 0 ]; do
  72. if [ -f "$1" ]; then
  73. args="$args '`cygpath -w $1`'";
  74. else
  75. if [ -d "$1" ]; then
  76. args="$args '`cygpath -w $1 | sed 's@\\\\\$@@'`'";
  77. else
  78. args="$args '$1'";
  79. fi;
  80. fi;
  81. shift;
  82. done;
  83. PATH=`echo $PATH |
  84. tr : '\n' |
  85. egrep -vw '^(/usr/local/bin|/usr/bin|/bin|/usr/X11R6/bin)$' |
  86. tr '\n' :`;
  87. unset BASH_ENV COLORTERM CYGWIN DISPLAY HISTCONTROL MAKE_MODE;
  88. unset MANPATH PKG_CONFIG_PATH PS1 PWD SHLVL TERM USER _;
  89. unset CVS CVSROOT CVS_RSH GEN_HOME GROOVY_HOME TOMCAT_DIR;
  90. eval $cmd /c "$c" $args
  91. )
  92. }
  93. # Runs a bash script. Under Cygwin, ignores Windows end-of-line characters.
  94. function run_bash {
  95. if iscygwin
  96. then
  97. BASH_OPTIONS='-o igncr'
  98. else
  99. BASH_OPTIONS=''
  100. fi
  101. bash $BASH_OPTIONS $@
  102. }
  103. # Returns value of property stored in $prop on JSON object stored in $json.
  104. # Author: Carlos Justiniano
  105. # https://gist.github.com/cjus/1047794
  106. function jsonval {
  107. local temp=`echo $json | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w $prop | awk -F": " '{print $2}'`
  108. echo ${temp##*|}
  109. }
  110. # Runs a script on a remote Linux host.
  111. function run_remote_script {
  112. local description=$1
  113. local username=$2
  114. local host=$3
  115. local private_key_file=$4
  116. local script_file=$5
  117. local log_file=$6
  118. echo "$description"
  119. echo "Running script $script_file on $host. To watch the progress, run in another terminal:"
  120. echo "tail -f $log_file"
  121. tr -d '\r' < $script_file | ssh $username@$host -i "$private_key_file" -o StrictHostKeyChecking=no -o BatchMode=yes "bash -s" &>$log_file
  122. }
  123. # Reboots a Linux host.
  124. function reboot_linux_host {
  125. local username=$1
  126. local host=$2
  127. local private_key_file=$3
  128. # Reboot.
  129. echo "Rebooting $host"
  130. retry ssh $username@$host -i "$private_key_file" -o StrictHostKeyChecking=no -o BatchMode=yes "sudo reboot" || fail "Couldn't reboot $host."
  131. # Wait for reboot to start.
  132. sleep 15s
  133. # Reconnect.
  134. echo "Verifying $host availability"
  135. retry ssh $username@$host -i "$private_key_file" -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectionAttempts=5 -o ConnectTimeout=60 "last reboot | head -1" || fail "Couldn't verify $host availability."
  136. echo "$host rebooted"
  137. }
  138. # Uploads a file to a remote Linux host.
  139. function upload_file {
  140. local file_to_upload=$1
  141. local remote_user=$2
  142. local remote_host=$3
  143. local target_directory=$4
  144. local private_key_file=$5
  145. echo "Uploading file $file_to_upload to $remote_host:$target_directory"
  146. retry scp -o StrictHostKeyChecking=no -i "$private_key_file" "$file_to_upload" "$remote_user@$remote_host:$target_directory" || fail "Error uploading file."
  147. }
  148. # Downloads a file from a remote Linux host.
  149. function download_file {
  150. local remote_user=$1
  151. local remote_host=$2
  152. local remote_file=$3
  153. local target_file=$4
  154. local private_key_file=$5
  155. echo "Downloading $remote_host:$remote_file"
  156. retry scp -o StrictHostKeyChecking=no -i "$private_key_file" "$remote_user@$remote_host:$remote_file" "$target_file" || fail "Error downloading file."
  157. }