def disk_format_gpt(self, host_uuid, idisk_dict, is_cinder_device): disk_node = idisk_dict.get('device_path') utils.disk_wipe(disk_node) utils.execute('parted', disk_node, 'mklabel', 'gpt') if is_cinder_device: LOG.debug("Removing .node_cinder_lvm_config_complete_file") try: os.remove(constants.NODE_CINDER_LVM_CONFIG_COMPLETE_FILE) except OSError: LOG.error(".node_cinder_lvm_config_complete_file not present.") pass # On SX ensure wipe succeeds before DB is updated. # Flag file is used to mark wiping in progress. try: os.remove(constants.DISK_WIPE_IN_PROGRESS_FLAG) except OSError: # it's ok if file is not present. pass # We need to send the updated info about the host disks back to # the conductor. idisk_update = self.idisk_get() ctxt = context.get_admin_context() rpcapi = conductor_rpcapi.ConductorAPI( topic=conductor_rpcapi.MANAGER_TOPIC) rpcapi.idisk_update_by_ihost(ctxt, host_uuid, idisk_update)
def _update_ttys_dcd_status(self, context, host_id): # Retrieve the serial line carrier detect flag ttys_dcd = None rpcapi = conductor_rpcapi.ConductorAPI( topic=conductor_rpcapi.MANAGER_TOPIC) try: ttys_dcd = rpcapi.get_host_ttys_dcd(context, host_id) except exception.InventoryException: LOG.exception("Inventory Agent exception getting host ttys_dcd.") pass if ttys_dcd is not None: self._config_ttys_login(ttys_dcd) else: LOG.debug("ttys_dcd is not configured")
def update_host_memory(self, context, host_uuid): """update the host memory :param context: an admin context :param host_uuid: ihost uuid unique id :return: None """ if self._ihost_uuid and self._ihost_uuid == host_uuid: rpcapi = conductor_rpcapi.ConductorAPI( topic=conductor_rpcapi.MANAGER_TOPIC) memory = self._inode_operator.inodes_get_imemory() rpcapi.memory_update_by_host(context, self._ihost_uuid, memory, force_update=True)
def configure_lldp_systemname(self, context, systemname): """Configure the systemname into the lldp agent with the supplied data. :param context: an admin context. :param systemname: the systemname """ # TODO(sc): This becomes an inventory-api call from # via systemconfig: configure_isystemname rpcapi = conductor_rpcapi.ConductorAPI( topic=conductor_rpcapi.MANAGER_TOPIC) # Update the lldp agent self._lldp_operator.lldp_update_systemname(systemname) # Trigger an audit to ensure the db is up to date self.host_lldp_get_and_report(context, rpcapi, self._ihost_uuid)
def add_lease(mac, ip_address): """Called when a new lease is created.""" ctxt = context.get_admin_context() rpcapi = \ conductor_rpcapi.ConductorAPI(topic=conductor_rpcapi.MANAGER_TOPIC) cid = None cid = os.getenv('DNSMASQ_CLIENT_ID') tags = None tags = os.getenv('DNSMASQ_TAGS') if tags is not None: # TODO(sc): Maybe this shouldn't be synchronous - if this hangs, # we could cause dnsmasq to get stuck... rpcapi.handle_dhcp_lease(ctxt, tags, mac, ip_address, cid)
def old_lease(mac, ip_address): """Called when an old lease is recognized.""" # This happens when a node is rebooted, but it can also happen if the # node was deleted and then rebooted, so we need to re-add in that case. ctxt = context.get_admin_context() rpcapi = conductor_rpcapi.ConductorAPI( topic=conductor_rpcapi.MANAGER_TOPIC) cid = None cid = os.getenv('DNSMASQ_CLIENT_ID') tags = None tags = os.getenv('DNSMASQ_TAGS') if tags is not None: # TODO(sc): Maybe this shouldn't be synchronous - if this hangs, # we could cause dnsmasq to get stuck... rpcapi.handle_dhcp_lease(ctxt, tags, mac, ip_address, cid)
def agent_audit(self, context, host_uuid, force_updates, cinder_device=None): # perform inventory audit if self._ihost_uuid != host_uuid: # The function call is not for this host agent return icontext = mycontext.get_admin_context() rpcapi = conductor_rpcapi.ConductorAPI( topic=conductor_rpcapi.MANAGER_TOPIC) if not self.report_to_conductor_required: LOG.info("Inventory Agent audit running inv_get_and_report.") self.ihost_inv_get_and_report(icontext) if self._ihost_uuid and os.path.isfile( tsc.INITIAL_CONFIG_COMPLETE_FLAG): if (not self._report_to_conductor_iplatform_avail_flag and not self._wait_for_nova_lvg(icontext, rpcapi, self._ihost_uuid)): imsg_dict = {'availability': k_host.AVAILABILITY_AVAILABLE} iscsi_initiator_name = self.get_host_iscsi_initiator_name() if iscsi_initiator_name is not None: imsg_dict.update( {'iscsi_initiator_name': iscsi_initiator_name}) # Before setting the host to AVAILABILITY_AVAILABLE make # sure that nova_local aggregates are correctly set self.platform_update_by_host(rpcapi, icontext, self._ihost_uuid, imsg_dict) self._report_to_conductor_iplatform_avail() if (self._ihost_personality == k_host.CONTROLLER and not self._notify_subfunctions_alarm_clear): subfunctions_list = self.subfunctions_list_get() if ((k_host.CONTROLLER in subfunctions_list) and (k_host.COMPUTE in subfunctions_list)): if self.subfunctions_configured(subfunctions_list) and \ not self._wait_for_nova_lvg( icontext, rpcapi, self._ihost_uuid): ihost_notify_dict = {'subfunctions_configured': True} rpcapi.notify_subfunctions_config( icontext, self._ihost_uuid, ihost_notify_dict) self._notify_subfunctions_alarm_clear = True else: if not self._notify_subfunctions_alarm_raise: ihost_notify_dict = { 'subfunctions_configured': False } rpcapi.notify_subfunctions_config( icontext, self._ihost_uuid, ihost_notify_dict) self._notify_subfunctions_alarm_raise = True else: self._notify_subfunctions_alarm_clear = True if self._ihost_uuid: LOG.debug("Inventory Agent Audit running.") if force_updates: LOG.debug("Inventory Agent Audit force updates: (%s)" % (', '.join(force_updates))) self._update_ttys_dcd_status(icontext, self._ihost_uuid) if self._agent_throttle > 5: # throttle updates self._agent_throttle = 0 imemory = self._inode_operator.inodes_get_imemory() rpcapi.memory_update_by_host(icontext, self._ihost_uuid, imemory) if self._is_config_complete(): self.host_lldp_get_and_report(icontext, rpcapi, self._ihost_uuid) else: self._lldp_enable_and_report(icontext, rpcapi, self._ihost_uuid) self._agent_throttle += 1 if os.path.isfile(tsc.PLATFORM_CONF_FILE): # read the platform config file and check for UUID if 'UUID' not in open(tsc.PLATFORM_CONF_FILE).read(): # the UUID is not in found, append it with open(tsc.PLATFORM_CONF_FILE, "a") as fd: fd.write("UUID=" + self._ihost_uuid)
def ihost_inv_get_and_report(self, icontext): """Collect data for an ihost. This method allows an ihost data to be collected. :param: icontext: an admin context :returns: updated ihost object, including all fields. """ rpcapi = conductor_rpcapi.ConductorAPI( topic=conductor_rpcapi.MANAGER_TOPIC) ihost = None # find list of network related inics for this ihost inics = self._ipci_operator.inics_get() # create an array of ports for each net entry of the NIC device iports = [] for inic in inics: lockfd = 0 try: # Get lock to avoid conflict with apply_network_config.sh lockfd = self._acquire_network_config_lock() pci_net_array = \ self._ipci_operator.pci_get_net_attrs(inic.pciaddr) finally: self._release_network_config_lock(lockfd) for net in pci_net_array: iports.append(pci.Port(inic, **net)) # find list of pci devices for this host pci_devices = self._ipci_operator.pci_devices_get() # create an array of pci_devs for each net entry of the device pci_devs = [] for pci_dev in pci_devices: pci_dev_array = \ self._ipci_operator.pci_get_device_attrs(pci_dev.pciaddr) for dev in pci_dev_array: pci_devs.append(pci.PCIDevice(pci_dev, **dev)) # create a list of MAC addresses that will be used to identify the # inventoried host (one of the MACs should be the management MAC) host_macs = [port.mac for port in iports if port.mac] # get my ihost record which should be avail since booted LOG.debug('Inventory Agent iports={}, host_macs={}'.format( iports, host_macs)) slept = 0 while slept < MAXSLEEP: # wait for controller to come up first may be a DOR try: ihost = rpcapi.get_host_by_macs(icontext, host_macs) except messaging.MessagingTimeout: LOG.info("get_host_by_macs Messaging Timeout.") except Exception as ex: LOG.warn("Conductor RPC get_host_by_macs exception " "response %s" % ex) if not ihost: hostname = socket.gethostname() if hostname != k_host.LOCALHOST_HOSTNAME: try: ihost = rpcapi.get_host_by_hostname(icontext, hostname) except messaging.MessagingTimeout: LOG.info("get_host_by_hostname Messaging Timeout.") return # wait for next audit cycle except Exception as ex: LOG.warn("Conductor RPC get_host_by_hostname " "exception response %s" % ex) if ihost and ihost.get('personality'): self.report_to_conductor_required = True self._ihost_uuid = ihost['uuid'] self._ihost_personality = ihost['personality'] if os.path.isfile(tsc.PLATFORM_CONF_FILE): # read the platform config file and check for UUID found = False with open(tsc.PLATFORM_CONF_FILE, "r") as fd: for line in fd: if line.find("UUID=") == 0: found = True if not found: # the UUID is not found, append it with open(tsc.PLATFORM_CONF_FILE, "a") as fd: fd.write("UUID=" + self._ihost_uuid + "\n") # Report host install status msg_dict = {} self.platform_update_by_host(rpcapi, icontext, self._ihost_uuid, msg_dict) LOG.info("Agent found matching ihost: %s" % ihost['uuid']) break time.sleep(30) slept += 30 if not self.report_to_conductor_required: # let the audit take care of it instead LOG.info("Inventory no matching ihost found... await Audit") return subfunctions = self.subfunctions_get() try: rpcapi.subfunctions_update_by_host(icontext, ihost['uuid'], subfunctions) except exception.InventoryException: LOG.exception("Inventory Agent exception updating " "subfunctions conductor.") pass # post to inventory db by ihost['uuid'] iport_dict_array = [] for port in iports: inic_dict = { 'pciaddr': port.ipci.pciaddr, 'pclass': port.ipci.pclass, 'pvendor': port.ipci.pvendor, 'pdevice': port.ipci.pdevice, 'prevision': port.ipci.prevision, 'psvendor': port.ipci.psvendor, 'psdevice': port.ipci.psdevice, 'pname': port.name, 'numa_node': port.numa_node, 'sriov_totalvfs': port.sriov_totalvfs, 'sriov_numvfs': port.sriov_numvfs, 'sriov_vfs_pci_address': port.sriov_vfs_pci_address, 'driver': port.driver, 'mac': port.mac, 'mtu': port.mtu, 'speed': port.speed, 'link_mode': port.link_mode, 'dev_id': port.dev_id, 'dpdksupport': port.dpdksupport } LOG.debug('Inventory Agent inic {}'.format(inic_dict)) iport_dict_array.append(inic_dict) try: # may get duplicate key if already sent on earlier init rpcapi.port_update_by_host(icontext, ihost['uuid'], iport_dict_array) except messaging.MessagingTimeout: LOG.info("pci_device_update_by_host Messaging Timeout.") self.report_to_conductor_required = False return # wait for next audit cycle # post to inventory db by ihost['uuid'] pci_device_dict_array = [] for dev in pci_devs: pci_dev_dict = { 'name': dev.name, 'pciaddr': dev.pci.pciaddr, 'pclass_id': dev.pclass_id, 'pvendor_id': dev.pvendor_id, 'pdevice_id': dev.pdevice_id, 'pclass': dev.pci.pclass, 'pvendor': dev.pci.pvendor, 'pdevice': dev.pci.pdevice, 'prevision': dev.pci.prevision, 'psvendor': dev.pci.psvendor, 'psdevice': dev.pci.psdevice, 'numa_node': dev.numa_node, 'sriov_totalvfs': dev.sriov_totalvfs, 'sriov_numvfs': dev.sriov_numvfs, 'sriov_vfs_pci_address': dev.sriov_vfs_pci_address, 'driver': dev.driver, 'enabled': dev.enabled, 'extra_info': dev.extra_info } LOG.debug('Inventory Agent dev {}'.format(pci_dev_dict)) pci_device_dict_array.append(pci_dev_dict) try: # may get duplicate key if already sent on earlier init rpcapi.pci_device_update_by_host(icontext, ihost['uuid'], pci_device_dict_array) except messaging.MessagingTimeout: LOG.info("pci_device_update_by_host Messaging Timeout.") self.report_to_conductor_required = True # Find list of numa_nodes and cpus for this ihost inumas, icpus = self._inode_operator.inodes_get_inumas_icpus() try: # may get duplicate key if already sent on earlier init rpcapi.numas_update_by_host(icontext, ihost['uuid'], inumas) except messaging.RemoteError as e: LOG.error("numas_update_by_host RemoteError exc_type=%s" % e.exc_type) except messaging.MessagingTimeout: LOG.info("pci_device_update_by_host Messaging Timeout.") self.report_to_conductor_required = True except Exception as e: LOG.exception("Inventory Agent exception updating inuma e=%s." % e) pass force_grub_update = self._force_grub_update() try: # may get duplicate key if already sent on earlier init rpcapi.cpus_update_by_host(icontext, ihost['uuid'], icpus, force_grub_update) except messaging.RemoteError as e: LOG.error("cpus_update_by_host RemoteError exc_type=%s" % e.exc_type) except messaging.MessagingTimeout: LOG.info("cpus_update_by_host Messaging Timeout.") self.report_to_conductor_required = True except Exception as e: LOG.exception("Inventory exception updating cpus e=%s." % e) self.report_to_conductor_required = True pass except exception.InventoryException: LOG.exception("Inventory exception updating cpus conductor.") pass imemory = self._inode_operator.inodes_get_imemory() if imemory: try: # may get duplicate key if already sent on earlier init rpcapi.memory_update_by_host(icontext, ihost['uuid'], imemory) except messaging.MessagingTimeout: LOG.info("memory_update_by_host Messaging Timeout.") except messaging.RemoteError as e: LOG.error("memory_update_by_host RemoteError exc_type=%s" % e.exc_type) except exception.InventoryException: LOG.exception("Inventory Agent exception updating imemory " "conductor.") if self._ihost_uuid and \ os.path.isfile(tsc.INITIAL_CONFIG_COMPLETE_FLAG): if not self._report_to_conductor_iplatform_avail_flag: # and not self._wait_for_nova_lvg() imsg_dict = {'availability': k_host.AVAILABILITY_AVAILABLE} iscsi_initiator_name = self.get_host_iscsi_initiator_name() if iscsi_initiator_name is not None: imsg_dict.update( {'iscsi_initiator_name': iscsi_initiator_name}) # Before setting the host to AVAILABILITY_AVAILABLE make # sure that nova_local aggregates are correctly set self.platform_update_by_host(rpcapi, icontext, self._ihost_uuid, imsg_dict) self._report_to_conductor_iplatform_avail()
def before(self, state): state.request.rpcapi = rpcapi.ConductorAPI()