From fb723851707d6a764cb8154343087affc19e5db0 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Sun, 11 Feb 2018 16:58:02 -0500 Subject: [PATCH] Handle volume-backed instances in IsolatedHostsFilter The RequestSpec.image object for a volume-backed instance will not have the 'id' attribute set because the nova.utils.get_image_metadata_from_volume() method doesn't convert the volume['volume_image_metadata']['image_id'] into the ImageMeta.id field. It is unclear if there are intentional reasons for omitting this information, but the IsolatedHostsFilter has just never supported filtering for volume-backed instances based on a provided image id. The logic within the filter depends on the restrict_isolated_hosts_to_isolated_images config option, which defaults to True. When True, a volume-backed instance will not be put on an isolated host. When False, a volume-backed instance can go on any host, isolated or not. Again, it's unclear if we should actually be filtering volume-backed servers using the image_id from the volume_image_metadata or not, but it's not what we've historically done so this change simply fixes the regression bug. Change-Id: Ieb8abb1a3f04ce008f9617e051e4d720dbe6917a Closes-Bug: #1746483 (cherry picked from commit 0a7427dc58eeb271646a962604106e0e84b870b6) (cherry picked from commit 4c6443c0b5579853f4b87eb8302d24aca99dddab) --- nova/scheduler/filters/isolated_hosts_filter.py | 5 ++++- .../tests/functional/regressions/test_bug_1746483.py | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/nova/scheduler/filters/isolated_hosts_filter.py b/nova/scheduler/filters/isolated_hosts_filter.py index 86ab1c4ce901..3402ecd49ac7 100644 --- a/nova/scheduler/filters/isolated_hosts_filter.py +++ b/nova/scheduler/filters/isolated_hosts_filter.py @@ -59,7 +59,10 @@ class IsolatedHostsFilter(filters.BaseHostFilter): return ((not restrict_isolated_hosts_to_isolated_images) or (host_state.host not in isolated_hosts)) - image_ref = spec_obj.image.id if spec_obj.image else None + # Check to see if the image id is set since volume-backed instances + # can be created without an imageRef in the server create request. + image_ref = spec_obj.image.id \ + if spec_obj.image and 'id' in spec_obj.image else None image_isolated = image_ref in isolated_images host_isolated = host_state.host in isolated_hosts diff --git a/nova/tests/functional/regressions/test_bug_1746483.py b/nova/tests/functional/regressions/test_bug_1746483.py index b49856fc2780..73629d7bc5db 100644 --- a/nova/tests/functional/regressions/test_bug_1746483.py +++ b/nova/tests/functional/regressions/test_bug_1746483.py @@ -92,7 +92,11 @@ class TestBootFromVolumeIsolatedHostsFilter( # networks='none'. with utils.temporary_mutation(self.api, microversion='2.37'): server = self.api.post_server(server_req_body) - server = self._wait_for_state_change(self.api, server, 'ERROR') - # Due to bug 1746483 we expect scheduling to fail. - self.assertIn("Cannot load 'id' in the base class", - server['fault']['message']) + server = self._wait_for_state_change(self.api, server, 'ACTIVE') + # NOTE(mriedem): The instance is successfully scheduled but since + # the image_id from the volume_image_metadata isn't stored in the + # RequestSpec.image.id, and restrict_isolated_hosts_to_isolated_images + # is True, the isolated host (host1) is filtered out because the + # filter doesn't have enough information to know if the image within + # the volume can be used on that host. + self.assertEqual('host2', server['OS-EXT-SRV-ATTR:host'])