Implement resize down for XenAPI
This patch implements resizing an instance to a smaller disk. It implements this by copying the VDI and running e2resize, before transferring to the new host. Change-Id: Ic901a59cb6cdb79605c70528cf85064d8335ee2f
This commit is contained in:
parent
473fb20949
commit
cfbaba3176
@ -830,10 +830,6 @@ class CannotResizeToSameSize(NovaException):
|
|||||||
message = _("When resizing, instances must change size!")
|
message = _("When resizing, instances must change size!")
|
||||||
|
|
||||||
|
|
||||||
class CannotResizeToSmallerSize(NovaException):
|
|
||||||
message = _("Resizing to a smaller size is not supported.")
|
|
||||||
|
|
||||||
|
|
||||||
class ImageTooLarge(NovaException):
|
class ImageTooLarge(NovaException):
|
||||||
message = _("Image is larger than instance type allows")
|
message = _("Image is larger than instance type allows")
|
||||||
|
|
||||||
|
@ -1568,23 +1568,6 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
|
|
||||||
self.compute.terminate_instance(context, instance['uuid'])
|
self.compute.terminate_instance(context, instance['uuid'])
|
||||||
|
|
||||||
def test_resize_down_fails(self):
|
|
||||||
"""Ensure resizing down raises and fails"""
|
|
||||||
instance = self._create_fake_instance()
|
|
||||||
context = self.context.elevated()
|
|
||||||
instance = db.instance_get_by_uuid(context, instance['uuid'])
|
|
||||||
self.compute.run_instance(self.context, instance['uuid'])
|
|
||||||
|
|
||||||
inst_type = instance_types.get_instance_type_by_name('m1.xlarge')
|
|
||||||
db.instance_update(self.context, instance['uuid'],
|
|
||||||
{'instance_type_id': inst_type['id']})
|
|
||||||
|
|
||||||
instance = db.instance_get_by_uuid(context, instance['uuid'])
|
|
||||||
self.assertRaises(exception.CannotResizeToSmallerSize,
|
|
||||||
self.compute_api.resize, context, instance, 1)
|
|
||||||
|
|
||||||
self.compute.terminate_instance(context, instance['uuid'])
|
|
||||||
|
|
||||||
def test_resize_same_size_fails(self):
|
def test_resize_same_size_fails(self):
|
||||||
"""Ensure invalid flavors raise"""
|
"""Ensure invalid flavors raise"""
|
||||||
context = self.context.elevated()
|
context = self.context.elevated()
|
||||||
|
@ -173,8 +173,9 @@ class _VirtDriverTestCase(test.TestCase):
|
|||||||
@catch_notimplementederror
|
@catch_notimplementederror
|
||||||
def test_migrate_disk_and_power_off(self):
|
def test_migrate_disk_and_power_off(self):
|
||||||
instance_ref, network_info = self._get_running_instance()
|
instance_ref, network_info = self._get_running_instance()
|
||||||
|
instance_type_ref = test_utils.get_test_instance_type()
|
||||||
self.connection.migrate_disk_and_power_off(
|
self.connection.migrate_disk_and_power_off(
|
||||||
self.ctxt, instance_ref, 'dest_host')
|
self.ctxt, instance_ref, 'dest_host', instance_type_ref)
|
||||||
|
|
||||||
@catch_notimplementederror
|
@catch_notimplementederror
|
||||||
def test_pause(self):
|
def test_pause(self):
|
||||||
|
@ -803,17 +803,20 @@ class XenAPIMigrateInstance(test.TestCase):
|
|||||||
product_version=(6, 0, 0))
|
product_version=(6, 0, 0))
|
||||||
stubs.stubout_loopingcall_start(self.stubs)
|
stubs.stubout_loopingcall_start(self.stubs)
|
||||||
conn = xenapi_conn.get_connection(False)
|
conn = xenapi_conn.get_connection(False)
|
||||||
conn._vmops.resize_instance(instance, '')
|
conn._vmops._resize_instance(instance, '')
|
||||||
self.assertEqual(called['resize'], True)
|
self.assertEqual(called['resize'], True)
|
||||||
|
|
||||||
def test_migrate_disk_and_power_off(self):
|
def test_migrate_disk_and_power_off(self):
|
||||||
instance = db.instance_create(self.context, self.instance_values)
|
instance = db.instance_create(self.context, self.instance_values)
|
||||||
|
instance_type = db.instance_type_get_by_name(self.context, 'm1.large')
|
||||||
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
|
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
|
||||||
conn = xenapi_conn.get_connection(False)
|
conn = xenapi_conn.get_connection(False)
|
||||||
conn.migrate_disk_and_power_off(self.context, instance, '127.0.0.1')
|
conn.migrate_disk_and_power_off(self.context, instance,
|
||||||
|
'127.0.0.1', instance_type)
|
||||||
|
|
||||||
def test_migrate_disk_and_power_off_passes_exceptions(self):
|
def test_migrate_disk_and_power_off_passes_exceptions(self):
|
||||||
instance = db.instance_create(self.context, self.instance_values)
|
instance = db.instance_create(self.context, self.instance_values)
|
||||||
|
instance_type = db.instance_type_get_by_name(self.context, 'm1.large')
|
||||||
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
|
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
|
||||||
|
|
||||||
def fake_raise(*args, **kwargs):
|
def fake_raise(*args, **kwargs):
|
||||||
@ -823,7 +826,7 @@ class XenAPIMigrateInstance(test.TestCase):
|
|||||||
conn = xenapi_conn.get_connection(False)
|
conn = xenapi_conn.get_connection(False)
|
||||||
self.assertRaises(exception.MigrationError,
|
self.assertRaises(exception.MigrationError,
|
||||||
conn.migrate_disk_and_power_off,
|
conn.migrate_disk_and_power_off,
|
||||||
self.context, instance, '127.0.0.1')
|
self.context, instance, '127.0.0.1', instance_type)
|
||||||
|
|
||||||
def test_revert_migrate(self):
|
def test_revert_migrate(self):
|
||||||
instance = db.instance_create(self.context, self.instance_values)
|
instance = db.instance_create(self.context, self.instance_values)
|
||||||
@ -1163,12 +1166,10 @@ class XenAPIAutoDiskConfigTestCase(test.TestCase):
|
|||||||
def assertIsPartitionCalled(self, called):
|
def assertIsPartitionCalled(self, called):
|
||||||
marker = {"partition_called": False}
|
marker = {"partition_called": False}
|
||||||
|
|
||||||
@classmethod
|
def fake_resize_part_and_fs(dev, start, old, new):
|
||||||
def fake_resize_partition_fs(cls, dev_path, partition_path):
|
|
||||||
marker["partition_called"] = True
|
marker["partition_called"] = True
|
||||||
|
self.stubs.Set(vm_utils, "_resize_part_and_fs",
|
||||||
self.stubs.Set(vm_utils.VMHelper, "_resize_partition_and_fs",
|
fake_resize_part_and_fs)
|
||||||
fake_resize_partition_fs)
|
|
||||||
|
|
||||||
instance = db.instance_create(self.context, self.instance_values)
|
instance = db.instance_create(self.context, self.instance_values)
|
||||||
disk_image_type = vm_utils.ImageType.DISK_VHD
|
disk_image_type = vm_utils.ImageType.DISK_VHD
|
||||||
@ -1193,12 +1194,10 @@ class XenAPIAutoDiskConfigTestCase(test.TestCase):
|
|||||||
"""Should not partition unless fail safes pass"""
|
"""Should not partition unless fail safes pass"""
|
||||||
self.instance_values['auto_disk_config'] = True
|
self.instance_values['auto_disk_config'] = True
|
||||||
|
|
||||||
@classmethod
|
def fake_get_partitions(dev):
|
||||||
def fake_resize_partition_allowed(cls, dev_path, partition_path):
|
return [(1, 0, 100, 'ext4'), (2, 100, 200, 'ext4')]
|
||||||
return False
|
self.stubs.Set(vm_utils, "_get_partitions",
|
||||||
|
fake_get_partitions)
|
||||||
self.stubs.Set(vm_utils.VMHelper, "_resize_partition_allowed",
|
|
||||||
fake_resize_partition_allowed)
|
|
||||||
|
|
||||||
self.assertIsPartitionCalled(False)
|
self.assertIsPartitionCalled(False)
|
||||||
|
|
||||||
@ -1209,10 +1208,9 @@ class XenAPIAutoDiskConfigTestCase(test.TestCase):
|
|||||||
"""
|
"""
|
||||||
self.instance_values['auto_disk_config'] = True
|
self.instance_values['auto_disk_config'] = True
|
||||||
|
|
||||||
@classmethod
|
def fake_get_partitions(dev):
|
||||||
def fake_resize_partition_allowed(cls, dev_path, partition_path):
|
return [(1, 0, 100, 'ext4')]
|
||||||
return True
|
self.stubs.Set(vm_utils, "_get_partitions",
|
||||||
self.stubs.Set(vm_utils.VMHelper, "_resize_partition_allowed",
|
fake_get_partitions)
|
||||||
fake_resize_partition_allowed)
|
|
||||||
|
|
||||||
self.assertIsPartitionCalled(True)
|
self.assertIsPartitionCalled(True)
|
||||||
|
Loading…
Reference in New Issue
Block a user