123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- #!/bin/bash
-
- # Released under the terms of GPLv3 or at your option any later version.
- # No warranties.
- # Copyright Enrico Tassi <gares@fettunta.org>
-
- # The config file name
- CONFFILE=~/.smd/loop
-
- # The lock file name
- LOCKFILE=~/.smd/loop.lock
-
- if [ -e $LOCKFILE ]; then
- if ps -p `cat $LOCKFILE` > /dev/null | grep smd-loop; then
- echo Another smd-loop instance is running. If it is not the case
- echo remove $LOCKFILE and retry
- 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))"
- exit 1
- else
- echo "Found lock file of a dead instance. Ignored."
- fi
- fi
-
- [ -d ~/.smd ] || mkdir -p ~/.smd
- echo $$ > $LOCKFILE
-
- # The log file
- LOGFILE=~/.smd/log/loop.log
- mkdir -p `dirname $LOGFILE`
- > $LOGFILE
- log() {
- echo `date '+%x %X'`: $@ >> $LOGFILE
- }
- log_cat() {
- cat $1 | sed 's/^/output: /' >> $LOGFILE
- }
-
- # The length of a minute, decrease to debug
- MINUTE=60
-
- # The clock, incremented every $MINUTE
- TIME=1
-
- # Verbose
- VERBOSE=0
-
- # Just create a template
- TEMPLATE_ONLY=0
-
- # Temp file, used to store subprocesses' output
- OUTPUT=`mktemp -q /tmp/smd-loop.XXXXXXXXXX`
-
- # List of commands that failed
- STOP_TAG="__STOP__"
- declare -a FAILURES=("$STOP_TAG")
-
- # Prefix
- PREFIX="@PREFIX@"
-
- if [ `echo $PREFIX | cut -c -1` = "@" ]; then
- echo "smd-loop not installed, assuming smd-pull is ./smd-pull"
- echo "smd-loop not installed, assuming smd-push is ./smd-push"
- log "smd-loop not installed, assuming smd-pull is ./smd-pull"
- log "smd-loop not installed, assuming smd-push is ./smd-push"
- PULL="./smd-pull"
- PUSH="./smd-push"
- else
- PULL="$PREFIX/bin/smd-pull"
- PUSH="$PREFIX/bin/smd-push"
- fi
-
- remove_from_failures() {
- local item="$1"
- for ((i=0; ; i++)); do
- if [ "${FAILURES[$i]}" = "$item" ]; then
- unset FAILURES[$i]
- fi
-
- if [ "${FAILURES[$i]}" = "$STOP_TAG" ]; then
- break
- fi
- done
- }
-
- add_to_failures() {
- local item="$1"
- for ((i=0; ; i++)); do
- if [ "${FAILURES[$i]}" = "" ]; then
- FAILURES[$i]="$item"
- break
- fi
-
- if [ "${FAILURES[$i]}" = "$STOP_TAG" ]; then
- FAILURES[$i]="$item"
- FAILURES[`expr $i + 1`]="$STOP_TAG"
- break
- fi
- done
- }
-
- has_not_failed() {
- local item="$1"
- local found=0
-
- for ((i=0; ; i++)); do
- if [ "${FAILURES[$i]}" = "$item" ]; then
- found=1
- fi
-
- if [ "${FAILURES[$i]}" = "$STOP_TAG" ]; then
- break
- fi
- done
-
- return $found
- }
-
- perform() {
- local cmd=$1
- local endpoint=$2
-
- local cmd_line="$cmd -s $endpoint"
- if [ "$VERBOSE" = 1 ]; then
- echo smd-loop: $cmd_line 1>&2
- fi
- log "$cmd_line"
- $cmd_line > $OUTPUT 2>&1
- if [ $? = 0 ]; then
- cat $OUTPUT
- remove_from_failures "$cmd_line"
- log "completed successfully"
- else
- if grep -q 'human-intervention(avoidable)' $OUTPUT &&
- grep -q 'suggested-actions(retry)' $OUTPUT &&
- has_not_failed "$cmd_line"; then
- if [ "$VERBOSE" = 1 ]; then
- echo smd-loop: warning: failed: $cmd_line 1>&2
- echo smd-loop: warning: will retry later 1>&2
- fi
- add_to_failures "$cmd_line"
- log "avoidable failure, retry later"
- log_cat $OUTPUT
- else
- cat $OUTPUT
- log "persistent or non avoidable failure"
- log_cat $OUTPUT
- exit 1
- fi
- fi
- }
-
- cleanup() {
- rm -f $OUTPUT
- rm -f $LOCKFILE
- log "exiting"
- }
-
- cleanup_killed() {
- cleanup
- log "killed"
- exit 1
- }
-
- trap cleanup "EXIT"
- trap cleanup_killed "SIGTERM"
-
- if [ "$1" = "-v" ]; then
- VERBOSE=1
- shift
- fi
-
- if [ "$1" = "-t" ]; then
- TEMPLATE_ONLY=1
- shift
- fi
-
- if [ ! -f $CONFFILE ]; then
- mkdir -p `dirname $CONFFILE`
- cat > $CONFFILE <<-EOT
- # smd-loop configuration file
- #
- # Line starting with '#' are comments.
- # Frequences are in minutes.
- #
- # pull-frequency push-frequency endpoint-name
- 3 10 default
- EOT
-
- echo No config file found: created a default one
- echo Please edit it: $CONFFILE
- exit 1
- fi
-
- if [ "$TEMPLATE_ONLY" = 1 ]; then
- exit 0
- fi
-
- log "starting"
- first_run=1
- while true; do
- while read pull push endpoint; do
- do_pull=1
- do_push=1
- if [ $pull -gt 0 ]; then do_pull=$((TIME % pull)); fi
- if [ $push -gt 0 ]; then do_push=$((TIME % push)); fi
-
- if [ $do_pull -eq 0 ]; then
- perform $PULL $endpoint
- first_run=0
- fi
- if [ $do_push -eq 0 ]; then
- perform $PUSH $endpoint
- first_run=0
- fi
- done < <(grep -v '^#' $CONFFILE)
- TIME=$((TIME+1))
- if [ $first_run -eq 0 ]; then sleep $MINUTE; fi
- done
|