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
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
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'])
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
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()
def remove_device(device): tries = 0 timer = utils.FixedIntervalLoopingCall(_wait_for_remove, device, tries) timer.start(interval=2).wait() timer.stop()
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