Beispiel #1
0
 def test_get_device_letter(self):
     self.assertEqual('', block_device.get_device_letter(''))
     self.assertEqual('a', block_device.get_device_letter('/dev/sda1'))
     self.assertEqual('b', block_device.get_device_letter('/dev/xvdb'))
     self.assertEqual('d', block_device.get_device_letter('/dev/d'))
     self.assertEqual('a', block_device.get_device_letter('a'))
     self.assertEqual('b', block_device.get_device_letter('sdb2'))
     self.assertEqual('c', block_device.get_device_letter('vdc'))
     self.assertEqual('c', block_device.get_device_letter('hdc'))
     self.assertIsNone(block_device.get_device_letter(None))
Beispiel #2
0
 def test_get_device_letter(self):
     self.assertEqual('', block_device.get_device_letter(''))
     self.assertEqual('a', block_device.get_device_letter('/dev/sda1'))
     self.assertEqual('b', block_device.get_device_letter('/dev/xvdb'))
     self.assertEqual('d', block_device.get_device_letter('/dev/d'))
     self.assertEqual('a', block_device.get_device_letter('a'))
     self.assertEqual('b', block_device.get_device_letter('sdb2'))
     self.assertEqual('c', block_device.get_device_letter('vdc'))
     self.assertEqual('c', block_device.get_device_letter('hdc'))
     self.assertIsNone(block_device.get_device_letter(None))
Beispiel #3
0
def get_next_device_name(instance, device_name_list,
                         root_device_name=None, device=None):
    """Validates (or generates) a device name for instance.

    If device is not set, it will generate a unique device appropriate
    for the instance. It uses the root_device_name (if provided) and
    the list of used devices to find valid device names. If the device
    name is valid but applicable to a different backend (for example
    /dev/vdc is specified but the backend uses /dev/xvdc), the device
    name will be converted to the appropriate format.
    """

    req_prefix = None
    req_letter = None

    if device:
        try:
            req_prefix, req_letter = block_device.match_device(device)
        except (TypeError, AttributeError, ValueError):
            raise exception.InvalidDevicePath(path=device)

    if not root_device_name:
        root_device_name = block_device.DEFAULT_ROOT_DEV_NAME

    try:
        prefix = block_device.match_device(
                block_device.prepend_dev(root_device_name))[0]
    except (TypeError, AttributeError, ValueError):
        raise exception.InvalidDevicePath(path=root_device_name)

    # NOTE(vish): remove this when xenapi is setting default_root_device
    if driver.is_xenapi():
        prefix = '/dev/xvd'

    if req_prefix != prefix:
        LOG.debug("Using %(prefix)s instead of %(req_prefix)s",
                  {'prefix': prefix, 'req_prefix': req_prefix})

    used_letters = set()
    for device_path in device_name_list:
        letter = block_device.get_device_letter(device_path)
        used_letters.add(letter)

    # NOTE(vish): remove this when xenapi is properly setting
    #             default_ephemeral_device and default_swap_device
    if driver.is_xenapi():
        flavor = instance.get_flavor()
        if flavor.ephemeral_gb:
            used_letters.add('b')

        if flavor.swap:
            used_letters.add('c')

    if not req_letter:
        req_letter = _get_unused_letter(used_letters)

    if req_letter in used_letters:
        raise exception.DevicePathInUse(path=device)

    return prefix + req_letter
Beispiel #4
0
 def test_get_device_letter(self):
     self.assertEqual(block_device.get_device_letter(''), '')
     self.assertEqual(block_device.get_device_letter('/dev/sda1'), 'a')
     self.assertEqual(block_device.get_device_letter('/dev/xvdb'), 'b')
     self.assertEqual(block_device.get_device_letter('/dev/d'), 'd')
     self.assertEqual(block_device.get_device_letter('a'), 'a')
     self.assertEqual(block_device.get_device_letter('sdb2'), 'b')
     self.assertEqual(block_device.get_device_letter('vdc'), 'c')
     self.assertEqual(block_device.get_device_letter('hdc'), 'c')
Beispiel #5
0
 def test_get_device_letter(self):
     self.assertEqual(block_device.get_device_letter(""), "")
     self.assertEqual(block_device.get_device_letter("/dev/sda1"), "a")
     self.assertEqual(block_device.get_device_letter("/dev/xvdb"), "b")
     self.assertEqual(block_device.get_device_letter("/dev/d"), "d")
     self.assertEqual(block_device.get_device_letter("a"), "a")
     self.assertEqual(block_device.get_device_letter("sdb2"), "b")
     self.assertEqual(block_device.get_device_letter("vdc"), "c")
     self.assertEqual(block_device.get_device_letter("hdc"), "c")
Beispiel #6
0
 def test_get_device_letter(self):
     self.assertEqual(block_device.get_device_letter(''), '')
     self.assertEqual(block_device.get_device_letter('/dev/sda1'), 'a')
     self.assertEqual(block_device.get_device_letter('/dev/xvdb'), 'b')
     self.assertEqual(block_device.get_device_letter('/dev/d'), 'd')
     self.assertEqual(block_device.get_device_letter('a'), 'a')
     self.assertEqual(block_device.get_device_letter('sdb2'), 'b')
     self.assertEqual(block_device.get_device_letter('vdc'), 'c')
     self.assertEqual(block_device.get_device_letter('hdc'), 'c')
Beispiel #7
0
def get_bdm_image_metadata(context,
                           image_api,
                           volume_api,
                           block_device_mapping,
                           legacy_bdm=True):
    """Attempt to retrive image metadata from a given block_device_mapping.

    If we are booting from a volume, we need to get the volume details from
    Cinder and make sure we pass the metadata back accordingly.

    :param context: request context
    :param image_api: Image API
    :param volume_api: Volume API
    :param block_device_mapping:
    :param legacy_bdm:
    """
    if not block_device_mapping:
        return {}

    for bdm in block_device_mapping:
        if (legacy_bdm and block_device.get_device_letter(
                bdm.get('device_name', '')) != 'a'):
            continue
        elif not legacy_bdm and bdm.get('boot_index') != 0:
            continue

        volume_id = bdm.get('volume_id')
        snapshot_id = bdm.get('snapshot_id')
        if snapshot_id:
            # NOTE(alaski): A volume snapshot inherits metadata from the
            # originating volume, but the API does not expose metadata
            # on the snapshot itself.  So we query the volume for it below.
            snapshot = volume_api.get_snapshot(context, snapshot_id)
            volume_id = snapshot['volume_id']

        if bdm.get('image_id'):
            try:
                image_id = bdm['image_id']
                image_meta = image_api.get(context, image_id)
                return image_meta
            except Exception:
                raise exception.InvalidBDMImage(id=image_id)
        elif volume_id:
            try:
                volume = volume_api.get(context, volume_id)
            except exception.CinderConnectionFailed:
                raise
            except Exception:
                raise exception.InvalidBDMVolume(id=volume_id)

            if not volume.get('bootable', True):
                raise exception.InvalidBDMVolumeNotBootable(id=volume_id)

            return get_image_metadata_from_volume(volume)
    return {}
Beispiel #8
0
def get_root_info(instance,
                  virt_type,
                  image_meta,
                  root_bdm,
                  disk_bus,
                  cdrom_bus,
                  root_device_name=None):

    # NOTE (ndipanov): This is a hack to avoid considering an image
    #                  BDM with local target, as we don't support them
    #                  yet. Only applies when passed non-driver format
    no_root_bdm = (not root_bdm
                   or (root_bdm.get('source_type') == 'image'
                       and root_bdm.get('destination_type') == 'local'))
    if no_root_bdm:
        # NOTE(mriedem): In case the image_meta object was constructed from
        # an empty dict, like in the case of evacuate, we have to first check
        # if disk_format is set on the ImageMeta object.
        if (image_meta.obj_attr_is_set('disk_format')
                and image_meta.disk_format == 'iso'):
            root_device_bus = cdrom_bus
            root_device_type = 'cdrom'
        else:
            root_device_bus = disk_bus
            root_device_type = 'disk'
        if root_device_name:
            root_device_bus = get_disk_bus_for_disk_dev(
                virt_type, root_device_name)
        else:
            root_device_name = find_disk_dev_for_disk_bus({}, root_device_bus)

        return {
            'bus': root_device_bus,
            'type': root_device_type,
            'dev': block_device.strip_dev(root_device_name),
            'boot_index': '1'
        }

    if not get_device_name(root_bdm) and root_device_name:
        root_bdm = root_bdm.copy()
        # it can happen, eg for libvirt+Xen, that the root_device_name is
        # incompatible with the disk bus. In that case fix the root_device_name
        if virt_type == 'xen':
            dev_prefix = get_dev_prefix_for_disk_bus(disk_bus)
            if not root_device_name.startswith(dev_prefix):
                letter = block_device.get_device_letter(root_device_name)
                root_device_name = '%s%s' % (dev_prefix, letter)
        root_bdm['device_name'] = root_device_name
    return get_info_from_bdm(instance, virt_type, image_meta, root_bdm, {},
                             disk_bus)
Beispiel #9
0
def get_root_info(instance, virt_type, image_meta, root_bdm,
                  disk_bus, cdrom_bus, root_device_name=None):

    # NOTE (ndipanov): This is a hack to avoid considering an image
    #                  BDM with local target, as we don't support them
    #                  yet. Only applies when passed non-driver format
    no_root_bdm = (not root_bdm or (
        root_bdm.get('source_type') == 'image' and
        root_bdm.get('destination_type') == 'local'))
    if no_root_bdm:
        # NOTE(mriedem): In case the image_meta object was constructed from
        # an empty dict, like in the case of evacuate, we have to first check
        # if disk_format is set on the ImageMeta object.
        if (image_meta.obj_attr_is_set('disk_format') and
                image_meta.disk_format == 'iso'):
            root_device_bus = cdrom_bus
            root_device_type = 'cdrom'
        else:
            root_device_bus = disk_bus
            root_device_type = 'disk'
        if root_device_name:
            root_device_bus = get_disk_bus_for_disk_dev(virt_type,
                                                        root_device_name)
        else:
            root_device_name = find_disk_dev_for_disk_bus({}, root_device_bus)

        return {'bus': root_device_bus,
                'type': root_device_type,
                'dev': block_device.strip_dev(root_device_name),
                'boot_index': '1'}

    if not get_device_name(root_bdm) and root_device_name:
        root_bdm = root_bdm.copy()
        # it can happen, eg for libvirt+Xen, that the root_device_name is
        # incompatible with the disk bus. In that case fix the root_device_name
        if virt_type == 'xen':
            dev_prefix = get_dev_prefix_for_disk_bus(disk_bus)
            if not root_device_name.startswith(dev_prefix):
                letter = block_device.get_device_letter(root_device_name)
                root_device_name = '%s%s' % (dev_prefix, letter)
        root_bdm['device_name'] = root_device_name
    return get_info_from_bdm(instance, virt_type, image_meta,
                             root_bdm, {}, disk_bus)