30
28
from eventlet import greenthread
31
29
from eventlet import greenpool
33
from sqlalchemy.exc import OperationalError
35
31
from nova import context
36
32
from nova import db
37
33
from nova import exception
34
from nova import flags
38
35
from nova import log as logging
39
from nova import flags
40
36
from nova import rpc
41
37
from nova import utils
42
38
from nova import version
81
77
vcs_string = version.version_string_with_vcs()
82
logging.audit(_("Starting %(topic)s node (version %(vcs_string)s)"),
78
logging.audit(_('Starting %(topic)s node (version %(vcs_string)s)'),
83
79
{'topic': self.topic, 'vcs_string': vcs_string})
84
80
self.manager.init_host()
85
81
self.model_disconnected = False
140
136
return getattr(manager, key)
148
report_interval=None,
149
periodic_interval=None):
139
def create(cls, host=None, binary=None, topic=None, manager=None,
140
report_interval=None, periodic_interval=None):
150
141
"""Instantiates class and passes back application object.
153
host, defaults to FLAGS.host
154
binary, defaults to basename of executable
155
topic, defaults to bin_name - "nova-" part
156
manager, defaults to FLAGS.<topic>_manager
157
report_interval, defaults to FLAGS.report_interval
158
periodic_interval, defaults to FLAGS.periodic_interval
143
:param host: defaults to FLAGS.host
144
:param binary: defaults to basename of executable
145
:param topic: defaults to bin_name - 'nova-' part
146
:param manager: defaults to FLAGS.<topic>_manager
147
:param report_interval: defaults to FLAGS.report_interval
148
:param periodic_interval: defaults to FLAGS.periodic_interval
161
152
host = FLAGS.host
163
154
binary = os.path.basename(inspect.stack()[-1][1])
165
topic = binary.rpartition("nova-")[2]
156
topic = binary.rpartition('nova-')[2]
167
158
manager = FLAGS.get('%s_manager' % topic, None)
168
159
if not report_interval:
175
166
return service_obj
178
"""Destroy the service object in the datastore"""
169
"""Destroy the service object in the datastore."""
181
172
db.service_destroy(context.get_admin_context(), self.service_id)
182
173
except exception.NotFound:
183
logging.warn(_("Service killed that has no database entry"))
174
logging.warn(_('Service killed that has no database entry'))
186
177
for x in self.timers:
209
200
service_ref = db.service_get(ctxt, self.service_id)
210
201
except exception.NotFound:
211
logging.debug(_("The service database object disappeared, "
202
logging.debug(_('The service database object disappeared, '
213
204
self._create_service_ref(ctxt)
214
205
service_ref = db.service_get(ctxt, self.service_id)
218
209
{'report_count': service_ref['report_count'] + 1})
220
211
# TODO(termie): make this pattern be more elegant.
221
if getattr(self, "model_disconnected", False):
212
if getattr(self, 'model_disconnected', False):
222
213
self.model_disconnected = False
223
logging.error(_("Recovered model server connection!"))
214
logging.error(_('Recovered model server connection!'))
225
216
# TODO(vish): this should probably only catch connection errors
226
217
except Exception: # pylint: disable=W0702
227
if not getattr(self, "model_disconnected", False):
218
if not getattr(self, 'model_disconnected', False):
228
219
self.model_disconnected = True
229
logging.exception(_("model server went away"))
220
logging.exception(_('model server went away'))
232
223
class WsgiService(object):
233
224
"""Base class for WSGI based services.
235
226
For each api you define, you must also define these flags:
236
:<api>_listen: The address on which to listen
237
:<api>_listen_port: The port on which to listen
227
:<api>_listen: The address on which to listen
228
:<api>_listen_port: The port on which to listen
240
232
def __init__(self, conf, apis):
252
244
class ApiService(WsgiService):
253
"""Class for our nova-api service"""
245
"""Class for our nova-api service."""
255
248
def create(cls, conf=None):
257
250
conf = wsgi.paste_config_file(FLAGS.api_paste_config)
259
message = (_("No paste configuration found for: %s"),
252
message = (_('No paste configuration found for: %s'),
260
253
FLAGS.api_paste_config)
261
254
raise exception.Error(message)
262
255
api_endpoints = ['ec2', 'osapi']
280
273
FLAGS.ParseNewFlags()
282
275
name = '_'.join(x.binary for x in services)
283
logging.debug(_("Serving %s"), name)
284
logging.debug(_("Full set of FLAGS:"))
276
logging.debug(_('Serving %s'), name)
277
logging.debug(_('Full set of FLAGS:'))
285
278
for flag in FLAGS:
286
279
flag_get = FLAGS.get(flag, None)
287
logging.debug("%(flag)s : %(flag_get)s" % locals())
280
logging.debug('%(flag)s : %(flag_get)s' % locals())
289
282
for x in services:
317
310
def _run_wsgi(paste_config_file, apis):
318
logging.debug(_("Using paste.deploy config at: %s"), paste_config_file)
311
logging.debug(_('Using paste.deploy config at: %s'), paste_config_file)
321
314
config = wsgi.load_paste_configuration(paste_config_file, api)
322
315
if config is None:
323
logging.debug(_("No paste configuration for app: %s"), api)
316
logging.debug(_('No paste configuration for app: %s'), api)
325
logging.debug(_("App Config: %(api)s\n%(config)r") % locals())
326
logging.info(_("Running %s API"), api)
318
logging.debug(_('App Config: %(api)s\n%(config)r') % locals())
319
logging.info(_('Running %s API'), api)
327
320
app = wsgi.load_paste_app(paste_config_file, api)
328
apps.append((app, getattr(FLAGS, "%s_listen_port" % api),
329
getattr(FLAGS, "%s_listen" % api)))
321
apps.append((app, getattr(FLAGS, '%s_listen_port' % api),
322
getattr(FLAGS, '%s_listen' % api)))
330
323
if len(apps) == 0:
331
logging.error(_("No known API applications configured in %s."),
324
logging.error(_('No known API applications configured in %s.'),
332
325
paste_config_file)