def __init__(self, message=None, **kwargs): self.kwargs = kwargs if 'code' not in self.kwargs: try: self.kwargs['code'] = self.code except AttributeError: pass if message: self.message = message try: self.message = self.message % kwargs except Exception as e: # kwargs doesn't match a variable in the message # log the issue and the kwargs LOG.exception(_LE('Exception in string format operation')) for name, value in kwargs.iteritems(): LOG.error( _LE("%(name)s: %(value)s") % { 'name': name, 'value': value }) if CONF.fatal_exception_format_errors: raise e super(MagnumException, self).__init__(self.message)
def __init__(self, message=None, **kwargs): self.kwargs = kwargs if 'code' not in self.kwargs: try: self.kwargs['code'] = self.code except AttributeError: pass if message: self.message = message try: self.message = self.message % kwargs except Exception as e: # kwargs doesn't match a variable in the message # log the issue and the kwargs LOG.exception(_LE('Exception in string format operation')) for name, value in kwargs.iteritems(): LOG.error(_LE("%(name)s: %(value)s") % {'name': name, 'value': value}) try: if CONF.fatal_exception_format_errors: raise e except cfg.NoSuchOptError: # Note: work around for Bug: #1447873 if CONF.oslo_versionedobjects.fatal_exception_format_errors: raise e super(MagnumException, self).__init__(self.message)
def mkfs(fs, path, label=None): """Format a file or block device :param fs: Filesystem type (examples include 'swap', 'ext3', 'ext4' 'btrfs', etc.) :param path: Path to file or block device to format :param label: Volume label to use """ if fs == 'swap': args = ['mkswap'] else: args = ['mkfs', '-t', fs] # add -F to force no interactive execute on non-block device. if fs in ('ext3', 'ext4'): args.extend(['-F']) if label: if fs in ('msdos', 'vfat'): label_opt = '-n' else: label_opt = '-L' args.extend([label_opt, label]) args.append(path) try: execute(*args, run_as_root=True, use_standard_locale=True) except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception() as ctx: if os.strerror(errno.ENOENT) in e.stderr: ctx.reraise = False LOG.exception(_LE('Failed to make file system. ' 'File system %s is not supported.'), fs) raise exception.FileSystemNotSupported(fs=fs) else: LOG.exception(_LE('Failed to create a file system ' 'in %(path)s. Error: %(error)s'), {'path': path, 'error': e})
def poll_and_check(self): # TODO(yuanying): temporary implementation to update api_address, # node_addresses and bay status stack = self.openstack_client.heat().stacks.get(self.bay.stack_id) self.attempts += 1 # poll_and_check is detached and polling long time to check status, # so another user/client can call delete bay/stack. if stack.stack_status == 'DELETE_COMPLETE': LOG.info(_LI('Bay has been deleted, stack_id: %s') % self.bay.stack_id) self.bay.destroy() raise loopingcall.LoopingCallDone() if (stack.stack_status in ['CREATE_COMPLETE', 'UPDATE_COMPLETE']): _update_stack_outputs(self.context, stack, self.bay) self.bay.status = stack.stack_status self.bay.save() raise loopingcall.LoopingCallDone() elif stack.stack_status != self.bay.status: self.bay.status = stack.stack_status self.bay.save() if stack.stack_status == 'CREATE_FAILED': LOG.error(_LE('Unable to create bay, stack_id: %(stack_id)s, ' 'reason: %(reason)s') % {'stack_id': self.bay.stack_id, 'reason': stack.stack_status_reason}) raise loopingcall.LoopingCallDone() if stack.stack_status == 'DELETE_FAILED': LOG.error(_LE('Unable to delete bay, stack_id: %(stack_id)s, ' 'reason: %(reason)s') % {'stack_id': self.bay.stack_id, 'reason': stack.stack_status_reason}) raise loopingcall.LoopingCallDone() if stack.stack_status == 'UPDATE_FAILED': LOG.error(_LE('Unable to update bay, stack_id: %(stack_id)s, ' 'reason: %(reason)s') % {'stack_id': self.bay.stack_id, 'reason': stack.stack_status_reason}) raise loopingcall.LoopingCallDone() # only check max attempts when the stack is being created when # the timeout hasn't been set. If the timeout has been set then # the loop will end when the stack completes or the timeout occurs if stack.stack_status == 'CREATE_IN_PROGRESS': if (stack.timeout_mins is None and self.attempts > cfg.CONF.k8s_heat.max_attempts): LOG.error(_LE('Bay check exit after %(attempts)s attempts,' 'stack_id: %(id)s, stack_status: %(status)s') % {'attempts': cfg.CONF.k8s_heat.max_attempts, 'id': self.bay.stack_id, 'status': stack.stack_status}) raise loopingcall.LoopingCallDone() else: if self.attempts > cfg.CONF.k8s_heat.max_attempts: LOG.error(_LE('Bay check exit after %(attempts)s attempts,' 'stack_id: %(id)s, stack_status: %(status)s') % {'attempts': cfg.CONF.k8s_heat.max_attempts, 'id': self.bay.stack_id, 'status': stack.stack_status}) raise loopingcall.LoopingCallDone()
def _v3_client_init(self): kwargs = {'auth_url': self.v3_endpoint, 'endpoint': self.v3_endpoint} # Note try trust_id first, as we can't reuse auth_token in that case if self.context.trust_id is not None: # We got a trust_id, so we use the admin credentials # to authenticate with the trust_id so we can use the # trust impersonating the trustor user. kwargs.update(self._service_admin_creds()) kwargs['trust_id'] = self.context.trust_id kwargs.pop('project_name') elif self.context.auth_token_info is not None: # The auth_ref version must be set according to the token version if 'access' in self.context.auth_token_info: kwargs['auth_ref'] = copy.deepcopy( self.context.auth_token_info['access']) kwargs['auth_ref']['version'] = 'v2.0' kwargs['auth_ref']['token']['id'] = self.context.auth_token elif 'token' in self.context.auth_token_info: kwargs['auth_ref'] = copy.deepcopy( self.context.auth_token_info['token']) kwargs['auth_ref']['version'] = 'v3' kwargs['auth_ref']['auth_token'] = self.context.auth_token else: LOG.error(_LE("Unknown version in auth_token_info")) raise exception.AuthorizationFailure() elif self.context.auth_token is not None: kwargs['token'] = self.context.auth_token kwargs['project_id'] = self.context.project_id else: LOG.error( _LE("Keystone v3 API connection failed, no password " "trust or auth_token!")) raise exception.AuthorizationFailure() client = kc_v3.Client(**kwargs) if 'auth_ref' not in kwargs: client.authenticate() # If we are authenticating with a trust set the context auth_token # with the trust scoped token if 'trust_id' in kwargs: # Sanity check if not client.auth_ref.trust_scoped: LOG.error(_LE("trust token re-scoping failed!")) raise exception.AuthorizationFailure() # All OK so update the context with the token self.context.auth_token = client.auth_ref.auth_token self.context.auth_url = self.v3_endpoint self.context.user = client.auth_ref.user_id self.context.project_id = client.auth_ref.project_id self.context.user_name = client.auth_ref.username return client
def run_periodic_tasks(self, context, raise_on_error=False): """Tasks to be run at a periodic interval.""" idle_for = DEFAULT_INTERVAL for task_name, task in self._periodic_tasks: full_task_name = '.'.join([self.__class__.__name__, task_name]) spacing = self._periodic_spacing[task_name] last_run = self._periodic_last_run[task_name] # Check if due, if not skip idle_for = min(idle_for, spacing) if last_run is not None: delta = last_run + spacing - time.time() if delta > 0: idle_for = min(idle_for, delta) continue LOG.debug("Running periodic task %(full_task_name)s", {"full_task_name": full_task_name}) self._periodic_last_run[task_name] = _nearest_boundary( last_run, spacing) try: task(self, context) except Exception as e: if raise_on_error: raise LOG.exception(_LE("Error during %(full_task_name)s: %(e)s"), {"full_task_name": full_task_name, "e": e}) time.sleep(0) return idle_for
def obj_class_from_name(cls, objname, objver): """Returns a class from the registry based on a name and version.""" if objname not in cls._obj_classes: LOG.error(_LE('Unable to instantiate unregistered object type ' '%(objtype)s'), dict(objtype=objname)) raise exception.UnsupportedObjectError(objtype=objname) latest = None compatible_match = None for objclass in cls._obj_classes[objname]: if objclass.VERSION == objver: return objclass version_bits = tuple([int(x) for x in objclass.VERSION.split(".")]) if latest is None: latest = version_bits elif latest < version_bits: latest = version_bits if versionutils.is_compatible(objver, objclass.VERSION): compatible_match = objclass if compatible_match: return compatible_match latest_ver = '%i.%i' % latest raise exception.IncompatibleObjectVersion(objname=objname, objver=objver, supported=latest_ver)
def stop_timers(self): for x in self.timers: try: x.stop() except Exception: LOG.exception(_LE('Error stopping timer.')) self.timers = []
def run_periodic_tasks(self, context, raise_on_error=False): """Tasks to be run at a periodic interval.""" idle_for = DEFAULT_INTERVAL for task_name, task in self._periodic_tasks: full_task_name = '.'.join([self.__class__.__name__, task_name]) spacing = self._periodic_spacing[task_name] last_run = self._periodic_last_run[task_name] # Check if due, if not skip idle_for = min(idle_for, spacing) if last_run is not None: delta = last_run + spacing - time.time() if delta > 0: idle_for = min(idle_for, delta) continue LOG.debug("Running periodic task %(full_task_name)s", {"full_task_name": full_task_name}) self._periodic_last_run[task_name] = _nearest_boundary( last_run, spacing) try: task(self, context) except Exception: if raise_on_error: raise LOG.exception(_LE("Error during %(full_task_name)s"), {"full_task_name": full_task_name}) time.sleep(0) return idle_for
def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: idle = self.f(*self.args, **self.kw) if not self._running: break if periodic_interval_max is not None: idle = min(idle, periodic_interval_max) LOG.debug('Dynamic looping call %(func_name)r sleeping ' 'for %(idle).02f seconds', {'func_name': self.f, 'idle': idle}) greenthread.sleep(idle) except LoopingCallDone as e: self.stop() done.send(e.retvalue) except Exception: LOG.exception(_LE('in dynamic looping call')) done.send_exception(*sys.exc_info()) return else: done.send(True)
def obj_class_from_name(cls, objname, objver): """Returns a class from the registry based on a name and version.""" if objname not in cls._obj_classes: LOG.error( _LE('Unable to instantiate unregistered object type ' '%(objtype)s'), dict(objtype=objname)) raise exception.UnsupportedObjectError(objtype=objname) latest = None compatible_match = None for objclass in cls._obj_classes[objname]: if objclass.VERSION == objver: return objclass version_bits = tuple([int(x) for x in objclass.VERSION.split(".")]) if latest is None: latest = version_bits elif latest < version_bits: latest = version_bits if versionutils.is_compatible(objver, objclass.VERSION): compatible_match = objclass if compatible_match: return compatible_match latest_ver = '%i.%i' % latest raise exception.IncompatibleObjectVersion(objname=objname, objver=objver, supported=latest_ver)
def main(): cfg.CONF(sys.argv[1:], project='magnum') logging.setup('magnum') LOG.info(_LI('Starting server in PID %s') % os.getpid()) LOG.debug("Configuration:") cfg.CONF.log_opt_values(LOG, std_logging.DEBUG) cfg.CONF.import_opt('topic', 'magnum.conductor.config', group='conductor') conductor_id = short_id.generate_id() endpoints = [ docker_conductor.Handler(), k8s_conductor.Handler(), bay_k8s_heat.Handler(), conductor_listener.Handler(), ] if (not os.path.isfile(cfg.CONF.bay.k8s_atomic_template_path) and not os.path.isfile(cfg.CONF.bay.k8s_coreos_template_path)): LOG.error(_LE("The Heat template can not be found for either k8s " "atomic %(atomic_template)s or coreos " "(coreos_template)%s. Install template first if you " "want to create bay.") % {'atomic_template': cfg.CONF.bay.k8s_atomic_template_path, 'coreos_template': cfg.CONF.bay.k8s_coreos_template_path}) server = service.Service(cfg.CONF.conductor.topic, conductor_id, endpoints) server.serve()
def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: start = _ts() self.f(*self.args, **self.kw) end = _ts() if not self._running: break delay = end - start - interval if delay > 0: LOG.warning(_LW('task %(func_name)r run outlasted ' 'interval by %(delay).2f sec'), {'func_name': self.f, 'delay': delay}) greenthread.sleep(-delay if delay < 0 else 0) except LoopingCallDone as e: self.stop() done.send(e.retvalue) except Exception: LOG.exception(_LE('in fixed duration looping call')) done.send_exception(*sys.exc_info()) return else: done.send(True)
def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: start = _ts() self.f(*self.args, **self.kw) end = _ts() if not self._running: break delay = end - start - interval if delay > 0: LOG.warn(_LW('task %(func_name)r run outlasted ' 'interval by %(delay).2f sec'), {'func_name': self.f, 'delay': delay}) greenthread.sleep(-delay if delay < 0 else 0) except LoopingCallDone as e: self.stop() done.send(e.retvalue) except Exception: LOG.exception(_LE('in fixed duration looping call')) done.send_exception(*sys.exc_info()) return else: done.send(True)
def main(): cfg.CONF(sys.argv[1:], project='magnum') logging.setup('magnum') LOG.info(_LI('Starting server in PID %s') % os.getpid()) LOG.debug("Configuration:") cfg.CONF.log_opt_values(LOG, std_logging.DEBUG) cfg.CONF.import_opt('topic', 'magnum.conductor.config', group='conductor') cfg.CONF.import_opt('host', 'magnum.conductor.config', group='conductor') endpoints = [ docker_conductor.Handler(), k8s_conductor.Handler(), bay_k8s_heat.Handler() ] if not os.path.isfile(cfg.CONF.k8s_heat.template_path): LOG.error( _LE("The Heat template %s is not found. Install template.") % (cfg.CONF.k8s_heat.template_path)) exit(-1) server = service.Service(cfg.CONF.conductor.topic, cfg.CONF.conductor.host, endpoints) server.serve()
def setter(self, value, name=name, typefn=typefn): self._changed_fields.add(name) try: return setattr(self, get_attrname(name), typefn(value)) except Exception: attr = "%s.%s" % (self.obj_name(), name) LOG.exception(_LE('Error setting %(attr)s'), {'attr': attr}) raise
def tempdir(**kwargs): tempfile.tempdir = CONF.tempdir tmpdir = tempfile.mkdtemp(**kwargs) try: yield tmpdir finally: try: shutil.rmtree(tmpdir) except OSError as e: LOG.error(_LE('Could not remove tmpdir: %s'), e)
def admin_client(self): if not self._admin_client: # Create admin client connection to v3 API admin_creds = self._service_admin_creds() c = kc_v3.Client(**admin_creds) if c.authenticate(): self._admin_client = c else: LOG.error(_LE("Admin client authentication failed")) raise exception.AuthorizationFailure() return self._admin_client
def rc_delete(self, api_address, name): LOG.debug("rc_delete %s" % name) try: out, err = utils.trycmd('kubectl', 'delete', 'rc', name, '-s', api_address) if err: return False except Exception as e: LOG.error(_LE("Couldn't delete rc %(rc)s due to error %(error)s") % {'rc': name, 'error': e}) return False return True
def pod_update(self, api_address, pod): LOG.debug("pod_update contents %s" % pod.as_dict()) try: out, err = _k8s_update(api_address, pod) if err: return False except Exception as e: LOG.error(_LE("Couldn't update pod with %(content)s due to error " "%(error)s") % {'content': pod, 'error': e}) return False return True
def service_delete(self, api_address, name): LOG.debug("service_delete %s" % name) try: out, err = utils.trycmd('kubectl', 'delete', 'service', name, '-s', api_address) if err: return False except Exception as e: LOG.error(_LE("Couldn't delete service %(service)s due to error " "%(error)s") % {'service': name, 'error': e}) return False return True
def rc_update(self, api_address, rc): LOG.debug("rc_update contents %s" % rc) try: out, err = _k8s_update(api_address, rc) if err: return False except Exception as e: LOG.error(_LE("Couldn't update rc with contents %(content)s due " "to error %(error)s") % {'content': rc, 'error': e}) return False return True
def pod_update(self, api_address, pod): LOG.debug("pod_update contents %s" % pod) try: out, err = _k8s_update(api_address, pod) if err: return False except Exception as e: LOG.error(_LE("Couldn't update pod with %(content)s due to error " "%(error)s") % {'content': pod, 'error': e}) return False return True
def rc_update(self, api_address, rc): LOG.debug("rc_update contents %s" % rc.as_dict()) try: out, err = _k8s_update(api_address, rc) if err: return False except Exception as e: LOG.error(_LE("Couldn't update rc with contents %(content)s due " "to error %(error)s") % {'content': rc, 'error': e}) return False return True
def wrapped(self, context, *args, **kwargs): try: return f(self, context, *args, **kwargs) except Exception as e: container_uuid = kwargs.get('container_uuid') if container_uuid is not None: LOG.exception(_LE("Error while connect to docker " "container %(name)s: %(error)s"), {'name': container_uuid, 'error': str(e)}) raise exception.ContainerException( "Docker internal Error: %s" % str(e))
def __call__(self, environ, start_response): # Request for this state, modified by replace_start_response() # and used when an error is being reported. state = {} def replacement_start_response(status, headers, exc_info=None): """Overrides the default response to make errors parsable.""" try: status_code = int(status.split(' ')[0]) state['status_code'] = status_code except (ValueError, TypeError): # pragma: nocover raise Exception( _('ErrorDocumentMiddleware received an invalid ' 'status %s') % status) else: if (state['status_code'] // 100) not in (2, 3): # Remove some headers so we can replace them later # when we have the full error message and can # compute the length. headers = [(h, v) for (h, v) in headers if h not in ('Content-Length', 'Content-Type')] # Save the headers in case we need to modify them. state['headers'] = headers return start_response(status, headers, exc_info) app_iter = self.app(environ, replacement_start_response) if (state['status_code'] // 100) not in (2, 3): req = webob.Request(environ) if (req.accept.best_match(['application/json', 'application/xml' ]) == 'application/xml'): try: # simple check xml is valid body = [ et.ElementTree.tostring( et.ElementTree.fromstring('<error_message>' + '\n'.join(app_iter) + '</error_message>')) ] except et.ElementTree.ParseError as err: LOG.error(_LE('Error parsing HTTP response: %s'), err) body = [ '<error_message>%s' % state['status_code'] + '</error_message>' ] state['headers'].append(('Content-Type', 'application/xml')) else: body = [json.dumps({'error_message': '\n'.join(app_iter)})] state['headers'].append(('Content-Type', 'application/json')) state['headers'].append(('Content-Length', len(body[0]))) else: body = app_iter return body
def service_update(self, api_address, service): LOG.debug("service_update with contents %s" % service) try: out, err = _k8s_update(api_address, service) if err: return False except Exception as e: LOG.error(_LE("Couldn't update service with contents %(content)s " "due to error %(error)s") % {'content': service, 'error': e}) return False return True
def mkfs(fs, path, label=None): """Format a file or block device :param fs: Filesystem type (examples include 'swap', 'ext3', 'ext4' 'btrfs', etc.) :param path: Path to file or block device to format :param label: Volume label to use """ if fs == 'swap': args = ['mkswap'] else: args = ['mkfs', '-t', fs] # add -F to force no interactive execute on non-block device. if fs in ('ext3', 'ext4'): args.extend(['-F']) if label: if fs in ('msdos', 'vfat'): label_opt = '-n' else: label_opt = '-L' args.extend([label_opt, label]) args.append(path) try: execute(*args, run_as_root=True, use_standard_locale=True) except processutils.ProcessExecutionError as e: with excutils.save_and_reraise_exception() as ctx: if os.strerror(errno.ENOENT) in e.stderr: ctx.reraise = False LOG.exception( _LE('Failed to make file system. ' 'File system %s is not supported.'), fs) raise exception.FileSystemNotSupported(fs=fs) else: LOG.exception( _LE('Failed to create a file system ' 'in %(path)s. Error: %(error)s'), { 'path': path, 'error': e })
def pod_create(self, api_address, pod): LOG.debug("pod_create contents %s" % pod) try: out, err = _k8s_create(api_address, pod) if err: return False except Exception as e: LOG.error(_LE("Couldn't create pod with contents %(content)s " "due to error %(error)s") % {'content': pod, 'error': e}) return False return True
def service_update(self, api_address, service): LOG.debug("service_update with contents %s" % service.as_dict()) try: out, err = _k8s_update(api_address, service) if err: return False except Exception as e: LOG.error(_LE("Couldn't update service with contents %(content)s " "due to error %(error)s") % {'content': service, 'error': e}) return False return True
def __call__(self, environ, start_response): # Request for this state, modified by replace_start_response() # and used when an error is being reported. state = {} def replacement_start_response(status, headers, exc_info=None): """Overrides the default response to make errors parsable.""" try: status_code = int(status.split(' ')[0]) state['status_code'] = status_code except (ValueError, TypeError): # pragma: nocover raise Exception(_( 'ErrorDocumentMiddleware received an invalid ' 'status %s') % status) else: if (state['status_code'] // 100) not in (2, 3): # Remove some headers so we can replace them later # when we have the full error message and can # compute the length. headers = [(h, v) for (h, v) in headers if h not in ('Content-Length', 'Content-Type') ] # Save the headers in case we need to modify them. state['headers'] = headers return start_response(status, headers, exc_info) app_iter = self.app(environ, replacement_start_response) if (state['status_code'] // 100) not in (2, 3): req = webob.Request(environ) if (req.accept.best_match(['application/json', 'application/xml']) == 'application/xml'): try: # simple check xml is valid body = [et.ElementTree.tostring( et.ElementTree.fromstring('<error_message>' + '\n'.join(app_iter) + '</error_message>'))] except et.ElementTree.ParseError as err: LOG.error(_LE('Error parsing HTTP response: %s'), err) body = ['<error_message>%s' % state['status_code'] + '</error_message>'] state['headers'].append(('Content-Type', 'application/xml')) else: body = [json.dumps({'error_message': '\n'.join(app_iter)})] state['headers'].append(('Content-Type', 'application/json')) state['headers'].append(('Content-Length', len(body[0]))) else: body = app_iter return body
def _stop_threads(self): current = threading.current_thread() # Iterate over a copy of self.threads so thread_done doesn't # modify the list while we're iterating for x in self.threads[:]: if x is current: # don't kill the current thread. continue try: x.stop() except eventlet.greenlet.GreenletExit: pass except Exception: LOG.exception(_LE('Error stopping thread.'))
def pod_delete(self, api_address, name): LOG.debug("pod_delete %s" % name) try: out, err = utils.trycmd('kubectl', 'delete', 'pod', name, '-s', api_address,) except Exception as e: LOG.error(_LE("Couldn't delete pod %(pod)s due to error " "%(error)s") % {'pod': name, 'error': e}) return False if err: if ('"%s" not found' % name) in err: raise exception.PodNotFound(pod=name) else: return False return True
def wait(self): for x in self.timers: try: x.wait() except eventlet.greenlet.GreenletExit: pass except Exception: LOG.exception(_LE('Error waiting on ThreadGroup.')) current = threading.current_thread() # Iterate over a copy of self.threads so thread_done doesn't # modify the list while we're iterating for x in self.threads[:]: if x is current: continue try: x.wait() except eventlet.greenlet.GreenletExit: pass except Exception as ex: LOG.exception(ex)
def wrapped(*args, **kw): try: return func(*args, **kw) except Exception as excp: if isinstance(excp, MagnumException): http_error_code = excp.code else: http_error_code = 500 if http_error_code >= 500: # log the error message with its associated # correlation id log_correlation_id = str(uuid.uuid4()) LOG.error(_LE("%(correlation_id)s:%(excp)s") % {'correlation_id': log_correlation_id, 'excp': str(excp)}) # raise a client error with an obfuscated message func_server_error(log_correlation_id, http_error_code) else: # raise a client error the original message LOG.debug(excp) func_client_error(excp, http_error_code)
def _child_wait_for_exit_or_signal(self, launcher): status = 0 signo = 0 # NOTE(johannes): All exceptions are caught to ensure this # doesn't fallback into the loop spawning children. It would # be bad for a child to spawn more children. try: launcher.wait() except SignalExit as exc: signame = _signo_to_signame(exc.signo) LOG.info(_LI('Child caught %s, exiting'), signame) status = exc.code signo = exc.signo except SystemExit as exc: status = exc.code except BaseException: LOG.exception(_LE('Unhandled exception')) status = 2 finally: launcher.stop() return status, signo
def main(): cfg.CONF(sys.argv[1:], project='magnum') logging.setup('magnum') LOG.info(_LI('Starting server in PID %s') % os.getpid()) LOG.debug("Configuration:") cfg.CONF.log_opt_values(LOG, std_logging.DEBUG) cfg.CONF.import_opt('topic', 'magnum.conductor.config', group='conductor') cfg.CONF.import_opt('host', 'magnum.conductor.config', group='conductor') endpoints = [ docker_conductor.Handler(), k8s_conductor.Handler(), bay_k8s_heat.Handler() ] if not os.path.isfile(cfg.CONF.k8s_heat.template_path): LOG.error(_LE("The Heat template %s is not found. Install template.") % (cfg.CONF.k8s_heat.template_path)) exit(-1) server = service.Service(cfg.CONF.conductor.topic, cfg.CONF.conductor.host, endpoints) server.serve()
def wrapped(*args, **kw): try: return func(*args, **kw) except Exception as excp: if isinstance(excp, MagnumException): http_error_code = excp.code else: http_error_code = 500 if http_error_code >= 500: # log the error message with its associated # correlation id log_correlation_id = str(uuid.uuid4()) LOG.error( _LE("%(correlation_id)s:%(excp)s") % { 'correlation_id': log_correlation_id, 'excp': str(excp) }) # raise a client error with an obfuscated message func_server_error(log_correlation_id, http_error_code) else: # raise a client error the original message LOG.debug(excp) func_client_error(excp, http_error_code)