Merge "Fixes Hyper-V snapshot spawning issue"
This commit is contained in:
commit
5f3dd2ea04
|
@ -178,6 +178,8 @@ class HyperVAPITestCase(test.NoDBTestCase):
|
|||
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'get_vhd_parent_path')
|
||||
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'get_vhd_info')
|
||||
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'resize_vhd')
|
||||
self._mox.StubOutWithMock(vhdutils.VHDUtils,
|
||||
'get_internal_vhd_size_by_file_size')
|
||||
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'validate_vhd')
|
||||
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'get_vhd_format')
|
||||
self._mox.StubOutWithMock(vhdutils.VHDUtils, 'create_dynamic_vhd')
|
||||
|
@ -965,6 +967,11 @@ class HyperVAPITestCase(test.NoDBTestCase):
|
|||
m.AndReturn({'MaxInternalSize': 1024})
|
||||
|
||||
fake.PathUtils.copyfile(mox.IsA(str), mox.IsA(str))
|
||||
|
||||
m = vhdutils.VHDUtils.get_internal_vhd_size_by_file_size(
|
||||
mox.IsA(str), mox.IsA(object))
|
||||
m.AndReturn(1025)
|
||||
|
||||
vhdutils.VHDUtils.resize_vhd(mox.IsA(str), mox.IsA(object))
|
||||
|
||||
def _setup_spawn_instance_mocks(self, cow, setup_vif_mocks_func=None,
|
||||
|
@ -1002,6 +1009,9 @@ class HyperVAPITestCase(test.NoDBTestCase):
|
|||
m = vhdutils.VHDUtils.get_vhd_info(mox.IsA(str))
|
||||
m.AndReturn({'MaxInternalSize': 1024, 'FileSize': 1024,
|
||||
'Type': 2})
|
||||
m = vhdutils.VHDUtils.get_internal_vhd_size_by_file_size(
|
||||
mox.IsA(str), mox.IsA(object))
|
||||
m.AndReturn(1025)
|
||||
vhdutils.VHDUtils.resize_vhd(mox.IsA(str), mox.IsA(object))
|
||||
|
||||
self._setup_check_admin_permissions_mocks(
|
||||
|
@ -1432,6 +1442,9 @@ class HyperVAPITestCase(test.NoDBTestCase):
|
|||
m = vhdutils.VHDUtils.get_vhd_info(mox.IsA(str))
|
||||
m.AndReturn({'ParentPath': fake_parent_vhd_path,
|
||||
'MaxInternalSize': 1})
|
||||
m = vhdutils.VHDUtils.get_internal_vhd_size_by_file_size(
|
||||
mox.IsA(str), mox.IsA(object))
|
||||
m.AndReturn(1025)
|
||||
|
||||
vhdutils.VHDUtils.reconnect_parent_vhd(mox.IsA(str), mox.IsA(str))
|
||||
|
||||
|
|
|
@ -60,8 +60,8 @@ class VHDUtilsTestCase(test.NoDBTestCase):
|
|||
vhdutil.get_vhd_info = mock.MagicMock()
|
||||
vhdutil.get_vhd_info.return_value = {'Type': constants.VHD_TYPE_FIXED}
|
||||
|
||||
real_size = vhdutil._get_internal_vhd_size_by_file_size(None,
|
||||
root_vhd_size)
|
||||
real_size = vhdutil.get_internal_vhd_size_by_file_size(None,
|
||||
root_vhd_size)
|
||||
expected_vhd_size = 1 * 1024 ** 3 - 512
|
||||
self.assertEqual(expected_vhd_size, real_size)
|
||||
|
||||
|
@ -74,8 +74,8 @@ class VHDUtilsTestCase(test.NoDBTestCase):
|
|||
vhdutil._get_vhd_dynamic_blk_size = mock.MagicMock()
|
||||
vhdutil._get_vhd_dynamic_blk_size.return_value = 2097152
|
||||
|
||||
real_size = vhdutil._get_internal_vhd_size_by_file_size(None,
|
||||
root_vhd_size)
|
||||
real_size = vhdutil.get_internal_vhd_size_by_file_size(None,
|
||||
root_vhd_size)
|
||||
expected_vhd_size = 20 * 1024 ** 3 - 43008
|
||||
self.assertEqual(expected_vhd_size, real_size)
|
||||
|
||||
|
@ -86,7 +86,7 @@ class VHDUtilsTestCase(test.NoDBTestCase):
|
|||
vhdutil.get_vhd_info.return_value = {'Type': 5}
|
||||
|
||||
self.assertRaises(vmutils.HyperVException,
|
||||
vhdutil._get_internal_vhd_size_by_file_size,
|
||||
vhdutil.get_internal_vhd_size_by_file_size,
|
||||
None, root_vhd_size)
|
||||
|
||||
def test_get_vhd_format_vhdx(self):
|
||||
|
|
|
@ -27,6 +27,7 @@ from nova.openstack.common.gettextutils import _
|
|||
from nova.openstack.common import log as logging
|
||||
from nova import utils
|
||||
from nova.virt.hyperv import utilsfactory
|
||||
from nova.virt.hyperv import vhdutilsv2
|
||||
from nova.virt.hyperv import vmutils
|
||||
from nova.virt import images
|
||||
|
||||
|
@ -65,14 +66,23 @@ class ImageCache(object):
|
|||
root_vhd_size_gb = self._get_root_vhd_size_gb(instance)
|
||||
root_vhd_size = root_vhd_size_gb * 1024 ** 3
|
||||
|
||||
if root_vhd_size < vhd_size:
|
||||
# NOTE(lpetrut): Checking the namespace is needed as the following
|
||||
# method is not yet implemented in the vhdutilsv2 module.
|
||||
if not isinstance(self._vhdutils, vhdutilsv2.VHDUtilsV2):
|
||||
root_vhd_internal_size = (
|
||||
self._vhdutils.get_internal_vhd_size_by_file_size(
|
||||
vhd_path, root_vhd_size))
|
||||
else:
|
||||
root_vhd_internal_size = root_vhd_size
|
||||
|
||||
if root_vhd_internal_size < vhd_size:
|
||||
raise vmutils.HyperVException(
|
||||
_("Cannot resize the image to a size smaller than the VHD "
|
||||
"max. internal size: %(vhd_size)s. Requested disk size: "
|
||||
"%(root_vhd_size)s") %
|
||||
{'vhd_size': vhd_size, 'root_vhd_size': root_vhd_size}
|
||||
)
|
||||
if root_vhd_size > vhd_size:
|
||||
if root_vhd_internal_size > vhd_size:
|
||||
path_parts = os.path.splitext(vhd_path)
|
||||
resized_vhd_path = '%s_%s%s' % (path_parts[0],
|
||||
root_vhd_size_gb,
|
||||
|
|
|
@ -99,7 +99,7 @@ class VHDUtils(object):
|
|||
|
||||
def resize_vhd(self, vhd_path, new_max_size, is_file_max_size=True):
|
||||
if is_file_max_size:
|
||||
new_internal_max_size = self._get_internal_vhd_size_by_file_size(
|
||||
new_internal_max_size = self.get_internal_vhd_size_by_file_size(
|
||||
vhd_path, new_max_size)
|
||||
else:
|
||||
new_internal_max_size = new_max_size
|
||||
|
@ -110,8 +110,7 @@ class VHDUtils(object):
|
|||
Path=vhd_path, MaxInternalSize=new_internal_max_size)
|
||||
self._vmutils.check_ret_val(ret_val, job_path)
|
||||
|
||||
def _get_internal_vhd_size_by_file_size(self, vhd_path,
|
||||
new_vhd_file_size):
|
||||
def get_internal_vhd_size_by_file_size(self, vhd_path, new_vhd_file_size):
|
||||
"""Fixed VHD size = Data Block size + 512 bytes
|
||||
Dynamic_VHD_size = Dynamic Disk Header
|
||||
+ Copy of hard disk footer
|
||||
|
|
|
@ -36,6 +36,7 @@ from nova.virt import configdrive
|
|||
from nova.virt.hyperv import constants
|
||||
from nova.virt.hyperv import imagecache
|
||||
from nova.virt.hyperv import utilsfactory
|
||||
from nova.virt.hyperv import vhdutilsv2
|
||||
from nova.virt.hyperv import vmutils
|
||||
from nova.virt.hyperv import volumeops
|
||||
|
||||
|
@ -157,13 +158,22 @@ class VMOps(object):
|
|||
self._pathutils.copyfile(base_vhd_path, root_vhd_path)
|
||||
|
||||
base_vhd_info = self._vhdutils.get_vhd_info(base_vhd_path)
|
||||
base_vhd_size = base_vhd_info['FileSize']
|
||||
base_vhd_size = base_vhd_info['MaxInternalSize']
|
||||
root_vhd_size = instance['root_gb'] * 1024 ** 3
|
||||
|
||||
if root_vhd_size < base_vhd_size:
|
||||
# NOTE(lpetrut): Checking the namespace is needed as the
|
||||
# following method is not yet implemented in vhdutilsv2.
|
||||
if not isinstance(self._vhdutils, vhdutilsv2.VHDUtilsV2):
|
||||
root_vhd_internal_size = (
|
||||
self._vhdutils.get_internal_vhd_size_by_file_size(
|
||||
root_vhd_path, root_vhd_size))
|
||||
else:
|
||||
root_vhd_internal_size = root_vhd_size
|
||||
|
||||
if root_vhd_internal_size < base_vhd_size:
|
||||
raise vmutils.HyperVException(_("Cannot resize a VHD to a "
|
||||
"smaller size"))
|
||||
elif root_vhd_size > base_vhd_size:
|
||||
elif root_vhd_internal_size > base_vhd_size:
|
||||
LOG.debug(_("Resizing VHD %(root_vhd_path)s to new "
|
||||
"size %(root_vhd_size)s"),
|
||||
{'base_vhd_path': base_vhd_path,
|
||||
|
|
Loading…
Reference in New Issue