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