~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

Viewing changes to nova/service.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-08-16 14:04:11 UTC
  • mto: This revision was merged to the branch mainline in revision 84.
  • Revision ID: package-import@ubuntu.com-20120816140411-0mr4n241wmk30t9l
Tags: upstream-2012.2~f3
ImportĀ upstreamĀ versionĀ 2012.2~f3

Show diffs side-by-side

added added

removed removed

Lines of Context:
103
103
FLAGS.register_opts(service_opts)
104
104
 
105
105
 
 
106
class SignalExit(SystemExit):
 
107
    def __init__(self, signo, exccode=1):
 
108
        super(SignalExit, self).__init__(exccode)
 
109
        self.signo = signo
 
110
 
 
111
 
106
112
class Launcher(object):
107
113
    """Launch one or more services and wait for them to complete."""
108
114
 
160
166
 
161
167
class ServiceLauncher(Launcher):
162
168
    def _handle_signal(self, signo, frame):
163
 
        signame = {signal.SIGTERM: 'SIGTERM', signal.SIGINT: 'SIGINT'}[signo]
164
 
        LOG.info(_('Caught %s, exiting'), signame)
165
 
 
166
169
        # Allow the process to be killed again and die from natural causes
167
170
        signal.signal(signal.SIGTERM, signal.SIG_DFL)
168
171
        signal.signal(signal.SIGINT, signal.SIG_DFL)
169
172
 
170
 
        sys.exit(1)
 
173
        raise SignalExit(signo)
171
174
 
172
175
    def wait(self):
173
176
        signal.signal(signal.SIGTERM, self._handle_signal)
187
190
        status = None
188
191
        try:
189
192
            super(ServiceLauncher, self).wait()
 
193
        except SignalExit as exc:
 
194
            signame = {signal.SIGTERM: 'SIGTERM',
 
195
                       signal.SIGINT: 'SIGINT'}[exc.signo]
 
196
            LOG.info(_('Caught %s, exiting'), signame)
 
197
            status = exc.code
190
198
        except SystemExit as exc:
191
199
            status = exc.code
 
200
        finally:
192
201
            self.stop()
193
202
        rpc.cleanup()
194
203
 
207
216
class ProcessLauncher(object):
208
217
    def __init__(self):
209
218
        self.children = {}
 
219
        self.sigcaught = None
210
220
        self.running = True
211
221
        rfd, self.writepipe = os.pipe()
212
222
        self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r')
215
225
        signal.signal(signal.SIGINT, self._handle_signal)
216
226
 
217
227
    def _handle_signal(self, signo, frame):
218
 
        signame = {signal.SIGTERM: 'SIGTERM', signal.SIGINT: 'SIGINT'}[signo]
219
 
        LOG.info(_('Caught %s, stopping children'), signame)
220
 
 
 
228
        self.sigcaught = signo
221
229
        self.running = False
222
 
        for pid in self.children:
223
 
            try:
224
 
                os.kill(pid, signal.SIGTERM)
225
 
            except OSError as exc:
226
 
                if exc.errno != errno.ESRCH:
227
 
                    raise
228
230
 
229
231
        # Allow the process to be killed again and die from natural causes
230
232
        signal.signal(signal.SIGTERM, signal.SIG_DFL)
242
244
    def _child_process(self, server):
243
245
        # Setup child signal handlers differently
244
246
        def _sigterm(*args):
245
 
            LOG.info(_('Received SIGTERM, stopping'))
246
247
            signal.signal(signal.SIGTERM, signal.SIG_DFL)
247
 
            server.stop()
 
248
            raise SignalExit(signal.SIGTERM)
248
249
 
249
250
        signal.signal(signal.SIGTERM, _sigterm)
250
251
        # Block SIGINT and let the parent send us a SIGTERM
287
288
            status = 0
288
289
            try:
289
290
                self._child_process(wrap.server)
 
291
            except SignalExit as exc:
 
292
                signame = {signal.SIGTERM: 'SIGTERM',
 
293
                           signal.SIGINT: 'SIGINT'}[exc.signo]
 
294
                LOG.info(_('Caught %s, exiting'), signame)
 
295
                status = exc.code
290
296
            except SystemExit as exc:
291
297
                status = exc.code
292
298
            except BaseException:
293
299
                LOG.exception(_('Unhandled exception'))
294
300
                status = 2
 
301
            finally:
 
302
                wrap.server.stop()
295
303
 
296
304
            os._exit(status)
297
305
 
334
342
 
335
343
    def wait(self):
336
344
        """Loop waiting on children to die and respawning as necessary"""
337
 
        # Loop calling wait and respawning as necessary
338
345
        while self.running:
339
346
            wrap = self._wait_child()
340
347
            if not wrap:
343
350
            while self.running and len(wrap.children) < wrap.workers:
344
351
                self._start_child(wrap)
345
352
 
 
353
        if self.sigcaught:
 
354
            signame = {signal.SIGTERM: 'SIGTERM',
 
355
                       signal.SIGINT: 'SIGINT'}[self.sigcaught]
 
356
            LOG.info(_('Caught %s, stopping children'), signame)
 
357
 
 
358
        for pid in self.children:
 
359
            try:
 
360
                os.kill(pid, signal.SIGTERM)
 
361
            except OSError as exc:
 
362
                if exc.errno != errno.ESRCH:
 
363
                    raise
 
364
 
346
365
        # Wait for children to die
347
366
        if self.children:
348
367
            LOG.info(_('Waiting on %d children to exit'), len(self.children))
376
395
        vcs_string = version.version_string_with_vcs()
377
396
        LOG.audit(_('Starting %(topic)s node (version %(vcs_string)s)'),
378
397
                  {'topic': self.topic, 'vcs_string': vcs_string})
379
 
        utils.cleanup_file_locks()
380
398
        self.manager.init_host()
381
399
        self.model_disconnected = False
382
400
        ctxt = context.get_admin_context()
597
615
        :returns: None
598
616
 
599
617
        """
600
 
        utils.cleanup_file_locks()
601
618
        if self.manager:
602
619
            self.manager.init_host()
603
620
        self.server.start()