Exemple #1
0
    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)
Exemple #2
0
 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")
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
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)
Exemple #6
0
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)
Exemple #7
0
    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)
Exemple #8
0
    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()
Exemple #9
0
 def before(self, state):
     state.request.rpcapi = rpcapi.ConductorAPI()