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})
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()
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)
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})
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 })
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})
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 })
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 })
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
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
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()
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)
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()
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)
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()
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)
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()