From ed959b94ee8a211a270d9d89a6021e76a16bf31f Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Sun, 11 Feb 2018 16:14:31 -0500 Subject: [PATCH] Add regression test for BFV+IsolatedHostsFilter failure Creating a volume-backed server while using the IsolatedHostsFilter results in a NoValidHost failure because the filter tries to load the RequestSpec.image.id but when you create a server from a volume, an image is not required directly in the server create request. Change-Id: Id21e0afa5cec401555bee679193c256e55be863b Related-Bug: #1746483 (cherry picked from commit 4f9667b7a92ffef4329380e39c64cf314203b06e) --- .../regressions/test_bug_1746483.py | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 nova/tests/functional/regressions/test_bug_1746483.py diff --git a/nova/tests/functional/regressions/test_bug_1746483.py b/nova/tests/functional/regressions/test_bug_1746483.py new file mode 100644 index 000000000000..9e55030f31e0 --- /dev/null +++ b/nova/tests/functional/regressions/test_bug_1746483.py @@ -0,0 +1,98 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from nova import config +from nova import test +from nova.tests import fixtures as nova_fixtures +from nova.tests.functional import integrated_helpers +from nova.tests.unit.image import fake as image_fakes +from nova.tests.unit import policy_fixture +from nova import utils +from nova.virt import fake + +CONF = config.CONF + + +class TestBootFromVolumeIsolatedHostsFilter( + test.TestCase, integrated_helpers.InstanceHelperMixin): + """Regression test for bug #1746483 + + The IsolatedHostsFilter checks for images restricted to certain hosts via + config options. When creating a server from a root volume, the image is + in the volume (and it's related metadata from Cinder). When creating a + volume-backed server, the imageRef is not required. + + The regression is that the RequestSpec.image.id field is not set and the + IsolatedHostsFilter blows up trying to load the image id. + """ + def setUp(self): + super(TestBootFromVolumeIsolatedHostsFilter, self).setUp() + + self.useFixture(policy_fixture.RealPolicyFixture()) + self.useFixture(nova_fixtures.NeutronFixture(self)) + self.useFixture(nova_fixtures.CinderFixtureNewAttachFlow(self)) + self.useFixture(nova_fixtures.PlacementFixture()) + + api_fixture = self.useFixture(nova_fixtures.OSAPIFixture( + api_version='v2.1')) + + self.api = api_fixture.admin_api + + image_fakes.stub_out_image_service(self) + self.addCleanup(image_fakes.FakeImageService_reset) + + self.start_service('conductor') + + # Add the IsolatedHostsFilter to the list of enabled filters since it + # is not enabled by default. + enabled_filters = CONF.filter_scheduler.enabled_filters + enabled_filters.append('IsolatedHostsFilter') + self.flags( + enabled_filters=enabled_filters, + isolated_images=[image_fakes.AUTO_DISK_CONFIG_ENABLED_IMAGE_UUID], + isolated_hosts=['host1'], + restrict_isolated_hosts_to_isolated_images=True, + group='filter_scheduler') + self.start_service('scheduler') + + # Create two compute nodes/services so we can restrict the image + # we'll use to one of the hosts. + for host in ('host1', 'host2'): + fake.set_nodes([host]) + self.addCleanup(fake.restore_nodes) + self.start_service('compute', host=host) + + def test_boot_from_volume_with_isolated_image(self): + # Create our server without networking just to keep things simple. + image_id = nova_fixtures.CinderFixtureNewAttachFlow.IMAGE_BACKED_VOL + server_req_body = { + # There is no imageRef because this is boot from volume. + 'server': { + 'flavorRef': '1', # m1.tiny from DefaultFlavorsFixture, + 'name': 'test_boot_from_volume_with_isolated_image', + 'networks': 'none', + 'block_device_mapping_v2': [{ + 'boot_index': 0, + 'uuid': image_id, + 'source_type': 'volume', + 'destination_type': 'volume' + }] + } + } + # Note that we're using v2.1 by default but need v2.37 to use + # 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'])