On rebuild, the compute.instance.exists
notification should contain the original image metadata. In order to do this, the original system metadata associated with the instance is preserved and passed along to the rebuild_instance() in the compute manager. (Code originally from Iccha Sethi and Rick Harris.) bug 1044008 Change-Id: Ieb60a2871a2a209ef467e2b51dab375872649a18
This commit is contained in:
parent
0318efe625
commit
ce4dbbd7d5
|
@ -1292,6 +1292,7 @@ class API(base.Base):
|
|||
# layer overhaul.
|
||||
sys_metadata = self.db.instance_system_metadata_get(context,
|
||||
instance['uuid'])
|
||||
orig_sys_metadata = dict(sys_metadata)
|
||||
# Remove the old keys
|
||||
for key in sys_metadata.keys():
|
||||
if key.startswith('image_'):
|
||||
|
@ -1302,6 +1303,7 @@ class API(base.Base):
|
|||
sys_metadata['image_%s' % key] = new_value
|
||||
self.db.instance_system_metadata_update(context,
|
||||
instance['uuid'], sys_metadata, True)
|
||||
return orig_sys_metadata
|
||||
|
||||
instance = self.update(context, instance,
|
||||
task_state=task_states.REBUILDING,
|
||||
|
@ -1313,11 +1315,12 @@ class API(base.Base):
|
|||
# On a rebuild, since we're potentially changing images, we need to
|
||||
# wipe out the old image properties that we're storing as instance
|
||||
# system metadata... and copy in the properties for the new image.
|
||||
_reset_image_metadata()
|
||||
orig_sys_metadata = _reset_image_metadata()
|
||||
|
||||
self.compute_rpcapi.rebuild_instance(context, instance=instance,
|
||||
new_pass=admin_password, injected_files=files_to_inject,
|
||||
image_ref=image_href, orig_image_ref=orig_image_ref)
|
||||
image_ref=image_href, orig_image_ref=orig_image_ref,
|
||||
orig_sys_metadata=orig_sys_metadata)
|
||||
|
||||
@wrap_check_policy
|
||||
@check_instance_lock
|
||||
|
|
|
@ -213,7 +213,7 @@ def _get_image_meta(context, image_ref):
|
|||
class ComputeManager(manager.SchedulerDependentManager):
|
||||
"""Manages the running instances from creation to destruction."""
|
||||
|
||||
RPC_API_VERSION = '2.0'
|
||||
RPC_API_VERSION = '2.1'
|
||||
|
||||
def __init__(self, compute_driver=None, *args, **kwargs):
|
||||
"""Load configuration options and connect to the hypervisor."""
|
||||
|
@ -968,9 +968,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
|||
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
|
||||
@reverts_task_state
|
||||
@wrap_instance_fault
|
||||
def rebuild_instance(self, context, instance,
|
||||
orig_image_ref, image_ref,
|
||||
injected_files, new_pass):
|
||||
def rebuild_instance(self, context, instance, orig_image_ref, image_ref,
|
||||
injected_files, new_pass, orig_sys_metadata=None):
|
||||
"""Destroy and re-make this instance.
|
||||
|
||||
A 'rebuild' effectively purges all existing data from the system and
|
||||
|
@ -982,6 +981,7 @@ class ComputeManager(manager.SchedulerDependentManager):
|
|||
:param image_ref: New image_ref for rebuild
|
||||
:param injected_files: Files to inject
|
||||
:param new_pass: password to set on rebuilt instance
|
||||
:param orig_sys_metadata: instance system metadata from pre-rebuild
|
||||
"""
|
||||
context = context.elevated()
|
||||
with self._error_out_instance_on_exception(context, instance['uuid']):
|
||||
|
@ -996,7 +996,8 @@ class ComputeManager(manager.SchedulerDependentManager):
|
|||
orig_image_ref_url = utils.generate_image_url(orig_image_ref)
|
||||
extra_usage_info = {'image_ref_url': orig_image_ref_url}
|
||||
compute_utils.notify_usage_exists(context, instance,
|
||||
current_period=True, extra_usage_info=extra_usage_info)
|
||||
current_period=True, system_metadata=orig_sys_metadata,
|
||||
extra_usage_info=extra_usage_info)
|
||||
|
||||
# This message should contain the new image_ref
|
||||
extra_usage_info = {'image_name': image_meta['name']}
|
||||
|
|
|
@ -127,9 +127,10 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
|
|||
1.44 - Adds reserve_block_device_name()
|
||||
|
||||
2.0 - Remove 1.x backwards compat
|
||||
2.1 - Adds orig_sys_metadata to rebuild()
|
||||
'''
|
||||
|
||||
BASE_RPC_API_VERSION = '2.0'
|
||||
BASE_RPC_API_VERSION = '2.1'
|
||||
|
||||
def __init__(self):
|
||||
super(ComputeAPI, self).__init__(
|
||||
|
@ -332,12 +333,13 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
|
|||
topic=_compute_topic(self.topic, ctxt, None, instance))
|
||||
|
||||
def rebuild_instance(self, ctxt, instance, new_pass, injected_files,
|
||||
image_ref, orig_image_ref):
|
||||
image_ref, orig_image_ref, orig_sys_metadata):
|
||||
instance_p = jsonutils.to_primitive(instance)
|
||||
self.cast(ctxt, self.make_msg('rebuild_instance',
|
||||
instance=instance_p, new_pass=new_pass,
|
||||
injected_files=injected_files, image_ref=image_ref,
|
||||
orig_image_ref=orig_image_ref),
|
||||
orig_image_ref=orig_image_ref,
|
||||
orig_sys_metadata=orig_sys_metadata),
|
||||
topic=_compute_topic(self.topic, ctxt, None, instance))
|
||||
|
||||
def refresh_provider_fw_rules(self, ctxt, host):
|
||||
|
|
|
@ -663,14 +663,16 @@ class ComputeTestCase(BaseTestCase):
|
|||
"""Ensure instance can be rebuilt"""
|
||||
instance = jsonutils.to_primitive(self._create_fake_instance())
|
||||
image_ref = instance['image_ref']
|
||||
|
||||
sys_metadata = db.instance_system_metadata_get(self.context,
|
||||
instance['uuid'])
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
db.instance_update(self.context, instance['uuid'],
|
||||
{"task_state": task_states.REBUILDING})
|
||||
self.compute.rebuild_instance(self.context, instance,
|
||||
image_ref, image_ref,
|
||||
injected_files=[],
|
||||
new_pass="new_password")
|
||||
new_pass="new_password",
|
||||
orig_sys_metadata=sys_metadata)
|
||||
self.compute.terminate_instance(self.context, instance=instance)
|
||||
|
||||
def test_rebuild_launch_time(self):
|
||||
|
@ -1389,7 +1391,8 @@ class ComputeTestCase(BaseTestCase):
|
|||
|
||||
test_notifier.NOTIFICATIONS = []
|
||||
instance = db.instance_get_by_uuid(self.context, inst_ref['uuid'])
|
||||
|
||||
orig_sys_metadata = db.instance_system_metadata_get(self.context,
|
||||
inst_ref['uuid'])
|
||||
image_ref = instance["image_ref"]
|
||||
new_image_ref = image_ref + '-new_image_ref'
|
||||
db.instance_update(self.context, inst_ref['uuid'],
|
||||
|
@ -1405,7 +1408,8 @@ class ComputeTestCase(BaseTestCase):
|
|||
jsonutils.to_primitive(instance),
|
||||
image_ref, new_image_ref,
|
||||
injected_files=[],
|
||||
new_pass=password)
|
||||
new_pass=password,
|
||||
orig_sys_metadata=orig_sys_metadata)
|
||||
|
||||
instance = db.instance_get_by_uuid(self.context, inst_ref['uuid'])
|
||||
|
||||
|
@ -4256,7 +4260,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||
rpc.cast(self.context, topic,
|
||||
{"method": "refresh_instance_security_rules",
|
||||
"args": {'instance': jsonutils.to_primitive(instance)},
|
||||
"version": compute_rpcapi.ComputeAPI.BASE_RPC_API_VERSION})
|
||||
"version":
|
||||
compute_rpcapi.SecurityGroupAPI.BASE_RPC_API_VERSION})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.security_group_api.trigger_members_refresh(self.context, [1])
|
||||
|
@ -4284,7 +4289,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||
rpc.cast(self.context, topic,
|
||||
{"method": "refresh_instance_security_rules",
|
||||
"args": {'instance': jsonutils.to_primitive(instance)},
|
||||
"version": compute_rpcapi.ComputeAPI.BASE_RPC_API_VERSION})
|
||||
"version":
|
||||
compute_rpcapi.SecurityGroupAPI.BASE_RPC_API_VERSION})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.security_group_api.trigger_members_refresh(self.context, [1, 2])
|
||||
|
@ -4324,7 +4330,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||
rpc.cast(self.context, topic,
|
||||
{"method": "refresh_instance_security_rules",
|
||||
"args": {'instance': jsonutils.to_primitive(instance)},
|
||||
"version": compute_rpcapi.ComputeAPI.BASE_RPC_API_VERSION})
|
||||
"version":
|
||||
compute_rpcapi.SecurityGroupAPI.BASE_RPC_API_VERSION})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.security_group_api.trigger_rules_refresh(self.context, [1])
|
||||
|
@ -4344,7 +4351,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||
rpc.cast(self.context, topic,
|
||||
{"method": "refresh_instance_security_rules",
|
||||
"args": {'instance': jsonutils.to_primitive(instance)},
|
||||
"version": compute_rpcapi.ComputeAPI.BASE_RPC_API_VERSION})
|
||||
"version":
|
||||
compute_rpcapi.SecurityGroupAPI.BASE_RPC_API_VERSION})
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.security_group_api.trigger_rules_refresh(self.context, [1, 2])
|
||||
|
|
|
@ -226,7 +226,8 @@ class ComputeRpcAPITestCase(test.TestCase):
|
|||
self._test_compute_api('rebuild_instance', 'cast',
|
||||
instance=self.fake_instance, new_pass='pass',
|
||||
injected_files='files', image_ref='ref',
|
||||
orig_image_ref='orig_ref')
|
||||
orig_image_ref='orig_ref',
|
||||
orig_sys_metadata='orig_sys_metadata')
|
||||
|
||||
def test_reserve_block_device_name(self):
|
||||
self._test_compute_api('reserve_block_device_name', 'call',
|
||||
|
|
Loading…
Reference in New Issue