Finished adding doxygen-style comments to document the app session
[OpenSRF.git] / src / python / opensrf.py
1 #!/usr/bin/python
2 # -----------------------------------------------------------------------
3 # Copyright (C) 2008  Equinox Software, Inc.
4 # Bill Erickson <erickson@esilibrary.com>
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA
20 # -----------------------------------------------------------------------
21
22 import sys, getopt, os, signal
23 import osrf.system, osrf.server, osrf.app, osrf.set, osrf.json
24
25 def do_help():
26     print '''
27     Manage OpenSRF application processes
28
29     Options:
30         -a <action>
31             start   -- Start a service
32             stop    -- stop a service
33             restart -- restart a service
34             start_all -- Start all services
35             stop_all -- Stop all services
36             restart_all -- Restart all services
37
38         -s <service>
39             The service name
40
41         -f <config file>
42             The OpenSRF config file
43
44         -c <config context>
45             The OpenSRF config file context
46
47         -p <PID dir>
48             The location of application PID files.  Default is /tmp
49
50         -d 
51             If set, run in daemon (background) mode.  This creates a PID 
52             file for managing the process.
53
54         -l
55             If set, run in 'localhost' mode
56
57         -h
58             Prints help message
59     '''
60     sys.exit(0)
61
62
63 # Parse the command line options
64 ops, args = None, None
65 try:
66     ops, args = getopt.getopt(sys.argv[1:], 'a:s:f:c:p:dhl')
67 except getopt.GetoptError, e:
68     print '* %s' % str(e)
69     do_help()
70
71 options = dict(ops)
72
73 if '-a' not in options or '-f' not in options:
74     do_help()
75
76 action = options['-a']
77 config_file = options['-f']
78 pid_dir = options['-p']
79
80 service = options.get('-s')
81 config_ctx = options.get('-c', 'config.opensrf')
82 as_localhost = '-l' in options
83 as_daemon = '-d' in options
84
85 domain = None
86 settings = None
87 services = {}
88
89
90 def get_pid_file(service):
91     return "%s/%s.pid" % (pid_dir, service)
92
93 def do_init():
94     global domain
95     global settings
96
97     # connect to the OpenSRF network
98     osrf.system.System.net_connect(
99         config_file = config_file, config_context = config_ctx)
100
101     if as_localhost:
102         domain = 'localhost'
103     else:
104         domain = osrf.conf.get('domain')
105
106     osrf.set.load(domain)
107
108     settings = osrf.set.get('apps')
109
110     for key in settings.keys():
111         svc = settings[key]
112         if isinstance(svc, dict) and svc['language'] == 'python':
113             services[key] = svc
114
115
116 def do_start(service):
117
118     pidfile = get_pid_file(service)
119
120     if service not in services:
121         print "* service %s is not a 'python' application" % service
122         return
123
124     if os.path.exists(pidfile):
125         print "* service %s already running" % service
126         return
127
128     print "* starting %s" % service
129
130     if as_daemon:
131
132         if osrf.system.System.daemonize(False):
133             return # parent process returns
134
135         # write PID file
136         file = open(pidfile, 'w')
137         file.write(str(os.getpid()))
138         file.close()
139
140     settings = services[service];
141
142     osrf.app.Application.load(service, settings['implementation'])
143     osrf.app.Application.register_sysmethods()
144     osrf.app.Application.application.global_init()
145
146     controller = osrf.server.Controller(service)
147     controller.max_requests = settings['unix_config']['max_requests']
148     controller.max_children = settings['unix_config']['max_children']
149     controller.min_children = settings['unix_config']['min_children']
150     controller.keepalive = settings['keepalive']
151
152     controller.run()
153     os._exit(0)
154
155 def do_start_all():
156     print "* starting all services for %s " % domain
157     for service in services.keys():
158         do_start(service)
159
160 def do_stop_all():
161     print "* stopping all services for %s " % domain
162     for service in services.keys():
163         do_stop(service)
164
165 def do_stop(service):
166     pidfile = get_pid_file(service)
167
168     if not os.path.exists(pidfile):
169         print "* %s is not running" % service
170         return
171
172     print "* stopping %s" % service
173
174     file = open(pidfile)
175     pid = file.read()
176     file.close()
177     try:
178         os.kill(int(pid), signal.SIGTERM)
179     except:
180         pass
181     os.remove(pidfile)
182
183 # -----------------------------------------------------
184
185 do_init()
186
187 if action == 'start':
188     do_start(service)
189
190 elif action == 'stop':
191     do_stop(service)
192
193 elif action == 'restart':
194     do_stop(service)
195     do_start(service)
196
197 elif action == 'start_all':
198     do_start_all()
199
200 elif action == 'stop_all':
201     do_stop_all()
202
203 elif action == 'restart_all':
204     do_stop_all()
205     do_start_all()
206
207 elif action == 'help':
208     do_help()