Example #1
0
    def __init__(self,
                 stdout=None,
                 stderr=None,
                 exit_code=None,
                 cmd=None,
                 description=None):
        self.exit_code = exit_code
        self.stderr = stderr
        self.stdout = stdout
        self.cmd = cmd
        self.description = description

        if description is None:
            description = _("Unexpected error while running command.")
        if exit_code is None:
            exit_code = '-'
        message = _('%(description)s\n'
                    'Command: %(cmd)s\n'
                    'Exit code: %(exit_code)s\n'
                    'Stdout: %(stdout)r\n'
                    'Stderr: %(stderr)r') % {
                        'description': description,
                        'cmd': cmd,
                        'exit_code': exit_code,
                        'stdout': stdout,
                        'stderr': stderr
                    }
        super(ProcessExecutionError, self).__init__(message)
Example #2
0
def validate_integer(value, name, min_value=None, max_value=None):
    """
    Make sure that value is a valid integer, potentially within range.
    """
    try:
        value = int(str(value))
    except (ValueError, UnicodeEncodeError):
        msg = _('%(value_name)s must be an integer')
        raise exception.InvalidInput(reason=(msg % {'value_name': name}))

    if min_value is not None:
        if value < min_value:
            msg = _('%(value_name)s must be >= %(min_value)d')
            raise exception.InvalidInput(reason=(msg % {
                'value_name': name,
                'min_value': min_value
            }))
    if max_value is not None:
        if value > max_value:
            msg = _('%(value_name)s must be <= %(max_value)d')
            raise exception.InvalidInput(reason=(msg % {
                'value_name': name,
                'max_value': max_value
            }))
    return value
Example #3
0
    def _wait_for_exit_or_signal(self, ready_callback=None):
        status = None
        signo = 0

        LOG.debug(_('Full set of CONF:'))
        CONF.log_opt_values(LOG, std_logging.DEBUG)

        try:
            if ready_callback:
                ready_callback()
            super(ServiceLauncher, self).wait()
        except SignalExit as exc:
            signame = _signo_to_signame(exc.signo)
            LOG.info(_('Caught %s, exiting'), signame)
            status = exc.code
            signo = exc.signo
        except SystemExit as exc:
            status = exc.code
        finally:
            self.stop()
            if rpc:
                try:
                    rpc.cleanup()
                except Exception:
                    # We're shutting down, so it doesn't matter at this point.
                    LOG.exception(_('Exception during rpc cleanup.'))

        return status, signo
Example #4
0
    def _wait_child(self):
        try:
            # Don't block if no child processes have exited
            pid, status = os.waitpid(0, os.WNOHANG)
            if not pid:
                return None
        except OSError as exc:
            if exc.errno not in (errno.EINTR, errno.ECHILD):
                raise
            return None

        if os.WIFSIGNALED(status):
            sig = os.WTERMSIG(status)
            LOG.info(_('Child %(pid)d killed by signal %(sig)d'),
                     dict(pid=pid, sig=sig))
        else:
            code = os.WEXITSTATUS(status)
            LOG.info(_('Child %(pid)s exited with status %(code)d'),
                     dict(pid=pid, code=code))

        if pid not in self.children:
            LOG.warning(_('pid %d not in child list'), pid)
            return None

        wrap = self.children.pop(pid)
        wrap.children.remove(pid)
        return wrap
Example #5
0
    def _start_child(self, wrap):
        if len(wrap.forktimes) > wrap.workers:
            # Limit ourselves to one process a second (over the period of
            # number of workers * 1 second). This will allow workers to
            # start up quickly but ensure we don't fork off children that
            # die instantly too quickly.
            if time.time() - wrap.forktimes[0] < wrap.workers:
                LOG.info(_('Forking too fast, sleeping'))
                time.sleep(1)

            wrap.forktimes.pop(0)

        wrap.forktimes.append(time.time())

        pid = os.fork()
        if pid == 0:
            launcher = self._child_process(wrap.service)
            while True:
                self._child_process_handle_signal()
                status, signo = self._child_wait_for_exit_or_signal(launcher)
                if not _is_sighup_and_daemon(signo):
                    break
                launcher.restart()

            os._exit(status)

        LOG.info(_('Started child %d'), pid)

        wrap.children.add(pid)
        self.children[pid] = wrap

        return pid
Example #6
0
    def _wait_child(self):
        try:
            # Don't block if no child processes have exited
            pid, status = os.waitpid(0, os.WNOHANG)
            if not pid:
                return None
        except OSError as exc:
            if exc.errno not in (errno.EINTR, errno.ECHILD):
                raise
            return None

        if os.WIFSIGNALED(status):
            sig = os.WTERMSIG(status)
            LOG.info(_('Child %(pid)d killed by signal %(sig)d'),
                     dict(pid=pid, sig=sig))
        else:
            code = os.WEXITSTATUS(status)
            LOG.info(_('Child %(pid)s exited with status %(code)d'),
                     dict(pid=pid, code=code))

        if pid not in self.children:
            LOG.warning(_('pid %d not in child list'), pid)
            return None

        wrap = self.children.pop(pid)
        wrap.children.remove(pid)
        return wrap
Example #7
0
    def _wait_for_exit_or_signal(self, ready_callback=None):
        status = None
        signo = 0

        LOG.debug(_('Full set of CONF:'))
        CONF.log_opt_values(LOG, std_logging.DEBUG)

        try:
            if ready_callback:
                ready_callback()
            super(ServiceLauncher, self).wait()
        except SignalExit as exc:
            signame = _signo_to_signame(exc.signo)
            LOG.info(_('Caught %s, exiting'), signame)
            status = exc.code
            signo = exc.signo
        except SystemExit as exc:
            status = exc.code
        finally:
            self.stop()
            if rpc:
                try:
                    rpc.cleanup()
                except Exception:
                    # We're shutting down, so it doesn't matter at this point.
                    LOG.exception(_('Exception during rpc cleanup.'))

        return status, signo
Example #8
0
        def _inner():
            if initial_delay:
                greenthread.sleep(initial_delay)

            try:
                while self._running:
                    start = timeutils.utcnow()
                    self.f(*self.args, **self.kw)
                    end = timeutils.utcnow()
                    if not self._running:
                        break
                    delay = interval - timeutils.delta_seconds(start, end)
                    if delay <= 0:
                        LOG.warn(_('task run outlasted interval by %s sec') %
                                 -delay)
                    greenthread.sleep(delay if delay > 0 else 0)
            except LoopingCallDone as e:
                self.stop()
                done.send(e.retvalue)
            except Exception:
                LOG.exception(_('in fixed duration looping call'))
                done.send_exception(*sys.exc_info())
                return
            else:
                done.send(True)
Example #9
0
        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 sleeping for %.02f '
                          'seconds'), idle)
                    greenthread.sleep(idle)
            except LoopingCallDone as e:
                self.stop()
                done.send(e.retvalue)
            except Exception:
                LOG.exception(_('in dynamic looping call'))
                done.send_exception(*sys.exc_info())
                return
            else:
                done.send(True)
Example #10
0
    def _error(self, inner, req):
        LOG.exception(_("Caught error: %s"), unicode(inner))

        safe = getattr(inner, 'safe', False)
        headers = getattr(inner, 'headers', None)
        status = getattr(inner, 'code', 500)
        if status is None:
            status = 500

        msg_dict = dict(url=req.url, status=status)
        LOG.info(_("%(url)s returned with HTTP %(status)d") % msg_dict)
        outer = self.status_to_type(status)
        if headers:
            outer.headers = headers
        # NOTE(johannes): We leave the explanation empty here on
        # purpose. It could possibly have sensitive information
        # that should not be returned back to the user. See
        # bugs 868360 and 874472
        # NOTE(eglynn): However, it would be over-conservative and
        # inconsistent with the EC2 API to hide every exception,
        # including those that are safe to expose, see bug 1021373
        if safe:
            if isinstance(inner.msg_fmt, gettextutils.Message):
                user_locale = req.best_match_language()
                inner_msg = gettextutils.translate(
                        inner.msg_fmt, user_locale)
            else:
                inner_msg = unicode(inner)
            outer.explanation = '%s: %s' % (inner.__class__.__name__,
                                            inner_msg)

        notifications.send_api_fault(req.url, status, inner)
        return wsgi.Fault(outer)
Example #11
0
        def _inner():
            if initial_delay:
                greenthread.sleep(initial_delay)

            try:
                while self._running:
                    start = timeutils.utcnow()
                    self.f(*self.args, **self.kw)
                    end = timeutils.utcnow()
                    if not self._running:
                        break
                    delay = interval - timeutils.delta_seconds(start, end)
                    if delay <= 0:
                        LOG.warn(
                            _('task run outlasted interval by %s sec') %
                            -delay)
                    greenthread.sleep(delay if delay > 0 else 0)
            except LoopingCallDone as e:
                self.stop()
                done.send(e.retvalue)
            except Exception:
                LOG.exception(_('in fixed duration looping call'))
                done.send_exception(*sys.exc_info())
                return
            else:
                done.send(True)
Example #12
0
    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])

            now = timeutils.utcnow()
            spacing = self._periodic_spacing[task_name]
            last_run = self._periodic_last_run[task_name]

            # If a periodic task is _nearly_ due, then we'll run it early
            if spacing is not None and last_run is not None:
                due = last_run + datetime.timedelta(seconds=spacing)
                if not timeutils.is_soon(due, 0.2):
                    idle_for = min(idle_for, timeutils.delta_seconds(now, due))
                    continue

            if spacing is not None:
                idle_for = min(idle_for, spacing)

            LOG.debug(_("Running periodic task %(full_task_name)s"), {"full_task_name": full_task_name})
            self._periodic_last_run[task_name] = timeutils.utcnow()

            try:
                task(self, context)
            except Exception as e:
                if raise_on_error:
                    raise
                LOG.exception(_("Error during %(full_task_name)s: %(e)s"), {"full_task_name": full_task_name, "e": e})
            time.sleep(0)

        return idle_for
Example #13
0
    def _error(self, inner, req):
        LOG.exception(_("Caught error: %s"), unicode(inner))

        safe = getattr(inner, 'safe', False)
        headers = getattr(inner, 'headers', None)
        status = getattr(inner, 'code', 500)
        if status is None:
            status = 500

        msg_dict = dict(url=req.url, status=status)
        LOG.info(_("%(url)s returned with HTTP %(status)d") % msg_dict)
        outer = self.status_to_type(status)
        if headers:
            outer.headers = headers
        # NOTE(johannes): We leave the explanation empty here on
        # purpose. It could possibly have sensitive information
        # that should not be returned back to the user. See
        # bugs 868360 and 874472
        # NOTE(eglynn): However, it would be over-conservative and
        # inconsistent with the EC2 API to hide every exception,
        # including those that are safe to expose, see bug 1021373
        if safe:
            if isinstance(inner.msg_fmt, gettextutils.Message):
                user_locale = req.best_match_language()
                inner_msg = gettextutils.translate(inner.msg_fmt, user_locale)
            else:
                inner_msg = unicode(inner)
            outer.explanation = '%s: %s' % (inner.__class__.__name__,
                                            inner_msg)

        notifications.send_api_fault(req.url, status, inner)
        return wsgi.Fault(outer)
Example #14
0
def limited(items, request, max_limit=CONF.osapi_max_limit):
    """
    Return a slice of items according to requested offset and limit.
    """
    try:
        offset = int(request.GET.get('offset', 0))
    except ValueError:
        msg = _('offset param must be an integer')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    try:
        limit = int(request.GET.get('limit', max_limit))
    except ValueError:
        msg = _('limit param must be an integer')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    if limit < 0:
        msg = _('limit param must be positive')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    if offset < 0:
        msg = _('offset param must be positive')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    limit = min(max_limit, limit or max_limit)
    range_end = offset + limit
    return items[offset:range_end]
Example #15
0
    def _start_child(self, wrap):
        if len(wrap.forktimes) > wrap.workers:
            # Limit ourselves to one process a second (over the period of
            # number of workers * 1 second). This will allow workers to
            # start up quickly but ensure we don't fork off children that
            # die instantly too quickly.
            if time.time() - wrap.forktimes[0] < wrap.workers:
                LOG.info(_('Forking too fast, sleeping'))
                time.sleep(1)

            wrap.forktimes.pop(0)

        wrap.forktimes.append(time.time())

        pid = os.fork()
        if pid == 0:
            launcher = self._child_process(wrap.service)
            while True:
                self._child_process_handle_signal()
                status, signo = self._child_wait_for_exit_or_signal(launcher)
                if not _is_sighup_and_daemon(signo):
                    break
                launcher.restart()

            os._exit(status)

        LOG.info(_('Started child %d'), pid)

        wrap.children.add(pid)
        self.children[pid] = wrap

        return pid
Example #16
0
def limited(items, request, max_limit=CONF.osapi_max_limit):
    """
    Return a slice of items according to requested offset and limit.
    """
    try:
        offset = int(request.GET.get('offset', 0))
    except ValueError:
        msg = _('offset param must be an integer')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    try:
        limit = int(request.GET.get('limit', max_limit))
    except ValueError:
        msg = _('limit param must be an integer')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    if limit < 0:
        msg = _('limit param must be positive')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    if offset < 0:
        msg = _('offset param must be positive')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    limit = min(max_limit, limit or max_limit)
    range_end = offset + limit
    return items[offset:range_end]
Example #17
0
def _get_int_param(request, param):
    """
    Extract integer param from request or fail.
    """
    try:
        int_param = int(request.GET[param])
    except ValueError:
        msg = _('%s param must be an integer') % param
        raise webob.exc.HTTPBadRequest(explanation=msg)
    if int_param < 0:
        msg = _('%s param must be positive') % param
        raise webob.exc.HTTPBadRequest(explanation=msg)
    return int_param
Example #18
0
def _get_int_param(request, param):
    """
    Extract integer param from request or fail.
    """
    try:
        int_param = int(request.GET[param])
    except ValueError:
        msg = _('%s param must be an integer') % param
        raise webob.exc.HTTPBadRequest(explanation=msg)
    if int_param < 0:
        msg = _('%s param must be positive') % param
        raise webob.exc.HTTPBadRequest(explanation=msg)
    return int_param
Example #19
0
def _get_not_supported_column(col_name_col_instance, column_name):
    try:
        column = col_name_col_instance[column_name]
    except KeyError:
        msg = _("Please specify column %s in col_name_col_instance "
                "param. It is required because column has unsupported "
                "type by sqlite).")
        raise ColumnError(msg % column_name)

    if not isinstance(column, Column):
        msg = _("col_name_col_instance param has wrong type of "
                "column instance for column %s It should be instance "
                "of sqlalchemy.Column.")
        raise ColumnError(msg % column_name)
    return column
Example #20
0
def _get_not_supported_column(col_name_col_instance, column_name):
    try:
        column = col_name_col_instance[column_name]
    except KeyError:
        msg = _("Please specify column %s in col_name_col_instance "
                "param. It is required because column has unsupported "
                "type by sqlite).")
        raise ColumnError(msg % column_name)

    if not isinstance(column, Column):
        msg = _("col_name_col_instance param has wrong type of "
                "column instance for column %s It should be instance "
                "of sqlalchemy.Column.")
        raise ColumnError(msg % column_name)
    return column
Example #21
0
    def __init__(self, name, app, host='0.0.0.0', port=0, pool_size=None,
                       protocol=eventlet.wsgi.HttpProtocol, backlog=128,
                       use_ssl=False, max_url_len=None):
        """
        Initialize, but do not start, a WSGI server.
        初始化但并不启动一个WSGI服务;
        """
        # Allow operators to customize http requests max header line size.
        eventlet.wsgi.MAX_HEADER_LINE = CONF.max_header_line
        self.name = name
        self.app = app
        self._server = None
        self._protocol = protocol
        self._pool = eventlet.GreenPool(pool_size or self.default_pool_size)
        
        self._logger = logging.getLogger("xdrs.%s.wsgi.server" % self.name)
        self._wsgi_logger = logging.WritableLogger(self._logger)
        
        self._use_ssl = use_ssl
        self._max_url_len = max_url_len

        if backlog < 1:
            raise exception.InvalidInput(
                    reason='The backlog must be more than 1')

        bind_addr = (host, port)
        # TODO(dims): eventlet's green dns/socket module does not actually
        # support IPv6 in getaddrinfo(). We need to get around this in the
        # future or monitor upstream for a fix
        try:
            info = socket.getaddrinfo(bind_addr[0],
                                      bind_addr[1],
                                      socket.AF_UNSPEC,
                                      socket.SOCK_STREAM)[0]
            family = info[0]
            bind_addr = info[-1]
        except Exception:
            family = socket.AF_INET

        try:
            self._socket = eventlet.listen(bind_addr, family, backlog=backlog)
        except EnvironmentError:
            LOG.error(_("Could not bind to %(host)s:%(port)s"),
                      {'host': host, 'port': port})
            raise

        (self.host, self.port) = self._socket.getsockname()[0:2]
        LOG.info(_("%(name)s listening on %(host)s:%(port)s") % self.__dict__)
Example #22
0
 def coerce(self, obj, attr, value):
     if not isinstance(value, list):
         raise ValueError(_('A list is required here'))
     for index, element in enumerate(list(value)):
         value[index] = self._element_type.coerce(
                 obj, '%s[%i]' % (attr, index), element)
     return value
Example #23
0
    def attach(self, *slaves):
        """
        Attach one or more slave templates.
        Attaches one or more slave templates to the master template.
        Slave templates must have a root element with the same tag as
        the master template.  The slave template's apply() method will
        be called to determine if the slave should be applied to this
        master; if it returns False, that slave will be skipped.
        (This allows filtering of slaves based on the version of the
        master template.)
        """

        slave_list = []
        for slave in slaves:
            slave = slave.wrap()

            # Make sure we have a tree match
            if slave.root.tag != self.root.tag:
                msg = _("Template tree mismatch; adding slave %(slavetag)s to "
                        "master %(mastertag)s") % {
                            'slavetag': slave.root.tag,
                            'mastertag': self.root.tag
                        }
                raise ValueError(msg)

            # Make sure slave applies to this template
            if not slave.apply(self):
                continue

            slave_list.append(slave)

        # Add the slaves
        self.slaves.extend(slave_list)
Example #24
0
    def render(self, parent, obj, patches=[], nsmap=None):
        """
        Render an object.
        Renders an object against this template node.  Returns a list
        of two-item tuples, where the first item is an etree.Element
        instance and the second item is the datum associated with that
        instance.
        """

        # First, get the datum we're rendering
        data = None if obj is None else self.selector(obj)

        # Check if we should render at all
        if not self.will_render(data):
            return []
        elif data is None:
            return [(self._render(parent, None, patches, nsmap), None)]

        # Make the data into a list if it isn't already
        if not isinstance(data, list):
            data = [data]
        elif parent is None:
            raise ValueError(_('root element selecting a list'))

        # Render all the elements
        elems = []
        for datum in data:
            if self.subselector is not None:
                datum = self.subselector(datum)
            elems.append((self._render(parent, datum, patches, nsmap), datum))

        # Return all the elements rendered, as well as the
        # corresponding datum for the next step down the tree
        return elems
Example #25
0
    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 not message:
            try:
                message = self.msg_fmt % kwargs

            except Exception:
                exc_info = sys.exc_info()
                # kwargs doesn't match a variable in the message
                # log the issue and the kwargs
                LOG.exception(_('Exception in string format operation'))
                for name, value in kwargs.iteritems():
                    LOG.error("%s: %s" % (name, value))

                if CONF.fatal_exception_format_errors:
                    raise exc_info[0], exc_info[1], exc_info[2]
                else:
                    # at least get the core message out if something happened
                    message = self.msg_fmt

        super(XdrsException, self).__init__(message)
Example #26
0
def initialize_if_enabled():
    backdoor_locals = {
        'exit': _dont_use_this,  # So we don't exit the entire process
        'quit': _dont_use_this,  # So we don't exit the entire process
        'fo': _find_objects,
        'pgt': _print_greenthreads,
        'pnt': _print_nativethreads,
    }

    if CONF.backdoor_port is None:
        return None

    start_port, end_port = _parse_port_range(str(CONF.backdoor_port))

    def displayhook(val):
        if val is not None:
            pprint.pprint(val)

    sys.displayhook = displayhook

    sock = _listen('localhost', start_port, end_port, eventlet.listen)

    # In the case of backdoor port being zero, a port number is assigned by
    # listen().  In any case, pull the port number out here.
    port = sock.getsockname()[1]
    LOG.info(
        _('Eventlet backdoor listening on %(port)s for process %(pid)d') % {
            'port': port,
            'pid': os.getpid()
        })
    eventlet.spawn_n(eventlet.backdoor.backdoor_server,
                     sock,
                     locals=backdoor_locals)
    return port
Example #27
0
 def read(self, i=None):
     result = self.data.read(i)
     self.bytes_read += len(result)
     if self.bytes_read > self.limit:
         msg = _("Request is too large.")
         raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
     return result
Example #28
0
    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(_('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 compatible_match:
            return compatible_match

        latest_ver = '%i.%i' % latest
        raise exception.IncompatibleObjectVersion(objname=objname,
                                                  objver=objver,
                                                  supported=latest_ver)
Example #29
0
        def wrapped(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except Exception as exc:
                if isinstance(exc, webob.exc.WSGIHTTPException):
                    if isinstance(errors, int):
                        t_errors = (errors, )
                    else:
                        t_errors = errors
                    if exc.code in t_errors:
                        raise
                elif isinstance(exc, exception.PolicyNotAuthorized):
                    # Note(cyeoh): Special case to handle
                    # PolicyNotAuthorized exceptions so every
                    # extension method does not need to wrap authorize
                    # calls. ResourceExceptionHandler silently
                    # converts NotAuthorized to HTTPForbidden
                    raise
                elif isinstance(exc, exception.ValidationError):
                    # Note(oomichi): Handle a validation error, which
                    # happens due to invalid API parameters, as an
                    # expected error.
                    raise

                LOG.exception(_("Unexpected exception in API method"))
                raise webob.exc.HTTPInternalServerError()
Example #30
0
    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 not message:
            try:
                message = self.msg_fmt % kwargs

            except Exception:
                exc_info = sys.exc_info()
                # kwargs doesn't match a variable in the message
                # log the issue and the kwargs
                LOG.exception(_('Exception in string format operation'))
                for name, value in kwargs.iteritems():
                    LOG.error("%s: %s" % (name, value))

                if CONF.fatal_exception_format_errors:
                    raise exc_info[0], exc_info[1], exc_info[2]
                else:
                    # at least get the core message out if something happened
                    message = self.msg_fmt

        super(XdrsException, self).__init__(message)
Example #31
0
def initialize_if_enabled():
    backdoor_locals = {
        'exit': _dont_use_this,      # So we don't exit the entire process
        'quit': _dont_use_this,      # So we don't exit the entire process
        'fo': _find_objects,
        'pgt': _print_greenthreads,
        'pnt': _print_nativethreads,
    }

    if CONF.backdoor_port is None:
        return None

    start_port, end_port = _parse_port_range(str(CONF.backdoor_port))

    def displayhook(val):
        if val is not None:
            pprint.pprint(val)
    sys.displayhook = displayhook

    sock = _listen('localhost', start_port, end_port, eventlet.listen)

    # In the case of backdoor port being zero, a port number is assigned by
    # listen().  In any case, pull the port number out here.
    port = sock.getsockname()[1]
    LOG.info(_('Eventlet backdoor listening on %(port)s for process %(pid)d') %
             {'port': port, 'pid': os.getpid()})
    eventlet.spawn_n(eventlet.backdoor.backdoor_server, sock,
                     locals=backdoor_locals)
    return port
Example #32
0
def model_query(context,
                model,
                session,
                args=None,
                project_only=False,
                read_deleted=None):
    """
    Query helper that accounts for context's `read_deleted` field.
    """

    if not read_deleted:
        if hasattr(context, 'read_deleted'):
            # NOTE(viktors): some projects use `read_deleted` attribute in
            # their contexts instead of `show_deleted`.
            read_deleted = context.read_deleted
        else:
            read_deleted = context.show_deleted

    if not issubclass(model, models.ModelBase):
        raise TypeError(_("model should be a subclass of ModelBase"))

    query = session.query(model) if not args else session.query(*args)
    query = _read_deleted_filter(query, model, read_deleted)
    query = _project_filter(query, model, context, project_only)

    return query
Example #33
0
 def deprecated(self, msg, *args, **kwargs):
     stdmsg = _("Deprecated: %s") % msg
     if CONF.fatal_deprecations:
         self.critical(stdmsg, *args, **kwargs)
         raise DeprecatedConfig(msg=stdmsg)
     else:
         self.warn(stdmsg, *args, **kwargs)
Example #34
0
 def deprecated(self, msg, *args, **kwargs):
     stdmsg = _("Deprecated: %s") % msg
     if CONF.fatal_deprecations:
         self.critical(stdmsg, *args, **kwargs)
         raise DeprecatedConfig(msg=stdmsg)
     else:
         self.warn(stdmsg, *args, **kwargs)
Example #35
0
    def wait_until_ready(self, context, early_timeout=10, early_attempts=10):
        '''
        Wait until a conductor service is up and running.

        This method calls the remote ping() method on the conductor topic until
        it gets a response.  It starts with a shorter timeout in the loop
        (early_timeout) up to early_attempts number of tries.  It then drops
        back to the globally configured timeout for rpc calls for each retry.
        '''
        attempt = 0
        timeout = early_timeout
        while True:
            if attempt == early_attempts:
                timeout = None
            attempt += 1

            try:
                self.base_rpcapi.ping(context,
                                      '1.21 GigaWatts',
                                      timeout=timeout)
                break
            except messaging.MessagingTimeout:
                LOG.warning(
                    _('Timed out waiting for xdrs-conductor. '
                      'Is it running? Or did this service start '
                      'before xdrs-conductor?'))
Example #36
0
        def wrapped(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except Exception as exc:
                if isinstance(exc, webob.exc.WSGIHTTPException):
                    if isinstance(errors, int):
                        t_errors = (errors,)
                    else:
                        t_errors = errors
                    if exc.code in t_errors:
                        raise
                elif isinstance(exc, exception.PolicyNotAuthorized):
                    # Note(cyeoh): Special case to handle
                    # PolicyNotAuthorized exceptions so every
                    # extension method does not need to wrap authorize
                    # calls. ResourceExceptionHandler silently
                    # converts NotAuthorized to HTTPForbidden
                    raise
                elif isinstance(exc, exception.ValidationError):
                    # Note(oomichi): Handle a validation error, which
                    # happens due to invalid API parameters, as an
                    # expected error.
                    raise

                LOG.exception(_("Unexpected exception in API method"))
                raise webob.exc.HTTPInternalServerError()
Example #37
0
 def read(self, i=None):
     result = self.data.read(i)
     self.bytes_read += len(result)
     if self.bytes_read > self.limit:
         msg = _("Request is too large.")
         raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
     return result
Example #38
0
    def __init__(cls, names, bases, dict_):
        """Metaclass that allows us to collect decorated periodic tasks."""
        super(_PeriodicTasksMeta, cls).__init__(names, bases, dict_)

        # NOTE(sirp): if the attribute is not present then we must be the base
        # class, so, go ahead an initialize it. If the attribute is present,
        # then we're a subclass so make a copy of it so we don't step on our
        # parent's toes.
        try:
            cls._periodic_tasks = cls._periodic_tasks[:]
        except AttributeError:
            cls._periodic_tasks = []

        try:
            cls._periodic_last_run = cls._periodic_last_run.copy()
        except AttributeError:
            cls._periodic_last_run = {}

        try:
            cls._periodic_spacing = cls._periodic_spacing.copy()
        except AttributeError:
            cls._periodic_spacing = {}

        for value in cls.__dict__.values():
            if getattr(value, '_periodic_task', False):
                task = value
                name = task.__name__

                if task._periodic_spacing < 0:
                    LOG.info(
                        _('Skipping periodic task %(task)s because '
                          'its interval is negative'), {'task': name})
                    continue
                if not task._periodic_enabled:
                    LOG.info(
                        _('Skipping periodic task %(task)s because '
                          'it is disabled'), {'task': name})
                    continue

                # A periodic spacing of zero indicates that this task should
                # be run every pass
                if task._periodic_spacing == 0:
                    task._periodic_spacing = None

                cls._periodic_tasks.append((name, task))
                cls._periodic_spacing[name] = task._periodic_spacing
                cls._periodic_last_run[name] = task._periodic_last_run
Example #39
0
    def _setup_extensions(self, ext_mgr):
        """
        get_controller_extensions:
        获取所有扩展文件中具体实现了get_controller_extensions方法的集合;
        1 获取controller指定的wsgi_action装饰器装饰的扩展方法;
          存储在self.wsgi_actions中;
        2 获取所有wsgi.extends装饰的扩展方法,有action参数的;
          存储在self.wsgi_action_extensions中;
          @wsgi.extends(action='create')
        3 获取所有wsgi.extends装饰的扩展方法,没有action参数的;
          存储在self.wsgi_action_extensions中;
          @wsgi.extends
        """
        for extension in ext_mgr.get_controller_extensions():
            collection = extension.collection
            controller = extension.controller

            msg_format_dict = {
                'collection': collection,
                'ext_name': extension.extension.name
            }
            if collection not in self.resources:
                LOG.warning(
                    _('Extension %(ext_name)s: Cannot extend '
                      'resource %(collection)s: No such resource'),
                    msg_format_dict)
                continue

            LOG.debug(
                _('Extension %(ext_name)s extended resource: '
                  '%(collection)s'), msg_format_dict)

            resource = self.resources[collection]
            """
            获取controller指定的wsgi_action装饰器装饰的扩展方法;
            存储在self.wsgi_actions中;
            """
            resource.register_actions(controller)
            """
            获取所有wsgi.extends装饰的扩展方法,有action参数的;
            存储在self.wsgi_action_extensions中;
            @wsgi.extends(action='create')
            获取所有wsgi.extends装饰的扩展方法,没有action参数的;
            存储在self.wsgi_action_extensions中;
            @wsgi.extends
            """
            resource.register_extensions(controller)
Example #40
0
    def _pipe_watcher(self):
        # This will block until the write end is closed when the parent
        # dies unexpectedly
        self.readpipe.read()

        LOG.info(_('Parent process has died unexpectedly, exiting'))

        sys.exit(1)
Example #41
0
def _read_deleted_filter(query, db_model, read_deleted):
    if 'deleted' not in db_model.__table__.columns:
        raise ValueError(
            _("There is no `deleted` column in `%s` table. "
              "Project doesn't use soft-deleted feature.") % db_model.__name__)

    default_deleted_value = db_model.__table__.c.deleted.default.arg
    if read_deleted == 'no':
        query = query.filter(db_model.deleted == default_deleted_value)
    elif read_deleted == 'yes':
        pass  # omit the filter to include deleted and active
    elif read_deleted == 'only':
        query = query.filter(db_model.deleted != default_deleted_value)
    else:
        raise ValueError(
            _("Unrecognized read_deleted value '%s'") % read_deleted)
    return query
Example #42
0
 def coerce(self, obj, attr, value):
     if not isinstance(value, list):
         raise ValueError(_('A list is required here'))
     for index, element in enumerate(list(value)):
         value[index] = self._element_type.coerce(obj,
                                                  '%s[%i]' % (attr, index),
                                                  element)
     return value
Example #43
0
 def basic_config_check(self):
     """Perform basic config checks before starting processing."""
     try:
         with utils.tempdir():
             pass
     except Exception as e:
         LOG.error(_('Temporary directory is invalid: %s'), e)
         sys.exit(1)
Example #44
0
 def __iter__(self):
     for chunk in self.data:
         self.bytes_read += len(chunk)
         if self.bytes_read > self.limit:
             msg = _("Request is too large.")
             raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
         else:
             yield chunk
Example #45
0
 def basic_config_check(self):
     """Perform basic config checks before starting processing."""
     try:
         with utils.tempdir():
             pass
     except Exception as e:
         LOG.error(_('Temporary directory is invalid: %s'), e)
         sys.exit(1)
Example #46
0
    def construct(self):
        """
        Construct a template.
        Called to construct a template instance, which it must return.
        Only called once.
        """

        raise NotImplementedError(_("subclasses must implement construct()!"))
Example #47
0
    def _pipe_watcher(self):
        # This will block until the write end is closed when the parent
        # dies unexpectedly
        self.readpipe.read()

        LOG.info(_('Parent process has died unexpectedly, exiting'))

        sys.exit(1)
Example #48
0
def _read_deleted_filter(query, db_model, read_deleted):
    if 'deleted' not in db_model.__table__.columns:
        raise ValueError(_("There is no `deleted` column in `%s` table. "
                           "Project doesn't use soft-deleted feature.")
                         % db_model.__name__)

    default_deleted_value = db_model.__table__.c.deleted.default.arg
    if read_deleted == 'no':
        query = query.filter(db_model.deleted == default_deleted_value)
    elif read_deleted == 'yes':
        pass  # omit the filter to include deleted and active
    elif read_deleted == 'only':
        query = query.filter(db_model.deleted != default_deleted_value)
    else:
        raise ValueError(_("Unrecognized read_deleted value '%s'")
                         % read_deleted)
    return query
Example #49
0
 def __iter__(self):
     for chunk in self.data:
         self.bytes_read += len(chunk)
         if self.bytes_read > self.limit:
             msg = _("Request is too large.")
             raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
         else:
             yield chunk
Example #50
0
    def _setup_extensions(self, ext_mgr):
        """
        get_controller_extensions:
        获取所有扩展文件中具体实现了get_controller_extensions方法的集合;
        1 获取controller指定的wsgi_action装饰器装饰的扩展方法;
          存储在self.wsgi_actions中;
        2 获取所有wsgi.extends装饰的扩展方法,有action参数的;
          存储在self.wsgi_action_extensions中;
          @wsgi.extends(action='create')
        3 获取所有wsgi.extends装饰的扩展方法,没有action参数的;
          存储在self.wsgi_action_extensions中;
          @wsgi.extends
        """
        for extension in ext_mgr.get_controller_extensions():
            collection = extension.collection
            controller = extension.controller

            msg_format_dict = {'collection': collection,
                               'ext_name': extension.extension.name}
            if collection not in self.resources:
                LOG.warning(_('Extension %(ext_name)s: Cannot extend '
                              'resource %(collection)s: No such resource'),
                            msg_format_dict)
                continue

            LOG.debug(_('Extension %(ext_name)s extended resource: '
                        '%(collection)s'),
                      msg_format_dict)

            resource = self.resources[collection]
            
            """
            获取controller指定的wsgi_action装饰器装饰的扩展方法;
            存储在self.wsgi_actions中;
            """
            resource.register_actions(controller)
            """
            获取所有wsgi.extends装饰的扩展方法,有action参数的;
            存储在self.wsgi_action_extensions中;
            @wsgi.extends(action='create')
            获取所有wsgi.extends装饰的扩展方法,没有action参数的;
            存储在self.wsgi_action_extensions中;
            @wsgi.extends
            """
            resource.register_extensions(controller)
Example #51
0
 def obj_attr_is_set(self, attrname):
     """
     Test object to see if attrname is present.
     """
     if attrname not in self.obj_fields:
         raise AttributeError(
             _("%(objname)s object has no attribute '%(attrname)s'") %
             {'objname': self.obj_name(), 'attrname': attrname})
     return hasattr(self, get_attrname(attrname))
Example #52
0
 def __call__(self, req):
     if req.content_length > CONF.osapi_max_request_body_size:
         msg = _("Request is too large.")
         raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
     if req.content_length is None and req.is_body_readable:
         limiter = LimitingReader(req.body_file,
                                  CONF.osapi_max_request_body_size)
         req.body_file = limiter
     return self.application
Example #53
0
 def delete(self, req, id):
     context = req.environ['xdrs.context']
     authorize(context, 'delete_vm_migration_record')
     
     try:
         vm_migration_record = self.vms_api.delete_vm_migration_record_by_id(context, id)
     except exception.VmMigrationRecordNotFound:
         msg = _('vm migration record not found')
         raise webob.exc.HTTPBadRequest(explanation=msg)
Example #54
0
 def wait(self):
     """
     Block, until the server has stopped.
     """
     try:
         if self._server is not None:
             self._server.wait()
     except greenlet.GreenletExit:
         LOG.info(_("WSGI server has stopped."))
Example #55
0
 def __call__(self, req):
     if req.content_length > CONF.osapi_max_request_body_size:
         msg = _("Request is too large.")
         raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
     if req.content_length is None and req.is_body_readable:
         limiter = LimitingReader(req.body_file,
                                  CONF.osapi_max_request_body_size)
         req.body_file = limiter
     return self.application
Example #56
0
 def kill(self):
     """
     Destroy the service object in the datastore.
     """
     self.stop()
     try:
         self.conductor_api.service_destroy(context.get_admin_context(),
                                            self.service_id)
     except exception.NotFound:
         LOG.warn(_('Service killed that has no database entry'))
Example #57
0
    def _get_vms_migration_records(self, req):
        context = req.environ['xdrs.context']
        
        try:
            vms_migration_records = self.vms_api.get_all_vms_migration_records(context)
        except exception.VmMigrationRecordNotFound:
            msg = _('vm migration record not found')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return vms_migration_records
Example #58
0
    def _get_vm_cpu_data(self, req):
        context = req.environ['xdrs.context']
        
        try:
            vms_cpu_data = self.hosts_api.get_all_vms_cpu_data(context)
        except exception.HostCpuDataNotFound:
            msg = _('host cpu data not found')
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return vms_cpu_data
Example #59
0
 def setter(self, value, name=name, field=field):
     self._changed_fields.add(name)
     try:
         return setattr(self, get_attrname(name),
                        field.coerce(self, name, value))
     except Exception:
         attr = "%s.%s" % (self.obj_name(), name)
         LOG.exception(_('Error setting %(attr)s') %
                       {'attr': attr})
         raise