Welcome, guest | Sign In | My Account | Store | Cart

If you are like me and your company has a custom piece of software for managing processes, you have your paster app installed in egg form in a virtualenv, then you might have a hard time running a paster server (turbogears 2) within those limits.

As I had so much trouble writing this I thought I would share. You can add this as a console script in your egg, then run it as --prod or --dev. When run as --prod it adds a signal handler so that if it is sigtermed by the "supervisor" program then it will kill off the rest of the paster processes (they usually don't get stopped if the main running process is killed).

The script is pretty rough and expects the production.ini to be in your package's main folder, with the development.ini being in the same directory as the setup.py (one directory above the production.ini). Make sure you change my_paster_package to be whatever your project is called, like "movies" from the turbogears example

Of course if someone has a better way of doing this that would be great too! (wsgi isn't an option for me, and it seems difficult to set it up when your project is installed as an egg)

Python, 57 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
'''
Simple script to allow us to run paster more easily (but probably in an unintended way)
'''
import subprocess
import argparse
import os
import sys
import signal

#change this to be whatever your project will be called, 
import my_paster_package

def main():
    parser = argparse.ArgumentParser(description='Run as --dev or --prod.')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--dev', action="store_true", default=False)
    group.add_argument('--prod', action="store_true", default=False)
    
    args = parser.parse_args()
    
    #make sure we are running the paster out of the venv by finding the bin directory that this script is being
    #run out of
    bin_dir = os.path.dirname(sys.executable)
    config_file_dir = my_paster_package.__path__[0]
    
    if args.dev:
        p = subprocess.Popen("./paster serve %s/development.ini --reload" % (config_file_dir + "/.."), 
                             shell=True, cwd=bin_dir)
        
        
    elif args.prod:
        paster_pid_file = bin_dir+"/paster.pid"
        
        p = subprocess.Popen("./paster serve %s/production.ini --pid-file=%s" % (config_file_dir, paster_pid_file), 
                             shell=True, cwd=bin_dir)
        
        #attach a signal handler so we can kill off the subprocesses when supervisor kills this script
        #otherwise the kill signal doens't propegate to all the paster processes
        def signal_handler(signal, frame):
            if os.path.exists(paster_pid_file):
                paster_pid = open(paster_pid_file, "r").read()
                os.system("kill -2 %s" % (paster_pid))
            else:
                print "Warning: Could not find paster pid file, paster might not have properly terminated"
                
        signal.signal(signal.SIGTERM, signal_handler)

    else:
        raise Exception("Please choose either --dev or --prod")
    
    sts = os.waitpid(p.pid, 0)[1]
    
    #return the code in case of a problem
    sys.exit(sts)

if __name__ == '__main__':
    main()
Created by Nick Holden on Wed, 20 Apr 2011 (MIT)
Python recipes (4591)
Nick Holden's recipes (1)

Required Modules

  • (none specified)

Other Information and Tasks