示例#1
0
文件: images.py 项目: maorin/nova
def qemu_img_info(path, format=None):
    """Return an object containing the parsed output from qemu-img info."""
    # TODO(mikal): this code should not be referring to a libvirt specific
    # flag.
    if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
        raise exception.DiskNotFound(location=path)

    try:
        # The following check is about ploop images that reside within
        # directories and always have DiskDescriptor.xml file beside them
        if (os.path.isdir(path)
                and os.path.exists(os.path.join(path, "DiskDescriptor.xml"))):
            path = os.path.join(path, "root.hds")

        cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path)
        if format is not None:
            cmd = cmd + ('-f', format)
        # Check to see if the qemu version is >= 2.10 because if so, we need
        # to add the --force-share flag.
        if QEMU_VERSION and operator.ge(QEMU_VERSION, QEMU_VERSION_REQ_SHARED):
            cmd = cmd + ('--force-share', )
        out, err = processutils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
    except processutils.ProcessExecutionError as exp:
        if exp.exit_code == -9:
            # this means we hit prlimits, make the exception more specific
            msg = (_("qemu-img aborted by prlimits when inspecting "
                     "%(path)s : %(exp)s") % {
                         'path': path,
                         'exp': exp
                     })
        elif exp.exit_code == 1 and 'No such file or directory' in exp.stderr:
            # The os.path.exists check above can race so this is a simple
            # best effort at catching that type of failure and raising a more
            # specific error.
            raise exception.DiskNotFound(location=path)
        else:
            msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") % {
                'path': path,
                'exp': exp
            })
        raise exception.InvalidDiskInfo(reason=msg)

    if not out:
        msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") % {
            'path': path,
            'error': err
        })
        raise exception.InvalidDiskInfo(reason=msg)

    return imageutils.QemuImgInfo(out)
示例#2
0
        def get_disk_path():
            disk_paths = set()
            volume_mappings = self._get_fc_volume_mappings(connection_info)
            if not volume_mappings:
                LOG.debug(
                    "Could not find FC mappings for volume "
                    "%(conn_info)s. Rescanning disks.",
                    dict(conn_info=connection_info))
                self._diskutils.rescan_disks()
            else:
                # Because of MPIO, we may not be able to get the device name
                # from a specific mapping if the disk was accessed through
                # an other HBA at that moment. In that case, the device name
                # will show up as an empty string.
                for mapping in volume_mappings:
                    device_name = mapping['device_name']
                    if device_name:
                        disk_paths.add(device_name)

                if disk_paths:
                    self._check_device_paths(disk_paths)
                    disk_path = list(disk_paths)[0]
                    return self._get_mounted_disk_path_by_dev_name(disk_path)

            err_msg = _("Could not find the physical disk "
                        "path for the requested volume.")
            raise exception.DiskNotFound(err_msg)
示例#3
0
def qemu_img_info(path, format=None):
    """Return an object containing the parsed output from qemu-img info."""
    # TODO(mikal): this code should not be referring to a libvirt specific
    # flag.
    if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
        raise exception.DiskNotFound(location=path)

    try:
        # The following check is about ploop images that reside within
        # directories and always have DiskDescriptor.xml file beside them
        if (os.path.isdir(path) and
            os.path.exists(os.path.join(path, "DiskDescriptor.xml"))):
            path = os.path.join(path, "root.hds")

        cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path)
        if format is not None:
            cmd = cmd + ('-f', format)
        out, err = utils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
    except processutils.ProcessExecutionError as exp:
        # this means we hit prlimits, make the exception more specific
        if exp.exit_code == -9:
            msg = (_("qemu-img aborted by prlimits when inspecting "
                    "%(path)s : %(exp)s") % {'path': path, 'exp': exp})
        else:
            msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") %
                   {'path': path, 'exp': exp})
        raise exception.InvalidDiskInfo(reason=msg)

    if not out:
        msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") %
               {'path': path, 'error': err})
        raise exception.InvalidDiskInfo(reason=msg)

    return imageutils.QemuImgInfo(out)
示例#4
0
def privileged_qemu_img_info(path, format=None, output_format='json'):
    """Return an object containing the parsed output from qemu-img info."""
    if not os.path.exists(path) and not path.startswith('rbd:'):
        raise exception.DiskNotFound(location=path)

    info = nova.privsep.qemu.privileged_qemu_img_info(path, format=format)
    return imageutils.QemuImgInfo(info, format='json')
示例#5
0
    def get_disk_resource_path(self, connection_info):
        for attempt in range(self._MAX_RESCAN_COUNT):
            disk_paths = set()

            self._diskutils.rescan_disks()
            volume_mappings = self._get_fc_volume_mappings(connection_info)

            LOG.debug(
                "Retrieved volume mappings %(vol_mappings)s "
                "for volume %(conn_info)s",
                dict(vol_mappings=volume_mappings, conn_info=connection_info))

            # Because of MPIO, we may not be able to get the device name
            # from a specific mapping if the disk was accessed through
            # an other HBA at that moment. In that case, the device name
            # will show up as an empty string.
            for mapping in volume_mappings:
                device_name = mapping['device_name']
                if device_name:
                    disk_paths.add(device_name)

            if disk_paths:
                self._check_device_paths(disk_paths)
                disk_path = list(disk_paths)[0]
                return self._get_mounted_disk_path_by_dev_name(disk_path)

        err_msg = _("Could not find the physical disk "
                    "path for the requested volume.")
        raise exception.DiskNotFound(err_msg)
示例#6
0
    def finish_revert_migration(self,
                                context,
                                instance,
                                network_info,
                                block_device_info=None,
                                power_on=True):
        LOG.debug("finish_revert_migration called", instance=instance)

        instance_name = instance.name
        self._revert_migration_files(instance_name)

        image_meta = objects.ImageMeta.from_instance(instance)
        vm_gen = self._vmops.get_image_vm_generation(instance.uuid, image_meta)

        self._block_dev_man.validate_and_update_bdi(instance, image_meta,
                                                    vm_gen, block_device_info)
        root_device = block_device_info['root_disk']

        if root_device['type'] == constants.DISK:
            root_vhd_path = self._pathutils.lookup_root_vhd_path(instance_name)
            root_device['path'] = root_vhd_path
            if not root_vhd_path:
                base_vhd_path = self._pathutils.get_instance_dir(instance_name)
                raise exception.DiskNotFound(location=base_vhd_path)

        ephemerals = block_device_info['ephemerals']
        self._check_ephemeral_disks(instance, ephemerals)

        self._vmops.create_instance(instance, network_info, root_device,
                                    block_device_info, vm_gen, image_meta)

        self._check_and_attach_config_drive(instance, vm_gen)
        self._vmops.set_boot_order(instance_name, vm_gen, block_device_info)
        if power_on:
            self._vmops.power_on(instance, network_info=network_info)
示例#7
0
def qemu_img_info(path, format=None):
    """Return an object containing the parsed output from qemu-img info."""
    # TODO(mikal): this code should not be referring to a libvirt specific
    # flag.
    # NOTE(sirp): The config option import must go here to avoid an import
    # cycle
    CONF.import_opt('images_type',
                    'nova.virt.libvirt.imagebackend',
                    group='libvirt')
    if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
        raise exception.DiskNotFound(location=path)

    try:
        cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path)
        if format is not None:
            cmd = cmd + ('-f', format)
        out, err = utils.execute(*cmd)
    except processutils.ProcessExecutionError as exp:
        msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") % {
            'path': path,
            'exp': exp
        })
        raise exception.InvalidDiskInfo(reason=msg)

    if not out:
        msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") % {
            'path': path,
            'error': err
        })
        raise exception.InvalidDiskInfo(reason=msg)

    return imageutils.QemuImgInfo(out)
示例#8
0
        def _extend():
            # Get the volume group
            vg_wrap = self._get_vg_wrap()
            # Find the disk by name
            vdisks = vg_wrap.virtual_disks
            disk_found = None
            for vdisk in vdisks:
                # Vdisk name can be either disk_name or /path/to/disk_name
                if vdisk.name.split('/')[-1] == vol_name.split('/')[-1]:
                    disk_found = vdisk
                    break

            if not disk_found:
                LOG.error('Disk %s not found during resize.',
                          vol_name,
                          instance=instance)
                raise nova_exc.DiskNotFound(location=self.vg_name + '/' +
                                            vol_name)
            self._validate_resizable(disk_found)

            # Set the new size
            disk_found.capacity = size

            # Post it to the VIOS
            vg_wrap.update()
示例#9
0
    def get_disk_resource_path(self, connection_info):
        disk_paths = self._connector.get_volume_paths(connection_info['data'])
        if not disk_paths:
            vol_id = connection_info['serial']
            err_msg = _("Could not find disk path. Volume id: %s")
            raise exception.DiskNotFound(err_msg % vol_id)

        return self._get_disk_res_path(disk_paths[0])
示例#10
0
 def _check_device_paths(self, device_paths):
     if len(device_paths) > 1:
         err_msg = _("Multiple disk paths were found: %s. This can "
                     "occur if multipath is used and MPIO is not "
                     "properly configured, thus not claiming the device "
                     "paths. This issue must be addressed urgently as "
                     "it can lead to data corruption.")
         raise exception.InvalidDevicePath(err_msg % device_paths)
     elif not device_paths:
         err_msg = _("Could not find the physical disk "
                     "path for the requested volume.")
         raise exception.DiskNotFound(err_msg)
示例#11
0
    def _get_vmdk_backed_disk_device(self, vm_ref, connection_info_data):
        # Get the vmdk file name that the VM is pointing to
        hardware_devices = vm_util.get_hardware_devices(self._session, vm_ref)

        # Get disk uuid
        disk_uuid = self._get_volume_uuid(vm_ref,
                                          connection_info_data['volume_id'])
        device = vm_util.get_vmdk_backed_disk_device(hardware_devices,
                                                     disk_uuid)
        if not device:
            raise exception.DiskNotFound(message=_("Unable to find volume"))
        return device
示例#12
0
def privileged_qemu_img_info(path, format=None, output_format=None):
    """Return an object containing the parsed output from qemu-img info."""
    # TODO(mikal): this code should not be referring to a libvirt specific
    # flag.
    if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
        raise exception.DiskNotFound(location=path)

    info = nova.privsep.qemu.privileged_qemu_img_info(
        path, format=format, qemu_version=QEMU_VERSION,
        output_format=output_format)
    if output_format:
        return imageutils.QemuImgInfo(info, format=output_format)
    else:
        return imageutils.QemuImgInfo(info)
示例#13
0
    def _get_disk_path(self, connection_info):
        share_addr = self._get_export_path(connection_info)
        disk_dir = share_addr

        if self._smbutils.is_local_share(share_addr):
            share_name = share_addr.lstrip('\\').split('\\')[1]
            disk_dir = self._smbutils.get_smb_share_path(share_name)
            if not disk_dir:
                err_msg = _("Could not find the local share path for %s.")
                raise exception.DiskNotFound(err_msg % share_addr)

        disk_name = connection_info['data']['name']
        disk_path = os.path.join(disk_dir, disk_name)
        return disk_path
示例#14
0
def unprivileged_qemu_img_info(path, format=None, output_format=None):
    """Return an object containing the parsed output from qemu-img info."""
    try:
        # The following check is about ploop images that reside within
        # directories and always have DiskDescriptor.xml file beside them
        if (os.path.isdir(path)
                and os.path.exists(os.path.join(path, "DiskDescriptor.xml"))):
            path = os.path.join(path, "root.hds")

        cmd = (
            'env',
            'LC_ALL=C',
            'LANG=C',
            'qemu-img',
            'info',
            path,
            '--force-share',
        )
        if format is not None:
            cmd = cmd + ('-f', format)
        if output_format is not None:
            cmd = cmd + ("--output=%s" % (output_format), )
        out, err = processutils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
    except processutils.ProcessExecutionError as exp:
        if exp.exit_code == -9:
            # this means we hit prlimits, make the exception more specific
            msg = (_("qemu-img aborted by prlimits when inspecting "
                     "%(path)s : %(exp)s") % {
                         'path': path,
                         'exp': exp
                     })
        elif exp.exit_code == 1 and 'No such file or directory' in exp.stderr:
            # The os.path.exists check above can race so this is a simple
            # best effort at catching that type of failure and raising a more
            # specific error.
            raise exception.DiskNotFound(location=path)
        else:
            msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") % {
                'path': path,
                'exp': exp
            })
        raise exception.InvalidDiskInfo(reason=msg)

    if not out:
        msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") % {
            'path': path,
            'error': err
        })
        raise exception.InvalidDiskInfo(reason=msg)
    return out
示例#15
0
    def finish_migration(self,
                         context,
                         migration,
                         instance,
                         disk_info,
                         network_info,
                         image_meta,
                         resize_instance=False,
                         block_device_info=None,
                         power_on=True):
        LOG.debug("finish_migration called", instance=instance)

        instance_name = instance.name

        if self._volumeops.ebs_root_in_block_devices(block_device_info):
            root_vhd_path = None
        else:
            root_vhd_path = self._pathutils.lookup_root_vhd_path(instance_name)
            if not root_vhd_path:
                raise exception.DiskNotFound(location=root_vhd_path)

            root_vhd_info = self._vhdutils.get_vhd_info(root_vhd_path)
            src_base_disk_path = root_vhd_info.get("ParentPath")
            if src_base_disk_path:
                self._check_base_disk(context, instance, root_vhd_path,
                                      src_base_disk_path)

            if resize_instance:
                new_size = instance.root_gb * units.Gi
                self._check_resize_vhd(root_vhd_path, root_vhd_info, new_size)

        eph_vhd_path = self._pathutils.lookup_ephemeral_vhd_path(instance_name)
        if resize_instance:
            new_size = instance.get('ephemeral_gb', 0) * units.Gi
            if not eph_vhd_path:
                if new_size:
                    eph_vhd_path = self._vmops.create_ephemeral_vhd(instance)
            else:
                eph_vhd_info = self._vhdutils.get_vhd_info(eph_vhd_path)
                self._check_resize_vhd(eph_vhd_path, eph_vhd_info, new_size)

        vm_gen = self._vmops.get_image_vm_generation(instance.uuid,
                                                     root_vhd_path, image_meta)
        self._vmops.create_instance(instance, network_info, block_device_info,
                                    root_vhd_path, eph_vhd_path, vm_gen)

        self._check_and_attach_config_drive(instance, vm_gen)

        if power_on:
            self._vmops.power_on(instance)
示例#16
0
    def finish_migration(self,
                         context,
                         migration,
                         instance,
                         disk_info,
                         network_info,
                         image_meta,
                         resize_instance=False,
                         block_device_info=None,
                         power_on=True):
        LOG.debug("finish_migration called", instance=instance)

        instance_name = instance.name

        vm_gen = self._vmops.get_image_vm_generation(instance.uuid, image_meta)

        self._block_dev_manager.validate_and_update_bdi(
            instance, image_meta, vm_gen, block_device_info)
        root_device = block_device_info['root_disk']

        if root_device['type'] == constants.DISK:
            root_device['path'] = self._pathutils.lookup_root_vhd_path(
                instance_name)
            if not root_device['path']:
                raise exception.DiskNotFound(
                    _("Cannot find boot VHD "
                      "file for instance: %s") % instance_name)

            root_vhd_info = self._vhdutils.get_vhd_info(root_device['path'])
            src_base_disk_path = root_vhd_info.get("ParentPath")
            if src_base_disk_path:
                self._check_base_disk(context, instance, root_device['path'],
                                      src_base_disk_path)

            if resize_instance:
                new_size = instance.root_gb * units.Gi
                self._check_resize_vhd(root_device['path'], root_vhd_info,
                                       new_size)

        ephemerals = block_device_info['ephemerals']
        self._check_ephemeral_disks(instance, ephemerals, resize_instance)

        self._vmops.create_instance(instance, network_info, root_device,
                                    block_device_info, vm_gen, image_meta)

        self._check_and_attach_config_drive(instance, vm_gen)
        self._vmops.set_boot_order(vm_gen, block_device_info, instance_name)
        if power_on:
            self._vmops.power_on(instance)
示例#17
0
    def _check_ephemeral_disks(self,
                               instance,
                               ephemerals,
                               resize_instance=False):
        instance_name = instance.name
        new_eph_gb = instance.get('ephemeral_gb', 0)

        if len(ephemerals) == 1:
            # NOTE(claudiub): Resize only if there is one ephemeral. If there
            # are more than 1, resizing them can be problematic. This behaviour
            # also exists in the libvirt driver and it has to be addressed in
            # the future.
            ephemerals[0]['size'] = new_eph_gb
        elif sum(eph['size'] for eph in ephemerals) != new_eph_gb:
            # New ephemeral size is different from the original ephemeral size
            # and there are multiple ephemerals.
            LOG.warning(_LW("Cannot resize multiple ephemeral disks for "
                            "instance."),
                        instance=instance)

        for index, eph in enumerate(ephemerals):
            eph_name = "eph%s" % index
            existing_eph_path = self._pathutils.lookup_ephemeral_vhd_path(
                instance_name, eph_name)

            if not existing_eph_path:
                eph['format'] = self._vhdutils.get_best_supported_vhd_format()
                eph['path'] = self._pathutils.get_ephemeral_vhd_path(
                    instance_name, eph['format'], eph_name)
                if not resize_instance:
                    # ephemerals should have existed.
                    raise exception.DiskNotFound(location=eph['path'])

                if eph['size']:
                    # create ephemerals
                    self._vmops.create_ephemeral_disk(instance.name, eph)
            elif eph['size'] > 0:
                # ephemerals exist. resize them.
                eph['path'] = existing_eph_path
                eph_vhd_info = self._vhdutils.get_vhd_info(eph['path'])
                self._check_resize_vhd(eph['path'], eph_vhd_info,
                                       eph['size'] * units.Gi)
            else:
                # ephemeral new size is 0, remove it.
                self._pathutils.remove(existing_eph_path)
                eph['path'] = None
示例#18
0
def qemu_img_info(path, format=None):
    """Return an object containing the parsed output from qemu-img info."""
    # TODO(mikal): this code should not be referring to a libvirt specific
    # flag.
    # NOTE(sirp): The config option import must go here to avoid an import
    # cycle
    CONF.import_opt('images_type',
                    'nova.virt.libvirt.imagebackend',
                    group='libvirt')
    if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
        msg = (_("Path does not exist %(path)s") % {'path': path})
        raise exception.InvalidDiskInfo(reason=msg)

    cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path)
    if format is not None:
        cmd = cmd + ('-f', format)
    try:
        if QEMU_IMG_LIMITS is not None:
            out, err = utils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
        else:
            out, err = utils.execute(*cmd)
    except processutils.ProcessExecutionError as exp:
        if exp.exit_code == -9:
            # this means we hit prlimits, make the exception more specific
            msg = (_("qemu-img aborted by prlimits when inspecting "
                     "%(path)s : %(exp)s") % {
                         'path': path,
                         'exp': exp
                     })
        elif exp.exit_code == 1 and 'No such file or directory' in exp.stderr:
            # The os.path.exists check above can race so this is a simple
            # best effort at catching that type of failure and raising a more
            # specific error.
            raise exception.DiskNotFound(location=path)

    if not out:
        msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") % {
            'path': path,
            'error': err
        })
        raise exception.InvalidDiskInfo(reason=msg)

    return imageutils.QemuImgInfo(out)
示例#19
0
    def _detach_volume_iscsi(self, connection_info, instance):
        """Detach volume storage to VM instance."""
        vm_ref = vm_util.get_vm_ref(self._session, instance)
        # Detach Volume from VM
        LOG.debug("_detach_volume_iscsi: %s", connection_info,
                  instance=instance)
        data = connection_info['data']

        # Discover iSCSI Target
        device_name, uuid = self._iscsi_get_target(data)
        if device_name is None:
            raise exception.StorageError(
                reason=_("Unable to find iSCSI Target"))

        # Get the vmdk file name that the VM is pointing to
        hardware_devices = vm_util.get_hardware_devices(self._session, vm_ref)
        device = vm_util.get_rdm_disk(hardware_devices, uuid)
        if device is None:
            raise exception.DiskNotFound(message=_("Unable to find volume"))
        self.detach_disk_from_vm(vm_ref, instance, device, destroy_disk=True)
        LOG.debug("Detached ISCSI: %s", connection_info, instance=instance)
示例#20
0
    def _check_ephemeral_disks(self,
                               instance,
                               ephemerals,
                               resize_instance=False):
        instance_name = instance.name
        new_eph_gb = instance.get('ephemeral_gb', 0) * units.Gi
        for index, eph in enumerate(ephemerals):
            eph_name = "eph%s" % index
            eph['path'] = self._pathutils.lookup_ephemeral_vhd_path(
                instance_name, eph_name)

            if not eph['path'] and not resize_instance:
                raise exception.DiskNotFound(
                    _("Cannot find ephemeral VHD "
                      "file for instance: %s") % instance_name)
            if resize_instance and not eph['path'] and new_eph_gb:
                eph['format'] = (
                    self._vhdutils.get_best_supported_vhd_format())
                eph['path'] = self._pathutils.get_ephemeral_vhd_path(
                    instance_name, eph['format'], eph_name)
                eph['size'] = new_eph_gb
                self._vmops._create_ephemeral_disk(instance.name, eph)
示例#21
0
        def _extend():
            # Get the volume group
            vg_wrap = self._get_vg_wrap()
            # Find the disk by name
            vdisks = vg_wrap.virtual_disks
            disk_found = None
            for vdisk in vdisks:
                if vdisk.name == vol_name:
                    disk_found = vdisk
                    break

            if not disk_found:
                LOG.error(_LE('Disk %s not found during resize.'), vol_name,
                          instance=instance)
                raise nova_exc.DiskNotFound(
                    location=self.vg_name + '/' + vol_name)

            # Set the new size
            disk_found.capacity = size

            # Post it to the VIOS
            vg_wrap.update()
示例#22
0
    def snapshot(self, context, instance, image_href, update_task_state):
        """
        Create sys vol image and upload to glance
        :param instance:
        :param image_href:
        :param update_task_state:
        :return:
        """

        if not constant.CONF.fusioncompute.fc_image_path:
            LOG.error(_("config option fc_image_path is None."))
            raise fc_exc.InvalidImageDir()

        # 0.get image service and image id
        _image_service = glance.get_remote_image_service(context, image_href)
        snapshot_image_service, image_id = _image_service

        # 1.import sys vol to nfs dir
        LOG.info(_("begin uploading sys vol to glance ..."))
        fc_vm = FC_MGR.get_vm_by_uuid(instance)
        sys_vol = self._get_sys_vol_from_vm_info(fc_vm)
        if not sys_vol:
            raise exception.DiskNotFound(_("can not find sys volume."))

        update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD)
        self._volume_ops.create_image_from_volume(self.site.volume_uri,
                                                  sys_vol, image_id)

        # 2.update image metadata
        LOG.info(_("begin update image metadata ..."))
        update_task_state(task_state=task_states.IMAGE_UPLOADING,
                          expected_state=task_states.IMAGE_PENDING_UPLOAD)

        name = snapshot_image_service.show(context, image_id).get('name')
        location = self._generate_image_location(image_id)
        metadata = self._generate_image_metadata(name, location, fc_vm,
                                                 instance)
        snapshot_image_service.update(context, image_id, metadata)
示例#23
0
def qemu_img_info(path, format=None):
    """Return an object containing the parsed output from qemu-img info."""
    # TODO(mikal): this code should not be referring to a libvirt specific
    # flag.
    if not os.path.exists(path) and CONF.libvirt.images_type != 'rbd':
        raise exception.DiskNotFound(location=path)

    try:
        cmd = ('env', 'LC_ALL=C', 'LANG=C', 'qemu-img', 'info', path)
        if format is not None:
            cmd = cmd + ('-f', format)
        out, err = utils.execute(*cmd, prlimit=QEMU_IMG_LIMITS)
    except processutils.ProcessExecutionError as exp:
        msg = (_("qemu-img failed to execute on %(path)s : %(exp)s") %
                {'path': path, 'exp': exp})
        raise exception.InvalidDiskInfo(reason=msg)

    if not out:
        msg = (_("Failed to run qemu-img info on %(path)s : %(error)s") %
               {'path': path, 'error': err})
        raise exception.InvalidDiskInfo(reason=msg)

    return imageutils.QemuImgInfo(out)
示例#24
0
    def finish_revert_migration(self,
                                context,
                                instance,
                                network_info,
                                block_device_info=None,
                                power_on=True):
        LOG.debug("finish_revert_migration called", instance=instance)

        instance_name = instance.name
        self._revert_migration_files(instance_name)

        image_meta = self._imagecache.get_image_details(context, instance)
        vm_gen = self._vmops.get_image_vm_generation(instance.uuid, image_meta)

        self._block_dev_manager.validate_and_update_bdi(
            instance, image_meta, vm_gen, block_device_info)
        root_device = block_device_info['root_disk']

        if root_device['type'] == constants.DISK:
            root_device['path'] = self._pathutils.lookup_root_vhd_path(
                instance_name)
            if not root_device['path']:
                raise exception.DiskNotFound(
                    _("Cannot find boot VHD file for instance: %s") %
                    instance_name)

        ephemerals = block_device_info['ephemerals']
        self._check_ephemeral_disks(instance, ephemerals)

        self._vmops.create_instance(instance, network_info, root_device,
                                    block_device_info, vm_gen, image_meta)

        self._check_and_attach_config_drive(instance, vm_gen)
        self._vmops.set_boot_order(vm_gen, block_device_info, instance_name)
        if power_on:
            self._vmops.power_on(instance, network_info=network_info)