summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-02-03 13:14:42 +0000
committerGerrit Code Review <review@openstack.org>2013-02-03 13:14:42 +0000
commit5d490117cd31b5e11a5746d5124fb343f0749c02 (patch)
treec81442b5eb77f8b51ebb71c12e0b7259b547fb84
parent2667e8fe2128c42c69bfb6163e96ad24f8151684 (diff)
parentacc30a869fa5b6c231fac713014f60216244672e (diff)
downloadnova-5d490117cd31b5e11a5746d5124fb343f0749c02.tar.gz
nova-5d490117cd31b5e11a5746d5124fb343f0749c02.tar.xz
nova-5d490117cd31b5e11a5746d5124fb343f0749c02.zip
Merge "Make system_metadata update in place"
-rw-r--r--nova/db/sqlalchemy/api.py20
-rw-r--r--nova/tests/test_db_api.py29
-rw-r--r--nova/utils.py3
3 files changed, 43 insertions, 9 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 393e1a03c..e7a871345 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1811,9 +1811,10 @@ def instance_update_and_get_original(context, instance_uuid, values):
# NOTE(danms): This updates the instance's metadata list in-place and in
# the database to avoid stale data and refresh issues. It assumes the
# delete=True behavior of instance_metadata_update(...)
-def _instance_metadata_update_in_place(context, instance, metadata, session):
+def _instance_metadata_update_in_place(context, instance, metadata_type, model,
+ metadata, session):
to_delete = []
- for keyvalue in instance['metadata']:
+ for keyvalue in instance[metadata_type]:
key = keyvalue['key']
if key in metadata:
keyvalue['value'] = metadata.pop(key)
@@ -1821,15 +1822,14 @@ def _instance_metadata_update_in_place(context, instance, metadata, session):
to_delete.append(keyvalue)
for condemned in to_delete:
- instance['metadata'].remove(condemned)
condemned.soft_delete(session=session)
for key, value in metadata.iteritems():
- newitem = models.InstanceMetadata()
+ newitem = model()
newitem.update({'key': key, 'value': value,
'instance_uuid': instance['uuid']})
session.add(newitem)
- instance['metadata'].append(newitem)
+ instance[metadata_type].append(newitem)
def _instance_update(context, instance_uuid, values, copy_old_instance=False):
@@ -1877,14 +1877,18 @@ def _instance_update(context, instance_uuid, values, copy_old_instance=False):
metadata = values.get('metadata')
if metadata is not None:
_instance_metadata_update_in_place(context, instance_ref,
+ 'metadata',
+ models.InstanceMetadata,
values.pop('metadata'),
session)
system_metadata = values.get('system_metadata')
if system_metadata is not None:
- instance_system_metadata_update(
- context, instance_ref['uuid'], values.pop('system_metadata'),
- delete=True, session=session)
+ _instance_metadata_update_in_place(context, instance_ref,
+ 'system_metadata',
+ models.InstanceSystemMetadata,
+ values.pop('system_metadata'),
+ session)
instance_ref.update(values)
instance_ref.save(session=session)
diff --git a/nova/tests/test_db_api.py b/nova/tests/test_db_api.py
index 684f9fded..db1f16440 100644
--- a/nova/tests/test_db_api.py
+++ b/nova/tests/test_db_api.py
@@ -29,6 +29,7 @@ from nova.openstack.common import cfg
from nova.openstack.common import timeutils
from nova import test
from nova.tests import matchers
+from nova import utils
CONF = cfg.CONF
@@ -467,6 +468,34 @@ class DbApiTestCase(test.TestCase):
self.assertEquals(spec, old_ref['extra_specs'])
self.assertEquals(spec, new_ref['extra_specs'])
+ def _test_instance_update_updates_metadata(self, metadata_type):
+ ctxt = context.get_admin_context()
+
+ instance = db.instance_create(ctxt, {})
+
+ def set_and_check(meta):
+ inst = db.instance_update(ctxt, instance['uuid'],
+ {metadata_type: dict(meta)})
+ _meta = utils.metadata_to_dict(inst[metadata_type])
+ self.assertEqual(meta, _meta)
+
+ meta = {'speed': '88', 'units': 'MPH'}
+ set_and_check(meta)
+
+ meta['gigawatts'] = '1.21'
+ set_and_check(meta)
+
+ del meta['gigawatts']
+ set_and_check(meta)
+
+ def test_instance_update_updates_system_metadata(self):
+ # Ensure that system_metadata is updated during instance_update
+ self._test_instance_update_updates_metadata('system_metadata')
+
+ def test_instance_update_updates_metadata(self):
+ # Ensure that metadata is updated during instance_update
+ self._test_instance_update_updates_metadata('metadata')
+
def test_instance_fault_create(self):
# Ensure we can create an instance fault.
ctxt = context.get_admin_context()
diff --git a/nova/utils.py b/nova/utils.py
index 83bf55583..cb75709ad 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -1291,5 +1291,6 @@ def last_bytes(file_like_object, num):
def metadata_to_dict(metadata):
result = {}
for item in metadata:
- result[item['key']] = item['value']
+ if not item.get('deleted'):
+ result[item['key']] = item['value']
return result