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 690f91b5c7)
(cherry picked from commit ad14e428f8)
(cherry picked from commit 059c2d4a8a)
This commit is contained in:
Jiří Suchomel 2018-08-21 09:10:07 +02:00 committed by Matt Riedemann
parent b1b5a5eb96
commit 62464883e1
2 changed files with 10 additions and 4 deletions

View File

@ -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

View File

@ -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.