def inspect(): """Optionally run inspection on the current node. If ``inspection_callback_url`` is set in the configuration, get the hardware inventory from the node and post it back to the inspector. :return: node UUID if inspection was successful, None if associated node was not found in inspector cache. None is also returned if inspector support is not enabled. """ if not CONF.inspection_callback_url: LOG.info('Inspection is disabled, skipping') return if CONF.inspection_callback_url == 'mdns': LOG.debug('Fetching the inspection URL from mDNS') url, params = mdns.get_endpoint('baremetal-introspection') # We expect a proper catalog URL, which doesn't include any path. CONF.set_override('inspection_callback_url', url.rstrip('/') + '/v1/continue') config.override(params) collector_names = [ x.strip() for x in CONF.inspection_collectors.split(',') if x.strip() ] LOG.info('inspection is enabled with collectors %s', collector_names) # NOTE(dtantsur): inspection process tries to delay raising any exceptions # until after we posted some data back to inspector. This is because # inspection is run automatically on (mostly) unknown nodes, so if it # fails, we don't have much information for debugging. failures = utils.AccumulatedFailures(exc_class=errors.InspectionError) data = {} try: ext_mgr = extension_manager(collector_names) collectors = [(ext.name, ext.plugin) for ext in ext_mgr] except Exception as exc: with excutils.save_and_reraise_exception(): failures.add(exc) call_inspector(data, failures) for name, collector in collectors: try: collector(data, failures) except Exception as exc: # No reraise here, try to keep going failures.add('collector %s failed: %s', name, exc) resp = call_inspector(data, failures) # Now raise everything we were delaying failures.raise_if_needed() if resp is None: raise errors.InspectionError('stopping inspection, as inspector ' 'returned an error') LOG.info('inspection finished successfully') return resp.get('uuid')
def __init__(self, api_url, advertise_address, listen_address, ip_lookup_attempts, ip_lookup_sleep, network_interface, lookup_timeout, lookup_interval, standalone, hardware_initialization_delay=0): super(IronicPythonAgent, self).__init__() if bool(cfg.CONF.keyfile) != bool(cfg.CONF.certfile): LOG.warning("Only one of 'keyfile' and 'certfile' options is " "defined in config file. Its value will be ignored.") self.ext_mgr = extension.ExtensionManager( namespace='ironic_python_agent.extensions', invoke_on_load=True, propagate_map_exceptions=True, invoke_kwds={'agent': self}, ) self.api_url = api_url if not self.api_url or self.api_url == 'mdns': try: self.api_url, params = mdns.get_endpoint('baremetal') except lib_exc.ServiceLookupFailure: if self.api_url: # mDNS explicitly requested, report failure. raise else: # implicit fallback to mDNS, do not fail (maybe we're only # running inspection). LOG.warning('Could not get baremetal endpoint from mDNS, ' 'will not heartbeat') else: config.override(params) if self.api_url: self.api_client = ironic_api_client.APIClient(self.api_url) self.heartbeater = IronicPythonAgentHeartbeater(self) self.listen_address = listen_address self.advertise_address = advertise_address self.version = pkg_resources.get_distribution('ironic-python-agent')\ .version self.api = app.VersionSelectorApplication(self) self.heartbeat_timeout = None self.started_at = None self.node = None # lookup timeout in seconds self.lookup_timeout = lookup_timeout self.lookup_interval = lookup_interval self.ip_lookup_attempts = ip_lookup_attempts self.ip_lookup_sleep = ip_lookup_sleep self.network_interface = network_interface self.standalone = standalone self.hardware_initialization_delay = hardware_initialization_delay # IPA will stop serving requests and exit after this is set to False self.serve_api = True self.iscsi_started = False
def inspect(): """Optionally run inspection on the current node. If ``inspection_callback_url`` is set in the configuration, get the hardware inventory from the node and post it back to the inspector. :return: node UUID if inspection was successful, None if associated node was not found in inspector cache. None is also returned if inspector support is not enabled. """ if not CONF.inspection_callback_url: LOG.info('Inspection is disabled, skipping') return if CONF.inspection_callback_url == 'mdns': LOG.debug('Fetching the inspection URL from mDNS') url, params = mdns.get_endpoint('baremetal-introspection') # We expect a proper catalog URL, which doesn't include any path. CONF.set_override('inspection_callback_url', url.rstrip('/') + '/v1/continue') config.override(params) collector_names = [x.strip() for x in CONF.inspection_collectors.split(',') if x.strip()] LOG.info('inspection is enabled with collectors %s', collector_names) # NOTE(dtantsur): inspection process tries to delay raising any exceptions # until after we posted some data back to inspector. This is because # inspection is run automatically on (mostly) unknown nodes, so if it # fails, we don't have much information for debugging. failures = utils.AccumulatedFailures(exc_class=errors.InspectionError) data = {} try: ext_mgr = extension_manager(collector_names) collectors = [(ext.name, ext.plugin) for ext in ext_mgr] except Exception as exc: with excutils.save_and_reraise_exception(): failures.add(exc) call_inspector(data, failures) for name, collector in collectors: try: collector(data, failures) except Exception as exc: # No reraise here, try to keep going failures.add('collector %s failed: %s', name, exc) resp = call_inspector(data, failures) # Now raise everything we were delaying failures.raise_if_needed() if resp is None: LOG.info('stopping inspection, as inspector returned an error') return LOG.info('inspection finished successfully') return resp.get('uuid')
def __init__(self, api_url, advertise_address, listen_address, ip_lookup_attempts, ip_lookup_sleep, network_interface, lookup_timeout, lookup_interval, standalone, hardware_initialization_delay=0): super(IronicPythonAgent, self).__init__() if bool(cfg.CONF.keyfile) != bool(cfg.CONF.certfile): LOG.warning("Only one of 'keyfile' and 'certfile' options is " "defined in config file. Its value will be ignored.") self.ext_mgr = extension.ExtensionManager( namespace='ironic_python_agent.extensions', invoke_on_load=True, propagate_map_exceptions=True, invoke_kwds={'agent': self}, ) self.api_url = api_url if not self.api_url or self.api_url == 'mdns': try: self.api_url, params = mdns.get_endpoint('baremetal') except lib_exc.ServiceLookupFailure: if self.api_url: # mDNS explicitly requested, report failure. raise else: # implicit fallback to mDNS, do not fail (maybe we're only # running inspection). LOG.warning('Could not get baremetal endpoint from mDNS, ' 'will not heartbeat') else: config.override(params) if self.api_url: self.api_client = ironic_api_client.APIClient(self.api_url) self.heartbeater = IronicPythonAgentHeartbeater(self) self.listen_address = listen_address self.advertise_address = advertise_address self.version = pkg_resources.get_distribution('ironic-python-agent')\ .version self.api = app.VersionSelectorApplication(self) self.heartbeat_timeout = None self.started_at = None self.node = None # lookup timeout in seconds self.lookup_timeout = lookup_timeout self.lookup_interval = lookup_interval self.ip_lookup_attempts = ip_lookup_attempts self.ip_lookup_sleep = ip_lookup_sleep self.network_interface = network_interface self.standalone = standalone self.hardware_initialization_delay = hardware_initialization_delay # IPA will stop serving requests and exit after this is set to False self.serve_api = True
def __init__(self, api_url, advertise_address, listen_address, ip_lookup_attempts, ip_lookup_sleep, network_interface, lookup_timeout, lookup_interval, standalone, agent_token, hardware_initialization_delay=0, advertise_protocol='http'): super(IronicPythonAgent, self).__init__() if bool(cfg.CONF.keyfile) != bool(cfg.CONF.certfile): LOG.warning("Only one of 'keyfile' and 'certfile' options is " "defined in config file. Its value will be ignored.") self.ext_mgr = base.init_ext_manager(self) self.api_url = api_url if (not self.api_url or self.api_url == 'mdns') and not standalone: try: self.api_url, params = mdns.get_endpoint('baremetal') except lib_exc.ServiceLookupFailure: if self.api_url: # mDNS explicitly requested, report failure. raise else: # implicit fallback to mDNS, do not fail (maybe we're only # running inspection). LOG.warning('Could not get baremetal endpoint from mDNS, ' 'will not heartbeat') else: config.override(params) if self.api_url: self.api_client = ironic_api_client.APIClient(self.api_url) self.heartbeater = IronicPythonAgentHeartbeater(self) self.listen_address = listen_address self.advertise_address = advertise_address self.advertise_protocol = advertise_protocol self.version = pkg_resources.get_distribution('ironic-python-agent')\ .version self.api = app.Application(self, cfg.CONF) self.heartbeat_timeout = None self.started_at = None self.node = None # lookup timeout in seconds self.lookup_timeout = lookup_timeout self.lookup_interval = lookup_interval self.ip_lookup_attempts = ip_lookup_attempts self.ip_lookup_sleep = ip_lookup_sleep self.network_interface = network_interface self.standalone = standalone self.hardware_initialization_delay = hardware_initialization_delay # IPA will stop serving requests and exit after this is set to False self.serve_api = True self.agent_token = agent_token # Allows this to be turned on by the conductor while running, # in the event of long running ramdisks where the conductor # got upgraded somewhere along the way. self.agent_token_required = cfg.CONF.agent_token_required self.iscsi_started = False