2014-01-08 11:31:49 +00:00
#!/bin/bash
# Copyright 2010-2014 Frank Liepold / 1&1 Internet AG
2013-07-04 08:05:39 +00:00
#
2014-01-08 11:31:49 +00:00
# Email: frank.liepold@1und1.de
2013-07-04 08:05:39 +00:00
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#####################################################################
2014-01-08 11:31:49 +00:00
# wrapper for the exit builtin to be able to remove temporary files
function start_test_exit
{
rm -f $environ_save
exit $1
}
2013-07-04 08:05:39 +00:00
2013-08-06 12:29:21 +00:00
shopt -s extdebug
2013-07-04 08:05:39 +00:00
# Use directory names as basis for configuration variants
script_dir = " $( cd " $( dirname " $( which " $0 " ) " ) " ; pwd ) "
2014-01-08 09:18:31 +00:00
lib_dir = $script_dir /modules
2014-01-09 06:31:18 +00:00
echo " ================= Sourcing libraries in $lib_dir =============================== "
2014-01-08 09:18:31 +00:00
for lib in $lib_dir /lib*.sh; do
echo " Sourcing $lib "
2014-01-08 11:31:49 +00:00
source " $lib " || start_test_exit $?
2013-07-04 08:05:39 +00:00
done
2014-01-09 06:31:18 +00:00
echo "================= End sourcing libraries ======================================="
2013-07-04 08:05:39 +00:00
to_produce = " ${ to_produce :- replay .gz } "
to_check = " ${ to_check :- } "
to_start = " ${ to_start :- main } "
dry_run_script = 0
2013-12-20 16:01:37 +00:00
start_dir = $( pwd )
# all directories between config_root_dir and the actual test directory will be
# considered as "configuration options". That means that a <dirname>.conf file must
# be provided for all these directories
config_root_dir = $start_dir
2013-12-24 06:55:57 +00:00
verbose_script = 1
2013-07-04 08:05:39 +00:00
# check some preconditions
check_list = "grep sed gawk head tail cut nice date gzip gunzip zcat buffer"
check_installed " $check_list "
# include modules
prepare_list = ""
setup_list = ""
run_list = ""
cleanup_list = ""
finish_list = ""
2013-11-07 09:33:43 +00:00
function set_host_locks
{
local host
if [ ${# main_host_list [*] } -eq 0 ] ; then
lib_vmsg " warning: main_host_list empty"
return
fi
2014-01-09 06:31:18 +00:00
echo "================= Creating lock files =========================================="
2013-11-07 09:33:43 +00:00
for host in " ${ main_host_list [@] } " ; do
local lock_file = ${ main_lock_file_list [ $host ] }
if [ -z " $lock_file " ] ; then
lib_exit 1 " no entry in main_lock_file_list for host $host "
fi
if [ -f $lock_file ] ; then
echo " Failure lockfile $lock_file for host $host exists! " >& 2
lib_exit $main_prevent_remove_lock_files_code
fi
date > $lock_file || lib_exit 1
lib_vmsg " created lockfile $lock_file on $host "
done
2014-01-09 06:31:18 +00:00
echo "================= End creating lock files ======================================"
2013-11-07 09:33:43 +00:00
}
function release_host_locks
{
2014-01-09 06:31:18 +00:00
echo "================= Deleting lock files =========================================="
2013-11-07 09:33:43 +00:00
for host in " ${ main_host_list [@] } " ; do
local lock_file = ${ main_lock_file_list [ $host ] }
rm -f $lock_file || lib_exit 1
lib_vmsg " deleted lockfile $lock_file on $host "
done
2014-01-09 06:31:18 +00:00
echo "================= End deleting lock files ======================================"
2013-11-07 09:33:43 +00:00
}
2013-07-04 08:05:39 +00:00
function source_module
{
module = " $1 "
modname = " $( basename $module | sed 's/^[0-9]*_\([^.]*\)\..*/\1/' ) "
if source_config default-$modname ; then
2013-11-07 09:33:43 +00:00
echo " Sourcing module $modname "
2014-01-08 11:31:49 +00:00
source $module || start_test_exit $?
2013-07-04 08:05:39 +00:00
elif [ " $modname " = "main" ] ; then
2013-11-07 09:33:43 +00:00
echo " Cannot use main module. Please provide some config file 'default- $modname .conf' in $( pwd ) or in some parent directory. "
2014-01-08 11:31:49 +00:00
start_test_exit -1
2013-07-04 08:05:39 +00:00
fi
}
2013-12-30 09:28:30 +00:00
function save_environment
{
# we cannot use lib_exit because the libs are not yet sourced in
environ_save = /tmp/environ.sav.$$
rm -f $environ_save || lib_exit 1 " cannot remove $environ_save "
set >$environ_save || lib_exit 1 " cannot create $environ_save "
}
# prints all shell variables which are set via sourcing the *.conf files
function print_config_environment
{
local f
local environ_actual = /tmp/environ.act.$$
[ -n " $environ_save " ] || lib_exit 1 "variable environ_save not set"
[ -r " $environ_save " ] || lib_exit 1 " file $environ_save not readable "
rm -f $environ_actual || lib_exit 1 " cannot remove $environ_actual "
set >$environ_actual || lib_exit 1 " cannot create $environ_actual "
# delete function definitions and sort
for f in $environ_save $environ_actual ; do
sed -i -e '/^.* () *$/d;/^{ *$/,/^} *$/d' $f || lib_exit 1
sort -o $f $f || lib_exit 1
done
2014-01-09 06:31:18 +00:00
echo "================= Configuration variables ======================================"
2013-12-30 09:28:30 +00:00
# print lines uniq to $environ_actual and remove some not interesting
# variables
comm -2 -3 $environ_actual $environ_save | \
egrep -v '^(BASH_LINENO|FUNCNAME|OLDPWD|_)='
2014-01-08 11:31:49 +00:00
rm -f $environ_actual
2014-01-09 06:31:18 +00:00
echo "================= End configuration variables =================================="
2013-12-30 09:28:30 +00:00
}
save_environment # for later use in print_config_environment
2013-07-04 08:05:39 +00:00
shopt -s nullglob
2014-01-09 06:31:18 +00:00
echo "================= Sourcing modules and default configuration ==================="
2013-07-04 08:05:39 +00:00
for module in $module_dir /[ 0-9] *.sh; do
source_module " $module "
done
2014-01-09 06:31:18 +00:00
echo "================= End sourcing modules and default configuration ==============="
2013-07-04 08:05:39 +00:00
# parse options.
while [ $# -ge 1 ] ; do
key = " $( echo " $1 " | cut -d= -f1) "
val = " $( echo " $1 " | cut -d= -f2-) "
case " $key " in
2013-11-07 09:33:43 +00:00
--test | --dry-run)
2013-07-04 08:05:39 +00:00
dry_run_script = " $val "
2013-11-07 09:33:43 +00:00
shift
2013-07-04 08:05:39 +00:00
; ;
2013-11-07 09:33:43 +00:00
--override)
shift
echo " => Overriding $1 "
eval $1
shift
2013-07-04 08:05:39 +00:00
; ;
2013-12-20 16:01:37 +00:00
--config_root_dir)
config_root_dir = " $val "
shift
; ;
2013-11-07 09:33:43 +00:00
*)
break
2013-07-04 08:05:39 +00:00
; ;
esac
done
2013-12-20 16:01:37 +00:00
if ! cd $config_root_dir ; then
echo " cannot cd $config_root_dir " >& 2
2014-01-08 11:31:49 +00:00
start_test_exit 1
2013-12-20 16:01:37 +00:00
else
config_root_dir = $( pwd ) # we need the absolute path
cd $start_dir
fi
2013-07-04 08:05:39 +00:00
ignore_cmd = "grep -v '[/.]old' | grep -v 'ignore'"
sort_cmd = "while read i; do if [ -e \"\$i\"/prio-[0-9]* ]; then echo \"\$(cd \$i; ls prio-[0-9]*):\$i\"; else echo \"z:\$i\"; fi; done | sort | sed 's/^[^:]*://'"
# find directories
2014-01-09 06:31:18 +00:00
echo " ================= Scanning subdirectories of $start_dir ======================== "
2013-11-07 09:33:43 +00:00
for test_dir in $( find . -type d | eval " $ignore_cmd " | eval " $sort_cmd " ) ; do
( ( dry_run_script ) ) || rm -f $test_dir /dry-run.$to_produce
if [ -e " $test_dir /skip " ] ; then
echo " Skipping directory $test_dir "
continue
fi
if [ $( find $test_dir -type d | eval " $ignore_cmd " | wc -l) -gt 1 ] ; then
echo " Ignoring inner directory $test_dir "
continue
fi
shopt -u nullglob
if ls $test_dir /*.$to_produce > /dev/null 2>& 1; then
echo " Already finished $test_dir "
continue
fi
if [ -n " $to_check " ] && ! ls $test_dir /*.$to_check > /dev/null 2>& 1; then
echo " No *. $to_check files exist in $test_dir "
continue
fi
echo ""
if [ -e " $test_dir /stop " ] || [ -e "./stop" ] ; then
echo " would start $test_dir "
echo "echo stopping due to stop file."
break
fi
(
cd $test_dir
2014-01-09 06:31:18 +00:00
echo " ================= Test directory $( pwd ) $date ================================== "
2014-01-08 09:18:31 +00:00
echo " ================= Sourcing config files between $config_root_dir and $( pwd ) ==== "
2013-11-07 09:33:43 +00:00
# to be able to call error recovery functions in case of signals
trap 'lib_exit 1 "caught signal"' SIGHUP SIGINT
# source additional user modules (if available)
source_config "user_modules" || echo "(ignored)"
shopt -s nullglob
for module in $user_module_dir /[ 0-9] *.sh; do
source_module " $module "
done
# source all individual config files (for overrides)
2013-12-20 16:01:37 +00:00
# between $config_root_dir (exclusive) and $(pwd) (inclusive)
2013-11-07 09:33:43 +00:00
shopt -s nullglob
2013-12-23 06:13:11 +00:00
t = $( pwd ) # absolute path
if [ " $t " = " $config_root_dir " ] ; then
2013-12-20 16:01:37 +00:00
components = $( basename $( pwd ) )
else
components = $( echo ${ t # $config_root_dir / } | sed 's/\// /g' )
fi
2013-11-07 09:33:43 +00:00
for i in $components ; do
[ " $i " = "." ] && continue
if ! source_config " $i " ; then
echo " Cannot source config file ' $i .conf' -- please provide one. "
2014-01-08 11:31:49 +00:00
start_test_exit -1
2013-11-07 09:33:43 +00:00
fi
done
2014-01-09 06:31:18 +00:00
echo " ================= End sourcing config files between $config_root_dir and $( pwd ) "
2013-12-30 09:28:30 +00:00
print_config_environment
2013-07-04 08:05:39 +00:00
shopt -u nullglob
2013-11-07 09:33:43 +00:00
if ( ( dry_run_script ) ) ; then
echo "==> Dry Run ..."
touch dry-run.$to_produce
else
set_host_locks
2014-01-09 06:31:18 +00:00
echo " ================= Starting $( pwd ) $( date) ====================================== "
2013-11-07 09:33:43 +00:00
eval " $to_start " # must call exit in case of failure
release_host_locks
2013-07-04 08:05:39 +00:00
fi
2013-11-07 09:33:43 +00:00
)
rc = $?
if [ $rc -ne 0 ] ; then
2014-01-09 11:04:38 +00:00
echo " ========================== Failure $rc $( cd $test_dir ; pwd ) $date ============== " >& 2
2013-11-07 09:33:43 +00:00
else
2014-01-09 11:04:38 +00:00
echo " ========================== Finished $( cd $test_dir ; pwd ) $( date) =============== "
2013-11-07 09:33:43 +00:00
fi
2014-01-08 11:31:49 +00:00
[ $rc -ne 0 ] && start_test_exit $rc
2013-07-04 08:05:39 +00:00
done
if ( ( dry_run_script ) ) ; then
echo " removing dry-run. $to_produce everywhere... "
rm -f $( find . -name " dry-run. $to_produce " )
fi
2014-01-09 06:31:18 +00:00
echo " ========================== Finished start directory $start_dir ================= "
2014-01-08 11:31:49 +00:00
start_test_exit 0