Update vm_mode when rebuilding instance with new image
Rebuilds can be made with a totally different image than what the instance was originally built with. If an image change also changes from HVM to PV mode, then vm_mode needs to updated on the instance as well. This also applies to os_type, architecture and auto_disk_config. Change-Id: I82f4580f0aab30dd3c1fa4cfc0ca76cc81d487e4 Closes-bug: 1296818
This commit is contained in:
@@ -2100,6 +2100,7 @@ class API(base.Base):
|
||||
files_to_inject = files_to_inject or []
|
||||
metadata = kwargs.get('metadata', {})
|
||||
preserve_ephemeral = kwargs.get('preserve_ephemeral', False)
|
||||
auto_disk_config = kwargs.get('auto_disk_config')
|
||||
|
||||
image_id, image = self._get_image(context, image_href)
|
||||
self._check_auto_disk_config(image=image, **kwargs)
|
||||
@@ -2137,6 +2138,12 @@ class API(base.Base):
|
||||
instance.save()
|
||||
return orig_sys_metadata
|
||||
|
||||
# Since image might have changed, we may have new values for
|
||||
# os_type, vm_mode, etc
|
||||
options_from_image = self._inherit_properties_from_image(
|
||||
image, auto_disk_config)
|
||||
instance.update(options_from_image)
|
||||
|
||||
instance.task_state = task_states.REBUILDING
|
||||
instance.image_ref = image_href
|
||||
instance.kernel_id = kernel_id or ""
|
||||
|
@@ -25,6 +25,7 @@ from nova.compute import flavors
|
||||
from nova.compute import instance_actions
|
||||
from nova.compute import task_states
|
||||
from nova.compute import utils as compute_utils
|
||||
from nova.compute import vm_mode
|
||||
from nova.compute import vm_states
|
||||
from nova import context
|
||||
from nova import db
|
||||
@@ -1757,6 +1758,65 @@ class _ComputeAPIUnitTestMixIn(object):
|
||||
None, image, flavor, {}, [])
|
||||
self.assertNotEqual(orig_system_metadata, instance.system_metadata)
|
||||
|
||||
@mock.patch.object(instance_obj.Instance, 'save')
|
||||
@mock.patch.object(instance_obj.Instance, 'get_flavor')
|
||||
@mock.patch.object(block_device_obj.BlockDeviceMappingList,
|
||||
'get_by_instance_uuid')
|
||||
@mock.patch.object(compute_api.API, '_get_image')
|
||||
@mock.patch.object(compute_api.API, '_check_auto_disk_config')
|
||||
@mock.patch.object(compute_api.API, '_checks_for_create_and_rebuild')
|
||||
@mock.patch.object(compute_api.API, '_record_action_start')
|
||||
def test_rebuild_change_image(self, _record_action_start,
|
||||
_checks_for_create_and_rebuild, _check_auto_disk_config,
|
||||
_get_image, bdm_get_by_instance_uuid, get_flavor, instance_save):
|
||||
orig_system_metadata = {}
|
||||
get_flavor.return_value = test_flavor.fake_flavor
|
||||
orig_image_href = 'orig_image'
|
||||
orig_image = {"min_ram": 10, "min_disk": 1,
|
||||
"properties": {'architecture': 'x86_64',
|
||||
'vm_mode': 'hvm'}}
|
||||
new_image_href = 'new_image'
|
||||
new_image = {"min_ram": 10, "min_disk": 1,
|
||||
"properties": {'architecture': 'x86_64',
|
||||
'vm_mode': 'xen'}}
|
||||
admin_pass = ''
|
||||
files_to_inject = []
|
||||
bdms = []
|
||||
|
||||
instance = fake_instance.fake_instance_obj(self.context,
|
||||
vm_state=vm_states.ACTIVE, cell_name='fake-cell',
|
||||
launched_at=timeutils.utcnow(),
|
||||
system_metadata=orig_system_metadata,
|
||||
expected_attrs=['system_metadata'],
|
||||
image_ref=orig_image_href,
|
||||
vm_mode=vm_mode.HVM)
|
||||
flavor = instance.get_flavor()
|
||||
|
||||
def get_image(context, image_href):
|
||||
if image_href == new_image_href:
|
||||
return (None, new_image)
|
||||
if image_href == orig_image_href:
|
||||
return (None, orig_image)
|
||||
_get_image.side_effect = get_image
|
||||
bdm_get_by_instance_uuid.return_value = bdms
|
||||
|
||||
with mock.patch.object(self.compute_api.compute_rpcapi,
|
||||
'rebuild_instance') as rebuild_instance:
|
||||
self.compute_api.rebuild(self.context, instance, new_image_href,
|
||||
admin_pass, files_to_inject)
|
||||
|
||||
rebuild_instance.assert_called_once_with(self.context,
|
||||
instance=instance, new_pass=admin_pass,
|
||||
injected_files=files_to_inject, image_ref=new_image_href,
|
||||
orig_image_ref=orig_image_href,
|
||||
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
||||
preserve_ephemeral=False, kwargs={})
|
||||
|
||||
_check_auto_disk_config.assert_called_once_with(image=new_image)
|
||||
_checks_for_create_and_rebuild.assert_called_once_with(self.context,
|
||||
None, new_image, flavor, {}, [])
|
||||
self.assertEqual(vm_mode.XEN, instance.vm_mode)
|
||||
|
||||
@mock.patch('nova.quota.QUOTAS.commit')
|
||||
@mock.patch('nova.quota.QUOTAS.reserve')
|
||||
@mock.patch('nova.objects.instance.Instance.save')
|
||||
|
Reference in New Issue
Block a user