blob: e80aea39e40823e1bdcd0c1e45380f4b6fb66a18 [file] [log] [blame]
#!/bin/sh -efu
# Copyright 2011-2012 Intel Corporation
# Author: Artem Bityutskiy
# License: GPLv2
srcdir="$(readlink -ev -- ${0%/*})"
PATH="$srcdir:$srcdir/..:$srcdir/../helpers:$srcdir/../helpers/libshell:$PATH"
echo $PATH
. shell-error
. shell-args
. shell-signal
. aiaiai-sh-functions
. aiaiai-email-sh-functions
PROG="${0##*/}"
message_time="yes"
# This is a small trick to make sure the script is portable - check if 'dash'
# is present, and if yes - use it.
if can_switch_to_dash; then
exec dash -euf -- "$srcdir/$PROG" "$@"
exit $?
fi
show_usage()
{
cat <<-EOF
Usage: $PROG [options] <queuedir> <cfgfile.ini>
This program dispatches the incoming queue of patches in the <queuedir>
directory and runs the aiaiai-email-test-patchset program for each patch (or
patch series). Patches are supposed to be in mbox format. <cfgfile.ini> is used
for general configuration of aiaiai-email-test-patchset.
<queuedir> - the directory containing the queue of patches
<cfgfile.ini> - aiaiai-email-test-patchset's configuration file
Options:
-v, --verbose be verbose;
-h, --help show this text and exit.
EOF
}
fail_usage()
{
[ -z "$1" ] || printf "%s\n" "$1"
show_usage
exit 1
}
verbose=
quiet="-q"
# Recursively follow the process tree starting from PID $1 and kill the process
# with name $2
kill_by_name()
{
local parent="$1"; shift
local name="$1"; shift
local child
for child in $(ps -o pid --no-headers --ppid "$parent"); do
kill_by_name "$child" "$name"
done
! ps -p "$parent" -o comm= | grep -q -x -- "$name" || kill "$parent"
}
in_fifo=
tmpdir=
inotify_pid=
cleanup_handler()
{
rm -rf $verbose -- "$tmpdir" >&2
if [ -n "$in_fifo" ] && [ -n "$queuedir" ]; then
# Move files from "in_fifo" directory back to the queue
# directory - this will make sure we do not lose file if we are
# interrupted. We use "mv" to make sure we are protected from
# possible race conditions.
local tmp
tmp="$(mktemp -dt "$PROG.tmp.XXXX")"
mv $verbose -- "$in_fifo" "$tmp" >&2
in_fifo="$tmp/${in_fifo##*/}"
ls -A -- "$in_fifo" | xargs $verbose -I{} -- \
sh -c "mv -- \"$in_fifo/{}\" \"$queuedir\" >&2"
rm $verbose -rf -- "$tmp" >&2
fi
# Kill the tail process - this will send EOF to the fifo and xargs will
# exit when all the items in the fifo are processed
kill_by_name $$ "tail"
[ -z "$inotify_pid" ] || kill "$inotify_pid"
}
set_cleanup_handler cleanup_handler
TEMP=`getopt -n $PROG -o J:,v,h --long verbose,help -- "$@"` ||
fail_usage ""
eval set -- "$TEMP"
while true; do
case "$1" in
-v|--verbose) verbose="--verbose"
;;
-h|--help)
show_usage
exit 0
;;
--) shift; break
;;
*) fail_usage "Unrecognized option: $1"
;;
esac
shift
done
[ "$#" -eq 2 ] || fail_usage "Insufficient or too many arguments"
program_required "inotifywait" ""
[ -z "$verbose" ] || quiet=
mkdir $verbose -p -- "$1" 1>&2
queuedir="$(readlink -fv -- "$1")"; shift
cfgfile="$1"; shift
parse_config "$cfgfile"
in_fifo="$(mktemp -dt "$PROG.in_fifo.XXXX")"
tmpdir="$(mktemp -dt "$PROG.tmpdir.XXXX")"
fifo="$tmpdir/fifo"
mkfifo -- "$fifo"
# tail -f is use to make sure we continue reading the fifo even after EOF.
#
# -P option of xargs provides us the parallelism.
#
# We execute the below command as a separate process - it will run the
# aiaiai-email-test-patchset for every file name read from the fifo.
tail -f -- "$fifo" | xargs -I{} -P"$cfg_max_validators" -- \
aiaiai-email-dispatcher-helper $verbose -- "$in_fifo/{}" "$tmpdir/STOP" \
"$queuedir" "$cfgfile" >&2 &
# Loop forever, wait for new files in the queue directory using inotify and
# validate them
while :; do
if [ -e "$tmpdir/STOP" ]; then
message "Exiting due to error"
exit 1
fi
queue="$(ls -A -c -r -1 -- "$queuedir")"
if [ -z "$queue" ]; then
if [ -z "$inotify_pid" ]; then
inotifywait $quiet $quiet -e create -e moved_to "$queuedir" >&2 &
inotify_pid="$!"
fi
# Check the queue directory again to handle race conditions
queue="$(ls -A -c -r -1 -- "$queuedir")"
[ -z "$queue" ] || continue
verbose "Waiting for new files in $queuedir"
wait "$inotify_pid"
inotify_pid=
[ -z "$verbose" ] || echo >&2
verbose "Inotify event happened in $queuedir"
else
# Move files to the temporary directory and send file names to
# the fifo
printf "%s" "$queue" | xargs $verbose -I{} -- \
sh -c "mv -- \"$queuedir/{}\" \"$in_fifo\""
printf "%s" "$queue" | xargs $verbose -I{} -- \
sh -c "echo \"{}\" > \"$fifo\""
# Let the xargs a chance to start building before we give it
# more work
sleep 5
fi
done