Merge "NFS drivers don't honor vm size with volume from an image"
This commit is contained in:
commit
6e79a8aff2
@ -191,6 +191,12 @@ def convert_image(source, dest, out_format):
|
||||
utils.execute(*cmd, run_as_root=True)
|
||||
|
||||
|
||||
def resize_image(source, size):
|
||||
"""Changes the virtual size of the image."""
|
||||
cmd = ('qemu-img', 'resize', source, '%sG' % size)
|
||||
utils.execute(*cmd, run_as_root=False)
|
||||
|
||||
|
||||
def fetch(context, image_service, image_id, path, _user_id, _project_id):
|
||||
# TODO(vish): Improve context handling and add owner and auth data
|
||||
# when it is added to glance. Right now there is no
|
||||
|
45
cinder/tests/test_image_utils.py
Normal file
45
cinder/tests/test_image_utils.py
Normal file
@ -0,0 +1,45 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2013 eNovance , Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Unit tests for image utils."""
|
||||
|
||||
from cinder.image import image_utils
|
||||
from cinder import test
|
||||
from cinder import utils
|
||||
import mox
|
||||
|
||||
|
||||
class TestUtils(test.TestCase):
|
||||
def setUp(self):
|
||||
super(TestUtils, self).setUp()
|
||||
self._mox = mox.Mox()
|
||||
self.addCleanup(self._mox.UnsetStubs)
|
||||
|
||||
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()
|
@ -33,6 +33,8 @@ from cinder.exception import ProcessExecutionError
|
||||
from cinder import test
|
||||
from cinder import units
|
||||
|
||||
from cinder.image import image_utils
|
||||
|
||||
from cinder.volume import configuration as conf
|
||||
from cinder.volume.drivers import nfs
|
||||
|
||||
@ -169,6 +171,37 @@ class NfsDriverTestCase(test.TestCase):
|
||||
|
||||
mox.VerifyAll()
|
||||
|
||||
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()
|
||||
|
||||
def test_mount_nfs_should_suppress_already_mounted_error(self):
|
||||
"""_mount_nfs should suppress already mounted error if ensure=True
|
||||
"""
|
||||
|
@ -125,6 +125,23 @@ class RemoteFsDriver(driver.VolumeDriver):
|
||||
image_id,
|
||||
self.local_path(volume))
|
||||
|
||||
# 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))
|
||||
|
||||
def copy_volume_to_image(self, context, volume, image_service, image_meta):
|
||||
"""Copy the volume to the specified image."""
|
||||
image_utils.upload_volume(context,
|
||||
|
Loading…
Reference in New Issue
Block a user