No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

smd-loop 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #!/bin/bash
  2. # Released under the terms of GPLv3 or at your option any later version.
  3. # No warranties.
  4. # Copyright Enrico Tassi <gares@fettunta.org>
  5. # The config file name
  6. CONFFILE=~/.smd/loop
  7. # The lock file name
  8. LOCKFILE=~/.smd/loop.lock
  9. if [ -e $LOCKFILE ]; then
  10. if ps -p `cat $LOCKFILE` > /dev/null | grep smd-loop; then
  11. echo Another smd-loop instance is running. If it is not the case
  12. echo remove $LOCKFILE and retry
  13. echo "any: smd-loop@localhost: TAGS: error::context(locking) probable-cause(another-instance-is-running) human-intervention(necessary) suggested-actions(run(kill `cat $LOCKFILE`) run(rm $LOCKFILE))"
  14. exit 1
  15. else
  16. echo "Found lock file of a dead instance. Ignored."
  17. fi
  18. fi
  19. [ -d ~/.smd ] || mkdir -p ~/.smd
  20. echo $$ > $LOCKFILE
  21. # The log file
  22. LOGFILE=~/.smd/log/loop.log
  23. mkdir -p `dirname $LOGFILE`
  24. > $LOGFILE
  25. log() {
  26. echo `date '+%x %X'`: $@ >> $LOGFILE
  27. }
  28. log_cat() {
  29. cat $1 | sed 's/^/output: /' >> $LOGFILE
  30. }
  31. # The length of a minute, decrease to debug
  32. MINUTE=60
  33. # The clock, incremented every $MINUTE
  34. TIME=1
  35. # Verbose
  36. VERBOSE=0
  37. # Just create a template
  38. TEMPLATE_ONLY=0
  39. # Temp file, used to store subprocesses' output
  40. OUTPUT=`mktemp -q /tmp/smd-loop.XXXXXXXXXX`
  41. # List of commands that failed
  42. STOP_TAG="__STOP__"
  43. declare -a FAILURES=("$STOP_TAG")
  44. # Prefix
  45. PREFIX="@PREFIX@"
  46. if [ `echo $PREFIX | cut -c -1` = "@" ]; then
  47. echo "smd-loop not installed, assuming smd-pull is ./smd-pull"
  48. echo "smd-loop not installed, assuming smd-push is ./smd-push"
  49. log "smd-loop not installed, assuming smd-pull is ./smd-pull"
  50. log "smd-loop not installed, assuming smd-push is ./smd-push"
  51. PULL="./smd-pull"
  52. PUSH="./smd-push"
  53. else
  54. PULL="$PREFIX/bin/smd-pull"
  55. PUSH="$PREFIX/bin/smd-push"
  56. fi
  57. remove_from_failures() {
  58. local item="$1"
  59. for ((i=0; ; i++)); do
  60. if [ "${FAILURES[$i]}" = "$item" ]; then
  61. unset FAILURES[$i]
  62. fi
  63. if [ "${FAILURES[$i]}" = "$STOP_TAG" ]; then
  64. break
  65. fi
  66. done
  67. }
  68. add_to_failures() {
  69. local item="$1"
  70. for ((i=0; ; i++)); do
  71. if [ "${FAILURES[$i]}" = "" ]; then
  72. FAILURES[$i]="$item"
  73. break
  74. fi
  75. if [ "${FAILURES[$i]}" = "$STOP_TAG" ]; then
  76. FAILURES[$i]="$item"
  77. FAILURES[`expr $i + 1`]="$STOP_TAG"
  78. break
  79. fi
  80. done
  81. }
  82. has_not_failed() {
  83. local item="$1"
  84. local found=0
  85. for ((i=0; ; i++)); do
  86. if [ "${FAILURES[$i]}" = "$item" ]; then
  87. found=1
  88. fi
  89. if [ "${FAILURES[$i]}" = "$STOP_TAG" ]; then
  90. break
  91. fi
  92. done
  93. return $found
  94. }
  95. perform() {
  96. local cmd=$1
  97. local endpoint=$2
  98. local cmd_line="$cmd -s $endpoint"
  99. if [ "$VERBOSE" = 1 ]; then
  100. echo smd-loop: $cmd_line 1>&2
  101. fi
  102. log "$cmd_line"
  103. $cmd_line > $OUTPUT 2>&1
  104. if [ $? = 0 ]; then
  105. cat $OUTPUT
  106. remove_from_failures "$cmd_line"
  107. log "completed successfully"
  108. else
  109. if grep -q 'human-intervention(avoidable)' $OUTPUT &&
  110. grep -q 'suggested-actions(retry)' $OUTPUT &&
  111. has_not_failed "$cmd_line"; then
  112. if [ "$VERBOSE" = 1 ]; then
  113. echo smd-loop: warning: failed: $cmd_line 1>&2
  114. echo smd-loop: warning: will retry later 1>&2
  115. fi
  116. add_to_failures "$cmd_line"
  117. log "avoidable failure, retry later"
  118. log_cat $OUTPUT
  119. else
  120. cat $OUTPUT
  121. log "persistent or non avoidable failure"
  122. log_cat $OUTPUT
  123. exit 1
  124. fi
  125. fi
  126. }
  127. cleanup() {
  128. rm -f $OUTPUT
  129. rm -f $LOCKFILE
  130. log "exiting"
  131. }
  132. cleanup_killed() {
  133. cleanup
  134. log "killed"
  135. exit 1
  136. }
  137. trap cleanup "EXIT"
  138. trap cleanup_killed "SIGTERM"
  139. if [ "$1" = "-v" ]; then
  140. VERBOSE=1
  141. shift
  142. fi
  143. if [ "$1" = "-t" ]; then
  144. TEMPLATE_ONLY=1
  145. shift
  146. fi
  147. if [ ! -f $CONFFILE ]; then
  148. mkdir -p `dirname $CONFFILE`
  149. cat > $CONFFILE <<-EOT
  150. # smd-loop configuration file
  151. #
  152. # Line starting with '#' are comments.
  153. # Frequences are in minutes.
  154. #
  155. # pull-frequency push-frequency endpoint-name
  156. 3 10 default
  157. EOT
  158. echo No config file found: created a default one
  159. echo Please edit it: $CONFFILE
  160. exit 1
  161. fi
  162. if [ "$TEMPLATE_ONLY" = 1 ]; then
  163. exit 0
  164. fi
  165. log "starting"
  166. first_run=1
  167. while true; do
  168. while read pull push endpoint; do
  169. do_pull=1
  170. do_push=1
  171. if [ $pull -gt 0 ]; then do_pull=$((TIME % pull)); fi
  172. if [ $push -gt 0 ]; then do_push=$((TIME % push)); fi
  173. if [ $do_pull -eq 0 ]; then
  174. perform $PULL $endpoint
  175. first_run=0
  176. fi
  177. if [ $do_push -eq 0 ]; then
  178. perform $PUSH $endpoint
  179. first_run=0
  180. fi
  181. done < <(grep -v '^#' $CONFFILE)
  182. TIME=$((TIME+1))
  183. if [ $first_run -eq 0 ]; then sleep $MINUTE; fi
  184. done