So, for the love of every other non-expert-unix-system-programmer that
has given turbogears a try and hit this problem, here are my notes on
it. I hope they help someone. (incidentally, I got ZERO feedback from
the irc channel which really stunned and disappointed me (my question
was 'where is the best place to go for documentation?')).
The environment:
Fedora Core 4
PostgreSQL 8.1.3
Python 2.4.1
TurboGears-0.8.9-py2.4
psycopg2
working on production config ...
http://www.turbogears.org/docs/deployment/config.html
http://www.cherrypy.org/trunk/docs/book/chunk/ch03.html#id3060952
http://www.cherrypy.org/trunk/docs/book/chunk/ch03s02.html#id3139886
attempting like mad to create an init.d script for this crap ...
> Should there be a start-stop-daemon file somewhere on the system ?? In which Package ?
Have a look at Fedora init scripts: what Fedora uses is "daemon" which
is a function defined in /etc/init.d/functions. So adjust the code you
found in your iptables log analyzer source.
<<<<
confirming this ... ok. there is said functions file with 'daemon'
defined. not
sure how to use it. PID file will be a problem in any case. The pid
hack, below , is only a minimal start to a working solution.
(here is a link to start-stop-daemon download??
http://www.linuxfromscratch.org/download/ssd-0.4.1-lfs.tar.gz)
Crazy. circa 2000 link dead as a doornail. Can't find start-stop-daemon
references on the net after ~2004. Debian has a package called 'daemon'
http://packages.debian.org/stable/utils/daemon, but the maintainer
hasn't
posted changes since 04...Marc
Article on init scripting:
http://enterprise.linux.com/enterprise/05/08/02/1821218.shtml?tid=129
init script stub from fedora:
/usr/share/doc/initscripts-8.11.1/sysvinitfiles
[root@www conf]# cp /usr/share/doc/initscripts-8.11.1/sysvinitfiles .
[root@www conf]# mv sysvinitfiles jrd_marketing_web.init.d
added this to conf/ in repos ... ok r301
from turbogears google group:
What's stumping me now is that my TurboGears app, when it starts, does
> not write out a .pid file or anything of the like, so I'm not sure what
> the proper way is for my rc script to shut the server down when I tell
> it to.
> Does anyone have any hints on how to make this work? Do I need to
> subclass and add functionality to the server class in order to do this?
quick fix: add these lines to your application-start.py (assuming you
used quickstart)
import os
pid = file('app.pid', 'w')
pid.write(str(os.getpid()))
pid.close()
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731
http://starship.python.net/~jjkunce/
looks like 'daemonize.py' is the python technique to use. what a
blazing pain.
turning off autoreload in the prod.cfg ... ok (seems to speed up
things.
still bloody slow on a blitzing new dedicated svr)
progress! apparently, the daemonize.py does not pass arguments given to
commands called! Lovely. Instead, when I hard code the paths, etc in
the
jrd_marketing_web-start.py, the thing works.
[root@www jrd_marketing_web]# ./daemonize.py -o ~/out
"/var/www/jrd_marketing_web/jrd_marketing_web-start.py"
now, to see if it can be worked in the init script ...
---
#!/sbin/runscript
start() {
ebegin "Starting TurboGears application server"
start-stop-daemon --start --pidfile /var/run/tg.pid -m -b \
--exec /usr/local/bin/start-topfloor.py
eend $?
}
stop() {
local retval
ebegin "Stopping TurboGears application server"
start-stop-daemon --stop --pidfile /var/run/tg.pid
retval=$?
eend ${retval}
# This should vanish when baselayout-1.12.0 is marked stable.
[[ -f /var/run/tg.pid ]] && rm -f /var/run/tg.pid
return ${retval}
}
/rune
---------------------------------------------------------------------
Behind the firewall, nobody can hear you scream...
---
#!/bin/sh
# Comments to support chkconfig on RedHat Linux
# chkconfig: 35 96 96
# description: Cherrypy start/stop script
. /etc/init.d/functions
python=/absolute/path/to/python/binary
server=Your_start_script.py
serverdir=/absoulte/path/to/your/server/dir
serverpidfile=$serverdir/Your_applications_pid.pid
serverlog=$serverdir/your_std_out_log.log
[ -x $python ] || exit 0
RETVAL=0
start () {
echo "Starting $server: "
if test -f $serverdir/$server
then
cd $serverdir
$python $server >> $serverlog 2>&1 &
RETVAL=$?
else
RETVAL=1
fi
start_success_or_fail $RETVAL
return $RETVAL
}
stop() {
if test -f $serverpidfile
then
serverpid=`cat $serverpidfile`
kill -15 $serverpid
rm -f $serverpidfile
RETVAL=$?
else
RETVAL=1
fi
stop_success_or_fail $RETVAL
return $RETVAL
}
start_success_or_fail(){
if [ $RETVAL -eq 1 ]; then
echo -n "Can't start $server"
echo_failure
echo
else
echo -n $server "started"
echo_success
echo
fi
}
stop_success_or_fail(){
if [ $RETVAL -eq 1 ]; then
echo -n "Killing $server"
echo_failure
echo
else
echo -n "Killing $server"
echo_success
echo
fi
}
status() {
local base=${1##*/}
if test -f $serverpidfile
then
pid=`cat $serverpidfile`
checkpid $pid
RETVAL=$?
else
RETVAL=1
fi
if [ $RETVAL -eq 0 ];then
echo "$server pid($pid) is running..."
return 0
else
if [ -f /var/run/${base}.pid ] ; then
read pid < /var/run/${base}.pid
if [ -n "$pid" ]; then
echo $"${base} dead but pid file exists"
return 1
fi
fi
echo $"${base} is stopped"
return 2
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $server
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|status}"
exit 1
esac
exit $RETVAL
---
Debian's start-stop-daemon has an option for this. My init script for a
sitechecker I wrote, which identical to CherryPY in terms of IO and
functionality is pasted below. Maybe these are Debian-only
modifications, I dunno, but you can get their source and compile it :-)
Based on the sample Debian initscript.
rob@backux:~$ cat /etc/init.d/sitechecker
#! /bin/sh
#
# Author: Robin Haswell <r...@bronco.co.uk>.
#
# Please remove the "Author" lines above and replace them
# with your own name if you copy and modify this script.
#
set -e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="Site checker"
NAME=sitechecker
DAEMON=/usr/local/bin/$NAME
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0
# Read config file if it is present.
#if [ -r /etc/default/$NAME ]
#then
# . /etc/default/$NAME
#fi
#
# Function that starts the daemon/service.
#
d_start() {
start-stop-daemon --start --pidfile $PIDFILE \
--make-pidfile --background --startas $DAEMON
}
#
# Function that stops the daemon/service.
#
d_stop() {
start-stop-daemon --stop --pidfile $PIDFILE
}
#
# Function that sends a SIGHUP to the daemon/service.
#
d_reload() {
start-stop-daemon --stop --pidfile $PIDFILE \
--name $NAME --signal 1
}
case "$1" in
start)
echo -n "Starting $DESC: $NAME"
d_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
d_stop
echo "."
;;
#reload)
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
# If the daemon responds to changes in its config file
# directly anyway, make this an "exit 0".
#
# echo -n "Reloading $DESC configuration..."
# d_reload
# echo "done."
#;;
restart|force-reload)
#
# If the "reload" option is implemented, move the
"force-reload"
# option to the "reload" entry above. If not,
"force-reload" is
# just the same as "restart".
#
echo -n "Restarting $DESC: $NAME"
d_stop
sleep 1
d_start
echo "."
;;
*)
# echo "Usage: $SCRIPTNAME
{start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
# Comments to support chkconfig on RedHat Linux
# chkconfig: 35 96 96
# description: Cherrypy/turbogears start/stop script
# Source: Rune Hansen on
#
http://groups.google.com/group/turbogears/browse_thread/thread/af07ba5360a28a95/73dd5193802b8f70
# Authors: Rune Hansen, $Author: handerson $
# $Id: jrdweb 321 2006-03-28 18:38:46Z handerson $
. /etc/init.d/functions
python=/usr/bin/python
server=daemonize.py
serverdir=/var/www/jrd_marketing_web
serverpidfile=$serverdir/jrdweb.pid
serverlog=$serverdir/jrdlog.log
[ -x $python ] || exit 0
RETVAL=0
start () {
echo "Starting $server: "
if test -f $serverdir/$server
then
cd $serverdir
$serverdir/$server -p $serverpidfile
"$serverdir/jrd_marketing_web-start.py"
echo $serverdir/$server -p $serverpidfile
"$serverdir/jrd_marketing_web-start.py"
RETVAL=$?
echo "\$RETVAL=$RETVAL"
}
}
}
}
THANK YOU.
> I have blown untold hours trying to find a statement of best practice
> for actually running cherrypy in a production installation to NO avail
> (unless you want the httpd mod_rewrite, which I don't).
(...)
I've written an initscript a long time ago and I've updated it today, after
reading this discussion.
You can find it in http://trac.turbogears.org/turbogears/ticket/172
Download
http://trac.turbogears.org/turbogears/attachment/ticket/172/lsb-initscript.project
and copy it to /etc/init.d/<project> and also make a symlink into
(/usr)/sbin/rc<project>. This way you can use "chkconfig <project>" (or
whatever tool you use to add it to start automatically at a specific
runlevel) or "rc<project> {start|stop|status|restart}" as well.
The changes you need to do are all at the beginning of the file. Changing the
few variables there and the starting comment should be all you need to have it
documented and working.
Assumptions:
- you'll be running in production mode
- your system is LSB-compliant
Here are the variables you'll need to change and their "default" value:
TG_PROJECT="project_name"
PIDFILE=/srv/www/my_tg_website/project.pid
TG_PROJECT_BIN=/srv/www/my_tg_website/start-project.py
TG_PROJECT_CONFIG=/srv/www/my_tg_website/prod.cfg
Where:
TG_PROJECT -> Your project name. It can be anything and will be
echoed at all operations. It is just an informative
text.
PIDFILE -> Where your program's PID will be stored (the initscript
will create this file for you)
TG_PROJECT_BIN -> Your "start-<project>.py" file
TG_PROJECT_CONFIG -> Your "prod.cfg" file
I hope it helps everybody... :-)
--
Jorge Godoy <jgo...@gmail.com>