[Web-SIG] Daemon server management

mso@oz.net mso at oz.net
Fri Jun 10 00:00:36 CEST 2005

Shannon -jj Behrens said:
> On 6/9/05, mso at oz.net <mso at oz.net> wrote:
>> Shannon -jj Behrens said:
>> > I usually just write a wrapper that matches whatever OS I'm on.  I.e.
>> > I sacrifice the cross-platform requirement.  Creating a FreeBSD
>> > rc.sh-type script is quite simple.  Perhaps I'm being naive.
>> I've got a similar situation now.  I've been using start-stop-daemon on
>> Linux to daemonize a naive Quixote application, but there's no
>> equivalent
>> wrapper for Mac OSX 10.3.  We're looking at teaching the Python program
>> itself to daemonize, although I think that's less ideal than using a
>> platform-standard wrapper.  There's a couple examples in the Python
>> Cookbook (search for "daemon"); this is the one we're going to try:
>> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731
>> Essentially, your application calls a function and then continues,
>> blissfully unaware it's been forked.  However, it doesn't make a PID
>> file
>> or change uid.  These are essential for production services.  We're
>> looking at extending the function to do these.
>> The top-level executable needs --pidfile, --user and --group flags or
>> the
>> equivalent.  (start-stop-daemon uses --chuid USER:GROUP).
> I would give up root manually.  Afterall, no library code knows when
> the right time is, eh?

Perhaps it should be a separate function then.  I'm thinking mostly of
code reuse.  It would be nice to have a common module Paste and Quixote
and others can use to handle daemonizing, one that works with Unix and Mac
and Windows.

daemon.daemonize(pidfile=None, overwrite=False)
daemon.chuid(user=None, group=None)

But who does the stop operation?  I guess the executable needs a --stop
flag, which would imply:

# === daemon.py ===
daemon.start(pidfile=None, overwrite=False)
    @param pidfile filename or None.  If none, no PID file.
    @param overwrite boolean.  If false and PID file exists, abort.
        If true and PID file exists but process doesn't, overwrite.
    PURPOSE: a reference implementation for daemozing and PID creation.

daemon.chuid(user=None, group=None)
    @param user name or uid.  None means don't change.
    @param group name or gid.  None means don't change.
    PURPOSE: do the name-to-id lookup and change in one step.

    @param pidfile filename.

As for the RC script itself, those are very OS dependent.  For instance,
Gentoo, Red Hat, and Debian are all different.  The best you can do is a
directory of sample RC scripts.  But even the "right" sample can be wrong
if the target OS has recently changed a feature.  The best advice is to
copy a currently-installed script on the target platform.

-- Mike Orr <mso at oz.net>

More information about the Web-SIG mailing list