示例#1
0
def get_from_path(items, path):
    """Returns a list of items matching the specified path.

    Takes an XPath-like expression e.g. prop1/prop2/prop3, and for each item
    in items, looks up items[prop1][prop2][prop3]. Like XPath, if any of the
    intermediate results are lists it will treat each list item individually.
    A 'None' in items or any child expressions will be ignored, this function
    will not throw because of None (anywhere) in items.  The returned list
    will contain no None values.

    """
    if path is None:
        raise exception.Error('Invalid mini_xpath')

    (first_token, sep, remainder) = path.partition('/')

    if first_token == '':
        raise exception.Error('Invalid mini_xpath')

    results = []

    if items is None:
        return results

    if not isinstance(items, list):
        # Wrap single objects in a list
        items = [items]

    for item in items:
        if item is None:
            continue
        get_method = getattr(item, 'get', None)
        if get_method is None:
            continue
        child = get_method(first_token)
        if child is None:
            continue
        if isinstance(child, list):
            # Flatten intermediate lists
            for x in child:
                results.append(x)
        else:
            results.append(child)

    if not sep:
        # No more tokens
        return results
    else:
        return get_from_path(results, remainder)
示例#2
0
    def register(self, ext):
        # Do nothing if the extension doesn't check out
        if not self._check_extension(ext):
            return

        alias = ext.alias
        LOG.info(_LI('Loaded extension: %s'), alias)

        if alias in self.extensions:
            raise exception.Error("Found duplicate extension: %s" % alias)
        self.extensions[alias] = ext
示例#3
0
    def _await_volume_status(self, context, vol_id, status):
        # TODO(yamahata): creating volume simultaneously
        #                 reduces creation time?
        # TODO(yamahata): eliminate dumb polling
        start = time.time()
        retries = CONF.block_device_allocate_retries
        if retries < 0:
            LOG.warn(
                _LW("Treating negative config value (%(retries)s) for "
                    "'block_device_retries' as 0."), {'retries': retries})
        # (1) treat  negative config value as 0
        # (2) the configured value is 0, one attempt should be made
        # (3) the configured value is > 0, then the total number attempts
        #      is (retries + 1)
        attempts = 1
        if retries >= 1:
            attempts = retries + 1
        for attempt in range(1, attempts + 1):
            volume = self.volume_api.get(context, vol_id)
            volume_status = volume['status']
            if volume_status == status:
                LOG.debug(_("Volume id: %s finished being detached"), vol_id)
                return attempt

            greenthread.sleep(CONF.block_device_allocate_retries_interval)

        # NOTE(harlowja): Should only happen if we ran out of attempts
        if 'available' == status:
            LOG.error(_("Volume id: %s detach failed"), vol_id)
            raise exception.VolumeNotdetach(volume_id=vol_id,
                                            seconds=int(time.time() - start),
                                            attempts=attempts)
        elif 'in-use' == status:
            LOG.error(_("Volume id: %s attach failed"), vol_id)
            raise exception.VolumeNotAttach(volume_id=vol_id,
                                            seconds=int(time.time() - start),
                                            attempts=attempts)
        else:
            raise exception.Error(message="Volume option error.")
示例#4
0
    def _await_instance_status(self, context, instance_id, status):
        start = time.time()
        retries = CONF.block_device_allocate_retries
        if retries < 0:
            LOG.warn(
                _LW("Treating negative config value (%(retries)s) for "
                    "'block_device_retries' as 0."), {'retries': retries})
        # (1) treat  negative config value as 0
        # (2) the configured value is 0, one attempt should be made
        # (3) the configured value is > 0, then the total number attempts
        #      is (retries + 1)
        attempts = 1
        if retries >= 1:
            attempts = retries + 1
        for attempt in range(1, attempts + 1):
            instance = self.nova_api.get_server(context, instance_id)
            instance_status = instance.get('status', None)
            if instance_status == status:
                LOG.error(_("Instance id: %(id)s finished being %(st)s"), {
                    'id': instance_id,
                    'st': status
                })
                return attempt
            greenthread.sleep(CONF.block_device_allocate_retries_interval)

        if 'SHUTOFF' == status:
            LOG.error(_("Instance id: %s stop failed"), instance_id)
            raise exception.InstanceNotStop(instance_id=instance_id,
                                            seconds=int(time.time() - start),
                                            attempts=attempts)
        elif 'ACTIVE' == status:
            LOG.error(_("Instance id: %s start failed"), instance_id)
            raise exception.InstanceNotStart(instance_id=instance_id,
                                             seconds=int(time.time() - start),
                                             attempts=attempts)
        else:
            raise exception.Error(message="Instance option error.")
示例#5
0
def get_blkdev_major_minor(path, lookup_for_file=True):
    """Get the device's "major:minor" number of a block device to control
    I/O ratelimit of the specified path.
    If lookup_for_file is True and the path is a regular file, lookup a disk
    device which the file lies on and returns the result for the device.
    """
    st = os.stat(path)
    if stat.S_ISBLK(st.st_mode):
        path, st = _get_disk_of_partition(path, st)
        return '%d:%d' % (os.major(st.st_rdev), os.minor(st.st_rdev))
    elif stat.S_ISCHR(st.st_mode):
        # No I/O ratelimit control is provided for character devices
        return None
    elif lookup_for_file:
        # lookup the mounted disk which the file lies on
        out, _err = execute('df', path)
        devpath = out.split("\n")[1].split()[0]
        if devpath[0] is not '/':
            # the file is on a network file system
            return None
        return get_blkdev_major_minor(devpath, False)
    else:
        msg = _("Unable to get a block device for file \'%s\'") % path
        raise exception.Error(msg)