summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammed Naser <mnaser@vexxhost.com>2018-11-02 12:21:26 +0100
committerMatt Riedemann <mriedem.os@gmail.com>2018-11-21 15:37:09 -0500
commitb8702ded74aad826432dcedaf65535af52835aa5 (patch)
treeb71864876e5f958f135566dfd1a33e46d1758926
parent8c663dbd25a0dab1c2d903efc7cf7fc3d9d07b00 (diff)
Default embedded instance.flavor.is_public attributestable/ocata
It is possible that really old instances don't actually have this attribute defined which can lead to raising exceptions when loading their embedded flavors from the database. This patch fixes this by defaulting these values to true if they are not set. Change-Id: If04cd802ce7184dc94f94804c743faebe0d4bd8c Closes-Bug: #1789423 (cherry picked from commit c4f6b0bf6cc903cf52c4b238c3771604dda174b8) (cherry picked from commit c689c09996c4a3da9e05ccd5178a4b5060949889) (cherry picked from commit 61bf7ae5795a3dfac7afc57bed9b4195cfdb6042) (cherry picked from commit 9a0d338c6775803516c5fdb99f0581e40957cb0c)
Notes
Notes (review): Code-Review+1: Mohammed Naser <mnaser@vexxhost.com> Code-Review+1: kangyufei <kangyf@inspur.com> Code-Review+1: Alexander Pugachev <alexander.pugachev@workday.com> Code-Review+1: Takashi NATSUME <natsume.takashi@lab.ntt.co.jp> Code-Review+1: Elod Illes <elod.illes@ericsson.com> Code-Review+2: Sean McGinnis <sean.mcginnis@gmail.com> Code-Review+2: melanie witt <melwittt@gmail.com> Workflow+1: melanie witt <melwittt@gmail.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Fri, 08 Feb 2019 05:09:49 +0000 Reviewed-on: https://review.openstack.org/619366 Project: openstack/nova Branch: refs/heads/stable/ocata
-rw-r--r--nova/objects/instance.py20
-rw-r--r--nova/tests/unit/objects/test_instance.py10
2 files changed, 19 insertions, 11 deletions
diff --git a/nova/objects/instance.py b/nova/objects/instance.py
index 6e9b7fa..6f08e8e 100644
--- a/nova/objects/instance.py
+++ b/nova/objects/instance.py
@@ -318,29 +318,31 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
318 # Before we stored flavors in instance_extra, certain fields, defined 318 # Before we stored flavors in instance_extra, certain fields, defined
319 # in nova.compute.flavors.system_metadata_flavor_props, were stored 319 # in nova.compute.flavors.system_metadata_flavor_props, were stored
320 # in the instance.system_metadata for the embedded instance.flavor. 320 # in the instance.system_metadata for the embedded instance.flavor.
321 # The "disabled" field wasn't one of those keys, however, so really 321 # The "disabled" and "is_public" fields weren't one of those keys,
322 # old instances that had their embedded flavor converted to the 322 # however, so really old instances that had their embedded flavor
323 # serialized instance_extra form won't have the disabled attribute 323 # converted to the serialized instance_extra form won't have the
324 # set and we need to default those here so callers don't explode trying 324 # disabled attribute set and we need to default those here so callers
325 # to load instance.flavor.disabled. 325 # don't explode trying to load instance.flavor.disabled.
326 def _default_disabled(flavor): 326 def _default_flavor_values(flavor):
327 if 'disabled' not in flavor: 327 if 'disabled' not in flavor:
328 flavor.disabled = False 328 flavor.disabled = False
329 if 'is_public' not in flavor:
330 flavor.is_public = True
329 331
330 flavor_info = jsonutils.loads(db_flavor) 332 flavor_info = jsonutils.loads(db_flavor)
331 333
332 self.flavor = objects.Flavor.obj_from_primitive(flavor_info['cur']) 334 self.flavor = objects.Flavor.obj_from_primitive(flavor_info['cur'])
333 _default_disabled(self.flavor) 335 _default_flavor_values(self.flavor)
334 if flavor_info['old']: 336 if flavor_info['old']:
335 self.old_flavor = objects.Flavor.obj_from_primitive( 337 self.old_flavor = objects.Flavor.obj_from_primitive(
336 flavor_info['old']) 338 flavor_info['old'])
337 _default_disabled(self.old_flavor) 339 _default_flavor_values(self.old_flavor)
338 else: 340 else:
339 self.old_flavor = None 341 self.old_flavor = None
340 if flavor_info['new']: 342 if flavor_info['new']:
341 self.new_flavor = objects.Flavor.obj_from_primitive( 343 self.new_flavor = objects.Flavor.obj_from_primitive(
342 flavor_info['new']) 344 flavor_info['new'])
343 _default_disabled(self.new_flavor) 345 _default_flavor_values(self.new_flavor)
344 else: 346 else:
345 self.new_flavor = None 347 self.new_flavor = None
346 self.obj_reset_changes(['flavor', 'old_flavor', 'new_flavor']) 348 self.obj_reset_changes(['flavor', 'old_flavor', 'new_flavor'])
diff --git a/nova/tests/unit/objects/test_instance.py b/nova/tests/unit/objects/test_instance.py
index abbd355..13359f9 100644
--- a/nova/tests/unit/objects/test_instance.py
+++ b/nova/tests/unit/objects/test_instance.py
@@ -339,8 +339,10 @@ class _TestInstanceObject(object):
339 # make sure we default the "new" flavor's disabled value to False on 339 # make sure we default the "new" flavor's disabled value to False on
340 # load from the database. 340 # load from the database.
341 fake_flavor = jsonutils.dumps( 341 fake_flavor = jsonutils.dumps(
342 {'cur': objects.Flavor(disabled=False).obj_to_primitive(), 342 {'cur': objects.Flavor(disabled=False,
343 'old': objects.Flavor(disabled=True).obj_to_primitive(), 343 is_public=True).obj_to_primitive(),
344 'old': objects.Flavor(disabled=True,
345 is_public=False).obj_to_primitive(),
344 'new': objects.Flavor().obj_to_primitive()}) 346 'new': objects.Flavor().obj_to_primitive()})
345 fake_inst = dict(self.fake_instance, extra={'flavor': fake_flavor}) 347 fake_inst = dict(self.fake_instance, extra={'flavor': fake_flavor})
346 mock_get.return_value = fake_inst 348 mock_get.return_value = fake_inst
@@ -348,6 +350,10 @@ class _TestInstanceObject(object):
348 self.assertFalse(inst.flavor.disabled) 350 self.assertFalse(inst.flavor.disabled)
349 self.assertTrue(inst.old_flavor.disabled) 351 self.assertTrue(inst.old_flavor.disabled)
350 self.assertFalse(inst.new_flavor.disabled) 352 self.assertFalse(inst.new_flavor.disabled)
353 # Assert the is_public values on the flavors
354 self.assertTrue(inst.flavor.is_public)
355 self.assertFalse(inst.old_flavor.is_public)
356 self.assertTrue(inst.new_flavor.is_public)
351 357
352 @mock.patch.object(db, 'instance_get_by_uuid') 358 @mock.patch.object(db, 'instance_get_by_uuid')
353 def test_get_remote(self, mock_get): 359 def test_get_remote(self, mock_get):