示例#1
0
 def _wait_for_task(self, instance_uuid, task_ref):
     """
     Return a Deferred that will give the result of the given task.
     The task is polled until it completes.
     """
     done = event.Event()
     loop = utils.FixedIntervalLoopingCall(self._poll_task, instance_uuid,
                                           task_ref, done)
     loop.start(CONF.vmwareapi_task_poll_interval)
     ret_val = done.wait()
     loop.stop()
     return ret_val
示例#2
0
文件: db_driver.py 项目: ameade/nova
    def join(self, member_id, group_id, service=None):
        """Join the given service with it's group"""

        msg = _('DB_Driver: join new ServiceGroup member %(member_id)s to '
                    'the %(group_id)s group, service = %(service)s')
        LOG.debug(msg, locals())
        if service is None:
            raise RuntimeError(_('service is a mandatory argument for DB based'
                                 ' ServiceGroup driver'))
        report_interval = service.report_interval
        if report_interval:
            pulse = utils.FixedIntervalLoopingCall(self._report_state, service)
            pulse.start(interval=report_interval,
                        initial_delay=report_interval)
            return pulse
示例#3
0
    def activate_node(self, context, node, instance):
        """Wait for PXE deployment to complete."""

        locals = {'error': '', 'started': False}

        def _wait_for_deploy():
            """Called at an interval until the deployment completes."""
            try:
                row = db.bm_node_get(context, node['id'])
                if instance['uuid'] != row.get('instance_uuid'):
                    locals['error'] = _("Node associated with another instance"
                                        " while waiting for deploy of %s")
                    raise utils.LoopingCallDone()

                status = row.get('task_state')
                if (status == baremetal_states.DEPLOYING
                        and locals['started'] == False):
                    LOG.info(
                        _("PXE deploy started for instance %s") %
                        instance['uuid'])
                    locals['started'] = True
                elif status in (baremetal_states.DEPLOYDONE,
                                baremetal_states.ACTIVE):
                    LOG.info(
                        _("PXE deploy completed for instance %s") %
                        instance['uuid'])
                    raise utils.LoopingCallDone()
                elif status == baremetal_states.DEPLOYFAIL:
                    locals['error'] = _("PXE deploy failed for instance %s")
            except exception.NodeNotFound:
                locals['error'] = _("Baremetal node deleted while waiting "
                                    "for deployment of instance %s")

            if (CONF.baremetal.pxe_deploy_timeout
                    and timeutils.utcnow() > expiration):
                locals['error'] = _("Timeout reached while waiting for "
                                    "PXE deploy of instance %s")
            if locals['error']:
                raise utils.LoopingCallDone()

        expiration = timeutils.utcnow() + datetime.timedelta(
            seconds=CONF.baremetal.pxe_deploy_timeout)
        timer = utils.FixedIntervalLoopingCall(_wait_for_deploy)
        timer.start(interval=1).wait()

        if locals['error']:
            raise exception.InstanceDeployFailure(locals['error'] %
                                                  instance['uuid'])
示例#4
0
    def connect_volume(self, connection_info, mount_device):
        shelf = connection_info['data']['target_shelf']
        lun = connection_info['data']['target_lun']
        aoedev = 'e%s.%s' % (shelf, lun)
        aoedevpath = '/dev/etherd/%s' % (aoedev)

        if os.path.exists(aoedevpath):
            # NOTE(jbr_): If aoedevpath already exists, revalidate the LUN.
            self._aoe_revalidate(aoedev)
        else:
            # NOTE(jbr_): If aoedevpath does not exist, do a discover.
            self._aoe_discover()

        #NOTE(jbr_): Device path is not always present immediately
        def _wait_for_device_discovery(aoedevpath, mount_device):
            tries = self.tries
            if os.path.exists(aoedevpath):
                raise utils.LoopingCallDone()

            if self.tries >= CONF.num_aoe_discover_tries:
                raise exception.NovaException(_("AoE device not found at %s") %
                                                (aoedevpath))
            LOG.warn(_("AoE volume not yet found at: %(aoedevpath)s. "
                       "Try number: %(tries)s") %
                     locals())

            self._aoe_discover()
            self.tries = self.tries + 1

        self.tries = 0
        timer = utils.FixedIntervalLoopingCall(_wait_for_device_discovery,
                                               aoedevpath, mount_device)
        timer.start(interval=2).wait()

        tries = self.tries
        if tries != 0:
            LOG.debug(_("Found AoE device %(aoedevpath)s "
                        "(after %(tries)s rediscover)") %
                      locals())

        conf = super(LibvirtAOEVolumeDriver,
                     self).connect_volume(connection_info, mount_device)
        conf.source_type = "block"
        conf.source_path = aoedevpath
        return conf
示例#5
0
    def _power_off(self):
        """Turn the power to this node OFF."""
        def _wait_for_power_off():
            """Called at an interval until the node's power is off."""

            if self._is_power("off"):
                self.state = baremetal_states.DELETED
                raise utils.LoopingCallDone()
            if self.retries > CONF.baremetal.ipmi_power_retry:
                self.state = baremetal_states.ERROR
                raise utils.LoopingCallDone()
            try:
                self.retries += 1
                self._exec_ipmitool("power off")
            except Exception:
                LOG.exception(_("IPMI power off failed"))

        self.retries = 0
        timer = utils.FixedIntervalLoopingCall(_wait_for_power_off)
        timer.start(interval=0.5).wait()
示例#6
0
def remove_device(device):
    tries = 0
    timer = utils.FixedIntervalLoopingCall(_wait_for_remove, device, tries)
    timer.start(interval=2).wait()
    timer.stop()
示例#7
0
    def connect_volume(self, connection_info, disk_info):
        """Attach the volume to instance_name."""
        fc_properties = connection_info['data']
        mount_device = disk_info["dev"]

        ports = fc_properties['target_wwn']
        wwns = []
        # we support a list of wwns or a single wwn
        if isinstance(ports, list):
            for wwn in ports:
                wwns.append(wwn)
        elif isinstance(ports, str):
            wwns.append(ports)

        # We need to look for wwns on every hba
        # because we don't know ahead of time
        # where they will show up.
        hbas = virtutils.get_fc_hbas_info()
        host_devices = []
        for hba in hbas:
            pci_num = self._get_pci_num(hba)
            if pci_num is not None:
                for wwn in wwns:
                    target_wwn = "0x%s" % wwn.lower()
                    host_device = ("/dev/disk/by-path/pci-%s-fc-%s-lun-%s" %
                                  (pci_num,
                                   target_wwn,
                                   fc_properties.get('target_lun', 0)))
                    host_devices.append(host_device)

        if len(host_devices) == 0:
            # this is empty because we don't have any FC HBAs
            msg = _("We are unable to locate any Fibre Channel devices")
            raise exception.NovaException(msg)

        # The /dev/disk/by-path/... node is not always present immediately
        # We only need to find the first device.  Once we see the first device
        # multipath will have any others.
        def _wait_for_device_discovery(host_devices, mount_device):
            tries = self.tries
            for device in host_devices:
                LOG.debug(_("Looking for Fibre Channel dev %(device)s")
                          % locals())
                if os.path.exists(device):
                    self.host_device = device
                    # get the /dev/sdX device.  This is used
                    # to find the multipath device.
                    self.device_name = os.path.realpath(device)
                    raise utils.LoopingCallDone()

            if self.tries >= CONF.num_iscsi_scan_tries:
                msg = _("Fibre Channel device not found.")
                raise exception.NovaException(msg)

            LOG.warn(_("Fibre volume not yet found at: %(mount_device)s. "
                       "Will rescan & retry.  Try number: %(tries)s") %
                     locals())

            linuxscsi.rescan_hosts(hbas)
            self.tries = self.tries + 1

        self.host_device = None
        self.device_name = None
        self.tries = 0
        timer = utils.FixedIntervalLoopingCall(_wait_for_device_discovery,
                                               host_devices, mount_device)
        timer.start(interval=2).wait()

        tries = self.tries
        if self.host_device is not None and self.device_name is not None:
            LOG.debug(_("Found Fibre Channel volume %(mount_device)s "
                        "(after %(tries)s rescans)") % locals())

        # see if the new drive is part of a multipath
        # device.  If so, we'll use the multipath device.
        mdev_info = linuxscsi.find_multipath_device(self.device_name)
        if mdev_info is not None:
            LOG.debug(_("Multipath device discovered %(device)s")
                      % {'device': mdev_info['device']})
            device_path = mdev_info['device']
            connection_info['data']['devices'] = mdev_info['devices']
        else:
            # we didn't find a multipath device.
            # so we assume the kernel only sees 1 device
            device_path = self.host_device
            device_info = linuxscsi.get_device_info(self.device_name)
            connection_info['data']['devices'] = [device_info]

        conf = super(LibvirtFibreChannelVolumeDriver,
                     self).connect_volume(connection_info, disk_info)

        conf.source_type = "block"
        conf.source_path = device_path
        return conf