]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/python/opensrf.py.in
Limit list of Python services to those within the domain-specific activeapps section
[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     osrf.set.load(domain)
96
97     settings = osrf.set.get('apps')
98     activeapps = osrf.set.get('activeapps')
99
100     for key in (set(settings.keys()) & set(activeapps['appname'])):
101         svc = settings[key]
102         if isinstance(svc, dict) and 'language' in svc and svc['language'] == 'python':
103             services[key] = svc
104
105 def do_start(service):
106     '''
107     Start the named Python service
108     '''
109
110     pidfile = get_pid_file(service)
111
112     if service not in services:
113         print "* service %s is not a 'python' application" % service
114         return
115
116     if os.path.exists(pidfile):
117         try:
118             pid_fd = open(pidfile, 'r')
119             alive = os.getsid(int(pid_fd.read()))
120             print "* service %s already running" % service
121             return
122         except OSError:
123             os.remove(pidfile)
124
125     print "* starting %s" % service
126
127     if as_daemon:
128
129         if osrf.system.System.daemonize(False):
130             return # parent process returns
131
132         # write PID file
133         pid_fd = open(pidfile, 'w')
134         pid_fd.write(str(os.getpid()))
135         pid_fd.close()
136
137     svc_settings = services[service]
138
139     osrf.app.Application.load(service, svc_settings['implementation'])
140     osrf.app.Application.register_sysmethods()
141     osrf.app.Application.application.global_init()
142
143     controller = osrf.server.Controller(service)
144     controller.max_requests = svc_settings['unix_config']['max_requests']
145     controller.max_children = svc_settings['unix_config']['max_children']
146     controller.min_children = svc_settings['unix_config']['min_children']
147     controller.keepalive = svc_settings['keepalive']
148
149     controller.run()
150     os._exit(0)
151
152 def do_list_all():
153     '''
154     List all Python services listed in the OpenSRF configuration file
155     '''
156     for service in services.keys():
157         print service
158
159 def do_start_all():
160     '''
161     Start all Python services listed in the OpenSRF configuration file
162     '''
163
164     # You can't start more than one service without daemonizing
165     global as_daemon
166     as_daemon = True
167
168     print "* starting all services for %s " % domain
169     for service in services.keys():
170         do_start(service)
171
172 def do_stop_all():
173     '''
174     Stop all Python services listed in the OpenSRF configuration file
175     '''
176
177     print "* stopping all services for %s " % domain
178     for service in services.keys():
179         do_stop(service)
180
181 def do_stop(service):
182     '''
183     Stop the named Python service
184     '''
185
186     pidfile = get_pid_file(service)
187
188     if not os.path.exists(pidfile):
189         print "* %s is not running" % service
190         return
191
192     print "* stopping %s" % service
193
194     pid_fd = open(pidfile)
195     pid = pid_fd.read()
196     pid_fd.close()
197     try:
198         os.kill(int(pid), signal.SIGTERM)
199     except:
200         pass
201     os.remove(pidfile)
202
203 # -----------------------------------------------------
204
205 # Parse the command line options
206 ops, args = None, None
207 try:
208     ops, args = getopt.getopt(sys.argv[1:], 'a:s:f:c:p:dhl')
209 except getopt.GetoptError, e:
210     print '* %s' % str(e)
211     do_help()
212
213 options = dict(ops)
214
215 if '-a' not in options:
216     do_help()
217
218 action = options['-a']
219
220 config_file = options.get('-f', '@CONF_DIR@/opensrf_core.xml')
221 pid_dir = options.get('-p', '@PID_DIR@/run/opensrf')
222
223 service_name = options.get('-s')
224 config_ctx = options.get('-c', 'config.opensrf')
225 as_localhost = '-l' in options
226 as_daemon = '-d' in options
227
228 domain = None
229 settings = None
230 services = {}
231
232 do_init()
233
234 if action == 'start':
235     do_start(service_name)
236
237 elif action == 'stop':
238     do_stop(service_name)
239
240 elif action == 'restart':
241     do_stop(service_name)
242     do_start(service_name)
243
244 elif action == 'list_all':
245     do_list_all()
246
247 elif action == 'start_all':
248     do_start_all()
249
250 elif action == 'stop_all':
251     do_stop_all()
252
253 elif action == 'restart_all':
254     do_stop_all()
255     do_start_all()
256
257 elif action == 'help':
258     do_help()