Example #1
0
def rmtree_without_raise(path):
    try:
        if os.path.isdir(path):
            shutil.rmtree(path)
    except OSError as e:
        LOG.warn(_LW("Failed to remove dir %(path)s, error: %(e)s"),
                 {'path': path, 'e': e})
Example #2
0
    def init_host(self):
        self.dbapi = dbapi.get_instance()

        self._keepalive_evt = threading.Event()
        """Event for the keepalive thread."""

        self._worker_pool = greenpool.GreenPool(
            size=CONF.conductor.workers_pool_size)
        """GreenPool of background workers for performing tasks async."""

        try:
            # Register this conductor with the cluster
            cdr = self.dbapi.register_conductor({'hostname': self.host})
        except exception.ConductorAlreadyRegistered:
            LOG.warn(
                _LW("A conductor with hostname %(hostname)s "
                    "was previously registered. Updating registration"),
                {'hostname': self.host})

            cdr = self.dbapi.register_conductor({'hostname': self.host},
                                                update_existing=True)
        self.conductor = cdr

        # Spawn a dedicated greenthread for the keepalive
        try:
            self._spawn_worker(self._conductor_service_record_keepalive)
            LOG.info(
                _LI('Successfully started conductor with hostname '
                    '%(hostname)s.'), {'hostname': self.host})
        except exception.NoFreeConductorWorker:
            with excutils.save_and_reraise_exception():
                LOG.critical(_LC('Failed to start keepalive'))
                self.del_host()
Example #3
0
 def _conductor_service_record_keepalive(self):
     while not self._keepalive_evt.is_set():
         try:
             self.dbapi.touch_conductor(self.host)
         except db_exception.DBConnectionError:
             LOG.warning(
                 _LW('Conductor could not connect to database '
                     'while heartbeating.'))
         self._keepalive_evt.wait(CONF.conductor.heartbeat_interval)
Example #4
0
def unlink_without_raise(path):
    try:
        os.unlink(path)
    except OSError as e:
        if e.errno == errno.ENOENT:
            return
        else:
            LOG.warn(_LW("Failed to unlink %(path)s, error: %(e)s"),
                     {'path': path, 'e': e})
Example #5
0
def rmtree_without_raise(path):
    try:
        if os.path.isdir(path):
            shutil.rmtree(path)
    except OSError as e:
        LOG.warn(_LW("Failed to remove dir %(path)s, error: %(e)s"), {
            'path': path,
            'e': e
        })
Example #6
0
def create_link_without_raise(source, link):
    try:
        os.symlink(source, link)
    except OSError as e:
        if e.errno == errno.EEXIST:
            return
        else:
            LOG.warn(_LW("Failed to create symlink from %(source)s to %(link)s"
                         ", error: %(e)s"),
                     {'source': source, 'link': link, 'e': e})
Example #7
0
def unlink_without_raise(path):
    try:
        os.unlink(path)
    except OSError as e:
        if e.errno == errno.ENOENT:
            return
        else:
            LOG.warn(_LW("Failed to unlink %(path)s, error: %(e)s"), {
                'path': path,
                'e': e
            })
Example #8
0
def create_link_without_raise(source, link):
    try:
        os.symlink(source, link)
    except OSError as e:
        if e.errno == errno.EEXIST:
            return
        else:
            LOG.warn(
                _LW("Failed to create symlink from %(source)s to %(link)s"
                    ", error: %(e)s"), {
                        'source': source,
                        'link': link,
                        'e': e
                    })
Example #9
0
def safe_rstrip(value, chars=None):
    """Removes trailing characters from a string if that does not make it empty

    :param value: A string value that will be stripped.
    :param chars: Characters to remove.
    :return: Stripped value.

    """
    if not isinstance(value, six.string_types):
        LOG.warn(_LW("Failed to remove trailing character. Returning original "
                     "object. Supplied object is not a string: %s,"), value)
        return value

    return value.rstrip(chars) or value
Example #10
0
def safe_rstrip(value, chars=None):
    """Removes trailing characters from a string if that does not make it empty

    :param value: A string value that will be stripped.
    :param chars: Characters to remove.
    :return: Stripped value.

    """
    if not isinstance(value, six.string_types):
        LOG.warn(
            _LW("Failed to remove trailing character. Returning original "
                "object. Supplied object is not a string: %s,"), value)
        return value

    return value.rstrip(chars) or value
Example #11
0
    def __init__(self, host):

        signal.signal(signal.SIGINT, self.stop_handler)

        logging.register_options(CONF)

        CONF(project='iotronic')
        logging.setup(CONF, "iotronic-wamp-agent")

        if CONF.debug:
            txaio.start_logging(level="debug")

        # to be removed asap
        self.host = host
        self.dbapi = dbapi.get_instance()

        try:
            wpa = self.dbapi.register_wampagent({
                'hostname':
                self.host,
                'wsurl':
                CONF.wamp.wamp_transport_url
            })

        except exception.WampAgentAlreadyRegistered:
            LOG.warn(
                _LW("A wampagent with hostname %(hostname)s "
                    "was previously registered. Updating registration"),
                {'hostname': self.host})

        wpa = self.dbapi.register_wampagent(
            {
                'hostname': self.host,
                'wsurl': CONF.wamp.wamp_transport_url
            },
            update_existing=True)
        self.wampagent = wpa
        self.wampagent.ragent = CONF.wamp.register_agent
        self.wampagent.save()

        global AGENT_HOST
        AGENT_HOST = self.host

        self.r = RPCServer()
        self.w = WampManager()

        self.r.start()
        self.w.start()
Example #12
0
    def __init__(self, host):
        logging.register_options(CONF)
        CONF(project='iotronic')
        logging.setup(CONF, "iotronic-conductor")

        signal.signal(signal.SIGINT, self.stop_handler)

        if not host:
            host = CONF.host
        self.host = host
        self.topic = MANAGER_TOPIC
        self.dbapi = dbapi.get_instance()

        try:
            cdr = self.dbapi.register_conductor(
                {'hostname': self.host})
        except exception.ConductorAlreadyRegistered:
            LOG.warn(_LW("A conductor with hostname %(hostname)s "
                         "was previously registered. Updating registration"),
                     {'hostname': self.host})

            cdr = self.dbapi.register_conductor({'hostname': self.host},
                                                update_existing=True)
        self.conductor = cdr

        transport = oslo_messaging.get_transport(cfg.CONF)
        target = oslo_messaging.Target(topic=self.topic, server=self.host,
                                       version=self.RPC_API_VERSION)

        ragent = self.dbapi.get_registration_wampagent()

        LOG.info("Found registration agent: %s on %s",
                 ragent.hostname, ragent.wsurl)

        endpoints = [
            endp.ConductorEndpoint(ragent),
        ]
        access_policy = dispatcher.DefaultRPCAccessPolicy
        self.server = oslo_messaging.get_rpc_server(
            transport, target,
            endpoints, executor='threading',
            access_policy=access_policy)

        self.server.start()

        while True:
            time.sleep(1)
Example #13
0
    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is None and self._spawn_method is not None:
            # Spawn a worker to complete the task
            # The linked callback below will be called whenever:
            #   - background task finished with no errors.
            #   - background task has crashed with exception.
            #   - callback was added after the background task has
            #     finished or crashed. While eventlet currently doesn't
            #     schedule the new thread until the current thread blocks
            #     for some reason, this is true.
            # All of the above are asserted in tests such that we'll
            # catch if eventlet ever changes this behavior.
            thread = None
            try:
                thread = self._spawn_method(*self._spawn_args,
                                            **self._spawn_kwargs)

                # NOTE(comstud): Trying to use a lambda here causes
                # the callback to not occur for some reason. This
                # also makes it easier to test.
                thread.link(self._thread_release_resources)
                # Don't unlock! The unlock will occur when the
                # thread finshes.
                return
            except Exception as e:
                with excutils.save_and_reraise_exception():
                    try:
                        # Execute the on_error hook if set
                        if self._on_error_method:
                            self._on_error_method(e, *self._on_error_args,
                                                  **self._on_error_kwargs)
                    except Exception:
                        LOG.warning(
                            _LW("Task's on_error hook failed to "
                                "call %(method)s on node %(node)s"), {
                                    'method': self._on_error_method.__name__,
                                    'node': self.node.uuid
                                })

                    if thread is not None:
                        # This means the link() failed for some
                        # reason. Nuke the thread.
                        thread.cancel()
                    self.release_resources()
        self.release_resources()
Example #14
0
def enforce(rule, target, creds, do_raise=False, exc=None, *args, **kwargs):
    """A shortcut for policy.Enforcer.enforce()

    Checks authorization of a rule against the target and credentials.
    Always returns true if CONF.auth_strategy == noauth.

    """
    # NOTE(deva): this method is obsoleted by authorize(), but retained for
    # backwards compatibility in case it has been used downstream.
    # It may be removed in the Pike cycle.
    LOG.warning(_LW(
        "Deprecation warning: calls to ironic.common.policy.enforce() "
        "should be replaced with authorize(). This method may be removed "
        "in a future release."))
    if CONF.auth_strategy == 'noauth':
        return True
    enforcer = get_enforcer()
    return enforcer.enforce(rule, target, creds, do_raise=do_raise,
                            exc=exc, *args, **kwargs)
Example #15
0
    def __init__(self, host):

        signal.signal(signal.SIGINT, self.stop_handler)

        logging.register_options(CONF)

        CONF(project='iotronic')
        logging.setup(CONF, "iotronic-wamp-agent")

        if CONF.debug:
            txaio.start_logging(level="debug")

        # to be removed asap
        self.host = host
        self.dbapi = dbapi.get_instance()

        try:
            wpa = self.dbapi.register_wampagent(
                {'hostname': self.host, 'wsurl': CONF.wamp.wamp_transport_url})

        except exception.WampAgentAlreadyRegistered:
            LOG.warn(_LW("A wampagent with hostname %(hostname)s "
                         "was previously registered. Updating registration"),
                     {'hostname': self.host})

        wpa = self.dbapi.register_wampagent(
            {'hostname': self.host, 'wsurl': CONF.wamp.wamp_transport_url},
            update_existing=True)
        self.wampagent = wpa
        self.wampagent.ragent = CONF.wamp.register_agent
        self.wampagent.save()

        global AGENT_HOST
        AGENT_HOST = self.host

        self.r = RPCServer()
        self.w = WampManager()

        self.r.start()
        self.w.start()
Example #16
0
def enforce(rule, target, creds, do_raise=False, exc=None, *args, **kwargs):
    """A shortcut for policy.Enforcer.enforce()

    Checks authorization of a rule against the target and credentials.
    Always returns true if CONF.auth_strategy == noauth.

    """
    # NOTE(deva): this method is obsoleted by authorize(), but retained for
    # backwards compatibility in case it has been used downstream.
    # It may be removed in the Pike cycle.
    LOG.warning(
        _LW("Deprecation warning: calls to ironic.common.policy.enforce() "
            "should be replaced with authorize(). This method may be removed "
            "in a future release."))
    if CONF.auth_strategy == 'noauth':
        return True
    enforcer = get_enforcer()
    return enforcer.enforce(rule,
                            target,
                            creds,
                            do_raise=do_raise,
                            exc=exc,
                            *args,
                            **kwargs)
Example #17
0
def node_power_action(task, new_state):
    """Change power state or reset for a node.

    Perform the requested power action if the transition is required.

    :param task: a TaskManager instance containing the node to act on.
    :param new_state: Any power state from iotronic.common.states. If the
        state is 'REBOOT' then a reboot will be attempted, otherwise
        the node power state is directly set to 'state'.
    :raises: InvalidParameterValue when the wrong state is specified
             or the wrong driver info is specified.
    :raises: other exceptions by the node's power driver if something
             wrong occurred during the power action.

    """
    node = task.node
    target_state = states.POWER_ON if new_state == states.REBOOT else new_state

    if new_state != states.REBOOT:
        try:
            curr_state = task.driver.power.get_power_state(task)
        except Exception as e:
            with excutils.save_and_reraise_exception():
                node['last_error'] = _(
                    "Failed to change power state to '%(target)s'. "
                    "Error: %(error)s") % {
                        'target': new_state,
                        'error': e
                    }
                node['target_power_state'] = states.NOSTATE
                node.save()

        if curr_state == new_state:
            # Neither the iotronic service nor the hardware has erred. The
            # node is, for some reason, already in the requested state,
            # though we don't know why. eg, perhaps the user previously
            # requested the node POWER_ON, the network delayed those IPMI
            # packets, and they are trying again -- but the node finally
            # responds to the first request, and so the second request
            # gets to this check and stops.
            # This isn't an error, so we'll clear last_error field
            # (from previous operation), log a warning, and return.
            node['last_error'] = None
            # NOTE(dtantsur): under rare conditions we can get out of sync here
            node['power_state'] = new_state
            node['target_power_state'] = states.NOSTATE
            node.save()
            LOG.warn(
                _LW("Not going to change_node_power_state because "
                    "current state = requested state = '%(state)s'."),
                {'state': curr_state})
            return

        if curr_state == states.ERROR:
            # be optimistic and continue action
            LOG.warn(_LW("Driver returns ERROR power state for node %s."),
                     node.uuid)

    # Set the target_power_state and clear any last_error, if we're
    # starting a new operation. This will expose to other processes
    # and clients that work is in progress.
    if node['target_power_state'] != target_state:
        node['target_power_state'] = target_state
        node['last_error'] = None
        node.save()

    # take power action
    try:
        if new_state != states.REBOOT:
            task.driver.power.set_power_state(task, new_state)
        else:
            task.driver.power.reboot(task)
    except Exception as e:
        with excutils.save_and_reraise_exception():
            node['last_error'] = _(
                "Failed to change power state to '%(target)s'. "
                "Error: %(error)s") % {
                    'target': target_state,
                    'error': e
                }
    else:
        # success!
        node['power_state'] = target_state
        LOG.info(
            _LI('Successfully set node %(node)s power state to '
                '%(state)s.'), {
                    'node': node.uuid,
                    'state': target_state
                })
    finally:
        node['target_power_state'] = states.NOSTATE
        node.save()