bd6c4f05f8bd966bd27c4c9ca3555cf9abd7f285
[OpenSRF.git] / src / python / opensrf.py.in
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 '''
23 Provides an environment for managing OpenSRF services written in Python
24 '''
25
26 import sys, getopt, os, signal
27 import osrf.system, osrf.server, osrf.app, osrf.set, osrf.json
28
29 def do_help():
30     '''
31     Print help for the OpenSRF Python application process manager
32     '''
33
34     print '''
35     Manage OpenSRF application processes
36
37     Options:
38         -a <action>
39             start   -- Start a service
40             stop    -- stop a service
41             restart -- restart a service
42             start_all -- Start all services
43             stop_all -- Stop all services
44             restart_all -- Restart all services
45
46         -s <service>
47             The service name
48
49         -f <config file>
50             The OpenSRF config file
51
52         -c <config context>
53             The OpenSRF config file context
54
55         -p <PID dir>
56             The location of application PID files.  Default is /tmp
57
58         -d 
59             If set, run in daemon (background) mode.  This creates a PID 
60             file for managing the process.
61
62         -l
63             If set, run in 'localhost' mode
64
65         -h
66             Prints help message
67     '''
68     sys.exit(0)
69
70 def get_pid_file(service):
71     '''
72     Return the PID file for the named service
73     '''
74
75     return "%s/%s.pid" % (pid_dir, service)
76
77 def do_init():
78     '''
79     Initialize the Python service environment
80     '''
81
82     global domain
83     global settings
84
85     # connect to the OpenSRF network
86     osrf.system.System.net_connect(
87         config_file = config_file, config_context = config_ctx)
88
89     if as_localhost:
90         domain = 'localhost'
91     else:
92         domain = osrf.conf.get('domain')
93
94     osrf.set.load(domain)
95
96     settings = osrf.set.get('apps')
97
98     for key in settings.keys():
99         svc = settings[key]
100         if isinstance(svc, dict) and 'language' in svc and svc['language'] == 'python':
101             services[key] = svc
102
103
104 def do_start(service):
105     '''
106     Start the named Python service
107     '''
108
109     pidfile = get_pid_file(service)
110
111     if service not in services:
112         print "* service %s is not a 'python' application" % service
113         return
114
115     if os.path.exists(pidfile):
116         print "* service %s already running" % service
117         return
118
119     print "* starting %s" % service
120
121     if as_daemon:
122
123         if osrf.system.System.daemonize(False):
124             return # parent process returns
125
126         # write PID file
127         pid_fd = open(pidfile, 'w')
128         pid_fd.write(str(os.getpid()))
129         pid_fd.close()
130
131     svc_settings = services[service]
132
133     osrf.app.Application.load(service, svc_settings['implementation'])
134     osrf.app.Application.register_sysmethods()
135     osrf.app.Application.application.global_init()
136
137     controller = osrf.server.Controller(service)
138     controller.max_requests = svc_settings['unix_config']['max_requests']
139     controller.max_children = svc_settings['unix_config']['max_children']
140     controller.min_children = svc_settings['unix_config']['min_children']
141     controller.keepalive = svc_settings['keepalive']
142
143     controller.run()
144     os._exit(0)
145
146 def do_start_all():
147     '''
148     Start all Python services listed in the OpenSRF configuration file
149     '''
150
151     # You can't start more than one service without daemonizing
152     global as_daemon
153     as_daemon = True
154
155     print "* starting all services for %s " % domain
156     for service in services.keys():
157         do_start(service)
158
159 def do_stop_all():
160     '''
161     Stop all Python services listed in the OpenSRF configuration file
162     '''
163
164     print "* stopping all services for %s " % domain
165     for service in services.keys():
166         do_stop(service)
167
168 def do_stop(service):
169     '''
170     Stop the named Python service
171     '''
172
173     pidfile = get_pid_file(service)
174
175     if not os.path.exists(pidfile):
176         print "* %s is not running" % service
177         return
178
179     print "* stopping %s" % service
180
181     pid_fd = open(pidfile)
182     pid = pid_fd.read()
183     pid_fd.close()
184     try:
185         os.kill(int(pid), signal.SIGTERM)
186     except:
187         pass
188     os.remove(pidfile)
189
190 # -----------------------------------------------------
191
192 # Parse the command line options
193 ops, args = None, None
194 try:
195     ops, args = getopt.getopt(sys.argv[1:], 'a:s:f:c:p:dhl')
196 except getopt.GetoptError, e:
197     print '* %s' % str(e)
198     do_help()
199
200 options = dict(ops)
201
202 if '-a' not in options:
203     do_help()
204
205 action = options['-a']
206
207 config_file = options.get('-f', '@CONF_DIR@/opensrf_core.xml')
208 pid_dir = options.get('-p', '@PID_DIR@/run/opensrf')
209
210 service_name = options.get('-s')
211 config_ctx = options.get('-c', 'config.opensrf')
212 as_localhost = '-l' in options
213 as_daemon = '-d' in options
214
215 domain = None
216 settings = None
217 services = {}
218
219 do_init()
220
221 if action == 'start':
222     do_start(service_name)
223
224 elif action == 'stop':
225     do_stop(service_name)
226
227 elif action == 'restart':
228     do_stop(service_name)
229     do_start(service_name)
230
231 elif action == 'start_all':
232     do_start_all()
233
234 elif action == 'stop_all':
235     do_stop_all()
236
237 elif action == 'restart_all':
238     do_stop_all()
239     do_start_all()
240
241 elif action == 'help':
242     do_help()