def setup_ipmi_credentials(resp): """Setup IPMI credentials, if requested. :param resp: JSON response from inspector. """ if not resp.get('ipmi_setup_credentials'): LOG.info('setting IPMI credentials was not requested') return user, password = resp['ipmi_username'], resp['ipmi_password'] LOG.debug('setting IPMI credentials: user %s', user) commands = [ ('user', 'set', 'name', '2', user), ('user', 'set', 'password', '2', password), ('user', 'enable', '2'), ('channel', 'setaccess', '1', '2', 'link=on', 'ipmi=on', 'callin=on', 'privilege=4'), ] for cmd in commands: try: utils.execute('ipmitool', *cmd) except processutils.ProcessExecutionError: LOG.exception('failed to update IPMI credentials') raise errors.InspectionError('failed to update IPMI credentials') LOG.info('successfully set IPMI credentials: user %s', user)
def extension_manager(names): try: return stevedore.NamedExtensionManager(_COLLECTOR_NS, names=names, name_order=True) except KeyError as exc: raise errors.InspectionError('Failed to load collector %s' % exc)
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 config_ipmi_info(sn): LOG.info('Config ipmi info...') if not CONF.arobot_callback_url: LOG.info('Config automation is disabled, skipping') return interval = 5 index = 1 while True: ipmi_conf = None try: ipmi_conf = call_arobot(sn) except Exception as e: LOG.info('Got exception %s', e) LOG.info('%s times', index) time.sleep(interval) index += 1 continue if ipmi_conf is not None and \ ipmi_conf.get('return_value') == 'NeedConf': LOG.info('Got ipmi conf OK! address %s, netmask %s, gateway %s', ipmi_conf.get('ipmi_address'), ipmi_conf.get('ipmi_netmask'), ipmi_conf.get('ipmi_gateway')) break elif ipmi_conf is not None and \ ipmi_conf.get('return_value') == 'Success': LOG.info('IPMI info already confed!') return LOG.info('%s times', index) time.sleep(interval) index += 1 commands = [ ('lan', 'set', '1', 'ipsrc', 'static'), ('lan', 'set', '1', 'ipaddr', ipmi_conf.get('ipmi_address')), ('lan', 'set', '1', 'netmask', ipmi_conf.get('ipmi_netmask')), ('lan', 'set', '1', 'defgw', 'ipaddr', ipmi_conf.get('ipmi_gateway')), # ('user', 'set', 'name', '5', 'inspur'), # ('user', 'set', 'password', '5', 'Czilpjhstcgx4Ru5'), # ('user', 'enable', '5'), # ('channel', 'setaccess', '1', '5', # 'link=on', 'ipmi=on', 'callin=on', 'privilege=4'), ] for cmd in commands: try: utils.execute('ipmitool', *cmd) except processutils.ProcessExecutionError: LOG.exception('failed to update IPMI ip/netmask/gw') raise errors.InspectionError('failed to update IPMI ip/netmask/gw') tell_arobot_ipmi(sn=sn) LOG.info('successfully set IPMI conf!')
def _run(self): try: daemon_mode = cfg.CONF.introspection_daemon post_interval = cfg.CONF.introspection_daemon_post_interval inspector.inspect() if not daemon_mode: # No reason to continue unless we're in daemon mode. return self.reader, self.writer = os.pipe() p = select.poll() p.register(self.reader) try: while daemon_mode: LOG.info('Sleeping until next check-in.') # TODO(TheJulia): It would likely be good to introduce # some jitter into this at some point... if p.poll(post_interval * 1000): if os.read(self.reader, 1).decode() == 'a': break try: inspector.inspect() except errors.InspectionError as e: # Failures happen, no reason to exit as # the failure could be intermittent. LOG.warning( 'Error reporting introspection ' 'data: %(err)s', {'err': e}) except exception.ServiceLookupFailure as e: # Likely a mDNS lookup failure. We should # keep retrying. LOG.error( 'Error looking up introspection ' 'endpoint: %(err)s', {'err': e}) finally: os.close(self.reader) os.close(self.writer) self.reader = None self.writer = None except errors.InspectionError as e: msg = "Inspection failed: %s" % e raise errors.InspectionError(msg)
def _extension_manager_err_callback(names): raise errors.InspectionError('Failed to load collector %s' % names)