Files
tripleo-image-elements/elements/os-svc-install/bin/os-svc-daemon
Gregory Haynes 4c31859fbb Log from upstart console
We are no longer piping our service output to logger, so we should be
logging the stdout via upstart. This is useful for detecting tracebacks
and other info which does not go through python logging.

Change-Id: I5d4abb94ff15f74fd2478e70d0fa4d3bb9c09f2d
2015-01-14 19:50:42 -08:00

262 lines
6.6 KiB
Bash
Executable File

#!/bin/bash
set -eu
DEFAULT_POSTSTART="exec sleep 1"
usage() {
echo "Usage: os-svc-daemon [ -ph ] [ -s POSTSTART ] [ -e ENV ] -n SERVICENAME -u RUNAS [ -c RUNCMD -- [arg [arg...]]]"
echo ""
echo "SERVICENAME, RUNAS, RUNCMD, and POSTSTART can be set via the"
echo "environment as well. Command line arguments will override"
echo "environment variables. By default this will create a python logging"
echo "configuration file in /etc/os-logging/servicename.conf"
echo ""
echo " -a Use alternate svc-map instead of map-services"
echo " -h Show help and exit"
echo " -p Print the job file instead of writing to disk"
echo " -l Create neither a python logging.conf nor pass --log-config-append argument to command."
echo " -d [NAME] Specify the name of the runtime directory, which will be"
echo " /var/run/[NAME]"
echo " -s POSTSTART post_start will be added to the upstart job. Ignored with systemd."
echo " default: $DEFAULT_POSTSTART"
echo " -e ENV Environment name=value entries to set in the service/job"
echo " -n SERVICENAME Name of job/service file."
echo " -i INSTALLDIR Optional: virtualenv installation directory. Defaults to: /opt/stack/venvs/<SERVICENAME>"
echo " -u RUNAS User to run main executable as."
echo " -c RUNCMD Command to execute. Must stay in foreground."
echo " arg... Arguments will be passed to COMMAND"
echo ""
}
# Can be set in environment now
SERVICENAME=${SERVICENAME:-""}
INSTALLDIR=
RUNAS=${RUNAS:-""}
RUNCMD=${RUNCMD:-""}
ENV=${ENV:-""}
DISABLE_LOGGING_CONF=
CREATE_DIR_NAME=${CREATE_DIR_NAME:-""}
# The default helps avoid race with daemon listening. http://pad.lv/1179766
POSTSTART=${POSTSTART:-$DEFAULT_POSTSTART}
MAPPING_COMMAND=map-services
print_only() {
cat
}
print_to_file() {
cat > $1
}
append_to_file() {
cat >> $1
}
OUTPUT=print_to_file
APPEND=append_to_file
nshift=0
while getopts "aplhd:s:n:i:u:c:e:" opt; do
case "$opt" in
n) SERVICENAME=$OPTARG;;
i) INSTALLDIR=$OPTARG;;
u) RUNAS=$OPTARG;;
c) RUNCMD=$OPTARG;;
s) POSTSTART=$OPTARG;;
e) ENV=$OPTARG;;
a) MAPPING_COMMAND=svc-map;;
p) OUTPUT=print_only; APPEND=print_only;;
l) DISABLE_LOGGING_CONF="1";;
d) CREATE_DIR_NAME=$OPTARG;;
h) usage; exit 0;;
\?) usage; exit 1;;
:) usage; exit 1;;
esac
done
shift $(($OPTIND-1))
if [ -z "$SERVICENAME" ] || [ -z "$RUNAS" ] ; then
if [ $# -lt 3 ] ; then
usage
exit 1
fi
fi
function deprecated_posarg_warning {
echo "WARNING: Setting $1 via positional argument is deprecated and will be removed in a future release."
}
# Compatibility with old style passing w/o switches
if [ -z "$SERVICENAME" ]; then
SERVICENAME=$1
shift
deprecated_posarg_warning "SERVICENAME"
fi
if [ -z "$RUNAS" ]; then
RUNAS=$1
shift
deprecated_posarg_warning "RUNAS"
fi
if [ -z "$RUNCMD" ]; then
CHECK=${1:-""}
if [ -n "$CHECK" ]; then
RUNCMD=$1
shift
deprecated_posarg_warning "CHECK"
fi
fi
# if INSTALLDIR isn't set use /opt/stack/venvs/RUNAS
# NOTE: this was our default before adding the -i option
if [ -z "$INSTALLDIR" ]; then
INSTALLDIR="/opt/stack/venvs/$RUNAS"
fi
if [ -z "$DISABLE_LOGGING_CONF" ]; then
# Set up service-specific logging config
LOGGING_CONFIG="/etc/os-logging/$SERVICENAME.config"
mkdir /etc/os-logging || true
$OUTPUT $LOGGING_CONFIG <<EOF
[loggers]
keys=root
[handlers]
keys=syslog
[formatters]
keys=normal
[logger_root]
handlers=syslog
[handler_syslog]
class=handlers.SysLogHandler
args=('/dev/log', handlers.SysLogHandler.LOG_USER)
formatter=normal
[formatter_normal]
format=$SERVICENAME: %(asctime)s %(levelname)s %(message)s
EOF
fi
function install_upstart {
local name=$1
local install_dir=$2
local user=$3
local dirname=${4:-$user}
local cmd=$5
shift; shift; shift; shift; shift
local args=$*
local env_entries=''
if [ -n "$ENV" ]; then
local env_pad=" $ENV"
env_entries=${env_pad// /
env }
fi
local target_file="/etc/init/$name.conf"
if [ -z "$DISABLE_LOGGING_CONF" ]; then
args="--log-config-append $LOGGING_CONFIG $args"
fi
$OUTPUT $target_file <<EOF
start on runlevel [2345]
stop on runlevel [016]
$env_entries
env OS_SVC_ENABLE_CONTROL=1
export OS_SVC_ENABLE_CONTROL
pre-start script
mkdir -p /var/run/$dirname
chown -R $user:$user /var/run/$dirname
end script
EOF
if [ -n "$cmd" ]; then
$APPEND $target_file <<EOF
respawn
# the default post-start of 1 second sleep delays respawning enough to
# not hit the default of 10 times in 5 seconds. Make it 2 times in 10s.
respawn limit 2 10
exec start-stop-daemon --start -c $user --exec $install_dir/bin/$cmd -- $args
post-start $POSTSTART
EOF
fi
}
function install_systemd {
local name=$1
local install_dir=$2
local user=$3
local cmd=$4
shift; shift; shift; shift;
local args=$*
local env_entries=''
if [ -n "$ENV" ]; then
local env_pad=" $ENV"
env_entries=${env_pad// /
Environment=}
fi
if [ -z "$DISABLE_LOGGING_CONF" ]; then
args="--log-config-append $LOGGING_CONFIG $args"
fi
$OUTPUT /lib/systemd/system/$name.service <<EOF
[Unit]
Description=$name Service
After=os-refresh-config.service
Requires=$name-create-dir.service
[Service]
ExecStart=$install_dir/bin/$cmd $args
User=$user
$env_entries
[Install]
WantedBy=multi-user.target
Alias=$name.service
EOF
}
function install_create_dir_systemd {
local name="$($MAPPING_COMMAND "$1")"
local user=$2
local dirname=${3:-$user}
$OUTPUT /lib/systemd/system/$name-create-dir.service <<EOF
[Unit]
Description=Create /var/run/$dirname
[Service]
ExecStartPre=/bin/mkdir -p /var/run/$dirname
ExecStartPre=/usr/local/bin/restore-selinux-file-context /var/run/$dirname
ExecStart=/bin/chown -R $user:$user /var/run/$dirname
[Install]
RequiredBy=$name.service
EOF
}
# TODO: SysV init fallback support
DIB_INIT_SYSTEM=$(dib-init-system)
if [ "$DIB_INIT_SYSTEM" == "upstart" ]; then
install_upstart $SERVICENAME $INSTALLDIR $RUNAS "$CREATE_DIR_NAME" "$RUNCMD" $*
elif [ "$DIB_INIT_SYSTEM" == "systemd" ]; then
if [ "$POSTSTART" != "$DEFAULT_POSTSTART" ] ; then
echo "WARNING: post start is ignored with systemd." >&2
fi
if [ -n "$RUNCMD" ]; then
install_systemd $SERVICENAME $INSTALLDIR $RUNAS $RUNCMD $*
fi
install_create_dir_systemd $SERVICENAME $RUNAS $CREATE_DIR_NAME
fi