Created
February 28, 2011 15:45
-
-
Save lericson/847486 to your computer and use it in GitHub Desktop.
Gunicorn init script for Gentoo that checks liveliness properly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/sbin/runscript | |
| [[ -z "${PIDFILE}" ]] && PIDFILE="/var/run/gunicorn/${SVCNAME}.pid" | |
| [[ -z "${BINARY}" ]] && BINARY="/usr/bin/gunicorn" | |
| depend() { | |
| need net | |
| use dns logger netmount | |
| } | |
| check_params() { | |
| if [[ "${SVCNAME}" == "gunicorn" && -z "${I_KNOW}" ]]; then | |
| ewarn "It is highly recommended to use a symbolic link for this" | |
| ewarn "script and start via that instead. This allows you to run" | |
| ewarn "multiple spawn services simultaneously. To do this, simply:" | |
| ewarn | |
| ewarn " ln -s /etc/init.d/gunicorn /etc/init.d/gunicorn.mysvc" | |
| ewarn " cp /etc/conf.d/gunicorn /etc/conf.d/gunicorn.mysvc" | |
| ewarn | |
| ewarn "If you don't want to be bothered by this message, set I_KNOW=yes" | |
| ewarn "in your configuration file." | |
| ewarn | |
| fi | |
| if [[ -z "${WSGI_APP}" ]] && [[ -z "${WSGI_TYPE}" ]]; then | |
| eerror "${WSGI_APP} not set. Exiting" | |
| return 1 | |
| fi | |
| if [[ -z "${PIDFILE}" ]]; then | |
| eerror "PIDFILE must be set in /etc/conf.d/${SVCNAME}" | |
| return 1 | |
| fi | |
| } | |
| test_pidfile() { | |
| if [[ ! -f "${PIDFILE}" ]]; then | |
| eerror "${PIDFILE} does not exist" | |
| return 1 | |
| fi | |
| read -r PID <"${PIDFILE}" | |
| if [[ -z "${PID}" ]]; then | |
| eerror "${PIDFILE} contains no PID" | |
| return 1 | |
| fi | |
| if [[ ! -d "/proc/${PID}" ]]; then | |
| eerror "${PID} does not appear to be an existing process" | |
| return 1 | |
| fi | |
| if awk -F: 'BEGIN { found = 0; } END { exit(found); }; $1 == "State" && $2 !~ /^[[:space:]]*Z / { found = 1; };' "/proc/${PID}/status"; then | |
| eerror "${PID} does not appear to be an active process" | |
| return 1 | |
| fi | |
| return 0 | |
| } | |
| kill_pidfile() { | |
| check_params && test_pidfile || return 1 | |
| ebegin "$1" | |
| shift | |
| read -r PID <"${PIDFILE}" | |
| kill "$@" "${PID}" | |
| local RC=$? | |
| eend $RC | |
| return $RC | |
| } | |
| # actions | |
| start() { | |
| check_params || return 1 | |
| local -a OPTS | |
| OPTS=( "-c" "${CONFIG}" | |
| "--daemon" | |
| "--pid=${PIDFILE}" | |
| "${WSGI_APP}" ) | |
| ebegin "Starting ${SVCNAME} using ${CONFIG}" | |
| env PYTHONPATH="${PYTHONPATH}" "${BINARY}" "${OPTS[@]}" | |
| local RC=$? | |
| eend "${RC}" | |
| if [[ "${RC}" == 0 ]]; then | |
| ebegin "No early errors, checking liveliness" | |
| sleep 1 | |
| if ! test_pidfile; then | |
| eend 1 | |
| return 1 | |
| fi | |
| eend 0 | |
| fi | |
| return "${RC}" | |
| } | |
| status() { | |
| check_params && test_pidfile | |
| } | |
| stop() { | |
| kill_pidfile "Stopping (gracefully) ${SVCNAME}" \ | |
| -s SIGQUIT | |
| } | |
| force_stop() { | |
| kill_pidfile "Stopping (disregarding jobs) ${SVCNAME}" \ | |
| -s SIGINT | |
| } | |
| reload() { | |
| kill_pidfile "Telling ${SVCNAME} to reload itself" \ | |
| -s SIGHUP | |
| } | |
| opts="${opts} status reload force_stop" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to use
Save as
/etc/init.d/gunicornCreate a basic configuration at
/etc/conf.d/gunicornthat says:Do as advised and create a symlink at
/etc/init.d/gunicorn.mysvc -> gunicornand copy the configuration template.Edit configuration, done.
Why would you use
Most init scripts suffer from the ailment that they don't actually know if the
daemon they control is living or not. This is a fundamental flaw, and the way
things are handled there is really no way to ascertain liveliness of Python
daemons because they run as the process "python", and
start-stop-daemonrelies on
pidofand other dumb trickery. (Feel free to tell me off if youknow of a good way to do this with
start-stop-daemon.)This script takes the stance that checking
/proc/$pid/statusisn't actuallyhard and can be done on a per-script basis. This yields the following desirable
behavior:
The init system is still a little dumb--it thinks the service is started even
though the status function returns non-zero--the script tells you something is
amiss. In this case the correct solution is to
zapand start the serviceagain, since
stopwill fail due to there being no pidfile.