Skip to content

Instantly share code, notes, and snippets.

@nilium
Last active May 4, 2017 20:00
Show Gist options
  • Save nilium/e298954d724a79db362388bb616ab1c6 to your computer and use it in GitHub Desktop.
Save nilium/e298954d724a79db362388bb616ab1c6 to your computer and use it in GitHub Desktop.
run script to spawn a runsvdir subprocess for a multi-instance service
#!/usr/bin/env sh
# vim: set ft=sh tw=80 sw=2 ts=2 et :
#
# Environment Variables:
# SV_INSTANCES -- the number of instances to spawn under ./instances
# SV_STOP_WAIT -- controls the shutdown wait time for instances
# SV_NAME -- controls the name of the service -- must not contain directory
# separators. Defaults to the basename of the current directory.
#
# If an env file is present in the current directory and readable, the run
# script sources it.
#
# A template directory must exist and contain a run file. When instantiating the
# service's instances, the template directory is recursively copied, for each
# instance, into ./instances. Upon stopping, the instance directories are
# destroyed.
if [ -r env ]; then
. ./env
fi
set --
exec 2>&1
logprefix="$(basename "$PWD"):"
log () {
echo "${logprefix}" "$@"
}
if [ ! -d template ]; then
log 'no template directory found'
exit 1
elif [ ! -x template/run ]; then
log 'no template/run executable found'
exit 1
fi
: "${proclog:=log: ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................}"
wsec="${SV_STOP_WAIT:-20}"
n="${SV_INSTANCES:-1}"
name="${SV_NAME:-$(basename "$PWD")}"
: "${name:=instance}"
if [ ! -d instances ]; then
if ! mkdir instances; then
log 'unable to create instances directory'
exit 1
fi
fi
runsvdir_pid=''
instance_dir () {
echo -n "./instances/${name}.$1"
}
cleanup_done=''
cleanup () {
if [ $cleanup_done ]; then
return 0
fi
cleanup_done=1
if [ $runsvdir_pid ]; then
if [ $# -gt 0 ]; then
sv -w "${wsec}" down "$@"
fi
kill -HUP $runsvdir_pid
fi
if [ $# -gt 0 ]; then
rm -rf "$@"
fi
}
trap 'cleanup "$@"' TERM
for i in `seq -w 1 $n`; do
i="$(instance_dir "$i")"
if [ -d "$i" ]; then
log "service directory already exists: $i"
sv check "$i"
svstatus=$?
# if runsv is down, clean up the old directory
if [ $svstatus = 1 ]; then
rm -rf "$i"
else
log "$i: service is not reporting as down -- exiting"
exit 1
fi
fi
set -- "$@" "$i"
cp -Rpv template "$i"
done
runsvdir "$PWD/instances" "$proclog" &
runsvdir_pid=$!
log started
wait "$runsvdir_pid"
log finished
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment