From 62464883e1c2ba98e1fddb1284171ca5bef4d8e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Suchomel?= Date: Tue, 21 Aug 2018 09:10:07 +0200 Subject: [PATCH] Filter out instances without a host when populating AZ It could happen that instance does not have a host set, e.g. when its creation failed before it was scheduled. During online_migration, populate_missing_availability_zones tries to add missing AZs to all instances. However for instances without a host there's no reasonable value for AZ (we can't use a logic that bases the value on a host) so let's skip this kind of instances completely. Change-Id: Ic6060beaa08af5ea70e5e54fffb94eea58aa7bbf Closes-Bug: #1788115 (cherry picked from commit 690f91b5c7f7e84a4e6d351b27c05818d947cce1) (cherry picked from commit ad14e428f82f02d71e0b33ec6d20e7810a978e3b) (cherry picked from commit 059c2d4a8a9967403755c40beda667c9463848a8) --- nova/objects/instance.py | 3 +++ nova/tests/functional/db/test_instance.py | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/nova/objects/instance.py b/nova/objects/instance.py index 1810c12a94d7..da6df09ad1bd 100644 --- a/nova/objects/instance.py +++ b/nova/objects/instance.py @@ -1222,7 +1222,10 @@ def _make_instance_list(context, inst_list, db_inst_list, expected_attrs): @db_api.pick_context_manager_writer def populate_missing_availability_zones(context, count): + # instances without host have no reasonable AZ to set + not_empty_host = models.Instance.host != None # noqa E711 instances = (context.session.query(models.Instance). + filter(not_empty_host). filter_by(availability_zone=None).limit(count).all()) count_all = len(instances) count_hit = 0 diff --git a/nova/tests/functional/db/test_instance.py b/nova/tests/functional/db/test_instance.py index 38b530134ac8..4394f557b4fb 100644 --- a/nova/tests/functional/db/test_instance.py +++ b/nova/tests/functional/db/test_instance.py @@ -50,17 +50,20 @@ class InstanceObjectTestCase(test.TestCase): uuid1 = inst1.uuid inst2 = self._create_instance(availability_zone="fake", host="fake-host2") + # ... and one without a host (simulating failed spawn) + self._create_instance(host=None) + self.assertIsNone(inst1.availability_zone) self.assertEqual("fake", inst2.availability_zone) count_all, count_hit = (objects.instance. populate_missing_availability_zones(self.context, 10)) - # we get only the instance whose avz was None. + # we get only the instance whose avz was None and where host is set self.assertEqual(1, count_all) self.assertEqual(1, count_hit) + # since instance has no avz, avz is set by get_host_availability_zone + # to CONF.default_availability_zone i.e 'nova' which is the default + # zone for compute services. inst1 = objects.Instance.get_by_uuid(self.context, uuid1) - # since instance.host was None, avz is set to - # CONF.default_availability_zone i.e 'nova' which is the default zone - # for compute services. self.assertEqual('nova', inst1.availability_zone) # create an instance with avz as None on a host that has avz.