Example #1
0
    def extend_volume(self, volume, new_size):
        """Extend an existing volume.

        :param volume: dictionary volume reference
        :param new_size: int size in GB to extend
        :raises InvalidResults:
        """
        nfs_mount = volume.provider_location
        path = self._get_file_path(nfs_mount, volume.name)

        # Resize the image file on share to new size.
        LOG.info("Checking file for resize.")

        if not self._is_file_size_equal(path, new_size):
            LOG.info("Resizing file to %(sz)sG", {'sz': new_size})
            image_utils.resize_image(path, new_size)

        if self._is_file_size_equal(path, new_size):
            LOG.info("LUN %(id)s extended to %(size)s GB.", {
                'id': volume.id,
                'size': new_size
            })
        else:
            msg = _("Resizing image file failed.")
            LOG.error(msg)
            raise exception.InvalidResults(msg)
Example #2
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        image_utils.fetch_to_raw(context,
                                 image_service,
                                 image_id,
                                 self.local_path(volume),
                                 self.configuration.volume_dd_blocksize,
                                 size=volume['size'])

        # NOTE (leseb): Set the virtual size of the image
        # the raw conversion overwrote the destination file
        # (which had the correct size)
        # with the fetched glance image size,
        # thus the initial 'size' parameter is not honored
        # this sets the size to the one asked in the first place by the user
        # and then verify the final virtual size
        image_utils.resize_image(self.local_path(volume), volume['size'])

        data = image_utils.qemu_img_info(self.local_path(volume))
        virt_size = data.virtual_size / units.GiB
        if virt_size != volume['size']:
            raise exception.ImageUnacceptable(
                image_id=image_id,
                reason=(_("Expected volume size was %d") % volume['size'])
                + (_(" but size is now %d") % virt_size))
Example #3
0
    def extend_volume(self, volume, new_size):
        """Extend an existing volume.

        :param volume: dictionary volume reference
        :param new_size: int size in GB to extend
        """

        nfs_mount = self._get_provider_location(volume['id'])
        path = self._get_volume_path(nfs_mount, volume['name'])

        # Resize the image file on share to new size.
        LOG.debug('Checking file for resize')

        if self._is_file_size_equal(path, new_size):
            return
        else:
            LOG.info(_LI('Resizing file to %sG'), new_size)
            image_utils.resize_image(path, new_size)
            if self._is_file_size_equal(path, new_size):
                LOG.info(
                    _LI("LUN %(id)s extended to %(size)s GB.") % {
                        'id': volume['id'],
                        'size': new_size
                    })
                return
            else:
                raise exception.InvalidResults(
                    _('Resizing image file failed.'))
Example #4
0
    def test_extend_volume(self):
        (mox, drv) = self._mox, self._driver

        volume = self._simple_volume()

        volume_path = '%s/%s/volume-%s' % (
            self.TEST_MNT_POINT_BASE,
            drv._get_hash_str(self.TEST_QUOBYTE_VOLUME), self.VOLUME_UUID)

        qemu_img_info_output = """image: volume-%s
        file format: qcow2
        virtual size: 1.0G (1073741824 bytes)
        disk size: 473K
        """ % self.VOLUME_UUID

        img_info = imageutils.QemuImgInfo(qemu_img_info_output)

        mox.StubOutWithMock(drv, '_execute')
        mox.StubOutWithMock(drv, 'get_active_image_from_info')
        mox.StubOutWithMock(image_utils, 'qemu_img_info')
        mox.StubOutWithMock(image_utils, 'resize_image')

        drv.get_active_image_from_info(volume).AndReturn(volume['name'])

        image_utils.qemu_img_info(volume_path).AndReturn(img_info)

        image_utils.resize_image(volume_path, 3)

        mox.ReplayAll()

        drv.extend_volume(volume, 3)

        mox.VerifyAll()
Example #5
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume."""
        image_utils.fetch_to_raw(context,
                                 image_service,
                                 image_id,
                                 self.local_path(volume),
                                 self.configuration.volume_dd_blocksize,
                                 size=volume['size'])

        # NOTE (leseb): Set the virtual size of the image
        # the raw conversion overwrote the destination file
        # (which had the correct size)
        # with the fetched glance image size,
        # thus the initial 'size' parameter is not honored
        # this sets the size to the one asked in the first place by the user
        # and then verify the final virtual size
        image_utils.resize_image(self.local_path(volume), volume['size'])

        data = image_utils.qemu_img_info(self.local_path(volume))
        virt_size = data.virtual_size / units.Gi
        if virt_size != volume['size']:
            raise exception.ImageUnacceptable(
                image_id=image_id,
                reason=(_("Expected volume size was %d") % volume['size'])
                + (_(" but size is now %d") % virt_size))
Example #6
0
    def test_extend_volume(self):
        (mox, drv) = self._mox, self._driver

        volume = self._simple_volume()

        volume_path = '%s/%s/volume-%s' % (self.TEST_MNT_POINT_BASE,
                                           drv._get_hash_str(
                                               self.TEST_QUOBYTE_VOLUME),
                                           self.VOLUME_UUID)

        qemu_img_info_output = """image: volume-%s
        file format: qcow2
        virtual size: 1.0G (1073741824 bytes)
        disk size: 473K
        """ % self.VOLUME_UUID

        img_info = imageutils.QemuImgInfo(qemu_img_info_output)

        mox.StubOutWithMock(drv, '_execute')
        mox.StubOutWithMock(drv, 'get_active_image_from_info')
        mox.StubOutWithMock(image_utils, 'qemu_img_info')
        mox.StubOutWithMock(image_utils, 'resize_image')

        drv.get_active_image_from_info(volume).AndReturn(volume['name'])

        image_utils.qemu_img_info(volume_path).AndReturn(img_info)

        image_utils.resize_image(volume_path, 3)

        mox.ReplayAll()

        drv.extend_volume(volume, 3)

        mox.VerifyAll()
Example #7
0
    def test_copy_image_to_volume(self):
        """resize_image common case usage."""
        mox = self._mox
        drv = self._driver

        TEST_IMG_SOURCE = 'foo.img'

        volume = {'size': self.TEST_SIZE_IN_GB, 'name': TEST_IMG_SOURCE}

        def fake_local_path(volume):
            return volume['name']

        self.stubs.Set(drv, 'local_path', fake_local_path)

        mox.StubOutWithMock(image_utils, 'fetch_to_raw')
        image_utils.fetch_to_raw(None, None, None, TEST_IMG_SOURCE)

        mox.StubOutWithMock(image_utils, 'resize_image')
        image_utils.resize_image(TEST_IMG_SOURCE, self.TEST_SIZE_IN_GB)

        mox.StubOutWithMock(image_utils, 'qemu_img_info')
        data = mox_lib.MockAnything()
        data.virtual_size = 1024**3
        image_utils.qemu_img_info(TEST_IMG_SOURCE).AndReturn(data)

        mox.ReplayAll()

        drv.copy_image_to_volume(None, volume, None, None)

        mox.VerifyAll()
Example #8
0
    def extend_volume(self, volume, new_size):
        """Extend an existing volume.

        :param volume: dictionary volume reference
        :param new_size: int size in GB to extend
        """

        nfs_mount = self._get_provider_location(volume['id'])
        path = self._get_volume_path(nfs_mount, volume['name'])

        # Resize the image file on share to new size.
        LOG.debug(_('Checking file for resize'))

        if self._is_file_size_equal(path, new_size):
            return
        else:
            LOG.info(_('Resizing file to %sG'), new_size)
            image_utils.resize_image(path, new_size)
            if self._is_file_size_equal(path, new_size):
                LOG.info(_("LUN %(id)s extended to %(size)s GB.")
                         % {'id': volume['id'], 'size': new_size})
                return
            else:
                raise exception.InvalidResults(
                    _('Resizing image file failed.'))
Example #9
0
    def test_copy_image_to_volume(self):
        """resize_image common case usage."""
        mox = self._mox
        drv = self._driver

        TEST_IMG_SOURCE = 'foo.img'

        volume = {'size': self.TEST_SIZE_IN_GB, 'name': TEST_IMG_SOURCE}

        def fake_local_path(volume):
            return volume['name']

        self.stubs.Set(drv, 'local_path', fake_local_path)

        mox.StubOutWithMock(image_utils, 'fetch_to_raw')
        image_utils.fetch_to_raw(None, None, None, TEST_IMG_SOURCE)

        mox.StubOutWithMock(image_utils, 'resize_image')
        image_utils.resize_image(TEST_IMG_SOURCE, self.TEST_SIZE_IN_GB)

        mox.StubOutWithMock(image_utils, 'qemu_img_info')
        data = mox_lib.MockAnything()
        data.virtual_size = 1024 ** 3
        image_utils.qemu_img_info(TEST_IMG_SOURCE).AndReturn(data)

        mox.ReplayAll()

        drv.copy_image_to_volume(None, volume, None, None)

        mox.VerifyAll()
Example #10
0
    def extend_volume(self, volume, new_size):
        """Extend an existing volume to the new size."""
        if self._is_volume_attached(volume):
            # NOTE(kaisers): no attached extensions until #1870367 is fixed
            msg = (_("Cannot extend volume %s while it is attached.")
                   % volume['id'])
            raise exception.ExtendVolumeError(msg)

        LOG.info('Extending volume %s.', volume.id)
        extend_by = int(new_size) - volume.size
        if not self._is_share_eligible(volume.provider_location,
                                       extend_by):
            raise exception.ExtendVolumeError(reason='Insufficient space to'
                                              ' extend volume %s to %sG'
                                              % (volume.id, new_size))
        path = self.local_path(volume)
        LOG.info('Resizing file to %sG...', new_size)
        file_format = None
        admin_metadata = objects.Volume.get_by_id(
            context.get_admin_context(), volume.id).admin_metadata
        if admin_metadata and 'format' in admin_metadata:
            file_format = admin_metadata['format']
        image_utils.resize_image(path, new_size,
                                 run_as_root=self._execute_as_root,
                                 file_format=file_format)
        if file_format == 'qcow2' and not self._is_file_size_equal(
                path, new_size):
            raise exception.ExtendVolumeError(
                reason='Resizing image file failed.')
Example #11
0
    def test_copy_image_to_volume(self):
        """resize_image common case usage."""
        mox = self._mox
        drv = self._driver

        TEST_IMG_SOURCE = "foo.img"

        volume = {"size": self.TEST_SIZE_IN_GB, "name": TEST_IMG_SOURCE}

        def fake_local_path(volume):
            return volume["name"]

        self.stubs.Set(drv, "local_path", fake_local_path)

        mox.StubOutWithMock(image_utils, "fetch_to_raw")
        image_utils.fetch_to_raw(None, None, None, TEST_IMG_SOURCE, mox_lib.IgnoreArg(), size=self.TEST_SIZE_IN_GB)

        mox.StubOutWithMock(image_utils, "resize_image")
        image_utils.resize_image(TEST_IMG_SOURCE, self.TEST_SIZE_IN_GB)

        mox.StubOutWithMock(image_utils, "qemu_img_info")
        data = mox_lib.MockAnything()
        data.virtual_size = 1 * units.GiB
        image_utils.qemu_img_info(TEST_IMG_SOURCE).AndReturn(data)

        mox.ReplayAll()

        drv.copy_image_to_volume(None, volume, None, None)

        mox.VerifyAll()
Example #12
0
 def _do_extend_volume(self, volume_path, size_gb, volume_format):
     if volume_format == DISK_FORMAT_PLOOP:
         self._execute('ploop', 'resize', '-s',
                       '%dG' % size_gb,
                       os.path.join(volume_path, 'DiskDescriptor.xml'),
                       run_as_root=True)
     else:
         image_utils.resize_image(volume_path, size_gb)
         if not self._is_file_size_equal(volume_path, size_gb):
             raise exception.ExtendVolumeError(
                 reason='Resizing image file failed.')
Example #13
0
 def _do_extend_volume(self, volume_path, size_gb, volume_format):
     if volume_format == DISK_FORMAT_PLOOP:
         self._execute('ploop', 'resize', '-s',
                       '%dG' % size_gb,
                       os.path.join(volume_path, 'DiskDescriptor.xml'),
                       run_as_root=True)
     else:
         image_utils.resize_image(volume_path, size_gb)
         if not self._is_file_size_equal(volume_path, size_gb):
             raise exception.ExtendVolumeError(
                 reason='Resizing image file failed.')
Example #14
0
 def _do_extend_volume(self, volume_path, size_gb, volume_format):
     if volume_format == "parallels":
         self._execute('ploop', 'grow', '-s',
                       '%dG' % size_gb,
                       os.path.join(volume_path, 'DiskDescriptor.xml'),
                       run_as_root=True)
         volume_path = os.path.join(volume_path, PLOOP_BASE_DELTA_NAME)
     else:
         image_utils.resize_image(volume_path, size_gb)
         if not self._is_file_size_equal(volume_path, size_gb):
             raise exception.ExtendVolumeError(
                 reason='Resizing image file failed.')
Example #15
0
    def extend_volume(self, volume, size_gb):
        volume_path = self.local_path(volume)

        info = self._qemu_img_info(volume_path, volume['name'])
        backing_fmt = info.file_format

        if backing_fmt not in ['raw', 'qcow2']:
            msg = _('Unrecognized backing format: %s')
            raise exception.InvalidVolume(msg % backing_fmt)

        # qemu-img can resize both raw and qcow2 files
        image_utils.resize_image(volume_path, size_gb)
Example #16
0
    def extend_volume(self, volume, size_gb):
        volume_path = self._active_volume_path(volume)

        info = self._qemu_img_info(volume_path, volume.name)
        backing_fmt = info.file_format

        if backing_fmt not in ['raw', 'qcow2']:
            msg = _('Unrecognized backing format: %s')
            raise exception.InvalidVolume(msg % backing_fmt)

        # qemu-img can resize both raw and qcow2 files
        image_utils.resize_image(volume_path, size_gb)
Example #17
0
 def _do_extend_volume(self, volume_path, size_gb, volume_format):
     if volume_format == "parallels":
         self._execute('ploop', 'grow', '-s',
                       '%dG' % size_gb,
                       os.path.join(volume_path, 'DiskDescriptor.xml'),
                       run_as_root=True)
         volume_path = os.path.join(volume_path, PLOOP_BASE_DELTA_NAME)
     else:
         image_utils.resize_image(volume_path, size_gb)
         if not self._is_file_size_equal(volume_path, size_gb):
             raise exception.ExtendVolumeError(
                 reason='Resizing image file failed.')
Example #18
0
File: nfs.py Project: jcru/cinder
 def _resize_image_file(self, path, new_size):
     """Resize the image file on share to new size."""
     LOG.debug(_("Checking file for resize"))
     if self._is_file_size_equal(path, new_size):
         return
     else:
         LOG.info(_("Resizing file to %sG"), new_size)
         image_utils.resize_image(path, new_size)
         if self._is_file_size_equal(path, new_size):
             return
         else:
             raise exception.InvalidResults(_("Resizing image file failed."))
Example #19
0
 def _resize_volume_file(self, path, new_size):
     """Resize the image file on share to new size."""
     LOG.info(_('Resizing file to %sG'), new_size)
     try:
         image_utils.resize_image(path, new_size)
     except processutils.ProcessExecutionError as e:
         msg = (_("Failed to resize volume "
                  "%(volume_id)s, error: %(error)s") %
                {'volume_id': os.path.basename(path).split('-')[1],
                 'error': e.stderr})
         LOG.error(msg)
         raise exception.VolumeBackendAPIException(data=msg)
     return True
Example #20
0
 def _resize_volume_file(self, path, new_size):
     """Resize the image file on share to new size."""
     LOG.debug("Resizing file to %sG.", new_size)
     try:
         image_utils.resize_image(path, new_size, run_as_root=True)
     except processutils.ProcessExecutionError as e:
         msg = (_("Failed to resize volume "
                  "%(volume_id)s, error: %(error)s") %
                {'volume_id': os.path.basename(path).split('-')[1],
                 'error': e.stderr})
         LOG.error(msg)
         raise exception.VolumeBackendAPIException(data=msg)
     return True
Example #21
0
 def _resize_image_file(self, path, new_size):
     """Resize the image file on share to new size."""
     LOG.debug(_('Checking file for resize'))
     if self._is_file_size_equal(path, new_size):
         return
     else:
         LOG.info(_('Resizing file to %sG'), new_size)
         image_utils.resize_image(path, new_size)
         if self._is_file_size_equal(path, new_size):
             return
         else:
             raise exception.InvalidResults(
                 _('Resizing image file failed.'))
Example #22
0
 def extend_volume(self, volume, new_size):
     """Extend an existing volume to the new size."""
     LOG.info(_LI("Extending volume %s."), volume["id"])
     extend_by = int(new_size) - volume["size"]
     if not self._is_share_eligible(volume["provider_location"], extend_by):
         raise exception.ExtendVolumeError(
             reason="Insufficient space to" " extend volume %s to %sG" % (volume["id"], new_size)
         )
     path = self.local_path(volume)
     LOG.info(_LI("Resizing file to %sG..."), new_size)
     image_utils.resize_image(path, new_size, run_as_root=self._execute_as_root)
     if not self._is_file_size_equal(path, new_size):
         raise exception.ExtendVolumeError(reason="Resizing image file failed.")
Example #23
0
    def test_resize_image(self):
        mox = self._mox
        mox.StubOutWithMock(utils, "execute")

        TEST_IMG_SOURCE = "boobar.img"
        TEST_IMG_SIZE_IN_GB = 1

        utils.execute("qemu-img", "resize", TEST_IMG_SOURCE, "%sG" % TEST_IMG_SIZE_IN_GB, run_as_root=False)

        mox.ReplayAll()

        image_utils.resize_image(TEST_IMG_SOURCE, TEST_IMG_SIZE_IN_GB)

        mox.VerifyAll()
Example #24
0
 def _resize_image_file(self, path, new_size):
     """Resize the image file on share to new size."""
     LOG.debug('Checking file for resize')
     if self._is_file_size_equal(path, new_size):
         return
     else:
         LOG.info(_LI('Resizing file to %sG'), new_size)
         image_utils.resize_image(path, new_size,
                                  run_as_root=self._execute_as_root)
         if self._is_file_size_equal(path, new_size):
             return
         else:
             raise exception.InvalidResults(
                 _('Resizing image file failed.'))
Example #25
0
    def _resize_volume_file(self, volume, new_size):
        """Resize volume file to new size."""
        vol_path = self.local_path(volume)
        try:
            image_utils.resize_image(vol_path, new_size)
        except processutils.ProcessExecutionError as exc:
            LOG.error(_("Failed to resize volume "
                        "%(volume_id)s, error: %(error)s") %
                      {'volume_id': volume['id'],
                       'error': exc.stderr})
            raise exception.VolumeBackendAPIException(data=exc.stderr)

        data = image_utils.qemu_img_info(vol_path)
        return data.virtual_size
Example #26
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume.

        Note that cinder.volume.flows.create_volume will attempt to use
        clone_image to efficiently create volume from image when both
        source and target are backed by gpfs storage.  If that is not the
        case, this function is invoked and uses fetch_to_raw to create the
        volume.
        """
        LOG.debug('Copy image to vol %s using image_utils fetch_to_raw' %
                  volume['id'])
        image_utils.fetch_to_raw(context, image_service, image_id,
                                 self.local_path(volume))
        image_utils.resize_image(self.local_path(volume), volume['size'])
Example #27
0
    def test_extend_volume_with_failure(self):
        new_vol_size = 15
        mox = mox_lib.Mox()
        volume = test_utils.create_volume(self.context, host=CONF.host)
        volpath = os.path.join(self.volumes_path, volume['name'])

        mox.StubOutWithMock(image_utils, 'resize_image')
        image_utils.resize_image(volpath, new_vol_size).AndRaise(
            processutils.ProcessExecutionError('error'))
        mox.ReplayAll()

        self.assertRaises(exception.VolumeBackendAPIException,
                          self.driver.extend_volume, volume, new_vol_size)
        mox.VerifyAll()
Example #28
0
 def extend_volume(self, volume, new_size):
     """Extend an existing volume to the new size."""
     LOG.info(_('Extending volume %s.'), volume['id'])
     extend_by = int(new_size) - volume['size']
     if not self._is_share_eligible(volume['provider_location'], extend_by):
         raise exception.ExtendVolumeError(reason='Insufficient space to'
                                           ' extend volume %s to %sG' %
                                           (volume['id'], new_size))
     path = self.local_path(volume)
     LOG.info(_('Resizing file to %sG...'), new_size)
     image_utils.resize_image(path, new_size)
     if not self._is_file_size_equal(path, new_size):
         raise exception.ExtendVolumeError(
             reason='Resizing image file failed.')
Example #29
0
    def _resize_volume_file(self, volume, new_size):
        """Resize volume file to new size."""
        vol_path = self.local_path(volume)
        try:
            image_utils.resize_image(vol_path, new_size)
        except processutils.ProcessExecutionError as exc:
            LOG.error(_("Failed to resize volume "
                        "%(volume_id)s, error: %(error)s") %
                      {'volume_id': volume['id'],
                       'error': exc.stderr})
            raise exception.VolumeBackendAPIException(data=exc.stderr)

        data = image_utils.qemu_img_info(vol_path)
        return data.virtual_size
Example #30
0
    def test_extend_volume_with_failure(self):
        new_vol_size = 15
        mox = mox_lib.Mox()
        volume = test_utils.create_volume(self.context, host=CONF.host)
        volpath = os.path.join(self.volumes_path, volume['name'])

        mox.StubOutWithMock(image_utils, 'resize_image')
        image_utils.resize_image(volpath, new_vol_size).AndRaise(
            processutils.ProcessExecutionError('error'))
        mox.ReplayAll()

        self.assertRaises(exception.VolumeBackendAPIException,
                          self.driver.extend_volume, volume, new_vol_size)
        mox.VerifyAll()
Example #31
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        """Fetch the image from image_service and write it to the volume.

        Note that cinder.volume.flows.create_volume will attempt to use
        clone_image to efficiently create volume from image when both
        source and target are backed by gpfs storage.  If that is not the
        case, this function is invoked and uses fetch_to_raw to create the
        volume.
        """
        # Check if GPFS is mounted
        self._verify_gpfs_path_state(self.configuration.gpfs_mount_point_base)

        LOG.debug("Copy image to vol %s using image_utils fetch_to_raw" % volume["id"])
        image_utils.fetch_to_raw(context, image_service, image_id, self.local_path(volume), size=volume["size"])
        image_utils.resize_image(self.local_path(volume), volume["size"])
Example #32
0
    def extend_volume(self, volume, size_gb):
        volume_path = self.local_path(volume)

        info = self._qemu_img_info(volume_path, volume.name)
        backing_fmt = info.file_format

        if backing_fmt not in ['raw', 'qcow2']:
            msg = _('Unrecognized backing format: %s')
            raise exception.InvalidVolume(msg % backing_fmt)

        # qemu-img can resize both raw and qcow2 files
        active_path = os.path.join(
            self._get_mount_point_for_share(volume.provider_location),
            self.get_active_image_from_info(volume))
        image_utils.resize_image(active_path, size_gb)
Example #33
0
    def extend_volume(self, volume, size_gb):
        volume_path = self.local_path(volume)

        info = self._qemu_img_info(volume_path, volume.name)
        backing_fmt = info.file_format

        if backing_fmt not in ['raw', 'qcow2']:
            msg = _('Unrecognized backing format: %s')
            raise exception.InvalidVolume(msg % backing_fmt)

        # qemu-img can resize both raw and qcow2 files
        active_path = os.path.join(
            self._get_mount_point_for_share(volume.provider_location),
            self.get_active_image_from_info(volume))
        image_utils.resize_image(active_path, size_gb)
Example #34
0
    def test_resize_image(self):
        mox = self._mox
        mox.StubOutWithMock(utils, 'execute')

        TEST_IMG_SOURCE = 'boobar.img'
        TEST_IMG_SIZE_IN_GB = 1

        utils.execute('qemu-img', 'resize', TEST_IMG_SOURCE,
                      '%sG' % TEST_IMG_SIZE_IN_GB, run_as_root=False)

        mox.ReplayAll()

        image_utils.resize_image(TEST_IMG_SOURCE, TEST_IMG_SIZE_IN_GB)

        mox.VerifyAll()
Example #35
0
    def test_resize_image(self):
        mox = self._mox
        mox.StubOutWithMock(utils, 'execute')

        TEST_IMG_SOURCE = 'boobar.img'
        TEST_IMG_SIZE_IN_GB = 1

        utils.execute('qemu-img', 'resize', TEST_IMG_SOURCE,
                      '%sG' % TEST_IMG_SIZE_IN_GB, run_as_root=False)

        mox.ReplayAll()

        image_utils.resize_image(TEST_IMG_SOURCE, TEST_IMG_SIZE_IN_GB)

        mox.VerifyAll()
Example #36
0
 def extend_volume(self, volume, new_size):
     """Extend an existing volume to the new size."""
     LOG.info(_('Extending volume %s.'), volume['id'])
     extend_by = int(new_size) - volume['size']
     if not self._is_share_eligible(volume['provider_location'],
                                    extend_by):
         raise exception.ExtendVolumeError(reason='Insufficient space to'
                                           ' extend volume %s to %sG'
                                           % (volume['id'], new_size))
     path = self.local_path(volume)
     LOG.info(_('Resizing file to %sG...'), new_size)
     image_utils.resize_image(path, new_size)
     if not self._is_file_size_equal(path, new_size):
         raise exception.ExtendVolumeError(
             reason='Resizing image file failed.')
Example #37
0
    def _clone_image(self, volume, image_location, image_id):
        """Attempt to create a volume by efficiently copying image to volume.

        If both source and target are backed by gpfs storage and the source
        image is in raw format move the image to create a volume using either
        gpfs clone operation or with a file copy. If the image format is not
        raw, convert it to raw at the volume path.
        """
        # Check if GPFS is mounted
        self._verify_gpfs_path_state(self.configuration.gpfs_mount_point_base)

        cloneable_image, reason, image_path = self._is_cloneable(image_id)
        if not cloneable_image:
            LOG.debug('Image %(img)s not cloneable: %(reas)s' %
                      {'img': image_id, 'reas': reason})
            return (None, False)

        vol_path = self.local_path(volume)
        # if the image is not already a GPFS snap file make it so
        if not self._is_gpfs_parent_file(image_path):
            self._create_gpfs_snap(image_path, modebits='666')

        data = image_utils.qemu_img_info(image_path)

        # if image format is already raw either clone it or
        # copy it depending on config file settings
        if data.file_format == 'raw':
            if (self.configuration.gpfs_images_share_mode ==
                    'copy_on_write'):
                LOG.debug('Clone image to vol %s using mmclone' %
                          volume['id'])
                self._create_gpfs_copy(image_path, vol_path)
            elif self.configuration.gpfs_images_share_mode == 'copy':
                LOG.debug('Clone image to vol %s using copyfile' %
                          volume['id'])
                shutil.copyfile(image_path, vol_path)
                self._execute('chmod', '666', vol_path, run_as_root=True)

        # if image is not raw convert it to raw into vol_path destination
        else:
            LOG.debug('Clone image to vol %s using qemu convert' %
                      volume['id'])
            image_utils.convert_image(image_path, vol_path, 'raw')
            self._execute('chmod', '666', vol_path, run_as_root=True)

        image_utils.resize_image(vol_path, volume['size'])

        return {'provider_location': None}, True
Example #38
0
    def _clone_image(self, volume, image_location, image_id):
        """Attempt to create a volume by efficiently copying image to volume.

        If both source and target are backed by gpfs storage and the source
        image is in raw format move the image to create a volume using either
        gpfs clone operation or with a file copy. If the image format is not
        raw, convert it to raw at the volume path.
        """
        # Check if GPFS is mounted
        self._verify_gpfs_path_state(self.configuration.gpfs_mount_point_base)

        cloneable_image, reason, image_path = self._is_cloneable(image_id)
        if not cloneable_image:
            LOG.debug('Image %(img)s not cloneable: %(reas)s' % {
                'img': image_id,
                'reas': reason
            })
            return (None, False)

        vol_path = self.local_path(volume)
        # if the image is not already a GPFS snap file make it so
        if not self._is_gpfs_parent_file(image_path):
            self._create_gpfs_snap(image_path, modebits='666')

        data = image_utils.qemu_img_info(image_path)

        # if image format is already raw either clone it or
        # copy it depending on config file settings
        if data.file_format == 'raw':
            if (self.configuration.gpfs_images_share_mode == 'copy_on_write'):
                LOG.debug('Clone image to vol %s using mmclone' % volume['id'])
                self._create_gpfs_copy(image_path, vol_path)
            elif self.configuration.gpfs_images_share_mode == 'copy':
                LOG.debug('Clone image to vol %s using copyfile' %
                          volume['id'])
                shutil.copyfile(image_path, vol_path)
                self._execute('chmod', '666', vol_path, run_as_root=True)

        # if image is not raw convert it to raw into vol_path destination
        else:
            LOG.debug('Clone image to vol %s using qemu convert' %
                      volume['id'])
            image_utils.convert_image(image_path, vol_path, 'raw')
            self._execute('chmod', '666', vol_path, run_as_root=True)

        image_utils.resize_image(vol_path, volume['size'])

        return {'provider_location': None}, True
Example #39
0
    def _do_extend_volume(self, volume_path, size_gb, volume_name):
        info = self._qemu_img_info(volume_path, volume_name)
        fmt = info.file_format

        # Note(lpetrut): as for version 2.0, qemu-img cannot resize
        # vhd/x images. For the moment, we'll just use an intermediary
        # conversion in order to be able to do the resize.
        if fmt in (self._DISK_FORMAT_VHDX, self._DISK_FORMAT_VHD_LEGACY):
            temp_image = volume_path + ".tmp"
            image_utils.convert_image(volume_path, temp_image, self._DISK_FORMAT_RAW)
            image_utils.resize_image(temp_image, size_gb)
            image_utils.convert_image(temp_image, volume_path, fmt)
            self._delete(temp_image)
        else:
            image_utils.resize_image(volume_path, size_gb)

        if not self._is_file_size_equal(volume_path, size_gb):
            raise exception.ExtendVolumeError(reason="Resizing image file failed.")
Example #40
0
    def extend_volume(self, volume, size_gb):
        volume_path = self.local_path(volume)
        volume_filename = os.path.basename(volume_path)

        # Ensure no snapshots exist for the volume
        active_image = self.get_active_image_from_info(volume)
        if volume_filename != active_image:
            msg = _("Extend volume is only supported for this" " driver when no snapshots exist.")
            raise exception.InvalidVolume(msg)

        info = self._qemu_img_info(volume_path, volume["name"])
        backing_fmt = info.file_format

        if backing_fmt not in ["raw", "qcow2"]:
            msg = _("Unrecognized backing format: %s")
            raise exception.InvalidVolume(msg % backing_fmt)

        # qemu-img can resize both raw and qcow2 files
        image_utils.resize_image(volume_path, size_gb)
Example #41
0
    def _copy_volume_from_snapshot(self, snapshot, volume, volume_size):
        """Copy data from snapshot to destination volume.

        This is done with a qemu-img convert to raw/qcow2 from the snapshot
        qcow2.
        """

        info_path = self._local_path_volume_info(snapshot['volume'])

        # For BC compat' with version < 2 of this driver
        try:
            snap_info = self._read_info_file(info_path)
        except IOError as exc:
            if exc.errno != errno.ENOENT:
                raise
            else:
                path_to_snap_img = self.local_path(snapshot)
        else:
            vol_path = self._local_volume_dir(snapshot['volume'])

            forward_file = snap_info[snapshot['id']]
            forward_path = os.path.join(vol_path, forward_file)

            # Find the file which backs this file, which represents the point
            # when this snapshot was created.
            img_info = self._qemu_img_info(forward_path,
                                           snapshot['volume']['name'])

            path_to_snap_img = os.path.join(vol_path, img_info.backing_file)

        LOG.debug("will copy from snapshot at %s", path_to_snap_img)

        path_to_new_vol = self.local_path(volume)
        out_format = 'raw'
        image_utils.convert_image(path_to_snap_img,
                                  path_to_new_vol,
                                  out_format,
                                  run_as_root=self._execute_as_root)

        self._set_rw_permissions_for_all(path_to_new_vol)

        image_utils.resize_image(path_to_new_vol, volume_size)
Example #42
0
    def extend_volume(self, volume, size_gb):
        volume_path = self.local_path(volume)
        volume_filename = os.path.basename(volume_path)

        # Ensure no snapshots exist for the volume
        active_image = self.get_active_image_from_info(volume)
        if volume_filename != active_image:
            msg = _('Extend volume is only supported for this'
                    ' driver when no snapshots exist.')
            raise exception.InvalidVolume(msg)

        info = self._qemu_img_info(volume_path, volume['name'])
        backing_fmt = info.file_format

        if backing_fmt not in ['raw', 'qcow2']:
            msg = _('Unrecognized backing format: %s')
            raise exception.InvalidVolume(msg % backing_fmt)

        # qemu-img can resize both raw and qcow2 files
        image_utils.resize_image(volume_path, size_gb)
Example #43
0
    def _do_extend_volume(self, volume_path, size_gb, volume_name):
        info = self._qemu_img_info(volume_path, volume_name)
        fmt = info.file_format

        # Note(lpetrut): as for version 2.0, qemu-img cannot resize
        # vhd/x images. For the moment, we'll just use an intermediary
        # conversion in order to be able to do the resize.
        if fmt in (self._DISK_FORMAT_VHDX, self._DISK_FORMAT_VHD_LEGACY):
            temp_image = volume_path + '.tmp'
            image_utils.convert_image(volume_path, temp_image,
                                      self._DISK_FORMAT_RAW)
            image_utils.resize_image(temp_image, size_gb)
            image_utils.convert_image(temp_image, volume_path, fmt)
            self._delete(temp_image)
        else:
            image_utils.resize_image(volume_path, size_gb)

        if not self._is_file_size_equal(volume_path, size_gb):
            raise exception.ExtendVolumeError(
                reason='Resizing image file failed.')
Example #44
0
    def test_extend_volume(self):
        new_vol_size = 15
        mox = mox_lib.Mox()
        volume = test_utils.create_volume(self.context, host=CONF.host)
        volpath = os.path.join(self.volumes_path, volume['name'])

        qemu_img_info_output = """image: %s
        file format: raw
        virtual size: %sG (%s bytes)
        backing file: %s
        """ % (volume['name'], new_vol_size, new_vol_size * units.GiB, volpath)
        mox.StubOutWithMock(image_utils, 'resize_image')
        image_utils.resize_image(volpath, new_vol_size)

        mox.StubOutWithMock(image_utils, 'qemu_img_info')
        img_info = imageutils.QemuImgInfo(qemu_img_info_output)
        image_utils.qemu_img_info(volpath).AndReturn(img_info)
        mox.ReplayAll()

        self.driver.extend_volume(volume, new_vol_size)
        mox.VerifyAll()
Example #45
0
    def test_extend_volume(self):
        new_vol_size = 15
        mox = mox_lib.Mox()
        volume = test_utils.create_volume(self.context, host=CONF.host)
        volpath = os.path.join(self.volumes_path, volume['name'])

        qemu_img_info_output = """image: %s
        file format: raw
        virtual size: %sG (%s bytes)
        backing file: %s
        """ % (volume['name'], new_vol_size, new_vol_size * units.GiB, volpath)
        mox.StubOutWithMock(image_utils, 'resize_image')
        image_utils.resize_image(volpath, new_vol_size)

        mox.StubOutWithMock(image_utils, 'qemu_img_info')
        img_info = imageutils.QemuImgInfo(qemu_img_info_output)
        image_utils.qemu_img_info(volpath).AndReturn(img_info)
        mox.ReplayAll()

        self.driver.extend_volume(volume, new_vol_size)
        mox.VerifyAll()
Example #46
0
    def extend_volume(self, volume, size_gb):
        if self._is_volume_attached(volume):
            # NOTE(kaisers): no attached extensions until #1870367 is fixed
            msg = (_("Cannot extend volume %s while it is attached.") %
                   volume['id'])
            raise exception.ExtendVolumeError(msg)

        volume_path = self.local_path(volume)

        info = self._qemu_img_info(volume_path, volume.name)
        backing_fmt = info.file_format

        if backing_fmt not in ['raw', 'qcow2']:
            msg = _('Unrecognized backing format: %s')
            raise exception.InvalidVolume(msg % backing_fmt)

        # qemu-img can resize both raw and qcow2 files
        active_path = os.path.join(
            self._get_mount_point_for_share(volume.provider_location),
            self.get_active_image_from_info(volume))
        image_utils.resize_image(active_path, size_gb)
Example #47
0
    def extend_volume(self, volume, new_size):
        """Extend an existing volume to the new size."""
        if self._is_volume_attached(volume):
            # NOTE(kaisers): no attached extensions until #1870367 is fixed
            msg = (_("Cannot extend volume %s while it is attached.")
                   % volume['id'])
            raise exception.ExtendVolumeError(msg)

        LOG.info('Extending volume %s.', volume.id)
        extend_by = int(new_size) - volume.size
        if not self._is_share_eligible(volume.provider_location,
                                       extend_by):
            raise exception.ExtendVolumeError(reason='Insufficient space to'
                                              ' extend volume %s to %sG'
                                              % (volume.id, new_size))
        path = self.local_path(volume)
        LOG.info('Resizing file to %sG...', new_size)
        image_utils.resize_image(path, new_size,
                                 run_as_root=self._execute_as_root)
        if not self._is_file_size_equal(path, new_size):
            raise exception.ExtendVolumeError(
                reason='Resizing image file failed.')
Example #48
0
    def extend_volume(self, volume, new_size):
        """Extend an existing volume.

        :param volume: dictionary volume reference
        :param new_size: int size in GB to extend
        :raises: InvalidResults
        """
        nfs_mount = volume.provider_location
        path = self._get_volume_path(nfs_mount, volume.name)

        # Resize the image file on share to new size.
        LOG.debug("Checking file for resize")

        if not self._is_file_size_equal(path, new_size):
            LOG.info(_LI("Resizing file to %(sz)sG"), {'sz': new_size})
            image_utils.resize_image(path, new_size)

        if self._is_file_size_equal(path, new_size):
            LOG.info(_LI("LUN %(id)s extended to %(size)s GB."),
                     {'id': volume.id, 'size': new_size})
        else:
            raise exception.InvalidResults(_("Resizing image file failed."))
Example #49
0
    def _do_extend_volume(self, volume_path, size_gb):
        image_utils.resize_image(volume_path, size_gb)

        if not self._is_file_size_equal(volume_path, size_gb):
            raise exception.ExtendVolumeError(
                reason='Resizing image file failed.')
Example #50
0
    def _do_extend_volume(self, volume_path, size_gb):
        image_utils.resize_image(volume_path, size_gb)

        if not self._is_file_size_equal(volume_path, size_gb):
            raise exception.ExtendVolumeError(
                reason='Resizing image file failed.')
Example #51
0
        if self._discover_file_till_timeout(vol_path):
            self._set_rw_permissions(vol_path)
            self._resize_image_file(vol_path, volume['size'])
            return True
        raise exception.InvalidResults(
            _("NFS file could not be discovered."))

    def _resize_image_file(self, path, new_size):
        """Resize the image file on share to new size."""
        LOG.debug('Checking file for resize')
        if self._is_file_size_equal(path, new_size):
            return
        else:
            LOG.info(_LI('Resizing file to %sG'), new_size)
            image_utils.resize_image(path, new_size,
                                     run_as_root=self._execute_as_root)
            if self._is_file_size_equal(path, new_size):
                return
            else:
                raise exception.InvalidResults(
                    _('Resizing image file failed.'))

    def _is_file_size_equal(self, path, size):
        """Checks if file size at path is equal to size."""
        data = image_utils.qemu_img_info(path,
                                         run_as_root=self._execute_as_root)
        virt_size = data.virtual_size / units.Gi
        if virt_size == size:
            return True
        else:
            return False